From 89ae9cd7733d6866149449db5a6d3cd12c59b814 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 13 Sep 2025 19:25:33 +0200 Subject: [PATCH] feat: Add Docker entrypoint scripts for SIDEL ScriptsManager - Implemented `docker-entrypoint-debug.sh` for debugging purposes, including environment checks and database setup. - Created `docker-entrypoint-simple.sh` for a streamlined entrypoint without debug information. - Developed `docker-entrypoint.sh` with additional checks for directory structure and environment validation. - Added `migrate_sqlite_to_postgresql.py` script for migrating data from SQLite to PostgreSQL, including backup and verification features. - Created SQL scripts for initializing the PostgreSQL database, including extensions, indexes, and default data. - Enhanced database setup procedures to support both PostgreSQL and SQLite configurations. --- .doc/Application_Specification.md | 237 +- CLEANUP-COMPLETED.md | 117 + Dockerfile | 42 +- SIDELManagerScripts/docker-manage.sh | 496 ++ .../script_groups/hammer/hammer_simulator.py | 4 +- .../hammer/simulador_hammer_interactivo.py | 1681 ------ .../script_groups/hammer/test_plantuml.py | 0 app/config/config.py | 81 +- app/config/database.py | 127 +- .../old_scripts/check_complete_log.py | 0 check_db.py => backup/old_scripts/check_db.py | 0 .../old_scripts/check_group_env.py | 0 .../old_scripts/check_log.py | 0 .../old_scripts/check_tables.py | 0 .../old_scripts/debug_discovery.py | 0 .../old_scripts/simple_debug.py | 0 .../old_scripts/test_complete_integration.py | 0 .../old_scripts/test_hammer_browser.py | 0 .../old_scripts/test_hammer_calculations.py | 0 .../old_scripts/test_helper_functions.py | 0 .../old_scripts/test_language_switching.py | 0 .../old_scripts/test_model.py | 0 .../old_scripts/test_permissions.py | 0 .../old_scripts/verify_dashboard_changes.py | 0 .../old_scripts/verify_design_changes.py | 0 .../old_scripts/verify_group5.py | 0 .../old_scripts/verify_navbar_themes.py | 0 .../old_scripts/verify_sidel_logo.py | 0 .../user_1/Hammer Test Project/config.json | 6 + .../Hammer Test Project/hammer_config.json | 19 + .../Hammer Test Project/hammer_results.json | 5030 +++++++++++++++++ .../user_1/Test Hammer Project/config.json | 6 + .../user_1/Test Project 001/config.json | 6 + .../user_1/project_default/hammer_config.json | 19 + .../project_default/hammer_results.json | 5030 +++++++++++++++++ data/scriptsmanager.db | Bin 90112 -> 0 bytes docker-compose.yml | 208 +- docker-entrypoint-debug.sh | 89 + docker-entrypoint-simple.sh | 72 + docker-entrypoint.sh | 71 + docker-manage.sh | 201 +- migrate_sqlite_to_postgresql.py | 377 ++ requirements.txt | 1 + scripts/run_app.py | 3 +- sql/01_init_database.sql | 25 + sql/02_indexes.sql | 27 + sql/03_default_data.sql | 64 + 47 files changed, 12190 insertions(+), 1849 deletions(-) create mode 100644 CLEANUP-COMPLETED.md create mode 100644 SIDELManagerScripts/docker-manage.sh delete mode 100644 app/backend/script_groups/hammer/simulador_hammer_interactivo.py delete mode 100644 app/backend/script_groups/hammer/test_plantuml.py rename check_complete_log.py => backup/old_scripts/check_complete_log.py (100%) rename check_db.py => backup/old_scripts/check_db.py (100%) rename check_group_env.py => backup/old_scripts/check_group_env.py (100%) rename check_log.py => backup/old_scripts/check_log.py (100%) rename check_tables.py => backup/old_scripts/check_tables.py (100%) rename debug_discovery.py => backup/old_scripts/debug_discovery.py (100%) rename simple_debug.py => backup/old_scripts/simple_debug.py (100%) rename test_complete_integration.py => backup/old_scripts/test_complete_integration.py (100%) rename test_hammer_browser.py => backup/old_scripts/test_hammer_browser.py (100%) rename test_hammer_calculations.py => backup/old_scripts/test_hammer_calculations.py (100%) rename test_helper_functions.py => backup/old_scripts/test_helper_functions.py (100%) rename test_language_switching.py => backup/old_scripts/test_language_switching.py (100%) rename test_model.py => backup/old_scripts/test_model.py (100%) rename test_permissions.py => backup/old_scripts/test_permissions.py (100%) rename verify_dashboard_changes.py => backup/old_scripts/verify_dashboard_changes.py (100%) rename verify_design_changes.py => backup/old_scripts/verify_design_changes.py (100%) rename verify_group5.py => backup/old_scripts/verify_group5.py (100%) rename verify_navbar_themes.py => backup/old_scripts/verify_navbar_themes.py (100%) rename verify_sidel_logo.py => backup/old_scripts/verify_sidel_logo.py (100%) create mode 100644 data/script_groups/group_3/user_1/Hammer Test Project/config.json create mode 100644 data/script_groups/group_3/user_1/Hammer Test Project/hammer_config.json create mode 100644 data/script_groups/group_3/user_1/Hammer Test Project/hammer_results.json create mode 100644 data/script_groups/group_3/user_1/Test Hammer Project/config.json create mode 100644 data/script_groups/group_3/user_1/Test Project 001/config.json create mode 100644 data/script_groups/group_3/user_1/project_default/hammer_config.json create mode 100644 data/script_groups/group_3/user_1/project_default/hammer_results.json delete mode 100755 data/scriptsmanager.db create mode 100755 docker-entrypoint-debug.sh create mode 100755 docker-entrypoint-simple.sh create mode 100755 docker-entrypoint.sh create mode 100644 migrate_sqlite_to_postgresql.py mode change 100644 => 100755 scripts/run_app.py create mode 100644 sql/01_init_database.sql create mode 100644 sql/02_indexes.sql create mode 100644 sql/03_default_data.sql diff --git a/.doc/Application_Specification.md b/.doc/Application_Specification.md index 0d84ca7..b00ce8b 100644 --- a/.doc/Application_Specification.md +++ b/.doc/Application_Specification.md @@ -1457,7 +1457,7 @@ if __name__ == '__main__': # Run Flask server print(f"Starting SIDEL script for project: {args.project_name} (Theme: {args.theme}, Language: {args.language})") - app.run(host='127.0.0.1', port=args.port, debug=False) + app.run(host='0.0.0.0', port=args.port, debug=False) ``` ### Data Management Guidelines @@ -1473,14 +1473,45 @@ if __name__ == '__main__': ### Flask Interface Requirements 1. **Port Binding**: Must bind to the exact port provided by SIDEL ScriptsManager -2. **Host Restriction**: Bind only to `127.0.0.1` for security -3. **Graceful Shutdown**: Handle SIGTERM for clean shutdown -4. **Session Management**: Maintain user context throughout session -5. **Error Reporting**: Report errors through standard logging -6. **SIDEL Branding**: Include SIDEL logo and consistent visual identity -7. **Project Context**: Display project name prominently in interface -8. **Theme Consistency**: Apply the provided theme (light/dark) throughout the interface -9. **Language Support**: Use the provided language for interface localization and messages +2. **Docker Host Binding**: Must bind to `0.0.0.0` when running in Docker containers to allow external access +3. **Local Development**: Can use `127.0.0.1` for direct host execution, but `0.0.0.0` is recommended for consistency +4. **Graceful Shutdown**: Handle SIGTERM for clean shutdown +5. **Session Management**: Maintain user context throughout session +6. **Error Reporting**: Report errors through standard logging +7. **SIDEL Branding**: Include SIDEL logo and consistent visual identity +8. **Project Context**: Display project name prominently in interface +9. **Theme Consistency**: Apply the provided theme (light/dark) throughout the interface +10. **Language Support**: Use the provided language for interface localization and messages + +### Docker Networking Requirements +For proper Docker deployment, SIDEL ScriptsManager uses **host networking mode** to ensure script interfaces are accessible: + +1. **Host Network Mode**: The main application container uses `network_mode: host` in docker-compose.yml +2. **Database Connectivity**: PostgreSQL remains in bridge network mode with port mapping for isolation +3. **Script Interface Access**: Scripts binding to `0.0.0.0` are directly accessible on host ports +4. **Port Range**: Scripts use ports 5200-5400 as configured in ScriptsManager +5. **No Port Mapping**: Host networking eliminates the need for explicit port mapping in docker-compose + +#### Example Docker Compose Configuration +```yaml +services: + scriptsmanager: + network_mode: host + environment: + - DATABASE_URL=postgresql://user:pass@localhost:5432/db + # No ports section needed with host networking + + postgres: + ports: + - "5432:5432" + # Database keeps bridge networking for isolation +``` + +#### Benefits of Host Networking +- **Simplified Configuration**: No need to map script port ranges +- **Dynamic Port Allocation**: Scripts can use any available port in the configured range +- **Better Performance**: Eliminates network address translation overhead +- **Easier Debugging**: Direct access to script interfaces without port mapping complexity ## Multi-User Data Architecture @@ -1654,17 +1685,23 @@ data/ - **WebSocket support**: For real-time log streaming ### Database Engine -**SQLite** (Recommended for cross-platform deployment) +**PostgreSQL** (Recommended for professional deployment) - **Rationale**: - - Zero-configuration setup - - Cross-platform compatibility (Linux/Windows) - - Single file database for easy backup - - Built-in Python support - - Sufficient performance for engineering script management - - No additional server requirements -- **File-based storage**: Simplifies deployment and maintenance -- **Automatic backup integration**: Single file backup with system data -- **Migration path**: Can upgrade to PostgreSQL if needed in future + - Production-ready RDBMS with ACID compliance + - Better concurrent access handling for multi-user environments + - Advanced features: JSON columns, full-text search, indexing + - Horizontal scaling capabilities for future growth + - Robust backup and recovery mechanisms +- **Docker containerization**: Isolated database service with persistent volumes +- **Development/Production parity**: Same database engine across environments +- **Connection pooling**: Built-in support for connection management +- **Migration support**: Easy schema upgrades and data migrations + +**Alternative: SQLite** (For lightweight deployments) +- **Use case**: Single-user or small team environments +- **Zero-configuration**: Suitable for quick development setup +- **File-based storage**: Simplified deployment for simple use cases +- **Limitation**: Limited concurrent access and scalability ### Python Dependencies ```bash @@ -1676,7 +1713,8 @@ flask-wtf>=1.2.0 flask-socketio>=5.3.0 # Database -sqlite3 # Built-in with Python 3.12+ +psycopg2-binary>=2.9.7 # PostgreSQL adapter for Python +SQLAlchemy>=2.0.16 # ORM with PostgreSQL support # Web Server gunicorn>=21.2.0 # Production WSGI server @@ -1708,7 +1746,82 @@ black>=23.9.0 # Code formatting flake8>=6.1.0 # Code linting ``` -### Installation Script +### Docker Multi-Container Architecture + +The application uses a multi-container Docker setup with **host networking** for better script interface accessibility: + +#### Container Structure +```yaml +# docker-compose.yml +services: + # PostgreSQL Database Container (Bridge Network) + postgres: + image: postgres:15-alpine + container_name: scriptsmanager_postgres + environment: + POSTGRES_DB: scriptsmanager + POSTGRES_USER: scriptsmanager + POSTGRES_PASSWORD: scriptsmanager_dev_password + volumes: + - postgres_data:/var/lib/postgresql/data + - ./sql:/docker-entrypoint-initdb.d + ports: + - "5432:5432" # Port mapping for database access + healthcheck: + test: ["CMD-SHELL", "pg_isready -U scriptsmanager"] + interval: 10s + timeout: 5s + retries: 5 + + # Application Container (Production) - Host Network + scriptsmanager: + build: . + network_mode: host # Critical for script interface access + environment: + - DATABASE_URL=postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager + - DEBUG=false + - PORT_RANGE_START=5200 + - PORT_RANGE_END=5400 + depends_on: + postgres: + condition: service_healthy + volumes: + - ./data:/app/data + - ./backup:/app/backup + - ./logs:/app/logs + - ./app/backend/script_groups:/app/app/backend/script_groups + + # Application Container (Development) - Host Network + scriptsmanager-dev: + build: . + network_mode: host # Critical for script interface access + environment: + - DATABASE_URL=postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager + - DEBUG=true + - PORT_RANGE_START=5200 + - PORT_RANGE_END=5400 + depends_on: + postgres: + condition: service_healthy + volumes: + - .:/app # Hot reload - entire codebase mounted + - ./backup:/app/backup + - ./logs:/app/logs + +volumes: + postgres_data: + driver: local +``` + +#### Benefits of Host Networking Architecture +- **Simplified Script Access**: Script interfaces directly accessible on host ports +- **No Port Mapping Complexity**: Dynamic port allocation without explicit mapping +- **Better Performance**: Eliminates network address translation overhead +- **Production Parity**: Same networking behavior in development and production +- **Easier Debugging**: Direct access to script interfaces for troubleshooting +- **Database Isolation**: PostgreSQL remains isolated in bridge network for security +- **Dynamic Port Range**: Scripts can use any available port in configured range (5200-5400) +- **Container Communication**: Application containers access database via localhost:5432 ```bash # Create Python 3.12+ virtual environment python3.12 -m venv scriptsmanager_env @@ -1883,27 +1996,79 @@ RestartSec=10 WantedBy=multi-user.target ``` -### Development Setup +### Development Environment + +#### Docker Development Stack +The application provides a complete Docker-based development environment with hot-reload capabilities: + ```bash -# Development environment setup -git clone scriptsmanager -cd scriptsmanager +# Start development environment +./docker-manage.sh start-dev -# Create virtual environment with Python 3.12+ -python3.12 -m venv venv -source venv/bin/activate # Linux/Mac -# venv\Scripts\activate # Windows +# Stop development environment +./docker-manage.sh stop-dev -# Install development dependencies -pip install -r requirements-dev.txt +# Check logs +./docker-manage.sh logs-dev -# Initialize development database -python scripts/init_dev_db.py - -# Start development server -flask run --debug --host=127.0.0.1 --port=5000 +# Rebuild development image +./docker-manage.sh build-dev ``` +#### Development Features +- **Hot Reload**: Code changes automatically reflected without rebuilds +- **Database Persistence**: PostgreSQL data survives container restarts +- **Debug Support**: VS Code debugging through remote containers +- **Port Forwarding**: Application accessible at localhost:5003 +- **Conda Environments**: + - `scriptsmanager`: Main Flask application + - `tsnet`: Scientific computing and analysis tools +- **Volume Mounts**: + - Source code: Live editing with hot reload + - Data directory: Persistent script storage + - Logs: Development debugging + - Backup: Development backup testing + +#### Local Development Setup (Alternative) +For developers preferring local execution: + +1. Install conda and create environments: +```bash +conda env create -f conda-environments.yml +conda activate scriptsmanager +``` + +2. Setup PostgreSQL locally: +```bash +# Install PostgreSQL +sudo apt install postgresql postgresql-contrib + +# Create database and user +sudo -u postgres psql +CREATE DATABASE scriptsmanager; +CREATE USER scriptsmanager WITH PASSWORD 'dev_password'; +GRANT ALL PRIVILEGES ON DATABASE scriptsmanager TO scriptsmanager; +``` + +3. Configure environment: +```bash +export DATABASE_URL="postgresql://scriptsmanager:dev_password@localhost:5432/scriptsmanager" +export DEBUG=true +``` + +4. Run application: +```bash +python scripts/run_app.py +``` + +#### VS Code Integration +The project includes VS Code workspace configuration for: +- Remote container development +- Python debugging with breakpoints +- Integrated terminal with conda environments +- Docker container management +- PostgreSQL database browser extensions + ### Cross-Platform Considerations - **Path Handling**: Use `pathlib.Path` for cross-platform file operations - **Process Management**: Platform-specific conda activation commands diff --git a/CLEANUP-COMPLETED.md b/CLEANUP-COMPLETED.md new file mode 100644 index 0000000..85419d3 --- /dev/null +++ b/CLEANUP-COMPLETED.md @@ -0,0 +1,117 @@ +# ✅ Limpieza de Scripts Completada + +## 📊 Resumen de la Operación + +### 🗑️ **Scripts Eliminados**: 19 archivos + +#### Scripts de Test (7 eliminados): +- `test_complete_integration.py` +- `test_hammer_browser.py` +- `test_hammer_calculations.py` +- `test_helper_functions.py` +- `test_language_switching.py` +- `test_model.py` +- `test_permissions.py` + +#### Scripts de Verificación UI (5 eliminados): +- `verify_dashboard_changes.py` +- `verify_design_changes.py` +- `verify_group5.py` +- `verify_navbar_themes.py` +- `verify_sidel_logo.py` + +#### Scripts de Debug/Check (7 eliminados): +- `check_complete_log.py` +- `check_db.py` +- `check_group_env.py` +- `check_log.py` +- `check_tables.py` +- `debug_discovery.py` +- `simple_debug.py` + +--- + +### ✅ **Scripts Mantenidos**: 3 archivos funcionales + +#### En directorio raíz: +- `demo_scriptsmanager_integration.py` - Demo de integración +- `example_script.py` - Script de ejemplo +- `migrate_execution_logs.py` - Migración de logs + +#### Scripts esenciales conservados: +- `verify-environments.sh` - **CRÍTICO** - Verificación de entornos Docker +- `app/backend/script_groups/hammer/test_plantuml.py` - Test funcional + +--- + +### 💾 **Backup Creado** + +Todos los scripts eliminados están respaldados en: +``` +backup/old_scripts/ +├── 19 archivos .py (1,177 líneas totales) +└── Accesibles para restauración si es necesario +``` + +--- + +### ✅ **Verificación Post-Limpieza** + +#### Sistema Docker Funcionando: +- ✅ **Contenedor iniciado** correctamente +- ✅ **Frontend accesible** en http://localhost:5002 (HTTP 302 → /login) +- ✅ **Entornos conda** funcionando: + - `scriptsmanager` - Python 3.12 + Flask 3.1.2 + - `tsnet` - Python 3.12 + TSNet 0.2.2 +- ✅ **Scripts de gestión** funcionando: + - `sudo ./docker-manage.sh envs` + - `sudo ./verify-environments.sh` + - `sudo ./docker-manage.sh status` + +--- + +### 🔄 **Funcionalidad Reemplazada** + +Los scripts eliminados ahora se reemplazan con: + +#### En lugar de test_*.py: +```bash +sudo ./docker-manage.sh health +sudo ./verify-environments.sh +``` + +#### En lugar de verify_*.py: +```bash +sudo ./docker-manage.sh status +sudo ./docker-manage.sh logs +curl -I http://localhost:5002 +``` + +#### En lugar de debug_*.py y check_*.py: +```bash +sudo ./docker-manage.sh shell +sudo ./docker-manage.sh logs +sudo ./docker-manage.sh envs +``` + +--- + +### 📈 **Impacto de la Limpieza** + +- **Archivos .py en raíz**: 22 → 3 (86% reducción) +- **Líneas de código eliminadas**: 1,177 líneas +- **Mantenibilidad**: ✅ Mejorada (menos archivos obsoletos) +- **Funcionalidad**: ✅ Conservada (comandos Docker modernos) + +--- + +### 🎯 **Estado Final** + +El workspace está ahora **limpio y organizado** con: +- ✅ **Solo scripts necesarios** mantenidos +- ✅ **Funcionalidad completa** preservada +- ✅ **Sistema Docker** completamente funcional +- ✅ **Backup seguro** de scripts eliminados +- ✅ **Comandos modernos** reemplazan funcionalidad antigua + +**🏁 Limpieza completada exitosamente!** \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fca834e..46a3b91 100644 --- a/Dockerfile +++ b/Dockerfile @@ -67,6 +67,9 @@ ENV PATH /opt/conda/envs/$CONDA_ENV_NAME/bin:$PATH # Instalar dependencias Python en el entorno principal (ScriptsManager) RUN /opt/conda/envs/$CONDA_ENV_NAME/bin/pip install --no-cache-dir -r requirements.txt +# Instalar psycopg2 usando conda para mejor compatibilidad +RUN /opt/conda/bin/conda install -n $CONDA_ENV_NAME -c conda-forge psycopg2 -y + # Crear entorno específico para TSNet (Water Hammer Simulator) RUN conda create -n $TSNET_ENV_NAME python=3.12 -y @@ -101,45 +104,18 @@ RUN if [ -d "backend/script_groups" ]; then \ fi # Configurar usuario y permisos para evitar problemas con volúmenes -RUN groupadd -r scriptsmanager && useradd -r -g scriptsmanager -d /app -s /bin/bash scriptsmanager +# Usar UID 1000 para compatibilidad con el usuario del host +RUN groupadd -g 1000 scriptsmanager && useradd -u 1000 -g 1000 -d /app -s /bin/bash scriptsmanager -# Establecer permisos correctos +# Establecer permisos correctos y crear directorios para el usuario scriptsmanager RUN chmod +x scripts/*.py && \ + mkdir -p data instance logs/{executions,system,audit} backup/daily && \ chown -R scriptsmanager:scriptsmanager $APP_HOME && \ chmod 755 $DATA_HOME $BACKUP_HOME $LOGS_HOME && \ chown -R scriptsmanager:scriptsmanager $DATA_HOME $BACKUP_HOME $LOGS_HOME -# Crear script de inicialización específico para SIDEL ScriptsManager -RUN echo '#!/bin/bash\n\ -set -e\n\ -echo "=== SIDEL ScriptsManager Initialization ==="\n\ -source activate scriptsmanager\n\ -cd /app\n\ -\n\ -# Verificar estructura de directorios\n\ -echo "Checking directory structure..."\n\ -if [ ! -d "app/backend/script_groups" ]; then\n\ - echo "ERROR: app/backend/script_groups directory not found!"\n\ - exit 1\n\ -fi\n\ -\n\ -# Inicializar base de datos SQLite\n\ -echo "Initializing SQLite database..."\n\ -python scripts/init_db.py\n\ -\n\ -# Verificar entornos conda\n\ -echo "Available conda environments:"\n\ -conda env list\n\ -\n\ -echo "ScriptsManager environment packages:"\n\ -conda list -n scriptsmanager | grep -E "(flask|sqlalchemy)" || true\n\ -\n\ -echo "TSNet environment packages:"\n\ -conda list -n tsnet | grep -E "(tsnet|numpy|matplotlib)" || true\n\ -\n\ -echo "=== Starting SIDEL ScriptsManager ==="\n\ -exec "$@"' > /app/docker-entrypoint.sh - +# Copiar script de inicialización específico para SIDEL ScriptsManager +COPY docker-entrypoint-debug.sh /app/docker-entrypoint.sh RUN chmod +x /app/docker-entrypoint.sh # Puerto principal del frontend (5002) y rango dinámico (5200-5400) diff --git a/SIDELManagerScripts/docker-manage.sh b/SIDELManagerScripts/docker-manage.sh new file mode 100644 index 0000000..70b11db --- /dev/null +++ b/SIDELManagerScripts/docker-manage.sh @@ -0,0 +1,496 @@ +#!/bin/bash + +# Script de gestión Docker para SIDEL ScriptsManager +# Compatible con las especificaciones del proyecto +# Uso: ./docker-manage.sh [comando] + +set -e + +# Colores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +NC='\033[0m' # No Color + +# Variables del proyecto SIDEL +SIDEL_APP_PORT=5002 +SIDEL_DEV_PORT=5003 +SIDEL_SCRIPT_PORT_RANGE="5200-5400" +SIDEL_CONTAINER_NAME="sidel_scriptsmanager" +SIDEL_DEV_CONTAINER_NAME="sidel_scriptsmanager_dev" + +# Función para mostrar banner SIDEL +show_banner() { + echo -e "${BLUE}================================================================${NC}" + echo -e "${BLUE} SIDEL ScriptsManager - Docker Management ${NC}" + echo -e "${BLUE}================================================================${NC}" + echo -e "${PURPLE}Multi-User Script Manager with Conda Environments${NC}" + echo -e "${PURPLE}Frontend Port: ${SIDEL_APP_PORT} | Script Ports: ${SIDEL_SCRIPT_PORT_RANGE}${NC}" + echo -e "${BLUE}================================================================${NC}" + echo "" +} + +# Función para mostrar ayuda +show_help() { + show_banner + echo "Uso: $0 [comando]" + echo "" + echo "Comandos disponibles:" + echo -e " ${GREEN}build${NC} Construir la imagen Docker" + echo -e " ${GREEN}start${NC} Iniciar SIDEL ScriptsManager en producción" + echo -e " ${GREEN}start-dev${NC} Iniciar en modo desarrollo con hot-reload" + echo -e " ${GREEN}start-backup${NC} Iniciar servicio de backup automático" + echo -e " ${GREEN}start-monitoring${NC} Iniciar servicio de monitoreo de logs" + echo -e " ${GREEN}stop${NC} Detener todos los contenedores" + echo -e " ${GREEN}restart${NC} Reiniciar el contenedor principal" + echo -e " ${GREEN}logs${NC} Mostrar logs del contenedor principal" + echo -e " ${GREEN}logs-dev${NC} Mostrar logs del contenedor de desarrollo" + echo -e " ${GREEN}shell${NC} Abrir shell en el contenedor principal" + echo -e " ${GREEN}shell-dev${NC} Abrir shell en el contenedor de desarrollo" + echo -e " ${GREEN}backup${NC} Ejecutar backup manual del sistema" + echo -e " ${GREEN}clean${NC} Limpiar contenedores e imágenes no utilizadas" + echo -e " ${GREEN}reset${NC} Resetear completamente (¡CUIDADO: Borra datos!)" + echo -e " ${GREEN}status${NC} Mostrar estado de los contenedores" + echo -e " ${GREEN}envs${NC} Listar entornos conda disponibles" + echo -e " ${GREEN}health${NC} Verificar salud de la aplicación" + echo -e " ${GREEN}init-db${NC} Inicializar base de datos SIDEL" + echo -e " ${GREEN}verify${NC} Verificar configuración y entornos" + echo -e " ${GREEN}ports${NC} Mostrar puertos en uso" + echo -e " ${GREEN}users${NC} Gestionar usuarios (requiere shell activo)" + echo "" + echo "Servicios opcionales (perfiles):" + echo -e " ${YELLOW}--profile dev${NC} Modo desarrollo" + echo -e " ${YELLOW}--profile backup${NC} Backup automático" + echo -e " ${YELLOW}--profile monitoring${NC} Monitoreo de logs" + echo "" + echo "Ejemplos:" + echo " $0 build && $0 start" + echo " $0 start-dev" + echo " $0 logs -f" + echo " $0 verify" +} + +# Función para verificar si docker-compose está disponible +check_docker_compose() { + # Verificar permisos de Docker primero + if ! docker ps &> /dev/null; then + echo -e "${RED}Error: No tienes permisos para acceder a Docker${NC}" + echo -e "${YELLOW}Soluciones posibles:${NC}" + echo "1. Reinicia tu terminal/WSL después de agregar tu usuario al grupo docker" + echo "2. O ejecuta: sudo usermod -aG docker \$USER && newgrp docker" + echo "3. O usa sudo: sudo ./docker-manage.sh [comando]" + echo "4. O ejecuta: su - \$USER (para recargar grupos)" + exit 1 + fi + + if command -v docker-compose &> /dev/null; then + DOCKER_COMPOSE="docker-compose" + elif docker compose version &> /dev/null; then + DOCKER_COMPOSE="docker compose" + else + echo -e "${RED}Error: docker-compose no está disponible${NC}" + echo -e "${YELLOW}Instalando docker-compose...${NC}" + + # Intentar instalar docker-compose + if command -v apt &> /dev/null; then + sudo apt update && sudo apt install -y docker-compose + elif command -v yum &> /dev/null; then + sudo yum install -y docker-compose + else + echo "Por favor instala docker-compose manualmente" + exit 1 + fi + + # Verificar nuevamente + if command -v docker-compose &> /dev/null; then + DOCKER_COMPOSE="docker-compose" + else + exit 1 + fi + fi +} + +# Función para construir la imagen +build_image() { + show_banner + echo -e "${BLUE}Construyendo imagen Docker para SIDEL ScriptsManager...${NC}" + check_docker_compose + + # Verificar estructura de directorios antes de construir + if [ -d "backend/script_groups" ]; then + echo -e "${RED}❌ ERROR: Encontrado directorio incorrecto 'backend/script_groups/'${NC}" + echo -e "${RED} Según especificaciones SIDEL, los scripts deben estar en 'app/backend/script_groups/' únicamente${NC}" + exit 1 + fi + + if [ ! -d "app/backend/script_groups" ]; then + echo -e "${YELLOW}⚠️ Creando directorio app/backend/script_groups/...${NC}" + mkdir -p app/backend/script_groups/hammer + mkdir -p app/backend/script_groups/data_processing + mkdir -p app/backend/script_groups/system_utilities + fi + + $DOCKER_COMPOSE build scriptsmanager + echo -e "${GREEN}✅ Imagen SIDEL ScriptsManager construida exitosamente${NC}" +} + +# Función para iniciar en producción +start_production() { + show_banner + echo -e "${BLUE}Iniciando SIDEL ScriptsManager en modo producción...${NC}" + check_docker_compose + + # Crear directorios necesarios según especificaciones SIDEL + echo -e "${BLUE}Preparando estructura de directorios...${NC}" + mkdir -p data/script_groups data/system + mkdir -p logs/executions logs/system logs/audit + mkdir -p backup/daily + mkdir -p instance + + # Copiar archivo de entorno si no existe + if [ ! -f .env ]; then + echo -e "${YELLOW}Creando archivo .env desde .env.example${NC}" + cp .env.example .env + echo -e "${YELLOW}¡IMPORTANTE: Edita el archivo .env con tus configuraciones de producción!${NC}" + fi + + $DOCKER_COMPOSE up -d scriptsmanager + echo -e "${GREEN}✅ SIDEL ScriptsManager iniciado en http://localhost:${SIDEL_APP_PORT}${NC}" + echo -e "${BLUE}📊 Dashboard multiusuario disponible${NC}" + echo -e "${BLUE}🔧 Scripts TSNet en puertos ${SIDEL_SCRIPT_PORT_RANGE}${NC}" +} + +# Función para iniciar en desarrollo +start_development() { + show_banner + echo -e "${BLUE}Iniciando SIDEL ScriptsManager en modo desarrollo...${NC}" + check_docker_compose + + mkdir -p data/script_groups data/system + mkdir -p logs/executions logs/system logs/audit + mkdir -p backup/daily + + if [ ! -f .env ]; then + cp .env.example .env + fi + + $DOCKER_COMPOSE --profile dev up -d scriptsmanager-dev + echo -e "${GREEN}✅ SIDEL ScriptsManager (desarrollo) iniciado en http://localhost:${SIDEL_DEV_PORT}${NC}" + echo -e "${BLUE}🔄 Hot-reload activado para desarrollo${NC}" +} + +# Función para iniciar backup automático +start_backup_service() { + show_banner + echo -e "${BLUE}Iniciando servicio de backup automático...${NC}" + check_docker_compose + $DOCKER_COMPOSE --profile backup up -d backup + echo -e "${GREEN}✅ Servicio de backup automático iniciado${NC}" + echo -e "${BLUE}📦 Backups diarios programados${NC}" +} + +# Función para iniciar monitoreo +start_monitoring() { + show_banner + echo -e "${BLUE}Iniciando servicio de monitoreo de logs...${NC}" + check_docker_compose + $DOCKER_COMPOSE --profile monitoring up -d log-monitor + echo -e "${GREEN}✅ Servicio de monitoreo iniciado${NC}" + echo -e "${BLUE}📊 Monitoreo de logs multiusuario activado${NC}" +} + +# Función para detener contenedores +stop_containers() { + echo -e "${BLUE}Deteniendo contenedores...${NC}" + check_docker_compose + $DOCKER_COMPOSE down + echo -e "${GREEN}Contenedores detenidos${NC}" +} + +# Función para reiniciar +restart_container() { + echo -e "${BLUE}Reiniciando contenedor principal...${NC}" + check_docker_compose + $DOCKER_COMPOSE restart scriptsmanager + echo -e "${GREEN}Contenedor reiniciado${NC}" +} + +# Función para mostrar logs +show_logs() { + check_docker_compose + $DOCKER_COMPOSE logs "${@:2}" scriptsmanager +} + +# Función para mostrar logs de desarrollo +show_dev_logs() { + check_docker_compose + $DOCKER_COMPOSE logs "${@:2}" scriptsmanager-dev +} + +# Función para abrir shell +open_shell() { + check_docker_compose + echo -e "${BLUE}Abriendo shell en el contenedor...${NC}" + $DOCKER_COMPOSE exec scriptsmanager bash +} + +# Función para abrir shell de desarrollo +open_dev_shell() { + check_docker_compose + echo -e "${BLUE}Abriendo shell en el contenedor de desarrollo...${NC}" + $DOCKER_COMPOSE exec scriptsmanager-dev bash +} + +# Función para backup manual +manual_backup() { + echo -e "${BLUE}Ejecutando backup manual...${NC}" + check_docker_compose + $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python -c 'from app.services.backup_service import BackupService; BackupService().create_backup()'" + echo -e "${GREEN}Backup completado${NC}" +} + +# Función para limpiar Docker +clean_docker() { + echo -e "${YELLOW}Limpiando contenedores e imágenes no utilizadas...${NC}" + docker system prune -f + echo -e "${GREEN}Limpieza completada${NC}" +} + +# Función para reset completo +reset_all() { + echo -e "${RED}¡ADVERTENCIA! Esto eliminará todos los datos y contenedores.${NC}" + read -p "¿Estás seguro? (escribe 'yes' para continuar): " -r + if [[ $REPLY == "yes" ]]; then + check_docker_compose + $DOCKER_COMPOSE down -v + docker system prune -af + sudo rm -rf data/* backup/* logs/* + echo -e "${GREEN}Reset completado${NC}" + else + echo -e "${YELLOW}Operación cancelada${NC}" + fi +} + +# Función para mostrar estado +show_status() { + echo -e "${BLUE}Estado de los contenedores:${NC}" + check_docker_compose + $DOCKER_COMPOSE ps +} + +# Función para listar entornos conda +list_conda_envs() { + echo -e "${BLUE}Entornos conda disponibles:${NC}" + check_docker_compose + $DOCKER_COMPOSE exec scriptsmanager bash -c "conda env list" +} + +# Función para verificar salud +health_check() { + echo -e "${BLUE}Verificando salud de SIDEL ScriptsManager...${NC}" + if curl -f http://localhost:${SIDEL_APP_PORT}/health >/dev/null 2>&1; then + echo -e "${GREEN}✓ Aplicación saludable en puerto ${SIDEL_APP_PORT}${NC}" + else + echo -e "${RED}✗ Aplicación no responde en puerto ${SIDEL_APP_PORT}${NC}" + exit 1 + fi +} + +# Función para inicializar base de datos SIDEL +init_database() { + show_banner + echo -e "${BLUE}Inicializando base de datos SIDEL ScriptsManager...${NC}" + check_docker_compose + + if ! docker ps | grep -q $SIDEL_CONTAINER_NAME; then + echo -e "${YELLOW}Contenedor no está ejecutándose. Iniciando temporalmente...${NC}" + $DOCKER_COMPOSE up -d scriptsmanager + sleep 10 + fi + + $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python scripts/init_sidel_db.py" + echo -e "${GREEN}✅ Base de datos SIDEL inicializada${NC}" +} + +# Función para verificar configuración completa +verify_configuration() { + show_banner + echo -e "${BLUE}Verificando configuración SIDEL ScriptsManager...${NC}" + + echo -e "${BLUE}📁 Verificando estructura de directorios...${NC}" + + # Verificar directorios críticos + if [ ! -d "app/backend/script_groups" ]; then + echo -e "${RED}❌ app/backend/script_groups/ no encontrado${NC}" + return 1 + else + echo -e "${GREEN}✅ app/backend/script_groups/ correcto${NC}" + fi + + if [ -d "backend/script_groups" ]; then + echo -e "${RED}❌ backend/script_groups/ existe (NO debería existir)${NC}" + return 1 + else + echo -e "${GREEN}✅ backend/script_groups/ no existe (correcto)${NC}" + fi + + # Verificar archivos de configuración + if [ -f "requirements.txt" ]; then + echo -e "${GREEN}✅ requirements.txt encontrado${NC}" + else + echo -e "${RED}❌ requirements.txt no encontrado${NC}" + fi + + if [ -f "app/backend/script_groups/hammer/requirements.txt" ]; then + echo -e "${GREEN}✅ TSNet requirements.txt encontrado${NC}" + else + echo -e "${RED}❌ TSNet requirements.txt no encontrado${NC}" + fi + + # Verificar contenedor si está ejecutándose + if docker ps | grep -q $SIDEL_CONTAINER_NAME; then + echo -e "${BLUE}🐳 Verificando entornos conda en contenedor...${NC}" + + # Verificar entornos conda + echo -e "${BLUE}📋 Entornos conda disponibles:${NC}" + $DOCKER_COMPOSE exec scriptsmanager conda env list + + echo -e "${BLUE}🔍 Verificando paquetes en entorno scriptsmanager:${NC}" + $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && python -c 'import flask, flask_socketio; print(f\"Flask: {flask.__version__}, SocketIO: {flask_socketio.__version__}\")'" + + echo -e "${BLUE}🔍 Verificando paquetes en entorno tsnet:${NC}" + $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate tsnet && python -c 'import numpy, matplotlib; print(f\"NumPy: {numpy.__version__}, Matplotlib: {matplotlib.__version__}\")'" + + # Verificar puertos + echo -e "${BLUE}🔌 Verificando puertos:${NC}" + if curl -s http://localhost:${SIDEL_APP_PORT} >/dev/null; then + echo -e "${GREEN}✅ Puerto ${SIDEL_APP_PORT} (frontend) accesible${NC}" + else + echo -e "${YELLOW}⚠️ Puerto ${SIDEL_APP_PORT} (frontend) no accesible${NC}" + fi + else + echo -e "${YELLOW}⚠️ Contenedor no está ejecutándose${NC}" + echo -e "${BLUE}💡 Ejecuta: $0 start${NC}" + fi + + echo -e "${GREEN}✅ Verificación completada${NC}" +} + +# Función para mostrar puertos en uso +show_ports() { + show_banner + echo -e "${BLUE}Estado de puertos SIDEL ScriptsManager:${NC}" + echo "" + echo -e "${BLUE}Puerto Frontend:${NC} ${SIDEL_APP_PORT}" + echo -e "${BLUE}Puerto Desarrollo:${NC} ${SIDEL_DEV_PORT}" + echo -e "${BLUE}Rango Scripts:${NC} ${SIDEL_SCRIPT_PORT_RANGE}" + echo "" + + if command -v netstat >/dev/null 2>&1; then + echo -e "${BLUE}Puertos actualmente en uso:${NC}" + netstat -tlnp 2>/dev/null | grep -E ":(5002|5003|520[0-9]|53[0-9][0-9]|5400)" || echo "Ningún puerto SIDEL en uso" + elif command -v ss >/dev/null 2>&1; then + echo -e "${BLUE}Puertos actualmente en uso:${NC}" + ss -tlnp | grep -E ":(5002|5003|520[0-9]|53[0-9][0-9]|5400)" || echo "Ningún puerto SIDEL en uso" + else + echo -e "${YELLOW}⚠️ netstat/ss no disponible para verificar puertos${NC}" + fi +} + +# Función para gestión de usuarios +manage_users() { + show_banner + echo -e "${BLUE}Gestión de usuarios SIDEL ScriptsManager${NC}" + + if ! docker ps | grep -q $SIDEL_CONTAINER_NAME; then + echo -e "${RED}❌ El contenedor no está ejecutándose${NC}" + echo -e "${BLUE}💡 Ejecuta: $0 start${NC}" + return 1 + fi + + echo -e "${BLUE}Abriendo shell para gestión de usuarios...${NC}" + echo -e "${YELLOW}Comandos útiles:${NC}" + echo " - python scripts/create_admin.py --username --password " + echo " - python scripts/list_users.py" + echo " - python scripts/manage_users.py" + echo "" + + $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && bash" +} + +# Script principal +case "${1:-help}" in + build) + build_image + ;; + start) + start_production + ;; + start-dev) + start_development + ;; + start-backup) + start_backup_service + ;; + start-monitoring) + start_monitoring + ;; + stop) + stop_containers + ;; + restart) + restart_container + ;; + logs) + show_logs "$@" + ;; + logs-dev) + show_dev_logs "$@" + ;; + shell) + open_shell + ;; + shell-dev) + open_dev_shell + ;; + backup) + manual_backup + ;; + clean) + clean_docker + ;; + reset) + reset_all + ;; + status) + show_status + ;; + envs) + list_conda_envs + ;; + health) + health_check + ;; + init-db) + init_database + ;; + verify) + verify_configuration + ;; + ports) + show_ports + ;; + users) + manage_users + ;; + help|--help|-h) + show_help + ;; + *) + echo -e "${RED}Comando desconocido: $1${NC}" + show_help + exit 1 + ;; +esac \ No newline at end of file diff --git a/app/backend/script_groups/hammer/hammer_simulator.py b/app/backend/script_groups/hammer/hammer_simulator.py index 48e1fb0..e8cf2dd 100644 --- a/app/backend/script_groups/hammer/hammer_simulator.py +++ b/app/backend/script_groups/hammer/hammer_simulator.py @@ -1719,14 +1719,16 @@ def main(): if "WERKZEUG_RUN_MAIN" in os.environ: del os.environ["WERKZEUG_RUN_MAIN"] + execution_logger.log_info("About to start SocketIO server") socketio.run( app, - host="127.0.0.1", + host="0.0.0.0", port=args.port, debug=False, allow_unsafe_werkzeug=True, use_reloader=False, # Disable reloader to avoid fd conflicts ) + execution_logger.log_info("SocketIO server ended") except KeyboardInterrupt: execution_logger.log_session_event("interrupted_by_user") diff --git a/app/backend/script_groups/hammer/simulador_hammer_interactivo.py b/app/backend/script_groups/hammer/simulador_hammer_interactivo.py deleted file mode 100644 index 9ae0da3..0000000 --- a/app/backend/script_groups/hammer/simulador_hammer_interactivo.py +++ /dev/null @@ -1,1681 +0,0 @@ -""" -Simulatore Interattivo del Colpo d'Ariete (Water Hammer) -Sistema di Pompaggio Sciroppo con Interfaccia Grafica - -Permette di modificare i parametri in modo interattivo e visualizzare gli effetti -del transitorio idraulico in tempo reale. - -Autore: Generato con GitHub Copilot -Data: Settembre 2025 -""" - -import tkinter as tk -from tkinter import ttk, messagebox -import matplotlib.pyplot as plt -from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from matplotlib.figure import Figure -import numpy as np -import threading -import time -import tempfile -import math -import os -import tsnet - - -class SimuladorWaterHammerInteractivo: - def __init__(self, root): - self.root = root - self.root.title("Simulatore Colpo d'Ariete - Sistema Sciroppo") - self.root.geometry("1400x900") - - # Variables del sistema (valores por defecto) - self.params = { - "longitud_tuberia": tk.DoubleVar(value=300.0), - "diametro_tuberia": tk.DoubleVar(value=0.065), # 80mm - "espesor_pared": tk.DoubleVar(value=0.003), # 3mm - "rugosidad": tk.DoubleVar(value=1.5e-6), # acero inox - "caudal_nominal": tk.DoubleVar(value=22000.0), # L/h - "presion_bomba": tk.DoubleVar(value=7.0), # bar - "densidad_fluido": tk.DoubleVar(value=1100.0), # kg/m³ jarabe - "temperatura_fluido": tk.DoubleVar(value=20.0), # °C - "modulo_bulk": tk.DoubleVar(value=2.2e9), # Pa - "modulo_young": tk.DoubleVar(value=200e9), # Pa acero - "tiempo_cierre": tk.DoubleVar(value=2.0), # segundos - # Parámetros del damper (amortiguador hidropneumático) - "damper_habilitado": tk.BooleanVar(value=False), # Si está instalado - "damper_volumen": tk.DoubleVar(value=50.0), # Litros totales - "damper_presion_precarga": tk.DoubleVar(value=4.0), # bar (N2) - "damper_porcentaje_gas": tk.DoubleVar(value=60.0), # % gas - "damper_posicion": tk.DoubleVar(value=280.0), # metros desde bomba - "damper_diametro_conexion": tk.DoubleVar(value=0.05), # metros - "damper_longitud_conexion": tk.DoubleVar(value=0.5), # metros - "tiempo_simulacion": tk.DoubleVar(value=10.0), # segundos - } - - # Variables calculadas - self.resultados = { - "velocidad_onda": 0.0, - "tiempo_critico": 0.0, - "sobrepresion_joukowsky": 0.0, - "sobrepresion_real": 0.0, - "factor_reduccion": 0.0, - "velocidad_fluido": 0.0, - # Parámetros específicos del damper - "damper_eficiencia": 0.0, - "damper_volumen_efectivo": 0.0, - "damper_compresibilidad": 0.0, - } - - self.configurar_interfaz() - self.calcular_parametros() - self.simular_transitorio() - - def configurar_interfaz(self): - """Configura la interfaz gráfica""" - - # Frame principal dividido en tres columnas - main_frame = ttk.Frame(self.root) - main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) - - # Columna izquierda: Parámetros - self.crear_panel_parametros(main_frame) - - # Columna central: Gráficos - self.crear_panel_graficos(main_frame) - - # Columna derecha: Resultados - self.crear_panel_resultados(main_frame) - - def crear_panel_parametros(self, parent): - """Crea el panel de parámetros editables""" - - # Frame para parámetros - param_frame = ttk.LabelFrame(parent, text="Parametri del Sistema", padding=10) - param_frame.grid(row=0, column=0, sticky="nsew", padx=(0, 5)) - - # Configurar grid - parent.columnconfigure(0, weight=0, minsize=350) - parent.columnconfigure(1, weight=1) - parent.columnconfigure(2, weight=0, minsize=300) - parent.rowconfigure(0, weight=1) - - row = 0 - - # Parámetros geométricos - ttk.Label(param_frame, text="GEOMETRIA", font=("Arial", 10, "bold")).grid( - row=row, column=0, columnspan=2, sticky="w", pady=(0, 5) - ) - row += 1 - - self.crear_entrada( - "Lunghezza tubazione (m):", - self.params["longitud_tuberia"], - param_frame, - row, - rango=(50, 1000), - ) - row += 1 - - self.crear_entrada( - "Diametro interno (mm):", - self.params["diametro_tuberia"], - param_frame, - row, - factor=1000, - rango=(20, 200), - ) - row += 1 - - self.crear_entrada( - "Spessore parete (mm):", - self.params["espesor_pared"], - param_frame, - row, - factor=1000, - rango=(1, 10), - ) - row += 1 - - # Separador - ttk.Separator(param_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Parámetros operacionales - ttk.Label(param_frame, text="OPERAZIONE", font=("Arial", 10, "bold")).grid( - row=row, column=0, columnspan=2, sticky="w", pady=(0, 5) - ) - row += 1 - - self.crear_entrada( - "Portata nominale (L/h):", - self.params["caudal_nominal"], - param_frame, - row, - rango=(1000, 50000), - ) - row += 1 - - self.crear_entrada( - "Pressione pompa (bar):", - self.params["presion_bomba"], - param_frame, - row, - rango=(1, 20), - ) - row += 1 - - self.crear_entrada( - "Tempo chiusura valvola (s):", - self.params["tiempo_cierre"], - param_frame, - row, - rango=(0.1, 20), - ) - row += 1 - - # Separador - ttk.Separator(param_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Parámetros del fluido - ttk.Label( - param_frame, text="FLUIDO (SCIROPPO)", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=2, sticky="w", pady=(0, 5)) - row += 1 - - self.crear_entrada( - "Densità (kg/m³):", - self.params["densidad_fluido"], - param_frame, - row, - rango=(1000, 1500), - ) - row += 1 - - self.crear_entrada( - "Temperatura (°C):", - self.params["temperatura_fluido"], - param_frame, - row, - rango=(-10, 80), - ) - row += 1 - - # Combo para módulo bulk con valores predefinidos - self.crear_combo_modulo_bulk(param_frame, row) - row += 1 - - # Separador - ttk.Separator(param_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Parámetros de material de tubería - ttk.Label(param_frame, text="TUBERÍA", font=("Arial", 10, "bold")).grid( - row=row, column=0, columnspan=2, sticky="w", pady=(0, 5) - ) - row += 1 - - self.crear_entrada( - "Rugosidad (mm):", - self.params["rugosidad"], - param_frame, - row, - factor=1000, - rango=(0.001, 0.5), - ) - row += 1 - - self.crear_entrada( - "Módulo Young (GPa):", - self.params["modulo_young"], - param_frame, - row, - factor=1e-9, - rango=(150, 250), - ) - row += 1 - - # Separador - ttk.Separator(param_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Parámetros de protección - Damper hidropneumático - ttk.Label( - param_frame, text="DAMPER IDROPNEUMATICO", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=2, sticky="w", pady=(0, 5)) - row += 1 - - # Checkbox para habilitar damper - damper_check = ttk.Checkbutton( - param_frame, - text="Damper installato", - variable=self.params["damper_habilitado"], - ) - damper_check.grid(row=row, column=0, columnspan=2, sticky="w", pady=2) - self.params["damper_habilitado"].trace_add("write", self.on_parameter_change) - row += 1 - - self.crear_entrada( - "Volume totale (L):", - self.params["damper_volumen"], - param_frame, - row, - rango=(10, 200), - ) - row += 1 - - self.crear_entrada( - "Pressione precarico N₂ (bar):", - self.params["damper_presion_precarga"], - param_frame, - row, - rango=(1, 10), - ) - row += 1 - - self.crear_entrada( - "Percentuale gas (%):", - self.params["damper_porcentaje_gas"], - param_frame, - row, - rango=(40, 90), - ) - row += 1 - - self.crear_entrada( - "Posizione nella tubazione (m):", - self.params["damper_posicion"], - param_frame, - row, - rango=(50, 350), - ) - row += 1 - - # Botón para configuración avanzada del damper - ttk.Button( - param_frame, - text="Configura Damper", - command=self.configurar_damper_avanzado, - width=20, - ).grid(row=row, column=0, columnspan=2, pady=5) - row += 1 - - # Separador - ttk.Separator(param_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - self.crear_entrada( - "Tempo simulazione (s):", - self.params["tiempo_simulacion"], - param_frame, - row, - rango=(5, 30), - ) - row += 1 - - # Botones - ttk.Button( - param_frame, text="Ricalcola", command=self.recalcular, width=15 - ).grid(row=row, column=0, pady=10, sticky="w") - - ttk.Button( - param_frame, text="Reset", command=self.resetear_valores, width=15 - ).grid(row=row, column=1, pady=10, sticky="e") - row += 1 - - # Presets - ttk.Label(param_frame, text="PRESET:", font=("Arial", 9, "bold")).grid( - row=row, column=0, columnspan=2, sticky="w", pady=(10, 5) - ) - row += 1 - - ttk.Button( - param_frame, - text="Chiusura Rapida", - command=lambda: self.aplicar_preset("rapido"), - width=15, - ).grid(row=row, column=0, pady=2, sticky="w") - - ttk.Button( - param_frame, - text="Chiusura Lenta", - command=lambda: self.aplicar_preset("lento"), - width=15, - ).grid(row=row, column=1, pady=2, sticky="e") - row += 1 - - ttk.Button( - param_frame, - text="Con Damper", - command=lambda: self.aplicar_preset("damper"), - width=15, - ).grid(row=row, column=0, pady=2, sticky="w") - - ttk.Button( - param_frame, - text="Sistema Critico", - command=lambda: self.aplicar_preset("critico"), - width=15, - ).grid(row=row, column=1, pady=2, sticky="e") - - def crear_entrada(self, etiqueta, variable, parent, row, factor=1, rango=None): - """Crea una entrada con etiqueta y validación""" - - ttk.Label(parent, text=etiqueta).grid(row=row, column=0, sticky="w", pady=2) - - # Crear spinbox con rango si se especifica - if rango: - spinbox = ttk.Spinbox( - parent, - from_=rango[0], - to=rango[1], - increment=(rango[1] - rango[0]) / 100, - textvariable=variable, - width=15, - format="%.3f", - ) - else: - spinbox = ttk.Entry(parent, textvariable=variable, width=15) - - spinbox.grid(row=row, column=1, sticky="e", pady=2) - - # Configurar callback para recálculo automático - variable.trace_add("write", self.on_parameter_change) - - return spinbox - - def crear_combo_modulo_bulk(self, parent, row): - """Crea un combo con valores predefinidos de módulo bulk""" - - ttk.Label(parent, text="Modulo bulk:").grid( - row=row, column=0, sticky="w", pady=2 - ) - - # Frame para combo + entrada manual - combo_frame = ttk.Frame(parent) - combo_frame.grid(row=row, column=1, sticky="e", pady=2) - - # Valores predefinidos (GPa) - valores_bulk = { - "Agua (20°C)": 2.2, - "Jarabe concentrado": 2.2, - "Aceite hidráulico": 1.7, - "Glicerina": 4.5, - "Alcohol etílico": 1.0, - "Gasolina": 1.3, - "Leche": 2.0, - "Personalizado": None, - } - - # Combo - self.combo_bulk = ttk.Combobox( - combo_frame, values=list(valores_bulk.keys()), state="readonly", width=12 - ) - self.combo_bulk.grid(row=0, column=0, padx=(0, 5)) - self.combo_bulk.set("Jarabe concentrado") - - # Entrada manual para valor personalizado - self.entry_bulk = ttk.Entry( - combo_frame, textvariable=self.params["modulo_bulk"], width=8 - ) - self.entry_bulk.grid(row=0, column=1) - - # Callback para combo - def on_combo_change(event=None): - seleccion = self.combo_bulk.get() - if seleccion in valores_bulk and valores_bulk[seleccion] is not None: - self.params["modulo_bulk"].set(valores_bulk[seleccion] * 1e9) - self.entry_bulk.config(state="disabled") - else: - self.entry_bulk.config(state="normal") - self.on_parameter_change() - - self.combo_bulk.bind("<>", on_combo_change) - - # Inicializar - on_combo_change() - - return self.combo_bulk - - def crear_panel_graficos(self, parent): - """Crea el panel central con gráficos""" - - # Frame para gráficos - graph_frame = ttk.LabelFrame( - parent, text="Visualización del Transitorio", padding=5 - ) - graph_frame.grid(row=0, column=1, sticky="nsew", padx=5) - - # Crear figura de matplotlib - self.fig = Figure(figsize=(10, 8), dpi=100) - - # Crear subplots - self.ax1 = self.fig.add_subplot(2, 2, 1) # Presión vs tiempo - self.ax2 = self.fig.add_subplot(2, 2, 2) # Caudal vs tiempo - self.ax3 = self.fig.add_subplot(2, 2, 3) # Presión vs posición - self.ax4 = self.fig.add_subplot(2, 2, 4) # Esquema del sistema - - # Configurar canvas - self.canvas = FigureCanvasTkAgg(self.fig, graph_frame) - self.canvas.draw() - self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) - - # Toolbar de navegación - toolbar_frame = ttk.Frame(graph_frame) - toolbar_frame.pack(fill=tk.X) - - from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk - - toolbar = NavigationToolbar2Tk(self.canvas, toolbar_frame) - toolbar.update() - - def crear_panel_resultados(self, parent): - """Crea el panel de resultados calculados""" - - # Frame para resultados - results_frame = ttk.LabelFrame(parent, text="Risultati Calcolati", padding=10) - results_frame.grid(row=0, column=2, sticky="nsew", padx=(5, 0)) - - # Variables para mostrar resultados - self.resultado_labels = {} - - row = 0 - - # Parámetros calculados - ttk.Label( - results_frame, text="PARAMETRI CALCOLATI", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=2, sticky="w") - row += 1 - - self.crear_resultado( - "Velocità del fluido:", "velocidad_fluido", "m/s", results_frame, row - ) - row += 1 - - self.crear_resultado( - "Velocidad de onda:", "velocidad_onda", "m/s", results_frame, row - ) - row += 1 - - self.crear_resultado( - "Tiempo crítico:", "tiempo_critico", "s", results_frame, row - ) - row += 1 - - # Separador - ttk.Separator(results_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Resultados del transitorio - ttk.Label( - results_frame, text="GOLPE DE ARIETE", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=2, sticky="w") - row += 1 - - self.crear_resultado( - "Sobrepresión Joukowsky:", - "sobrepresion_joukowsky", - "bar", - results_frame, - row, - ) - row += 1 - - self.crear_resultado( - "Factor de reducción:", "factor_reduccion", "", results_frame, row - ) - row += 1 - - self.crear_resultado( - "Sobrepresión real:", "sobrepresion_real", "bar", results_frame, row - ) - row += 1 - - # Separador - ttk.Separator(results_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Resultados del damper - ttk.Label( - results_frame, text="DAMPER HIDROPNEUMÁTICO", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=2, sticky="w") - row += 1 - - self.crear_resultado( - "Eficiencia damper:", "damper_eficiencia", "%", results_frame, row - ) - row += 1 - - self.crear_resultado( - "Volumen efectivo:", "damper_volumen_efectivo", "L", results_frame, row - ) - row += 1 - - self.crear_resultado( - "Compresibilidad:", "damper_compresibilidad", "", results_frame, row - ) - row += 1 - - # Separador - ttk.Separator(results_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Evaluación de seguridad - ttk.Label(results_frame, text="EVALUACIÓN", font=("Arial", 10, "bold")).grid( - row=row, column=0, columnspan=2, sticky="w" - ) - row += 1 - - self.evaluacion_text = tk.Text(results_frame, height=8, width=35, wrap=tk.WORD) - self.evaluacion_text.grid(row=row, column=0, columnspan=2, sticky="ew", pady=5) - row += 1 - - # Scrollbar para el texto - scrollbar = ttk.Scrollbar( - results_frame, orient="vertical", command=self.evaluacion_text.yview - ) - scrollbar.grid(row=row - 1, column=2, sticky="ns") - self.evaluacion_text.configure(yscrollcommand=scrollbar.set) - - # Separador - ttk.Separator(results_frame, orient="horizontal").grid( - row=row, column=0, columnspan=2, sticky="ew", pady=10 - ) - row += 1 - - # Botones de acción - ttk.Button( - results_frame, text="Exportar Gráficos", command=self.exportar_graficos - ).grid(row=row, column=0, pady=5, sticky="w") - - ttk.Button( - results_frame, text="Generar Reporte", command=self.generar_reporte - ).grid(row=row, column=1, pady=5, sticky="e") - row += 1 - - ttk.Button(results_frame, text="Ayuda", command=self.mostrar_ayuda).grid( - row=row, column=0, pady=5, sticky="w" - ) - - ttk.Button( - results_frame, text="Acerca de", command=self.mostrar_acerca_de - ).grid(row=row, column=1, pady=5, sticky="e") - - def crear_resultado(self, etiqueta, clave, unidad, parent, row): - """Crea una etiqueta de resultado""" - - ttk.Label(parent, text=etiqueta).grid(row=row, column=0, sticky="w", pady=2) - - resultado_label = ttk.Label(parent, text="0.00", font=("Arial", 9, "bold")) - resultado_label.grid(row=row, column=1, sticky="e", pady=2) - - if unidad: - ttk.Label(parent, text=unidad, font=("Arial", 8)).grid( - row=row, column=2, sticky="w", padx=(2, 0), pady=2 - ) - - self.resultado_labels[clave] = resultado_label - - def on_parameter_change(self, *args): - """Callback cuando cambia un parámetro""" - # Usar after para evitar múltiples llamadas rápidas - if hasattr(self, "_update_timer"): - self.root.after_cancel(self._update_timer) - self._update_timer = self.root.after(500, self.recalcular) - - def calcular_parametros(self): - """Calcula los parámetros del sistema""" - - # Obtener valores actuales - L = self.params["longitud_tuberia"].get() - D = self.params["diametro_tuberia"].get() - e = self.params["espesor_pared"].get() - Q = self.params["caudal_nominal"].get() / 3600 / 1000 # m³/s - P_bomba = self.params["presion_bomba"].get() - rho = self.params["densidad_fluido"].get() - K = self.params["modulo_bulk"].get() - E = self.params["modulo_young"].get() - t_cierre = self.params["tiempo_cierre"].get() - - # Parámetros del damper - damper_habilitado = self.params["damper_habilitado"].get() - damper_vol_total = self.params["damper_volumen"].get() / 1000 # m³ - damper_p0 = self.params["damper_presion_precarga"].get() * 100000 # Pa - damper_porcentaje_gas = self.params["damper_porcentaje_gas"].get() # % - # Calcular volumen de gas basado en el porcentaje - damper_vol_gas = damper_vol_total * damper_porcentaje_gas / 100.0 - damper_pos = self.params["damper_posicion"].get() - - # Calcular velocidad del fluido - A = np.pi * (D / 2) ** 2 - V = Q / A - self.resultados["velocidad_fluido"] = V - - # Calcular velocidad de onda (fórmula de Joukowsky) - a = np.sqrt(K / rho) / np.sqrt(1 + (K * D) / (E * e)) - self.resultados["velocidad_onda"] = a - - # Tiempo crítico - t_critico = 2 * L / a - self.resultados["tiempo_critico"] = t_critico - - # Sobrepresión de Joukowsky - delta_p_joukowsky = rho * a * V / 100000 # convertir a bar - self.resultados["sobrepresion_joukowsky"] = delta_p_joukowsky - - # Factor de reducción por tiempo de cierre - if t_cierre <= t_critico: - factor_tiempo = 1.0 - else: - factor_tiempo = t_critico / t_cierre - - # Calcular efecto del damper si está habilitado - factor_damper = 1.0 - damper_eficiencia = 0.0 - damper_vol_efectivo = 0.0 - damper_compresibilidad = 0.0 - - if damper_habilitado: - # Cálculo detallado del damper hidropneumático - P_operacion = P_bomba * 100000 # Pa - - # Volumen efectivo del gas considerando compresión isotérmica - # P0*V0 = P1*V1 (Ley de Boyle) - damper_vol_efectivo = (damper_vol_gas * damper_p0) / P_operacion - - # Compresibilidad equivalente del sistema damper + fluido - # C_eq = V_gas_efectivo / (V_tubo * K_fluido) - V_tubo = A * L - damper_compresibilidad = damper_vol_efectivo / (V_tubo * K / P_operacion) - - # Factor de reducción basado en compresibilidad efectiva - # Ecuación simplificada para damper hidropneumático - C_total = 1 / K + damper_compresibilidad - C_original = 1 / K - factor_compresibilidad = C_original / C_total - - # Eficiencia basada en posición del damper - distancia_normalizada = damper_pos / L - eficiencia_posicion = 1.0 - 0.3 * abs(distancia_normalizada - 0.9) - - # Factor de damper final - factor_damper = 1.0 - (1.0 - factor_compresibilidad) * eficiencia_posicion - - # Almacenar resultados del damper - damper_eficiencia = (1.0 - factor_damper) * 100 # Porcentaje - self.resultados["damper_volumen_efectivo"] = damper_vol_efectivo * 1000 # L - - # Factor de reducción total - factor_total = factor_tiempo * factor_damper - self.resultados["factor_reduccion"] = factor_total - - # Sobrepresión real - delta_p_real = delta_p_joukowsky * factor_total - self.resultados["sobrepresion_real"] = delta_p_real - - # Almacenar resultados específicos del damper - self.resultados["damper_eficiencia"] = damper_eficiencia - self.resultados["damper_compresibilidad"] = damper_compresibilidad - - # Actualizar display - self.actualizar_resultados() - self.evaluar_seguridad() - - def calcular_transitorio_tsnet(self): - """Calcula el transitorio usando TSNet para resultados más precisos""" - - try: - # Parámetros del sistema - L = self.params["longitud_tuberia"].get() - D = self.params["diametro_tuberia"].get() - e = self.params["espesor_pared"].get() - Q = self.params["caudal_nominal"].get() / 3600 / 1000 # m³/s - P_bomba = self.params["presion_bomba"].get() * 100000 # Pa - rho = self.params["densidad_fluido"].get() - K = self.params["modulo_bulk"].get() - E = self.params["modulo_young"].get() - t_cierre = self.params["tiempo_cierre"].get() - t_sim = self.params["tiempo_simulacion"].get() - - # Crear archivo temporal INP para TSNet - inp_content = self.crear_archivo_inp_temporal(L, D, Q, P_bomba) - - with tempfile.NamedTemporaryFile( - mode="w", suffix=".inp", delete=False - ) as f: - f.write(inp_content) - inp_file = f.name - - try: - # Crear modelo de TSNet - tm = tsnet.network.TransientModel(inp_file) - - # Configurar velocidad de onda usando set_wavespeed (método correcto) - import math - - wavev = math.sqrt(K / rho) / math.sqrt(1 + (K * D) / (E * e)) - tm.set_wavespeed(wavev) - - # Configurar simulación con paso de tiempo más pequeño - dt = min(0.004, t_sim / 1000) # Paso de tiempo seguro - tm.set_time(t_sim, dt) - - # Configurar la válvula de cierre - try: - # Agregar válvula programáticamente entre nodos existentes - tm.add_valve("VALVE1", "2", "3", D * 1000, "TCV", 1.0, 0) - print("Válvula agregada al modelo") - - # Por ahora saltamos valve_closure debido a errores de sintaxis - # en su lugar, usaremos add_demand_pulse como alternativa - demand_factor = [1.0, 0.0, 0.0, 0.0] - tm.add_demand_pulse("3", demand_factor) - print("Pulse de demanda configurado como cierre de válvula") - - except Exception as e: - print(f"Error configurando válvula: {e}") - # Continuar sin válvula - - # TSNet parece no tener un método estándar de ejecución - # Vamos a usar un enfoque híbrido: TSNet para parámetros, Joukowsky para cálculos - print("Usando TSNet para configuración y cálculos híbridos...") - - # Obtener tiempos de simulación - # TSNet no genera simulation_timestamps automáticamente - # Crear vector de tiempo manualmente - dt = min(0.004, t_sim / 1000) - tiempos = np.arange(0, t_sim + dt, dt) - print(f"Generados {len(tiempos)} puntos de tiempo de 0 a {t_sim}s") - - # Generar datos usando métodos híbridos - presiones, caudales = self.generar_datos_hibridos_tsnet( - tiempos, tm, wavev - ) - - print( - f"Simulación TSNet completada con {len(tiempos)} puntos de tiempo" - ) - return tiempos, presiones, caudales - - finally: - # Limpiar archivo temporal - if os.path.exists(inp_file): - os.unlink(inp_file) - - except Exception as e: - print(f"Error en simulación TSNet: {e}") - # Sin fallback - fallo completo si TSNet no funciona - raise Exception(f"TSNet falló: {e}") - - def generar_datos_hibridos_tsnet(self, tiempos, tm, wavev): - """Genera datos usando TSNet para configuración y Joukowsky para cálculos""" - - # Parámetros del sistema - Q0 = self.params["caudal_nominal"].get() / 3600 / 1000 # m³/s - P0 = self.params["presion_bomba"].get() # bar - rho = self.params["densidad_fluido"].get() - t_cierre = self.params["tiempo_cierre"].get() - - # CORREGIDO: Usar la sobrepresión real ya calculada con factores de reducción - # En lugar de recalcular la sobrepresión Joukowsky teórica - delta_P_real = self.resultados[ - "sobrepresion_real" - ] # Ya incluye factores de tiempo y damper - - # Para referencia, también calcular la teórica - delta_P_joukowsky_teorica = ( - rho - * wavev - * Q0 - / (math.pi * (self.params["diametro_tuberia"].get() / 2) ** 2) - ) / 100000 - - # Generar perfiles de presión y caudal - presiones = {"P1": [], "P2": [], "P3": []} - caudales = {"Q1": []} - - for t in tiempos: - # Factor de cierre (evitar división por cero) - if t_cierre > 0 and t <= t_cierre: - factor_cierre = 1.0 - (t / t_cierre) - elif t_cierre > 0: - factor_cierre = 0.0 - else: - # Si t_cierre es 0, cierre instantáneo - factor_cierre = 0.0 if t > 0 else 1.0 - - # Caudal actual - Q_actual = Q0 * factor_cierre * 3600 * 1000 # L/h - - # Presión con oscilaciones amortiguadas - if t <= t_cierre: - # Durante el cierre - usar sobrepresión real calculada - P_transitorio = P0 + delta_P_real * (1 - factor_cierre) - else: - # Después del cierre - oscilaciones amortiguadas - tiempo_post = t - t_cierre - periodo = 4 * self.params["longitud_tuberia"].get() / wavev - amortiguamiento = math.exp(-tiempo_post / (periodo * 2)) - - oscilacion = ( - delta_P_real - * math.cos(2 * math.pi * tiempo_post / periodo) - * amortiguamiento - ) - - P_transitorio = P0 + oscilacion - - # El efecto del damper ya está incluido en delta_P_real - # No necesitamos aplicarlo nuevamente aquí - - # Almacenar resultados - presiones["P1"].append(P_transitorio) # Presión en bomba - presiones["P2"].append(P_transitorio * 0.95) # Presión intermedia - presiones["P3"].append(P_transitorio * 0.9) # Presión en válvula - caudales["Q1"].append(Q_actual) - - return presiones, caudales - - def crear_archivo_inp_temporal(self, L, D, Q, P_bomba): - """Crea un archivo INP temporal para TSNet""" - - # Crear red simple: Bomba -> Tubería -> Válvula -> Tanque - inp_content = f"""[TITLE] -Simulacion Golpe de Ariete - Sistema Jarabe - -[JUNCTIONS] -;ID Elev Demand Pattern - 2 0 0 - 3 0 {Q*1000:.6f} - -[RESERVOIRS] -;ID Head Pattern - 1 {P_bomba/100000/9.81:.2f} - -[PIPES] -;ID Node1 Node2 Length Diameter Roughness MinorLoss Status - 1 1 2 {L/2:.1f} {D*1000:.1f} 0.0015 0 Open - 2 2 3 {L/2:.1f} {D*1000:.1f} 0.0015 0 Open - -[PATTERNS] -;ID Multipliers - -[CURVES] -;ID X-Value Y-Value - -[CONTROLS] - -[RULES] - -[ENERGY] - Global Efficiency 75 - Global Price 0.0 - Demand Charge 0.0 - -[EMITTERS] - -[QUALITY] - -[SOURCES] - -[REACTIONS] - -[MIXING] - -[TIMES] - Duration 24:00 - Hydraulic Timestep 1:00 - Quality Timestep 0:05 - Pattern Timestep 1:00 - Pattern Start 0:00 - Report Timestep 1:00 - Report Start 0:00 - Start ClockTime 12 am - Statistic NONE - -[REPORT] - Status No - Summary No - Page 0 - -[OPTIONS] - Units LPS - Headloss H-W - Specific Gravity {self.params["densidad_fluido"].get()/1000:.3f} - Viscosity 1.0 - Trials 40 - Accuracy 0.001 - CHECKFREQ 2 - MAXCHECK 10 - DAMPLIMIT 0 - -[COORDINATES] - 1 0 0 - 2 {L/2:.0f} 0 - 3 {L:.0f} 0 - -[END] -""" - return inp_content - - def actualizar_resultados(self): - """Actualiza los labels de resultados""" - - for clave, label in self.resultado_labels.items(): - valor = self.resultados[clave] - if valor < 0.01: - texto = f"{valor:.4f}" - elif valor < 1: - texto = f"{valor:.3f}" - elif valor < 100: - texto = f"{valor:.2f}" - else: - texto = f"{valor:.1f}" - label.config(text=texto) - - def evaluar_seguridad(self): - """Evalúa la seguridad del sistema y muestra recomendaciones""" - - P_nominal = self.params["presion_bomba"].get() - sobrepresion = self.resultados["sobrepresion_real"] - t_cierre = self.params["tiempo_cierre"].get() - t_critico = self.resultados["tiempo_critico"] - damper_habilitado = self.params["damper_habilitado"].get() - - evaluacion = [] - - # Análisis de sobrepresión - porcentaje_sobrepresion = (sobrepresion / P_nominal) * 100 - - evaluacion.append("=== ANÁLISIS DE SEGURIDAD ===\n") - - evaluacion.append( - f"Sobrepresión: {sobrepresion:.2f} bar ({porcentaje_sobrepresion:.1f}%)\n" - ) - - if porcentaje_sobrepresion > 50: - evaluacion.append("🔴 CRÍTICO: Sobrepresión muy alta\n") - evaluacion.append(" - Instalar válvulas de alivio\n") - evaluacion.append(" - Considerar tanques amortiguadores\n") - elif porcentaje_sobrepresion > 20: - evaluacion.append("🟡 PRECAUCIÓN: Sobrepresión moderada\n") - evaluacion.append(" - Monitorear presiones\n") - evaluacion.append(" - Evaluar protecciones\n") - else: - evaluacion.append("🟢 ACEPTABLE: Sobrepresión controlada\n") - - evaluacion.append("\n") - - # Análisis de tiempo de cierre - if t_cierre < t_critico: - evaluacion.append(f"⚠️ Tiempo de cierre < crítico ({t_critico:.2f}s)\n") - evaluacion.append(" - Aumentar tiempo de cierre\n") - evaluacion.append(" - Usar cierre gradual\n") - else: - evaluacion.append(f"✅ Tiempo de cierre adecuado (>{t_critico:.2f}s)\n") - - evaluacion.append("\n") - - # Análisis del damper hidropneumático - damper_hab = self.params["damper_habilitado"].get() - if damper_hab: - damper_ef = self.resultados["damper_eficiencia"] - damper_vol_ef = self.resultados["damper_volumen_efectivo"] - evaluacion.append(f"🛡️ Damper hidropneumático instalado\n") - evaluacion.append(f" - Eficiencia: {damper_ef:.1f}%\n") - evaluacion.append(f" - Volumen efectivo: {damper_vol_ef:.1f} L\n") - - # Evaluación del dimensionado del damper - if damper_ef > 40: - evaluacion.append(" ✅ Damper bien dimensionado\n") - elif damper_ef > 20: - evaluacion.append(" 🟡 Damper medianamente efectivo\n") - evaluacion.append(" - Considerar aumentar volumen\n") - else: - evaluacion.append(" 🔴 Damper insuficiente\n") - evaluacion.append(" - Aumentar volumen del damper\n") - evaluacion.append(" - Verificar presión de precarga\n") - else: - evaluacion.append("⚠️ Sin protección por damper\n") - evaluacion.append(" - Considerar instalar damper hidropneumático\n") - - evaluacion.append("\n=== RECOMENDACIONES ===\n") - - if porcentaje_sobrepresion > 30: - evaluacion.append("• Instalar válvula de alivio\n") - - if t_cierre < t_critico * 1.5: - evaluacion.append("• Aumentar tiempo de cierre\n") - - if not damper_habilitado and porcentaje_sobrepresion > 15: - evaluacion.append("• Instalar sistema amortiguador\n") - - evaluacion.append("• Verificar anclajes de tubería\n") - evaluacion.append("• Monitorear durante operación\n") - - # Mostrar en el widget de texto - self.evaluacion_text.delete(1.0, tk.END) - self.evaluacion_text.insert(1.0, "".join(evaluacion)) - - def simular_transitorio(self): - """Simula el transitorio usando TSNet y actualiza gráficos""" - - # Limpiar gráficos - for ax in [self.ax1, self.ax2, self.ax3, self.ax4]: - ax.clear() - - try: - # Usar TSNet para simulación real (sin fallback) - tiempos_tsnet, presiones_tsnet, caudales_tsnet = ( - self.calcular_transitorio_tsnet() - ) - - # Usar resultados de TSNet - tiempos = tiempos_tsnet - presiones = presiones_tsnet - caudales = caudales_tsnet - - # Obtener parámetros para gráficos - P_nominal = self.params["presion_bomba"].get() - Q_nominal = self.params["caudal_nominal"].get() - t_cierre = self.params["tiempo_cierre"].get() - L = self.params["longitud_tuberia"].get() - posiciones = [0, L / 2, L] # Inicio, medio, final - - except Exception as e: - # Sin fallback - mostrar error y salir - print(f"Error en TSNet: {e}") - messagebox.showerror("Error TSNet", f"TSNet falló: {e}") - return - - # Gráfico 1: Presión vs Tiempo - if "P1" in presiones: - self.ax1.plot( - tiempos, presiones["P1"], "b-", linewidth=2, label="Inicio tubería" - ) - if "P2" in presiones: - self.ax1.plot( - tiempos, presiones["P2"], "g-", linewidth=2, label="Medio tubería" - ) - if "P3" in presiones: - self.ax1.plot( - tiempos, presiones["P3"], "r-", linewidth=2, label="Final tubería" - ) - - P_nominal = self.params["presion_bomba"].get() - self.ax1.axhline( - y=P_nominal, color="gray", linestyle="--", alpha=0.7, label="Nominal" - ) - self.ax1.axvline( - x=t_cierre, - color="orange", - linestyle="--", - alpha=0.7, - label="Cierre válvula", - ) - self.ax1.set_xlabel("Tiempo (s)") - self.ax1.set_ylabel("Presión (bar)") - self.ax1.set_title("Evolución de Presiones (TSNet)") - self.ax1.legend() - self.ax1.grid(True, alpha=0.3) - - # Gráfico 2: Caudal vs Tiempo - Q_nominal = self.params["caudal_nominal"].get() - if "Q1" in caudales: - self.ax2.plot( - tiempos, - caudales["Q1"], - "purple", - linewidth=2, - label="Caudal sistema", - ) - self.ax2.axhline( - y=Q_nominal, color="gray", linestyle="--", alpha=0.7, label="Nominal" - ) - self.ax2.axvline(x=t_cierre, color="orange", linestyle="--", alpha=0.7) - self.ax2.set_xlabel("Tiempo (s)") - self.ax2.set_ylabel("Caudal (L/h)") - self.ax2.set_title("Evolución del Caudal (TSNet)") - self.ax2.legend() - self.ax2.grid(True, alpha=0.3) - - # Gráfico 3: Perfil de presiones a lo largo de la tubería - if "P1" in presiones and "P2" in presiones and "P3" in presiones: - tiempo_max = np.argmax(presiones["P2"]) - presion_momento_max = [ - presiones["P1"][tiempo_max], - presiones["P2"][tiempo_max], - presiones["P3"][tiempo_max], - ] - - self.ax3.plot( - posiciones, [P_nominal] * 3, "b--", linewidth=2, label="Estado inicial" - ) - self.ax3.plot( - posiciones, - presion_momento_max, - "r-o", - linewidth=2, - label="Máxima presión", - ) - self.ax3.set_xlabel("Posición (m)") - self.ax3.set_ylabel("Presión (bar)") - self.ax3.set_title("Perfil de Presiones") - self.ax3.legend() - self.ax3.grid(True, alpha=0.3) - - # Gráfico 4: Esquema del sistema - self.dibujar_esquema_sistema() - - # Actualizar canvas - self.fig.tight_layout() - self.canvas.draw() - - def dibujar_esquema_sistema(self): - """Dibuja esquema del sistema""" - - self.ax4.set_xlim(0, 10) - self.ax4.set_ylim(0, 6) - - # Reservorio - from matplotlib.patches import Rectangle - - self.ax4.add_patch( - Rectangle((0.5, 4), 1, 1.5, facecolor="lightblue", edgecolor="black") - ) - self.ax4.text( - 1, 4.75, "Reservorio\nJarabe", ha="center", va="center", fontsize=8 - ) - - # Bomba - circle = plt.Circle((2.5, 3), 0.3, facecolor="yellow", edgecolor="black") - self.ax4.add_patch(circle) - self.ax4.text(2.5, 3, "B", ha="center", va="center", fontweight="bold") - - # Tubería principal - L = self.params["longitud_tuberia"].get() - D = self.params["diametro_tuberia"].get() * 1000 - self.ax4.plot([3, 7], [3, 3], "k-", linewidth=8, alpha=0.6) - self.ax4.text( - 5, - 3.5, - f"Tubería\n{L:.0f}m, Ø{D:.0f}mm", - ha="center", - va="bottom", - fontsize=8, - ) - - # Válvula - t_cierre = self.params["tiempo_cierre"].get() - self.ax4.plot([7.2, 7.8], [2.7, 3.3], "r-", linewidth=4) - self.ax4.plot([7.2, 7.8], [3.3, 2.7], "r-", linewidth=4) - self.ax4.text( - 7.5, 2.3, f"Válvula\nt={t_cierre:.1f}s", ha="center", va="top", fontsize=8 - ) - - # Damper si está activado - damper_habilitado = self.params["damper_habilitado"].get() - if damper_habilitado: - self.ax4.add_patch( - Rectangle((6.5, 2.5), 0.3, 1, facecolor="gray", edgecolor="black") - ) - self.ax4.text( - 6.65, - 2, - f"Damper\n{self.params['damper_volumen'].get():.0f}L", - ha="center", - va="top", - fontsize=8, - ) - - # Tanque descarga - self.ax4.add_patch( - Rectangle((8.5, 1), 1, 1.5, facecolor="lightgreen", edgecolor="black") - ) - self.ax4.text(9, 1.75, "Tanque\nDescarga", ha="center", va="center", fontsize=8) - - # Conexiones - self.ax4.plot([1.5, 2.2], [4.75, 3.3], "k-", linewidth=2) - self.ax4.plot([2.8, 3], [3, 3], "k-", linewidth=2) - self.ax4.plot([7.8, 8.5], [3, 1.75], "k-", linewidth=2) - - # Puntos de medición - self.ax4.plot(3.5, 3, "bo", markersize=6) - self.ax4.text(3.5, 2.5, "P1", ha="center", va="top", fontsize=8) - self.ax4.plot(5, 3, "go", markersize=6) - self.ax4.text(5, 2.5, "P2", ha="center", va="top", fontsize=8) - self.ax4.plot(6.5, 3, "ro", markersize=6) - self.ax4.text(6.5, 2.5, "P3", ha="center", va="top", fontsize=8) - - self.ax4.set_title("Esquema del Sistema") - self.ax4.set_aspect("equal") - self.ax4.axis("off") - - def configurar_damper_avanzado(self): - """Abre ventana de configuración avanzada del damper""" - - damper_window = tk.Toplevel(self.root) - damper_window.title("Configuración Avanzada del Damper") - damper_window.geometry("800x600") - damper_window.transient(self.root) - damper_window.grab_set() - - # Frame principal - main_frame = ttk.Frame(damper_window, padding=20) - main_frame.pack(fill=tk.BOTH, expand=True) - - # Título y explicación - title_label = ttk.Label( - main_frame, text="DAMPER HIDROPNEUMÁTICO", font=("Arial", 14, "bold") - ) - title_label.pack(pady=(0, 10)) - - # Texto explicativo - explicacion = """ -Un damper hidropneumático es un dispositivo de protección contra golpe de ariete que consiste en: - -🔧 COMPONENTES: -• Recipiente de acero con membrana o vejiga -• Cámara superior con gas inerte (N₂) a presión -• Cámara inferior conectada a la tubería -• Válvula de conexión con la línea principal - -⚙️ FUNCIONAMIENTO: -1. En operación normal: El gas está comprimido a presión de precarga -2. Durante sobrepresión: El fluido comprime más el gas, absorbiendo energía -3. Durante depresión: El gas se expande, suministrando fluido - -📐 DIMENSIONADO: -• Volumen: Típicamente 0.5-2% del volumen de la tubería -• Presión precarga: 60-80% de la presión de operación -• Posición: Preferiblemente cerca del punto de perturbación - """ - - text_widget = tk.Text(main_frame, height=12, wrap=tk.WORD, font=("Arial", 9)) - text_widget.pack(fill=tk.BOTH, expand=True, pady=(0, 10)) - text_widget.insert(1.0, explicacion) - text_widget.config(state=tk.DISABLED) - - # Frame para configuración - config_frame = ttk.LabelFrame( - main_frame, text="Configuración Específica", padding=10 - ) - config_frame.pack(fill=tk.X, pady=(10, 0)) - - # Calcular valores recomendados - L = self.params["longitud_tuberia"].get() - D = self.params["diametro_tuberia"].get() - P_bomba = self.params["presion_bomba"].get() - - V_tuberia = np.pi * (D / 2) ** 2 * L * 1000 # Litros - vol_recomendado = V_tuberia * 0.01 # 1% del volumen de tubería - presion_recomendada = P_bomba * 0.7 # 70% de presión de operación - - row = 0 - - # Valores recomendados - ttk.Label( - config_frame, text="VALORES RECOMENDADOS:", font=("Arial", 10, "bold") - ).grid(row=row, column=0, columnspan=3, sticky="w", pady=(0, 5)) - row += 1 - - ttk.Label(config_frame, text=f"• Volumen tubería: {V_tuberia:.0f} L").grid( - row=row, column=0, columnspan=3, sticky="w" - ) - row += 1 - - ttk.Label( - config_frame, text=f"• Volumen damper recomendado: {vol_recomendado:.0f} L" - ).grid(row=row, column=0, columnspan=3, sticky="w") - row += 1 - - ttk.Label( - config_frame, - text=f"• Presión precarga recomendada: {presion_recomendada:.1f} bar", - ).grid(row=row, column=0, columnspan=3, sticky="w") - row += 1 - - # Separador - ttk.Separator(config_frame, orient="horizontal").grid( - row=row, column=0, columnspan=3, sticky="ew", pady=10 - ) - row += 1 - - # Botones de acción - button_frame = ttk.Frame(config_frame) - button_frame.grid(row=row, column=0, columnspan=3, pady=(10, 0)) - - ttk.Button( - button_frame, - text="Aplicar Valores Recomendados", - command=lambda: self.aplicar_valores_recomendados_damper( - vol_recomendado, presion_recomendada, damper_window - ), - ).pack(side=tk.LEFT, padx=(0, 10)) - - ttk.Button(button_frame, text="Cerrar", command=damper_window.destroy).pack( - side=tk.LEFT - ) - - def aplicar_valores_recomendados_damper(self, volumen, presion, ventana): - """Aplica los valores recomendados para el damper""" - - self.params["damper_habilitado"].set(True) - self.params["damper_volumen"].set(volumen) - self.params["damper_presion_precarga"].set(presion) - self.params["damper_porcentaje_gas"].set(60.0) # 60% gas típico - - # Recalcular - self.recalcular() - - # Cerrar ventana - ventana.destroy() - - # Mostrar mensaje - messagebox.showinfo( - "Damper Configurado", - f"Damper configurado con:\n" - f"• Volumen: {volumen:.0f} L\n" - f"• Presión precarga: {presion:.1f} bar\n" - f"• Volumen gas: {volumen * 0.6:.0f} L", - ) - - def recalcular(self): - """Recalcula todo el sistema""" - self.calcular_parametros() - self.simular_transitorio() - - def resetear_valores(self): - """Resetea todos los valores a los por defecto""" - defaults = { - "longitud_tuberia": 300.0, - "diametro_tuberia": 0.08, - "espesor_pared": 0.003, - "rugosidad": 1.5e-6, - "caudal_nominal": 22000.0, - "presion_bomba": 7.0, - "densidad_fluido": 1300.0, - "temperatura_fluido": 20.0, - "modulo_bulk": 2.2e9, - "modulo_young": 200e9, - "tiempo_cierre": 2.0, - "damper_habilitado": False, - "damper_volumen": 50.0, - "damper_presion_precarga": 4.0, - "damper_porcentaje_gas": 60.0, - "damper_posicion": 280.0, - "damper_diametro_conexion": 0.05, - "damper_longitud_conexion": 0.5, - "tiempo_simulacion": 10.0, - } - - for key, value in defaults.items(): - self.params[key].set(value) - - self.recalcular() - - def aplicar_preset(self, tipo): - """Aplica presets predefinidos""" - - if tipo == "rapido": - self.params["tiempo_cierre"].set(0.5) - self.params["damper_habilitado"].set(False) - elif tipo == "lento": - self.params["tiempo_cierre"].set(8.0) - self.params["damper_habilitado"].set(False) - elif tipo == "damper": - self.params["tiempo_cierre"].set(2.0) - self.params["damper_habilitado"].set(True) - self.params["damper_volumen"].set(75.0) - self.params["damper_presion_precarga"].set(5.0) - self.params["damper_porcentaje_gas"].set(60.0) # 60% gas - elif tipo == "critico": - self.params["longitud_tuberia"].set(500.0) - self.params["tiempo_cierre"].set(0.3) - self.params["caudal_nominal"].set(35000.0) - self.params["damper_habilitado"].set(False) - - self.recalcular() - - def exportar_graficos(self): - """Exporta los gráficos a archivo""" - from tkinter import filedialog - - filename = filedialog.asksaveasfilename( - title="Guardar gráficos", - defaultextension=".png", - filetypes=[ - ("PNG files", "*.png"), - ("PDF files", "*.pdf"), - ("All files", "*.*"), - ], - ) - - if filename: - self.fig.savefig(filename, dpi=300, bbox_inches="tight") - messagebox.showinfo("Éxito", f"Gráficos guardados en:\n{filename}") - - def generar_reporte(self): - """Genera un reporte completo""" - - reporte = [] - reporte.append("=" * 60) - reporte.append(" REPORTE DE ANÁLISIS DE GOLPE DE ARIETE") - reporte.append("=" * 60) - reporte.append(f"Fecha: {time.strftime('%Y-%m-%d %H:%M:%S')}") - reporte.append("") - - reporte.append("PARÁMETROS DEL SISTEMA:") - reporte.append( - f" Longitud tubería: {self.params['longitud_tuberia'].get():.1f} m" - ) - reporte.append( - f" Diámetro interno: {self.params['diametro_tuberia'].get()*1000:.1f} mm" - ) - reporte.append( - f" Espesor pared: {self.params['espesor_pared'].get()*1000:.1f} mm" - ) - reporte.append( - f" Caudal nominal: {self.params['caudal_nominal'].get():.0f} L/h" - ) - reporte.append( - f" Presión bomba: {self.params['presion_bomba'].get():.1f} bar" - ) - reporte.append( - f" Densidad jarabe: {self.params['densidad_fluido'].get():.0f} kg/m³" - ) - reporte.append( - f" Temperatura fluido: {self.params['temperatura_fluido'].get():.1f} °C" - ) - reporte.append( - f" Tiempo cierre válvula: {self.params['tiempo_cierre'].get():.2f} s" - ) - reporte.append( - f" Damper habilitado: {self.params['damper_habilitado'].get()}" - ) - if self.params["damper_habilitado"].get(): - reporte.append( - f" Volumen damper: {self.params['damper_volumen'].get():.0f} L" - ) - reporte.append("") - - reporte.append("RESULTADOS CALCULADOS:") - reporte.append( - f" Velocidad del fluido: {self.resultados['velocidad_fluido']:.2f} m/s" - ) - reporte.append( - f" Velocidad de onda: {self.resultados['velocidad_onda']:.1f} m/s" - ) - reporte.append( - f" Tiempo crítico: {self.resultados['tiempo_critico']:.3f} s" - ) - reporte.append( - f" Sobrepresión Joukowsky: {self.resultados['sobrepresion_joukowsky']:.2f} bar" - ) - reporte.append( - f" Factor de reducción: {self.resultados['factor_reduccion']:.3f}" - ) - reporte.append( - f" Sobrepresión real: {self.resultados['sobrepresion_real']:.2f} bar" - ) - reporte.append("") - - # Análisis de seguridad - texto_evaluacion = self.evaluacion_text.get(1.0, tk.END) - reporte.append("EVALUACIÓN DE SEGURIDAD:") - reporte.append(texto_evaluacion) - - # Guardar reporte - from tkinter import filedialog - - filename = filedialog.asksaveasfilename( - title="Guardar reporte", - defaultextension=".txt", - filetypes=[("Text files", "*.txt"), ("All files", "*.*")], - ) - - if filename: - with open(filename, "w", encoding="utf-8") as f: - f.write("\n".join(reporte)) - messagebox.showinfo("Éxito", f"Reporte guardado en:\n{filename}") - - def mostrar_ayuda(self): - """Muestra ventana de ayuda""" - - ayuda_text = """ -SIMULADOR DE GOLPE DE ARIETE - AYUDA - -PARÁMETROS PRINCIPALES: -• Longitud tubería: Distancia total de la tubería principal -• Diámetro interno: Diámetro interior de la tubería -• Tiempo cierre válvula: Tiempo que tarda en cerrar completamente - -DAMPER HIDROPNEUMÁTICO: -• Es un dispositivo de protección con gas comprimido (N₂) -• Absorbe sobrepresiones y suministra fluido en depresiones -• Volumen: Típicamente 0.5-2% del volumen de la tubería -• Presión precarga: 60-80% de la presión de operación -• Posición óptima: Cerca del punto de perturbación (válvula) - -CONFIGURACIÓN DAMPER: -• Habilitar checkbox "Damper instalado" -• Usar botón "Configurar Damper" para valores recomendados -• Volumen total: Capacidad del recipiente del damper -• Presión precarga N₂: Presión inicial del gas inerte -• Volumen gas N₂: Volumen ocupado por el gas (60-70% del total) -• Posición: Distancia desde la bomba donde se instala - -INTERPRETACIÓN DE RESULTADOS: -• Velocidad de onda: Velocidad de propagación del transitorio -• Tiempo crítico: Tiempo mínimo para evitar máxima sobrepresión -• Sobrepresión real: Incremento de presión esperado -• Eficiencia damper: Porcentaje de reducción de sobrepresión -• Volumen efectivo: Volumen de gas que actúa contra sobrepresión - -RECOMENDACIONES DE SEGURIDAD: -• Sobrepresión < 20%: Aceptable -• Sobrepresión 20-50%: Precaución, monitorear -• Sobrepresión > 50%: Crítico, instalar protecciones - -• Tiempo cierre > Tiempo crítico: Recomendado -• Eficiencia damper > 40%: Bien dimensionado -• Usar dampers para reducir transitorios -• Instalar válvulas de alivio si es necesario - -PRESETS DISPONIBLES: -• Cierre Rápido: Simula cierre en 0.5s sin protección -• Cierre Lento: Simula cierre en 8s sin protección -• Con Damper: Simula con sistema amortiguador (75L, 5 bar) -• Sistema Crítico: Condiciones extremas de operación - -TIPS DE USO: -• Use el preset "Con Damper" para ver el efecto -• Configure el damper con valores recomendados -• Observe cómo cambia la "Eficiencia damper" al modificar parámetros -• La posición del damper afecta su eficiencia -""" - - ventana_ayuda = tk.Toplevel(self.root) - ventana_ayuda.title("Ayuda - Simulador de Golpe de Ariete") - ventana_ayuda.geometry("600x500") - - text_widget = tk.Text(ventana_ayuda, wrap=tk.WORD, padx=10, pady=10) - text_widget.pack(fill=tk.BOTH, expand=True) - text_widget.insert(1.0, ayuda_text) - text_widget.config(state=tk.DISABLED) - - scrollbar = ttk.Scrollbar( - ventana_ayuda, orient="vertical", command=text_widget.yview - ) - scrollbar.pack(side=tk.RIGHT, fill=tk.Y) - text_widget.configure(yscrollcommand=scrollbar.set) - - def mostrar_acerca_de(self): - """Muestra información sobre la aplicación""" - - acerca_text = """ -SIMULADOR DE GOLPE DE ARIETE -Versión 1.0 - -Sistema de análisis de transitorios hidráulicos -para sistemas de bombeo de jarabe. - -Características: -• Cálculo de sobrepresiones según Joukowsky -• Simulación de efectos de dampers -• Análisis de seguridad automático -• Interfaz gráfica interactiva -• Exportación de resultados - -Desarrollado con: -• Python 3.12 -• Tkinter (interfaz gráfica) -• Matplotlib (gráficos) -• NumPy (cálculos) - -Autor: Generado con GitHub Copilot -Fecha: Septiembre 2025 - -Para soporte técnico o consultas: -Contactar al ingeniero responsable del proyecto. -""" - - messagebox.showinfo("Acerca de", acerca_text) - - -def main(): - """Función principal""" - - root = tk.Tk() - app = SimuladorWaterHammerInteractivo(root) - - # Configurar evento de cierre - def on_closing(): - root.quit() - root.destroy() - - root.protocol("WM_DELETE_WINDOW", on_closing) - - # Iniciar aplicación - root.mainloop() - - -if __name__ == "__main__": - main() diff --git a/app/backend/script_groups/hammer/test_plantuml.py b/app/backend/script_groups/hammer/test_plantuml.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/config/config.py b/app/config/config.py index c365982..753b5cf 100644 --- a/app/config/config.py +++ b/app/config/config.py @@ -1,5 +1,6 @@ import os from pathlib import Path +import urllib.parse # Base directory for the project BASE_DIR = Path(__file__).parent.parent.parent @@ -13,6 +14,43 @@ class Config: "DATABASE_URL", f"sqlite:///{BASE_DIR}/data/scriptsmanager.db" ) SQLALCHEMY_TRACK_MODIFICATIONS = False + + # PostgreSQL-specific database configuration + SQLALCHEMY_ENGINE_OPTIONS = { + 'pool_size': 10, + 'pool_timeout': 20, + 'pool_recycle': -1, + 'max_overflow': 0, + 'pool_pre_ping': True, + } + + # Additional database settings for PostgreSQL + SQLALCHEMY_ECHO = os.getenv("SQLALCHEMY_ECHO", "False").lower() == "true" + + @staticmethod + def get_database_config(): + """Get database configuration based on DATABASE_URL.""" + database_url = os.getenv("DATABASE_URL", f"sqlite:///{BASE_DIR}/data/scriptsmanager.db") + + if database_url.startswith('postgresql://'): + # Parse PostgreSQL URL + parsed = urllib.parse.urlparse(database_url) + return { + 'engine': 'postgresql', + 'host': parsed.hostname, + 'port': parsed.port or 5432, + 'database': parsed.path[1:], # Remove leading slash + 'username': parsed.username, + 'password': parsed.password, + 'url': database_url + } + else: + # SQLite configuration (fallback) + return { + 'engine': 'sqlite', + 'url': database_url, + 'file': database_url.replace('sqlite:///', '') + } # Application Settings SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key-change-in-production") @@ -78,19 +116,60 @@ class DevelopmentConfig(Config): """Development configuration.""" DEBUG = True + + # Development-specific database settings + SQLALCHEMY_ENGINE_OPTIONS = { + 'pool_size': 5, + 'pool_timeout': 10, + 'pool_recycle': 300, + 'max_overflow': 0, + 'pool_pre_ping': True, + 'echo': True, # Log SQL queries in development + } class ProductionConfig(Config): """Production configuration.""" DEBUG = False + + # Production-specific database settings with connection pooling + SQLALCHEMY_ENGINE_OPTIONS = { + 'pool_size': 20, + 'pool_timeout': 30, + 'pool_recycle': 3600, # Recycle connections every hour + 'max_overflow': 10, + 'pool_pre_ping': True, + 'echo': False, # Disable SQL logging in production + } + + # Production security enhancements + SECURITY_CONFIG = { + **Config.SECURITY_CONFIG, + "enable_project_sharing": True, # Enable in production + "session_cookie_secure": True, + "session_cookie_httponly": True, + "session_cookie_samesite": "Lax", + } class TestingConfig(Config): """Testing configuration.""" TESTING = True - DATABASE_URL = "sqlite:///:memory:" + SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" + + # Testing-specific settings + SQLALCHEMY_ENGINE_OPTIONS = { + 'pool_size': 1, + 'pool_timeout': 5, + 'pool_recycle': -1, + 'max_overflow': 0, + 'pool_pre_ping': False, + } + + # Disable backup in testing + BACKUP_ENABLED = False # Configuration dictionary diff --git a/app/config/database.py b/app/config/database.py index 54f5d27..ba51cd6 100644 --- a/app/config/database.py +++ b/app/config/database.py @@ -1,10 +1,32 @@ from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from datetime import datetime +import os +import logging +from sqlalchemy.engine import Engine +from sqlalchemy import event, text +import sqlite3 db = SQLAlchemy() login_manager = LoginManager() +# Configure logging for database operations +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +@event.listens_for(Engine, "connect") +def set_sqlite_pragma(dbapi_connection, connection_record): + """Set SQLite-specific pragmas for better performance and foreign key support.""" + if 'sqlite' in str(dbapi_connection): + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA foreign_keys=ON") + cursor.execute("PRAGMA journal_mode=WAL") + cursor.execute("PRAGMA synchronous=NORMAL") + cursor.execute("PRAGMA cache_size=10000") + cursor.execute("PRAGMA temp_store=MEMORY") + cursor.close() + def init_db(app): """Initialize database with Flask app.""" @@ -14,6 +36,109 @@ def init_db(app): login_manager.login_message = "Please log in to access this page." with app.app_context(): - db.create_all() + try: + # Get database configuration + from .config import Config + db_config = Config.get_database_config() + + if db_config['engine'] == 'postgresql': + logger.info(f"Connecting to PostgreSQL database: {db_config['host']}:{db_config['port']}/{db_config['database']}") + + # Test PostgreSQL connection + try: + with db.engine.connect() as connection: + connection.execute(text("SELECT 1")) + logger.info("PostgreSQL connection successful") + except Exception as e: + logger.error(f"PostgreSQL connection failed: {e}") + raise + + elif db_config['engine'] == 'sqlite': + logger.info(f"Using SQLite database: {db_config.get('file', ':memory:')}") + + # Create all tables + db.create_all() + logger.info("Database tables created successfully") + + except Exception as e: + logger.error(f"Database initialization failed: {e}") + raise return db + + +def get_db_info(): + """Get database connection information.""" + try: + from .config import Config + db_config = Config.get_database_config() + + if db_config['engine'] == 'postgresql': + # Get PostgreSQL version and connection info + with db.engine.connect() as connection: + result = connection.execute(text("SELECT version()")) + version = result.fetchone()[0] + + return { + 'engine': 'PostgreSQL', + 'version': version.split()[1], + 'host': db_config['host'], + 'port': db_config['port'], + 'database': db_config['database'], + 'connection_pool_size': db.engine.pool.size(), + 'checked_out_connections': db.engine.pool.checkedout(), + } + elif db_config['engine'] == 'sqlite': + # Get SQLite version + with db.engine.connect() as connection: + result = connection.execute(text("SELECT sqlite_version()")) + version = result.fetchone()[0] + + return { + 'engine': 'SQLite', + 'version': version, + 'file': db_config.get('file', ':memory:'), + } + except Exception as e: + logger.error(f"Failed to get database info: {e}") + return {'error': str(e)} + + +def check_db_health(): + """Check database health and connectivity.""" + try: + from .config import Config + db_config = Config.get_database_config() + + if db_config['engine'] == 'postgresql': + # Check PostgreSQL health + with db.engine.connect() as connection: + result = connection.execute(text("SELECT 1")) + result.fetchone() + + # Check connection pool status + pool = db.engine.pool + return { + 'status': 'healthy', + 'engine': 'PostgreSQL', + 'pool_size': pool.size(), + 'checked_out': pool.checkedout(), + 'overflow': pool.overflow(), + 'checked_in': pool.checkedin(), + } + elif db_config['engine'] == 'sqlite': + # Check SQLite health + with db.engine.connect() as connection: + result = connection.execute(text("SELECT 1")) + result.fetchone() + + return { + 'status': 'healthy', + 'engine': 'SQLite', + } + except Exception as e: + logger.error(f"Database health check failed: {e}") + return { + 'status': 'unhealthy', + 'error': str(e) + } diff --git a/check_complete_log.py b/backup/old_scripts/check_complete_log.py similarity index 100% rename from check_complete_log.py rename to backup/old_scripts/check_complete_log.py diff --git a/check_db.py b/backup/old_scripts/check_db.py similarity index 100% rename from check_db.py rename to backup/old_scripts/check_db.py diff --git a/check_group_env.py b/backup/old_scripts/check_group_env.py similarity index 100% rename from check_group_env.py rename to backup/old_scripts/check_group_env.py diff --git a/check_log.py b/backup/old_scripts/check_log.py similarity index 100% rename from check_log.py rename to backup/old_scripts/check_log.py diff --git a/check_tables.py b/backup/old_scripts/check_tables.py similarity index 100% rename from check_tables.py rename to backup/old_scripts/check_tables.py diff --git a/debug_discovery.py b/backup/old_scripts/debug_discovery.py similarity index 100% rename from debug_discovery.py rename to backup/old_scripts/debug_discovery.py diff --git a/simple_debug.py b/backup/old_scripts/simple_debug.py similarity index 100% rename from simple_debug.py rename to backup/old_scripts/simple_debug.py diff --git a/test_complete_integration.py b/backup/old_scripts/test_complete_integration.py similarity index 100% rename from test_complete_integration.py rename to backup/old_scripts/test_complete_integration.py diff --git a/test_hammer_browser.py b/backup/old_scripts/test_hammer_browser.py similarity index 100% rename from test_hammer_browser.py rename to backup/old_scripts/test_hammer_browser.py diff --git a/test_hammer_calculations.py b/backup/old_scripts/test_hammer_calculations.py similarity index 100% rename from test_hammer_calculations.py rename to backup/old_scripts/test_hammer_calculations.py diff --git a/test_helper_functions.py b/backup/old_scripts/test_helper_functions.py similarity index 100% rename from test_helper_functions.py rename to backup/old_scripts/test_helper_functions.py diff --git a/test_language_switching.py b/backup/old_scripts/test_language_switching.py similarity index 100% rename from test_language_switching.py rename to backup/old_scripts/test_language_switching.py diff --git a/test_model.py b/backup/old_scripts/test_model.py similarity index 100% rename from test_model.py rename to backup/old_scripts/test_model.py diff --git a/test_permissions.py b/backup/old_scripts/test_permissions.py similarity index 100% rename from test_permissions.py rename to backup/old_scripts/test_permissions.py diff --git a/verify_dashboard_changes.py b/backup/old_scripts/verify_dashboard_changes.py similarity index 100% rename from verify_dashboard_changes.py rename to backup/old_scripts/verify_dashboard_changes.py diff --git a/verify_design_changes.py b/backup/old_scripts/verify_design_changes.py similarity index 100% rename from verify_design_changes.py rename to backup/old_scripts/verify_design_changes.py diff --git a/verify_group5.py b/backup/old_scripts/verify_group5.py similarity index 100% rename from verify_group5.py rename to backup/old_scripts/verify_group5.py diff --git a/verify_navbar_themes.py b/backup/old_scripts/verify_navbar_themes.py similarity index 100% rename from verify_navbar_themes.py rename to backup/old_scripts/verify_navbar_themes.py diff --git a/verify_sidel_logo.py b/backup/old_scripts/verify_sidel_logo.py similarity index 100% rename from verify_sidel_logo.py rename to backup/old_scripts/verify_sidel_logo.py diff --git a/data/script_groups/group_3/user_1/Hammer Test Project/config.json b/data/script_groups/group_3/user_1/Hammer Test Project/config.json new file mode 100644 index 0000000..19c377c --- /dev/null +++ b/data/script_groups/group_3/user_1/Hammer Test Project/config.json @@ -0,0 +1,6 @@ +{ + "created_at": "2025-09-13T14:39:16.163602", + "last_modified": "2025-09-13T14:39:16.163613", + "project_settings": {}, + "user_preferences": {} +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/Hammer Test Project/hammer_config.json b/data/script_groups/group_3/user_1/Hammer Test Project/hammer_config.json new file mode 100644 index 0000000..0f718a7 --- /dev/null +++ b/data/script_groups/group_3/user_1/Hammer Test Project/hammer_config.json @@ -0,0 +1,19 @@ +{ + "pipe_length": 300, + "pipe_diameter": 0.065, + "wall_thickness": 0.003, + "roughness": 1.5e-06, + "flow_rate": 22000, + "pump_pressure": 7, + "fluid_density": 1100, + "fluid_temperature": 20, + "bulk_modulus": 2200000000, + "young_modulus": 200000000000, + "closure_time": 2, + "damper_volume": 50, + "damper_precharge": 4, + "damper_gas_percentage": 60, + "damper_position": 280, + "simulation_time": 10, + "damper_enabled": false +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/Hammer Test Project/hammer_results.json b/data/script_groups/group_3/user_1/Hammer Test Project/hammer_results.json new file mode 100644 index 0000000..8d766c8 --- /dev/null +++ b/data/script_groups/group_3/user_1/Hammer Test Project/hammer_results.json @@ -0,0 +1,5030 @@ +{ + "parameters": { + "fluid_velocity": 1.8416351074407347, + "wave_speed": 1270.8556268223824, + "critical_time": 0.47212286536451503, + "joukowsky_surge": 25.744975727291703, + "time_factor": 0.23606143268225752, + "damper_factor": 1.0, + "total_factor": 0.23606143268225752, + "real_surge": 6.077395854554424, + "damper_efficiency": 0.0, + "damper_effective_volume": 0.0 + }, + "simulation": { + "times": [ + 0.0, + 0.01, + 0.02, + 0.03, + 0.04, + 0.05, + 0.06, + 0.07, + 0.08, + 0.09, + 0.1, + 0.11, + 0.12, + 0.13, + 0.14, + 0.15, + 0.16, + 0.17, + 0.18, + 0.19, + 0.2, + 0.21, + 0.22, + 0.23, + 0.24, + 0.25, + 0.26, + 0.27, + 0.28, + 0.29, + 0.3, + 0.31, + 0.32, + 0.33, + 0.34, + 0.35000000000000003, + 0.36, + 0.37, + 0.38, + 0.39, + 0.4, + 0.41000000000000003, + 0.42, + 0.43, + 0.44, + 0.45, + 0.46, + 0.47000000000000003, + 0.48, + 0.49, + 0.5, + 0.51, + 0.52, + 0.53, + 0.54, + 0.55, + 0.56, + 0.5700000000000001, + 0.58, + 0.59, + 0.6, + 0.61, + 0.62, + 0.63, + 0.64, + 0.65, + 0.66, + 0.67, + 0.68, + 0.6900000000000001, + 0.7000000000000001, + 0.71, + 0.72, + 0.73, + 0.74, + 0.75, + 0.76, + 0.77, + 0.78, + 0.79, + 0.8, + 0.81, + 0.8200000000000001, + 0.8300000000000001, + 0.84, + 0.85, + 0.86, + 0.87, + 0.88, + 0.89, + 0.9, + 0.91, + 0.92, + 0.93, + 0.9400000000000001, + 0.9500000000000001, + 0.96, + 0.97, + 0.98, + 0.99, + 1.0, + 1.01, + 1.02, + 1.03, + 1.04, + 1.05, + 1.06, + 1.07, + 1.08, + 1.09, + 1.1, + 1.11, + 1.12, + 1.1300000000000001, + 1.1400000000000001, + 1.1500000000000001, + 1.16, + 1.17, + 1.18, + 1.19, + 1.2, + 1.21, + 1.22, + 1.23, + 1.24, + 1.25, + 1.26, + 1.27, + 1.28, + 1.29, + 1.3, + 1.31, + 1.32, + 1.33, + 1.34, + 1.35, + 1.36, + 1.37, + 1.3800000000000001, + 1.3900000000000001, + 1.4000000000000001, + 1.41, + 1.42, + 1.43, + 1.44, + 1.45, + 1.46, + 1.47, + 1.48, + 1.49, + 1.5, + 1.51, + 1.52, + 1.53, + 1.54, + 1.55, + 1.56, + 1.57, + 1.58, + 1.59, + 1.6, + 1.61, + 1.62, + 1.6300000000000001, + 1.6400000000000001, + 1.6500000000000001, + 1.6600000000000001, + 1.67, + 1.68, + 1.69, + 1.7, + 1.71, + 1.72, + 1.73, + 1.74, + 1.75, + 1.76, + 1.77, + 1.78, + 1.79, + 1.8, + 1.81, + 1.82, + 1.83, + 1.84, + 1.85, + 1.86, + 1.87, + 1.8800000000000001, + 1.8900000000000001, + 1.9000000000000001, + 1.9100000000000001, + 1.92, + 1.93, + 1.94, + 1.95, + 1.96, + 1.97, + 1.98, + 1.99, + 2.0, + 2.0100000000000002, + 2.02, + 2.0300000000000002, + 2.04, + 2.05, + 2.06, + 2.07, + 2.08, + 2.09, + 2.1, + 2.11, + 2.12, + 2.13, + 2.14, + 2.15, + 2.16, + 2.17, + 2.18, + 2.19, + 2.2, + 2.21, + 2.22, + 2.23, + 2.24, + 2.25, + 2.2600000000000002, + 2.27, + 2.2800000000000002, + 2.29, + 2.3000000000000003, + 2.31, + 2.32, + 2.33, + 2.34, + 2.35, + 2.36, + 2.37, + 2.38, + 2.39, + 2.4, + 2.41, + 2.42, + 2.43, + 2.44, + 2.45, + 2.46, + 2.47, + 2.48, + 2.49, + 2.5, + 2.5100000000000002, + 2.52, + 2.5300000000000002, + 2.54, + 2.5500000000000003, + 2.56, + 2.57, + 2.58, + 2.59, + 2.6, + 2.61, + 2.62, + 2.63, + 2.64, + 2.65, + 2.66, + 2.67, + 2.68, + 2.69, + 2.7, + 2.71, + 2.72, + 2.73, + 2.74, + 2.75, + 2.7600000000000002, + 2.77, + 2.7800000000000002, + 2.79, + 2.8000000000000003, + 2.81, + 2.82, + 2.83, + 2.84, + 2.85, + 2.86, + 2.87, + 2.88, + 2.89, + 2.9, + 2.91, + 2.92, + 2.93, + 2.94, + 2.95, + 2.96, + 2.97, + 2.98, + 2.99, + 3.0, + 3.0100000000000002, + 3.02, + 3.0300000000000002, + 3.04, + 3.0500000000000003, + 3.06, + 3.0700000000000003, + 3.08, + 3.09, + 3.1, + 3.11, + 3.12, + 3.13, + 3.14, + 3.15, + 3.16, + 3.17, + 3.18, + 3.19, + 3.2, + 3.21, + 3.22, + 3.23, + 3.24, + 3.25, + 3.2600000000000002, + 3.27, + 3.2800000000000002, + 3.29, + 3.3000000000000003, + 3.31, + 3.3200000000000003, + 3.33, + 3.34, + 3.35, + 3.36, + 3.37, + 3.38, + 3.39, + 3.4, + 3.41, + 3.42, + 3.43, + 3.44, + 3.45, + 3.46, + 3.47, + 3.48, + 3.49, + 3.5, + 3.5100000000000002, + 3.52, + 3.5300000000000002, + 3.54, + 3.5500000000000003, + 3.56, + 3.5700000000000003, + 3.58, + 3.59, + 3.6, + 3.61, + 3.62, + 3.63, + 3.64, + 3.65, + 3.66, + 3.67, + 3.68, + 3.69, + 3.7, + 3.71, + 3.72, + 3.73, + 3.74, + 3.75, + 3.7600000000000002, + 3.77, + 3.7800000000000002, + 3.79, + 3.8000000000000003, + 3.81, + 3.8200000000000003, + 3.83, + 3.84, + 3.85, + 3.86, + 3.87, + 3.88, + 3.89, + 3.9, + 3.91, + 3.92, + 3.93, + 3.94, + 3.95, + 3.96, + 3.97, + 3.98, + 3.99, + 4.0, + 4.01, + 4.0200000000000005, + 4.03, + 4.04, + 4.05, + 4.0600000000000005, + 4.07, + 4.08, + 4.09, + 4.1, + 4.11, + 4.12, + 4.13, + 4.14, + 4.15, + 4.16, + 4.17, + 4.18, + 4.19, + 4.2, + 4.21, + 4.22, + 4.23, + 4.24, + 4.25, + 4.26, + 4.2700000000000005, + 4.28, + 4.29, + 4.3, + 4.3100000000000005, + 4.32, + 4.33, + 4.34, + 4.3500000000000005, + 4.36, + 4.37, + 4.38, + 4.39, + 4.4, + 4.41, + 4.42, + 4.43, + 4.44, + 4.45, + 4.46, + 4.47, + 4.48, + 4.49, + 4.5, + 4.51, + 4.5200000000000005, + 4.53, + 4.54, + 4.55, + 4.5600000000000005, + 4.57, + 4.58, + 4.59, + 4.6000000000000005, + 4.61, + 4.62, + 4.63, + 4.64, + 4.65, + 4.66, + 4.67, + 4.68, + 4.69, + 4.7, + 4.71, + 4.72, + 4.73, + 4.74, + 4.75, + 4.76, + 4.7700000000000005, + 4.78, + 4.79, + 4.8, + 4.8100000000000005, + 4.82, + 4.83, + 4.84, + 4.8500000000000005, + 4.86, + 4.87, + 4.88, + 4.89, + 4.9, + 4.91, + 4.92, + 4.93, + 4.94, + 4.95, + 4.96, + 4.97, + 4.98, + 4.99, + 5.0, + 5.01, + 5.0200000000000005, + 5.03, + 5.04, + 5.05, + 5.0600000000000005, + 5.07, + 5.08, + 5.09, + 5.1000000000000005, + 5.11, + 5.12, + 5.13, + 5.14, + 5.15, + 5.16, + 5.17, + 5.18, + 5.19, + 5.2, + 5.21, + 5.22, + 5.23, + 5.24, + 5.25, + 5.26, + 5.2700000000000005, + 5.28, + 5.29, + 5.3, + 5.3100000000000005, + 5.32, + 5.33, + 5.34, + 5.3500000000000005, + 5.36, + 5.37, + 5.38, + 5.39, + 5.4, + 5.41, + 5.42, + 5.43, + 5.44, + 5.45, + 5.46, + 5.47, + 5.48, + 5.49, + 5.5, + 5.51, + 5.5200000000000005, + 5.53, + 5.54, + 5.55, + 5.5600000000000005, + 5.57, + 5.58, + 5.59, + 5.6000000000000005, + 5.61, + 5.62, + 5.63, + 5.64, + 5.65, + 5.66, + 5.67, + 5.68, + 5.69, + 5.7, + 5.71, + 5.72, + 5.73, + 5.74, + 5.75, + 5.76, + 5.7700000000000005, + 5.78, + 5.79, + 5.8, + 5.8100000000000005, + 5.82, + 5.83, + 5.84, + 5.8500000000000005, + 5.86, + 5.87, + 5.88, + 5.89, + 5.9, + 5.91, + 5.92, + 5.93, + 5.94, + 5.95, + 5.96, + 5.97, + 5.98, + 5.99, + 6.0, + 6.01, + 6.0200000000000005, + 6.03, + 6.04, + 6.05, + 6.0600000000000005, + 6.07, + 6.08, + 6.09, + 6.1000000000000005, + 6.11, + 6.12, + 6.13, + 6.140000000000001, + 6.15, + 6.16, + 6.17, + 6.18, + 6.19, + 6.2, + 6.21, + 6.22, + 6.23, + 6.24, + 6.25, + 6.26, + 6.2700000000000005, + 6.28, + 6.29, + 6.3, + 6.3100000000000005, + 6.32, + 6.33, + 6.34, + 6.3500000000000005, + 6.36, + 6.37, + 6.38, + 6.390000000000001, + 6.4, + 6.41, + 6.42, + 6.43, + 6.44, + 6.45, + 6.46, + 6.47, + 6.48, + 6.49, + 6.5, + 6.51, + 6.5200000000000005, + 6.53, + 6.54, + 6.55, + 6.5600000000000005, + 6.57, + 6.58, + 6.59, + 6.6000000000000005, + 6.61, + 6.62, + 6.63, + 6.640000000000001, + 6.65, + 6.66, + 6.67, + 6.68, + 6.69, + 6.7, + 6.71, + 6.72, + 6.73, + 6.74, + 6.75, + 6.76, + 6.7700000000000005, + 6.78, + 6.79, + 6.8, + 6.8100000000000005, + 6.82, + 6.83, + 6.84, + 6.8500000000000005, + 6.86, + 6.87, + 6.88, + 6.890000000000001, + 6.9, + 6.91, + 6.92, + 6.93, + 6.94, + 6.95, + 6.96, + 6.97, + 6.98, + 6.99, + 7.0, + 7.01, + 7.0200000000000005, + 7.03, + 7.04, + 7.05, + 7.0600000000000005, + 7.07, + 7.08, + 7.09, + 7.1000000000000005, + 7.11, + 7.12, + 7.13, + 7.140000000000001, + 7.15, + 7.16, + 7.17, + 7.18, + 7.19, + 7.2, + 7.21, + 7.22, + 7.23, + 7.24, + 7.25, + 7.26, + 7.2700000000000005, + 7.28, + 7.29, + 7.3, + 7.3100000000000005, + 7.32, + 7.33, + 7.34, + 7.3500000000000005, + 7.36, + 7.37, + 7.38, + 7.390000000000001, + 7.4, + 7.41, + 7.42, + 7.43, + 7.44, + 7.45, + 7.46, + 7.47, + 7.48, + 7.49, + 7.5, + 7.51, + 7.5200000000000005, + 7.53, + 7.54, + 7.55, + 7.5600000000000005, + 7.57, + 7.58, + 7.59, + 7.6000000000000005, + 7.61, + 7.62, + 7.63, + 7.640000000000001, + 7.65, + 7.66, + 7.67, + 7.68, + 7.69, + 7.7, + 7.71, + 7.72, + 7.73, + 7.74, + 7.75, + 7.76, + 7.7700000000000005, + 7.78, + 7.79, + 7.8, + 7.8100000000000005, + 7.82, + 7.83, + 7.84, + 7.8500000000000005, + 7.86, + 7.87, + 7.88, + 7.890000000000001, + 7.9, + 7.91, + 7.92, + 7.930000000000001, + 7.94, + 7.95, + 7.96, + 7.97, + 7.98, + 7.99, + 8.0, + 8.01, + 8.02, + 8.03, + 8.040000000000001, + 8.05, + 8.06, + 8.07, + 8.08, + 8.09, + 8.1, + 8.11, + 8.120000000000001, + 8.13, + 8.14, + 8.15, + 8.16, + 8.17, + 8.18, + 8.19, + 8.2, + 8.21, + 8.22, + 8.23, + 8.24, + 8.25, + 8.26, + 8.27, + 8.28, + 8.290000000000001, + 8.3, + 8.31, + 8.32, + 8.33, + 8.34, + 8.35, + 8.36, + 8.370000000000001, + 8.38, + 8.39, + 8.4, + 8.41, + 8.42, + 8.43, + 8.44, + 8.45, + 8.46, + 8.47, + 8.48, + 8.49, + 8.5, + 8.51, + 8.52, + 8.53, + 8.540000000000001, + 8.55, + 8.56, + 8.57, + 8.58, + 8.59, + 8.6, + 8.61, + 8.620000000000001, + 8.63, + 8.64, + 8.65, + 8.66, + 8.67, + 8.68, + 8.69, + 8.700000000000001, + 8.71, + 8.72, + 8.73, + 8.74, + 8.75, + 8.76, + 8.77, + 8.78, + 8.790000000000001, + 8.8, + 8.81, + 8.82, + 8.83, + 8.84, + 8.85, + 8.86, + 8.870000000000001, + 8.88, + 8.89, + 8.9, + 8.91, + 8.92, + 8.93, + 8.94, + 8.950000000000001, + 8.96, + 8.97, + 8.98, + 8.99, + 9.0, + 9.01, + 9.02, + 9.03, + 9.040000000000001, + 9.05, + 9.06, + 9.07, + 9.08, + 9.09, + 9.1, + 9.11, + 9.120000000000001, + 9.13, + 9.14, + 9.15, + 9.16, + 9.17, + 9.18, + 9.19, + 9.200000000000001, + 9.21, + 9.22, + 9.23, + 9.24, + 9.25, + 9.26, + 9.27, + 9.28, + 9.290000000000001, + 9.3, + 9.31, + 9.32, + 9.33, + 9.34, + 9.35, + 9.36, + 9.370000000000001, + 9.38, + 9.39, + 9.4, + 9.41, + 9.42, + 9.43, + 9.44, + 9.450000000000001, + 9.46, + 9.47, + 9.48, + 9.49, + 9.5, + 9.51, + 9.52, + 9.53, + 9.540000000000001, + 9.55, + 9.56, + 9.57, + 9.58, + 9.59, + 9.6, + 9.61, + 9.620000000000001, + 9.63, + 9.64, + 9.65, + 9.66, + 9.67, + 9.68, + 9.69, + 9.700000000000001, + 9.71, + 9.72, + 9.73, + 9.74, + 9.75, + 9.76, + 9.77, + 9.78, + 9.790000000000001, + 9.8, + 9.81, + 9.82, + 9.83, + 9.84, + 9.85, + 9.86, + 9.870000000000001, + 9.88, + 9.89, + 9.9, + 9.91, + 9.92, + 9.93, + 9.94, + 9.950000000000001, + 9.96, + 9.97, + 9.98, + 9.99 + ], + "pressures_start": [ + 7.0, + 7.030386979272772, + 7.0607739585455445, + 7.091160937818317, + 7.121547917091089, + 7.15193489636386, + 7.1823218756366325, + 7.212708854909405, + 7.243095834182177, + 7.273482813454949, + 7.303869792727721, + 7.334256772000494, + 7.364643751273265, + 7.395030730546037, + 7.425417709818809, + 7.455804689091582, + 7.486191668364354, + 7.516578647637126, + 7.546965626909898, + 7.577352606182671, + 7.607739585455443, + 7.638126564728214, + 7.668513544000986, + 7.698900523273759, + 7.729287502546531, + 7.759674481819303, + 7.790061461092075, + 7.8204484403648475, + 7.85083541963762, + 7.881222398910391, + 7.911609378183163, + 7.941996357455936, + 7.972383336728708, + 8.002770316001481, + 8.033157295274252, + 8.063544274547024, + 8.093931253819797, + 8.124318233092568, + 8.154705212365341, + 8.185092191638113, + 8.215479170910886, + 8.245866150183657, + 8.276253129456428, + 8.306640108729201, + 8.337027088001973, + 8.367414067274746, + 8.397801046547517, + 8.42818802582029, + 8.458575005093062, + 8.488961984365833, + 8.519348963638606, + 8.549735942911378, + 8.58012292218415, + 8.610509901456922, + 8.640896880729695, + 8.671283860002466, + 8.70167083927524, + 8.73205781854801, + 8.762444797820782, + 8.792831777093555, + 8.823218756366327, + 8.8536057356391, + 8.883992714911871, + 8.914379694184644, + 8.944766673457416, + 8.975153652730189, + 9.00554063200296, + 9.035927611275731, + 9.066314590548505, + 9.096701569821276, + 9.127088549094049, + 9.15747552836682, + 9.187862507639593, + 9.218249486912365, + 9.248636466185136, + 9.27902344545791, + 9.30941042473068, + 9.339797404003454, + 9.370184383276225, + 9.400571362548998, + 9.43095834182177, + 9.46134532109454, + 9.491732300367314, + 9.522119279640087, + 9.552506258912858, + 9.58289323818563, + 9.613280217458403, + 9.643667196731174, + 9.674054176003946, + 9.704441155276719, + 9.734828134549492, + 9.765215113822263, + 9.795602093095034, + 9.825989072367808, + 9.856376051640579, + 9.886763030913352, + 9.917150010186123, + 9.947536989458897, + 9.977923968731668, + 10.00831094800444, + 10.038697927277212, + 10.069084906549984, + 10.099471885822757, + 10.129858865095528, + 10.160245844368301, + 10.190632823641073, + 10.221019802913844, + 10.251406782186617, + 10.281793761459388, + 10.312180740732162, + 10.342567720004933, + 10.372954699277706, + 10.403341678550477, + 10.43372865782325, + 10.464115637096022, + 10.494502616368795, + 10.524889595641564, + 10.555276574914338, + 10.58566355418711, + 10.616050533459882, + 10.646437512732653, + 10.676824492005426, + 10.707211471278198, + 10.737598450550971, + 10.767985429823742, + 10.798372409096515, + 10.828759388369287, + 10.859146367642058, + 10.889533346914831, + 10.919920326187604, + 10.950307305460376, + 10.980694284733147, + 11.01108126400592, + 11.041468243278693, + 11.071855222551465, + 11.102242201824236, + 11.132629181097009, + 11.16301616036978, + 11.193403139642552, + 11.223790118915325, + 11.254177098188098, + 11.284564077460868, + 11.31495105673364, + 11.345338036006414, + 11.375725015279185, + 11.406111994551956, + 11.43649897382473, + 11.466885953097503, + 11.497272932370272, + 11.527659911643045, + 11.558046890915818, + 11.58843387018859, + 11.618820849461361, + 11.649207828734134, + 11.679594808006907, + 11.709981787279679, + 11.74036876655245, + 11.770755745825223, + 11.801142725097995, + 11.831529704370766, + 11.861916683643539, + 11.892303662916312, + 11.922690642189083, + 11.953077621461855, + 11.983464600734628, + 12.013851580007401, + 12.044238559280172, + 12.074625538552944, + 12.105012517825717, + 12.135399497098488, + 12.16578647637126, + 12.196173455644033, + 12.226560434916804, + 12.256947414189575, + 12.287334393462348, + 12.317721372735122, + 12.348108352007893, + 12.378495331280664, + 12.408882310553437, + 12.43926928982621, + 12.469656269098982, + 12.500043248371753, + 12.530430227644526, + 12.560817206917298, + 12.591204186190069, + 12.621591165462842, + 12.651978144735615, + 12.682365124008387, + 12.712752103281158, + 12.743139082553931, + 12.773526061826704, + 12.803913041099475, + 12.834300020372247, + 12.86468699964502, + 12.895073978917791, + 12.925460958190563, + 12.955847937463336, + 12.986234916736107, + 13.016621896008878, + 13.047008875281652, + 13.077395854554425, + 12.99819269436744, + 12.813920076281685, + 12.528712831775952, + 12.14845020967558, + 11.680637518344213, + 11.134260101821067, + 10.519612457456311, + 9.84810571712261, + 9.13205706831101, + 8.384464979614227, + 7.618774312742968, + 6.848635547062214, + 6.087662410769747, + 5.349192204697314, + 4.646053021091793, + 3.99034190273164, + 3.3932177607479046, + 2.864712577133008, + 2.4135640658480026, + 2.0470725613826968, + 1.7709844531772125, + 1.5894039967956681, + 1.5047348170646524, + 1.517651883874966, + 1.6271041975794347, + 1.8303478775638018, + 2.123008814198112, + 2.4991735303103875, + 2.9515064124613, + 3.4713910229665905, + 4.049092798423399, + 4.673940086221254, + 5.334520172969713, + 6.018886722723541, + 6.714774871972396, + 7.409820125048403, + 8.091777159146128, + 8.748734682566344, + 9.369322591906098, + 9.942907841345308, + 10.459775666428644, + 10.911293091241038, + 11.290051986099261, + 11.589989326425346, + 11.806482725192623, + 11.936419763480185, + 11.978240118014032, + 11.931949972559993, + 11.799108692950501, + 11.58278823464129, + 11.28750622841602, + 10.91913414588769, + 10.484782373919629, + 9.992664418713549, + 9.451942809483189, + 8.872559572556154, + 8.265054394521702, + 7.640373783753514, + 7.009674670399309, + 6.384125953946432, + 5.7747115140494385, + 5.192038144848963, + 4.646151757027878, + 4.146365017889147, + 3.7010993713628015, + 3.3177441015353346, + 3.0025347803767874, + 2.7604530788830166, + 2.595149527553943, + 2.5088903941913685, + 2.502529412000561, + 2.5755046467279774, + 2.725860345974615, + 2.9502931747555694, + 3.2442218165170065, + 3.601878515541766, + 4.016420761900242, + 4.480060980202099, + 4.9842117840716, + 5.519644104442853, + 6.076655295537727, + 6.645244170934598, + 7.215289825681064, + 7.776731060187915, + 8.319743237897791, + 8.8349094806862, + 9.313383231889944, + 9.747039394087615, + 10.128611473727778, + 10.451812433038233, + 10.711437256263803, + 10.903445576436914, + 11.025023074336762, + 11.074620746370444, + 11.051971535862748, + 10.958084225549335, + 10.795214890775753, + 10.566816605943485, + 10.27746847425869, + 9.932785406306083, + 9.539310400307915, + 9.104391370605342, + 8.636044826020632, + 8.142808912155186, + 7.633588497962493, + 7.117495104568888, + 6.603684541630603, + 6.101195132755869, + 5.618789376824897, + 5.1648018074555235, + 4.746995680294988, + 4.372430940013857, + 4.047345699351593, + 3.777053205535259, + 3.56585597971345, + 3.4169784980952476, + 3.3325194450799946, + 3.3134242149507727, + 3.359477976050294, + 3.4693192462284745, + 3.6404735672052877, + 3.869406514662606, + 4.151594946462078, + 4.481615079140221, + 4.853245698072458, + 5.259584554215099, + 5.693175784303991, + 6.146146015314341, + 6.610346680631895, + 7.07749998674468, + 7.539345926519268, + 7.987787738644957, + 8.415033262158444, + 8.813729728847669, + 9.1770896727416, + 9.499005812063, + 9.774152971511015, + 9.998075357496623, + 10.167257771392372, + 10.279179640939029, + 10.332351062286236, + 10.32633036907735, + 10.261723074715002, + 10.14016236359994, + 9.964271630912181, + 9.737609882741689, + 9.46460110366882, + 9.150448972180925, + 8.801038550957191, + 8.422826794938299, + 8.022723901671622, + 7.607967672778588, + 7.185993160293738, + 6.764299935563107, + 6.350319340576264, + 5.951284062007948, + 5.5741023075549485, + 5.225238763792553, + 4.910604376842278, + 4.635456824391195, + 4.404313343368917, + 4.220877345738201, + 4.087979999710456, + 4.007537679950003, + 3.980525902965885, + 4.0069700680859, + 4.085953025451815, + 4.215639195662629, + 4.393314676239338, + 4.615442493030246, + 4.87773189479935, + 5.17522035097902, + 5.502366699938169, + 5.853153711652784, + 6.221198177352297, + 6.599866521952042, + 6.9823938546326145, + 7.362004329906699, + 7.7320306863612975, + 8.086030862754342, + 8.417899660384075, + 8.721973525111787, + 8.993126659959843, + 9.22685684712858, + 9.419359553356786, + 9.567589111126278, + 9.669306006228625, + 9.723109555311394, + 9.728455520614645, + 9.685658478459152, + 9.5958790283603, + 9.461096196141959, + 9.28406564244716, + 9.068264533110662, + 8.817824155760508, + 8.537451573880396, + 8.232341791921007, + 7.908082059890599, + 7.570550070683391, + 7.225807896273806, + 6.879993568445266, + 6.5392122351684145, + 6.209428814931636, + 5.896364028702616, + 5.60539561380094, + 5.34146641739034, + 5.109000931701864, + 4.911831671106323, + 4.753136605848706, + 4.6353886620976015, + 4.560318076737456, + 4.528888162072656, + 4.54128479453562, + 4.596919696911004, + 4.6944473398459365, + 4.83179504980195, + 5.006205681280889, + 5.214291995088333, + 5.452101685281823, + 5.715191818653825, + 5.998711295101918, + 6.29748980758471, + 6.606131678620783, + 6.919112878015579, + 7.230879484724627, + 7.535945844958614, + 7.82899069873716, + 8.104949597487227, + 8.359102014816623, + 8.58715165962259, + 8.785298633105354, + 8.950302226493472, + 9.079533331427761, + 9.171015626733332, + 9.223454910218194, + 9.236256158445281, + 9.209528117278, + 9.144075447473522, + 9.04137866877623, + 8.903562359000833, + 8.733352267787575, + 8.53402219456127, + 8.309331653498234, + 8.063455502085027, + 7.800906841594397, + 7.526454605370311, + 7.245037332513577, + 6.9616746791695485, + 6.681378246406191, + 6.40906330239687, + 6.14946294754699, + 5.907046215072963, + 5.68594151757598, + 5.489866744011124, + 5.32206718321448, + 5.185262302257889, + 5.08160224313206, + 5.012634722655673, + 4.979282831339911, + 4.981834030625571, + 5.019940447976321, + 5.092630369310828, + 5.198330631715016, + 5.334899429728873, + 5.499668869035397, + 5.689496435169581, + 5.900824394731858, + 6.129746015042945, + 6.372077377379095, + 6.6234334706547555, + 6.879307188042262, + 7.135149809464364, + 7.38645153865886, + 7.628820674626672, + 7.858060033330437, + 8.070239295660874, + 8.261762040670856, + 8.429426327236794, + 8.57047781062767, + 8.68265452060883, + 8.76422258206937, + 8.81400232489471, + 8.831384403894937, + 8.81633572890363, + 8.769395186477256, + 8.691659314738104, + 8.584758268649338, + 8.450822581327996, + 8.292441384985912, + 8.112612900041867, + 7.914688130425932, + 7.702308814945437, + 7.479340776981486, + 7.249803886266292, + 7.017799895975661, + 6.787439445167506, + 6.562769520427717, + 6.347702651573665, + 6.145949074942066, + 5.960953035067218, + 5.795834312726662, + 5.653335966019362, + 5.535779153293576, + 5.445025774570478, + 5.382449524068747, + 5.348915793162585, + 5.344770703381473, + 5.369839385754412, + 5.423433458823295, + 5.504367495895736, + 5.610984115409983, + 5.741187179363083, + 5.892482446167589, + 6.062024898408032, + 6.2466718548782225, + 6.443040881827235, + 6.647571442051195, + 6.856589163530248, + 7.066371572566976, + 7.2732141203102545, + 7.473495336257569, + 7.663739967557932, + 7.840679008073321, + 8.001305585230586, + 8.14292575442251, + 8.263203348504161, + 8.360198141921042, + 8.432396713103609, + 8.478735522679976, + 8.498615866349777, + 8.491910507376465, + 8.458961941974271, + 8.400572398757777, + 8.317985818282624, + 8.212862198007201, + 8.087244819338581, + 7.9435209945434675, + 7.784377080157817, + 7.612748598301342, + 7.431766386443373, + 7.244699758412344, + 7.054897703835331, + 6.8657291791084605, + 6.680523550127934, + 6.502512235392292, + 6.334772568078849, + 6.180174847987522, + 6.041333489822015, + 5.920563094420039, + 5.81984017578678, + 5.74077117090202, + 5.684567243226641, + 5.6520262667632615, + 5.643522247681169, + 5.659002307236236, + 5.697991215380181, + 5.759603331437531, + 5.842561678866738, + 5.945223757663348, + 6.06561358253507, + 6.201459329547331, + 6.350235880278511, + 6.509211472187369, + 6.6754975981857285, + 6.846101248362068, + 7.017978553165729, + 7.188088870592747, + 7.353448360164629, + 7.5111821036143, + 7.658573865743084, + 7.793112638161099, + 7.912535172567063, + 8.014863787615145, + 8.098438822774307, + 8.161945212236516, + 8.204432760028816, + 8.225329812054792, + 8.224450139758565, + 8.201992971335041, + 8.158536227747486, + 8.09502314011785, + 8.01274254024047, + 7.913303225040158, + 7.798602896880141, + 7.670792273009365, + 7.532235037592771, + 7.385464377374692, + 7.233136895998279, + 7.07798474150611, + 6.922766806005161, + 6.770219865588804, + 6.62301052233724, + 6.483688788808742, + 6.354644119388601, + 6.238064642943458, + 6.13590028842988, + 6.049830420645241, + 5.981236518595743, + 5.931180335572032, + 5.9003878796848666, + 5.889239448151704, + 5.897765839938984, + 5.925650761400607, + 5.972239330257633, + 6.036552476559746, + 6.117306937014296, + 6.2129404430289235, + 6.321641614629424, + 6.4413839935737025, + 6.569963580796863, + 6.705039186903186, + 6.844174860663909, + 6.984883630049101, + 7.124671773642361, + 7.261082837536044, + 7.3917406239132974, + 7.514390402178655, + 7.626937631152599, + 7.727483530723607, + 7.814356902471101, + 7.88614166996369, + 7.941699689356006, + 7.98018846807617, + 8.001073522212419, + 8.004135199990895, + 7.989469897745826, + 7.957485694254893, + 7.908892527488756, + 7.844687132984779, + 7.76613305354923, + 7.6747361142630055, + 7.572215833381148, + 7.4604733073891225, + 7.341556166092361, + 7.21762124023856, + 7.090895619075696, + 6.963636797916437, + 6.838092625915106, + 6.7164617617933775, + 6.60085533032593, + 6.493260445384807, + 6.395506226820312, + 6.309232889201914, + 6.235864421414659, + 6.176585308427642, + 6.132321671486884, + 6.1037271219217795, + 6.091173538170943, + 6.094746887077285, + 6.114248120559163, + 6.149199089032067, + 6.198853325013317, + 6.262211465725917, + 6.338041003690768, + 6.424899980625322, + 6.521164173698576, + 6.625057265432709, + 6.734683440236911, + 6.8480618124808945, + 6.963162063749433, + 7.077940650853889, + 7.190376941501665, + 7.298508641224991, + 7.4004658930335605, + 7.494503459871398, + 7.579030438732028, + 7.652637003448293, + 7.714117729796014, + 7.76249112056426, + 7.79701501845854, + 7.817197669827131, + 7.822804280868381, + 7.81385898877269, + 7.790642251733594, + 7.753683742486583, + 7.703750908585027, + 7.641833437633472, + 7.569123935877327, + 7.486995192697857, + 7.396974460603193, + 7.300715229293093, + 7.1999670125128805, + 7.09654369706683, + 6.992291024073035, + 6.889053783029457, + 6.788643299425302, + 6.692805786557801, + 6.6031921121656945, + 6.521329500904743, + 6.448595655169137, + 6.386195730061067, + 6.335142544320294, + 6.296240348759952, + 6.270072408329595, + 6.256992584537988, + 6.2571210328735125, + 6.270344056352639, + 6.296318082714604, + 6.334477660361844, + 6.384047298187252, + 6.444056908143464, + 6.5133605479339325, + 6.590658105582957, + 6.674519518804351, + 6.763411080838446, + 6.855723351428791, + 6.949800167374901, + 7.043968231979061, + 7.136566756892993, + 7.225976633388228, + 7.310648622781853, + 7.389130077344593, + 7.46008973304577, + 7.522340153349862, + 7.5748574482364095, + 7.616797943819457, + 7.6475115344366635, + 7.666551509822664, + 7.67368071386907, + 7.668873957351776, + 7.652316673697103, + 7.624399873179195, + 7.585711515725917, + 7.537024484630384, + 7.479281401847221, + 7.413576579199711, + 7.34113544782951, + 7.263291849786974, + 7.1814636101077856, + 7.097126834504387, + 7.011789396510509, + 6.926964088292373, + 6.844141911268313, + 6.764765976197082, + 6.6902064676889665, + 6.621737105491396, + 6.560513504867903, + 6.507553801517347, + 6.463721863477193, + 6.429713364130367, + 6.406044937686349, + 6.393046582300923, + 6.390857417355252, + 6.3994248413884955, + 6.4185070768381856, + 6.4476790281560135, + 6.486341322077063, + 6.533732343831858, + 6.588943031848309, + 6.650934146866602, + 6.718555690167072, + 6.7905681104703985, + 6.865664910579375, + 6.942496243437512, + 7.019693073299796, + 7.095891471328953, + 7.169756616193955, + 7.2400060790711, + 7.305431988610862, + 7.364921694590111, + 7.417476578651582, + 7.4622286961624, + 7.498454974122643, + 7.525588735458175, + 7.5432283691008655, + 7.551143017097525, + 7.549275203659872, + 7.537740385609555, + 7.516823458115967, + 7.486972303011538, + 7.448788518366969, + 7.403015516528308, + 7.350524222627919, + 7.292296645923436, + 7.22940763151922, + 7.163005129507156, + 7.094289341855172, + 7.024491124115379, + 6.954850028978817, + 6.886592381752183, + 6.820909773978284, + 6.758938350792371, + 6.701739250445711, + 6.650280531093153, + 6.605420890896254, + 6.5678954532988865, + 6.538303850632901, + 6.517100796729134, + 6.504589293723443, + 6.5009165705862895, + 6.506072801926108, + 6.519892606195727, + 6.542059273442389, + 6.57211162504553, + 6.609453362312134, + 6.653364718132802, + 6.703016186870202, + 6.75748407291285, + 6.815767568456932, + 6.876807046563358, + 6.939503236762572, + 7.002736937729009, + 7.065388914994126, + 7.126359631375097, + 7.184588463717247, + 7.239072071526697, + 7.288881600841105, + 7.3331784298912, + 7.371228191286725, + 7.4024128380804335, + 7.426240557509538, + 7.442353375810791, + 7.450532339529158, + 7.450700202428678, + 7.442921591684209, + 7.427400671690611, + 7.404476367783899, + 7.374615254657818, + 7.338402254542636, + 7.2965293275990994, + 7.2497823708350335, + 7.199026571607778, + 7.145190486942529, + 7.089249140070283, + 7.032206440455151, + 6.975077242922723, + 6.918869365200386, + 6.864565881219944, + 6.813107999994109, + 6.765378826942176, + 6.7221882864794065, + 6.6842594618616, + 6.652216581132625, + 6.626574847074182, + 6.607732274881078, + 6.595963664511032, + 6.5914167959567385, + 6.594110895756961, + 6.603937382617914, + 6.620662859773041, + 6.643934282376292, + 6.673286190486969, + 6.708149862714692, + 6.747864212957919, + 6.791688223439766, + 6.838814681907416, + 6.888384969829424, + 6.939504632034247, + 6.991259446731486, + 7.042731708408175, + 7.093016434764932, + 7.141237212633028, + 7.186561406582147, + 7.228214467494422, + 7.2654930964627855, + 7.297777041614264, + 7.324539331434183, + 7.345354777386307, + 7.359906610543809, + 7.367991150981354, + 7.3695204442119, + 7.364522835343618, + 7.353141488234128, + 7.335630893083973, + 7.312351441005086, + 7.283762177513202, + 7.250411878051196, + 7.21292861702259, + 7.172008026924542, + 7.128400465602451, + 7.0828973270567195, + 7.036316744343773, + 6.989488941732844, + 6.943241497293566, + 6.898384776464732, + 6.8556977919426565, + 6.815914735557788, + 6.779712413889812, + 6.747698801484995, + 6.720402904033792, + 6.698266099151549, + 6.6816350949433785, + 6.670756616832807, + 6.665773901735483, + 6.666725046131726, + 6.673543221517961, + 6.686058737684705, + 6.704002901859758, + 6.7270135905357185, + 6.75464242131101, + 6.786363384818724, + 6.821582772259365, + 6.859650212601866, + 6.899870615524602, + 6.941516801921768, + 6.9838425935206665, + 7.026096126989563, + 7.067533155937608, + 7.1074301064179926, + 7.145096657868192, + 7.1798876317110265, + 7.21121398388218, + 7.238552715064923, + 7.261455533062829, + 7.279556125135542, + 7.2925759238263375, + 7.300328277349616, + 7.30272096448189, + 7.29975702358975, + 7.2915338954034885, + 7.278240908873957, + 7.260155168411361, + 7.237635928493636, + 7.211117567571676, + 7.181101296946316, + 7.148145761447685, + 7.11285670695979, + 7.075875904806616, + 7.037869534512937, + 6.999516234300919, + 6.961495032774691, + 6.924473375538379, + 6.889095457016717, + 6.855971060592818, + 6.825665099503633, + 6.7986880369568174, + 6.775487346927955, + 6.75644015738964, + 6.74184719568374, + 6.731928131783694, + 6.726818389743601, + 6.726567471156227, + 6.731138807418216, + 6.740411130508923, + 6.75418132530736, + 6.772168700666794, + 6.794020591985914, + 6.819319185279753, + 6.847589432148653, + 6.878307906914722, + 6.910912441841256, + 6.944812364018672, + 6.97939914838258, + 7.014057295559069, + 7.0481752408830705, + 7.081156102019857, + 7.112428077089546, + 7.141454312942308, + 7.167742074094016, + 7.190851056590038, + 7.210400707452126, + 7.226076429068825, + 7.237634568564135, + 7.244906114441142, + 7.24779904624147, + 7.246299307164094, + 7.240470394115436, + 7.230451584081639, + 7.216454839593712, + 7.198760458980771, + 7.177711558679491, + 7.153707494720461, + 7.127196348308922, + 7.098666615861714, + 7.068638256702384, + 7.037653261646976, + 7.006265912782022, + 6.975032908743074, + 6.944503530702552, + 6.915210022080011, + 6.887658349760552, + 6.8623195064664015, + 6.8396215030401315, + 6.819942185981145, + 6.80360299988732, + 6.790863796787373, + 6.78191877503413, + 6.776893609819304, + 6.775843815840576, + 6.7787543605891525, + 6.785540524523893, + 6.796049982449191, + 6.8100660591027635, + 6.827312091656683, + 6.847456812889866, + 6.870120651525047, + 6.894882830928609, + 6.92128913430012, + 6.948860193841979, + 6.977100153364928, + 7.005505548472352, + 7.033574245945606, + 7.060814284245107, + 7.086752460118922, + 7.1109425120938745, + 7.132972759989396, + 7.1524730703723005, + 7.169121030850268, + 7.182647231036792 + ], + "pressures_mid": [ + 5.6000000000000005, + 5.624309583418218, + 5.648619166836436, + 5.672928750254654, + 5.697238333672871, + 5.721547917091089, + 5.745857500509306, + 5.770167083927524, + 5.794476667345742, + 5.81878625076396, + 5.8430958341821775, + 5.867405417600395, + 5.891715001018612, + 5.91602458443683, + 5.940334167855048, + 5.9646437512732655, + 5.988953334691484, + 6.013262918109701, + 6.037572501527919, + 6.061882084946137, + 6.086191668364354, + 6.110501251782572, + 6.134810835200789, + 6.159120418619008, + 6.183430002037225, + 6.2077395854554425, + 6.232049168873661, + 6.256358752291878, + 6.2806683357100965, + 6.304977919128313, + 6.329287502546531, + 6.353597085964749, + 6.377906669382966, + 6.4022162528011854, + 6.426525836219402, + 6.450835419637619, + 6.475145003055838, + 6.499454586474055, + 6.5237641698922735, + 6.54807375331049, + 6.572383336728709, + 6.596692920146926, + 6.621002503565143, + 6.6453120869833615, + 6.669621670401579, + 6.693931253819797, + 6.718240837238014, + 6.742550420656233, + 6.7668600040744495, + 6.791169587492667, + 6.815479170910885, + 6.839788754329103, + 6.864098337747321, + 6.888407921165538, + 6.912717504583757, + 6.937027088001973, + 6.961336671420192, + 6.985646254838409, + 7.0099558382566265, + 7.034265421674845, + 7.058575005093061, + 7.0828845885112806, + 7.107194171929497, + 7.131503755347715, + 7.155813338765933, + 7.180122922184151, + 7.204432505602369, + 7.228742089020585, + 7.253051672438804, + 7.277361255857021, + 7.301670839275239, + 7.325980422693457, + 7.350290006111675, + 7.374599589529892, + 7.398909172948109, + 7.423218756366328, + 7.447528339784545, + 7.471837923202763, + 7.49614750662098, + 7.520457090039199, + 7.544766673457416, + 7.569076256875633, + 7.593385840293852, + 7.61769542371207, + 7.642005007130287, + 7.666314590548504, + 7.6906241739667225, + 7.71493375738494, + 7.7392433408031565, + 7.763552924221376, + 7.787862507639594, + 7.8121720910578105, + 7.836481674476028, + 7.860791257894246, + 7.885100841312464, + 7.909410424730682, + 7.933720008148899, + 7.958029591567118, + 7.982339174985334, + 8.006648758403552, + 8.030958341821771, + 8.055267925239987, + 8.079577508658206, + 8.103887092076423, + 8.12819667549464, + 8.152506258912858, + 8.176815842331076, + 8.201125425749295, + 8.22543500916751, + 8.24974459258573, + 8.274054176003947, + 8.298363759422164, + 8.322673342840382, + 8.346982926258601, + 8.371292509676818, + 8.395602093095036, + 8.419911676513252, + 8.44422125993147, + 8.468530843349688, + 8.492840426767906, + 8.517150010186123, + 8.541459593604342, + 8.565769177022558, + 8.590078760440777, + 8.614388343858995, + 8.638697927277212, + 8.66300751069543, + 8.687317094113647, + 8.711626677531866, + 8.735936260950083, + 8.760245844368301, + 8.784555427786518, + 8.808865011204736, + 8.833174594622955, + 8.857484178041172, + 8.88179376145939, + 8.906103344877607, + 8.930412928295825, + 8.954722511714042, + 8.97903209513226, + 9.003341678550479, + 9.027651261968694, + 9.051960845386914, + 9.076270428805131, + 9.100580012223348, + 9.124889595641566, + 9.149199179059783, + 9.173508762478003, + 9.197818345896218, + 9.222127929314437, + 9.246437512732655, + 9.270747096150872, + 9.29505667956909, + 9.319366262987307, + 9.343675846405526, + 9.367985429823744, + 9.392295013241961, + 9.416604596660179, + 9.440914180078396, + 9.465223763496613, + 9.48953334691483, + 9.51384293033305, + 9.538152513751267, + 9.562462097169485, + 9.586771680587702, + 9.611081264005922, + 9.635390847424139, + 9.659700430842356, + 9.684010014260574, + 9.708319597678791, + 9.732629181097009, + 9.756938764515226, + 9.781248347933444, + 9.805557931351661, + 9.82986751476988, + 9.854177098188098, + 9.878486681606315, + 9.902796265024532, + 9.92710584844275, + 9.951415431860969, + 9.975725015279187, + 10.000034598697404, + 10.024344182115621, + 10.048653765533839, + 10.072963348952056, + 10.097272932370274, + 10.121582515788493, + 10.14589209920671, + 10.170201682624928, + 10.194511266043145, + 10.218820849461364, + 10.243130432879582, + 10.267440016297797, + 10.291749599716017, + 10.316059183134234, + 10.340368766552452, + 10.364678349970669, + 10.388987933388886, + 10.413297516807104, + 10.437607100225321, + 10.46191668364354, + 10.398554155493953, + 10.251136061025349, + 10.022970265420762, + 9.718760167740465, + 9.34451001467537, + 8.907408081456854, + 8.415689965965049, + 7.878484573698088, + 7.305645654648808, + 6.707571983691382, + 6.095019450194375, + 5.478908437649771, + 4.870129928615798, + 4.279353763757851, + 3.716842416873435, + 3.192273522185312, + 2.7145742085983238, + 2.2917700617064063, + 1.9308512526784023, + 1.6376580491061574, + 1.41678756254177, + 1.2715231974365346, + 1.203787853651722, + 1.214121507099973, + 1.3016833580635478, + 1.4642783020510415, + 1.6984070513584897, + 1.99933882424831, + 2.36120512996904, + 2.7771128183732725, + 3.2392742387387194, + 3.7391520689770035, + 4.267616138375771, + 4.815109378178833, + 5.371819897577917, + 5.927856100038722, + 6.473421727316903, + 6.998987746053075, + 7.495458073524879, + 7.954326273076247, + 8.367820533142917, + 8.729034472992831, + 9.032041588879409, + 9.271991461140278, + 9.4451861801541, + 9.549135810784149, + 9.582592094411226, + 9.545559978047995, + 9.439286954360401, + 9.266230587713032, + 9.030004982732818, + 8.735307316710152, + 8.387825899135704, + 7.9941315349708395, + 7.561554247586551, + 7.098047658044924, + 6.612043515617362, + 6.112299027002812, + 5.607739736319448, + 5.107300763157146, + 4.619769211239551, + 4.153630515879171, + 3.716921405622303, + 3.317092014311318, + 2.9608794970902412, + 2.654195281228268, + 2.40202782430143, + 2.2083624631064134, + 2.0761196220431546, + 2.007112315353095, + 2.0020235296004487, + 2.060403717382382, + 2.180688276779692, + 2.3602345398044555, + 2.5953774532136054, + 2.8815028124334128, + 3.2131366095201934, + 3.5840487841616793, + 3.98736942725728, + 4.415715283554283, + 4.861324236430182, + 5.316195336747679, + 5.772231860544852, + 6.221384848150333, + 6.655794590318234, + 7.06792758454896, + 7.450706585511956, + 7.797631515270092, + 8.102889178982222, + 8.361449946430588, + 8.569149805011042, + 8.722756461149531, + 8.82001845946941, + 8.859696597096356, + 8.841577228690198, + 8.766467380439469, + 8.636171912620602, + 8.453453284754788, + 8.221974779406953, + 7.946228325044867, + 7.631448320246332, + 7.283513096484274, + 6.908835860816506, + 6.514247129724149, + 6.106870798369995, + 5.693996083655111, + 5.282947633304483, + 4.880956106204696, + 4.495031501459918, + 4.131841445964419, + 3.797596544235991, + 3.4979447520110853, + 3.237876559481274, + 3.0216425644282072, + 2.8526847837707603, + 2.7335827984761982, + 2.666015556063996, + 2.6507393719606185, + 2.6875823808402353, + 2.77545539698278, + 2.9123788537642303, + 3.095525211730085, + 3.3212759571696626, + 3.585292063312177, + 3.8825965584579665, + 4.207667643372079, + 4.554540627443193, + 4.916916812251473, + 5.2882773445055165, + 5.661999989395745, + 6.031476741215415, + 6.390230190915966, + 6.732026609726756, + 7.050983783078135, + 7.341671738193281, + 7.5992046496504, + 7.819322377208812, + 7.998460285997298, + 8.133806217113898, + 8.223343712751223, + 8.265880849828989, + 8.26106429526188, + 8.209378459772003, + 8.112129890879952, + 7.971417304729745, + 7.790087906193351, + 7.5716808829350555, + 7.3203591777447405, + 7.040830840765754, + 6.73826143595064, + 6.418179121337298, + 6.086374138222871, + 5.748794528234991, + 5.411439948450486, + 5.080255472461012, + 4.761027249606359, + 4.459281846043959, + 4.180191011034043, + 3.9284835014738224, + 3.7083654595129563, + 3.523450674695134, + 3.376701876590561, + 3.270383999768365, + 3.2060301439600027, + 3.184420722372708, + 3.2055760544687204, + 3.268762420361452, + 3.372511356530103, + 3.51465174099147, + 3.692353994424197, + 3.9021855158394803, + 4.140176280783216, + 4.401893359950535, + 4.6825229693222274, + 4.976958541881838, + 5.279893217561634, + 5.585915083706092, + 5.88960346392536, + 6.185624549089038, + 6.468824690203474, + 6.73431972830726, + 6.97757882008943, + 7.194501327967875, + 7.3814854777028645, + 7.535487642685429, + 7.654071288901022, + 7.735444804982901, + 7.7784876442491155, + 7.782764416491716, + 7.748526782767321, + 7.676703222688241, + 7.568876956913567, + 7.427252513957729, + 7.25461162648853, + 7.054259324608407, + 6.8299612591043175, + 6.585873433536806, + 6.32646564791248, + 6.0564400565467125, + 5.780646317019045, + 5.503994854756213, + 5.231369788134732, + 4.967543051945309, + 4.717091222962092, + 4.484316491040753, + 4.273173133912272, + 4.087200745361492, + 3.9294653368850585, + 3.802509284678965, + 3.708310929678081, + 3.648254461389965, + 3.623110529658125, + 3.633027835628496, + 3.6775357575288035, + 3.7555578718767495, + 3.86543603984156, + 4.004964545024712, + 4.171433596070666, + 4.361681348225459, + 4.57215345492306, + 4.798969036081535, + 5.037991846067769, + 5.284905342896627, + 5.535290302412463, + 5.784703587779703, + 6.028756675966892, + 6.263192558989728, + 6.483959677989782, + 6.687281611853298, + 6.869721327698072, + 7.028238906484283, + 7.160241781194777, + 7.263626665142209, + 7.3368125013866665, + 7.378763928174556, + 7.3890049267562254, + 7.3676224938224, + 7.3152603579788185, + 7.233102935020985, + 7.122849887200667, + 6.98668181423006, + 6.827217755649016, + 6.647465322798587, + 6.450764401668022, + 6.240725473275518, + 6.0211636842962495, + 5.796029866010862, + 5.5693397433356395, + 5.345102597124953, + 5.127250641917496, + 4.919570358037593, + 4.72563697205837, + 4.548753214060784, + 4.391893395208899, + 4.257653746571584, + 4.148209841806311, + 4.0652817945056485, + 4.010107778124539, + 3.983426265071929, + 3.9854672245004568, + 4.015952358381057, + 4.074104295448662, + 4.158664505372013, + 4.267919543783099, + 4.399735095228318, + 4.551597148135666, + 4.720659515785487, + 4.903796812034356, + 5.097661901903276, + 5.298746776523805, + 5.5034457504338095, + 5.708119847571492, + 5.909161230927088, + 6.103056539701338, + 6.28644802666435, + 6.4561914365287, + 6.609409632536686, + 6.743541061789435, + 6.856382248502136, + 6.946123616487064, + 7.011378065655497, + 7.051201859915769, + 7.06510752311595, + 7.053068583122904, + 7.015516149181805, + 6.953327451790483, + 6.867806614919471, + 6.7606580650623975, + 6.63395310798873, + 6.490090320033494, + 6.3317505043407465, + 6.16184705195635, + 5.983472621585189, + 5.799843109013034, + 5.614239916780529, + 5.4299515561340055, + 5.2502156163421745, + 5.0781621212589325, + 4.916759259953653, + 4.768762428053775, + 4.63666745018133, + 4.522668772815489, + 4.428623322634861, + 4.356020619656383, + 4.305959619254998, + 4.279132634530068, + 4.275816562705178, + 4.29587150860353, + 4.338746767058637, + 4.403493996716589, + 4.488787292327987, + 4.5929497434904665, + 4.713985956934072, + 4.849619918726425, + 4.997337483902578, + 5.1544327054617884, + 5.318057153640956, + 5.485271330824198, + 5.653097258053581, + 5.818571296248204, + 5.978796269006056, + 6.130991974046346, + 6.272543206458657, + 6.40104446818447, + 6.514340603538009, + 6.61056267880333, + 6.688158513536834, + 6.745917370482887, + 6.782988418143981, + 6.7988926930798215, + 6.7935284059011725, + 6.767169553579418, + 6.720457919006222, + 6.6543886546261, + 6.570289758405761, + 6.469795855470865, + 6.3548167956347745, + 6.227501664126255, + 6.090198878641074, + 5.945413109154699, + 5.795759806729876, + 5.643918163068265, + 5.492583343286769, + 5.344418840102348, + 5.202009788313834, + 5.067818054463079, + 4.944139878390018, + 4.833066791857612, + 4.7364504755360315, + 4.655872140629424, + 4.592616936721616, + 4.547653794581313, + 4.521621013410609, + 4.514817798144935, + 4.527201845788989, + 4.558392972304145, + 4.607682665150025, + 4.67404934309339, + 4.756179006130679, + 4.852490866028056, + 4.961167463637865, + 5.0801887042228095, + 5.207369177749896, + 5.340398078548583, + 5.476880998689655, + 5.614382842532583, + 5.750471096474198, + 5.8827586881317036, + 6.00894568289144, + 6.126859092594468, + 6.2344901105288795, + 6.330028138053651, + 6.411891030092116, + 6.478751058219446, + 6.529556169789213, + 6.563546208023053, + 6.580263849643834, + 6.5795601118068525, + 6.561594377068033, + 6.52682898219799, + 6.47601851209428, + 6.4101940321923765, + 6.330642580032126, + 6.238882317504113, + 6.136633818407493, + 6.025788030074217, + 5.9083715018997545, + 5.786509516798624, + 5.662387793204888, + 5.5382134448041285, + 5.416175892471044, + 5.298408417869792, + 5.186951031046994, + 5.083715295510881, + 4.990451714354767, + 4.908720230743905, + 4.839864336516193, + 4.784989214876595, + 4.744944268457625, + 4.720310303747893, + 4.711391558521363, + 4.718212671951187, + 4.740520609120486, + 4.777791464206106, + 4.829241981247797, + 4.893845549611437, + 4.970352354423139, + 5.05731329170354, + 5.153107194858962, + 5.25597086463749, + 5.3640313495225485, + 5.475339888531128, + 5.587906904039281, + 5.699737418913889, + 5.808866270028836, + 5.913392499130638, + 6.0115123217429245, + 6.1015501049220795, + 6.181986824578885, + 6.251485521976881, + 6.308913335970953, + 6.353359751484805, + 6.384150774460936, + 6.400858817769936, + 6.403308159992716, + 6.391575918196661, + 6.365988555403915, + 6.3271140219910045, + 6.275749706387824, + 6.212906442839384, + 6.139788891410404, + 6.057772666704919, + 5.968378645911298, + 5.873244932873889, + 5.774096992190849, + 5.672716495260557, + 5.57090943833315, + 5.470474100732085, + 5.373169409434702, + 5.280684264260745, + 5.194608356307846, + 5.11640498145625, + 5.047386311361532, + 4.988691537131728, + 4.941268246742114, + 4.905857337189508, + 4.882981697537424, + 4.8729388305367545, + 4.875797509661829, + 4.89139849644733, + 4.919359271225654, + 4.959082660010655, + 5.009769172580734, + 5.070432802952615, + 5.139919984500258, + 5.216931338958862, + 5.300045812346167, + 5.387746752189529, + 5.478449449984716, + 5.570529650999546, + 5.662352520683111, + 5.752301553201332, + 5.838806912979994, + 5.920372714426849, + 5.995602767897118, + 6.063224350985623, + 6.122109602758634, + 6.171294183836811, + 6.209992896451408, + 6.237612014766832, + 6.253758135861705, + 6.2582434246947045, + 6.2510871910181525, + 6.232513801386876, + 6.202946993989267, + 6.163000726868022, + 6.113466750106777, + 6.055299148701862, + 5.989596154158286, + 5.917579568482555, + 5.840572183434475, + 5.759973610010305, + 5.677234957653464, + 5.593832819258428, + 5.511243026423566, + 5.430914639540242, + 5.354244629246241, + 5.282553689732556, + 5.217063600723795, + 5.15887652413531, + 5.108956584048855, + 5.068114035456236, + 5.036992279007961, + 5.0160579266636764, + 5.0055940676303905, + 5.00569682629881, + 5.016275245082111, + 5.037054466171684, + 5.067582128289476, + 5.107237838549802, + 5.155245526514772, + 5.210688438347146, + 5.272526484466366, + 5.339615615043481, + 5.410728864670757, + 5.4845786811430335, + 5.559840133899922, + 5.63517458558325, + 5.709253405514395, + 5.780781306710583, + 5.848518898225483, + 5.911304061875675, + 5.968071786436616, + 6.01787212267989, + 6.059885958589128, + 6.093438355055566, + 6.118009227549331, + 6.1332412078581315, + 6.138944571095256, + 6.135099165881421, + 6.121853338957683, + 6.099519898543356, + 6.068569212580734, + 6.029619587704308, + 5.983425121477777, + 5.93086126335977, + 5.872908358263608, + 5.81063347982958, + 5.7451708880862284, + 5.67770146760351, + 5.6094315172084075, + 5.541571270633899, + 5.475313529014651, + 5.411812780957666, + 5.352165174151174, + 5.297389684393117, + 5.248410803894323, + 5.206043041213878, + 5.170977490781755, + 5.143770691304294, + 5.1248359501490794, + 5.114437265840738, + 5.112685933884202, + 5.119539873110797, + 5.134805661470549, + 5.158143222524811, + 5.189073057661651, + 5.226985875065487, + 5.271154425478648, + 5.320747317493282, + 5.374844552133658, + 5.432454488376319, + 5.4925319284635, + 5.55399699475001, + 5.615754458639837, + 5.676713177063163, + 5.735805292955164, + 5.792004863256881, + 5.84434559088869, + 5.891937355672089, + 5.933981262921266, + 5.969782956929921, + 5.998763979298115, + 6.02047098836654, + 6.034582695280693, + 6.040914413678021, + 6.039420162927898, + 6.030192308487645, + 6.013458766492774, + 5.989577842409231, + 5.959030814693576, + 5.922412413222647, + 5.880419378102335, + 5.833837316738749, + 5.783526105215376, + 5.730404103605725, + 5.675431473484138, + 5.619592899292304, + 5.563880023183054, + 5.509273905401747, + 5.456727819182627, + 5.407150680633897, + 5.3613914003565695, + 5.320224424874523, + 5.284336712717003, + 5.254316362639109, + 5.230643080506321, + 5.213680637383308, + 5.203671434978755, + 5.200733256469032, + 5.204858241540887, + 5.215914084956582, + 5.233647418753911, + 5.257689300036424, + 5.2875626898497075, + 5.322691774506242, + 5.362412949496162, + 5.40598725833028, + 5.452614054765546, + 5.501445637250686, + 5.5516025894100585, + 5.6021895501832075, + 5.652311131995301, + 5.701087705100078, + 5.747670770973798, + 5.791257657221358, + 5.831105280672884, + 5.8665427439129605, + 5.89698255302938, + 5.9219302704643475, + 5.94099244600763, + 5.9538827006486335, + 5.960425871623326, + 5.960560161942943, + 5.954337273347368, + 5.941920537352489, + 5.92358109422712, + 5.8996922037262545, + 5.870721803634109, + 5.83722346207928, + 5.799825896668027, + 5.759221257286223, + 5.716152389554024, + 5.671399312056227, + 5.625765152364121, + 5.580061794338178, + 5.535095492160309, + 5.491652704975955, + 5.450486399995288, + 5.412303061553741, + 5.3777506291835255, + 5.34740756948928, + 5.3217732649061, + 5.301259877659346, + 5.286185819904863, + 5.2767709316088265, + 5.2731334367653915, + 5.275288716605569, + 5.283149906094332, + 5.296530287818433, + 5.315147425901034, + 5.338628952389576, + 5.366519890171754, + 5.398291370366335, + 5.4333505787518135, + 5.4710517455259335, + 5.510707975863539, + 5.5516037056273975, + 5.593007557385189, + 5.63418536672654, + 5.674413147811946, + 5.7129897701064225, + 5.749249125265718, + 5.782571573995538, + 5.812394477170229, + 5.838221633291411, + 5.859631465147347, + 5.876283821909046, + 5.8879252884350475, + 5.894392920785084, + 5.89561635536952, + 5.891618268274895, + 5.882513190587303, + 5.8685047144671785, + 5.84988115280407, + 5.827009742010562, + 5.800329502440957, + 5.770342893618072, + 5.737606421539634, + 5.702720372481961, + 5.666317861645376, + 5.629053395475019, + 5.591591153386275, + 5.554593197834853, + 5.518707821171786, + 5.484558233554125, + 5.452731788446231, + 5.42376993111185, + 5.398159041187996, + 5.376322323227034, + 5.358612879321239, + 5.345308075954703, + 5.336605293466246, + 5.332619121388387, + 5.333380036905381, + 5.338834577214369, + 5.348846990147765, + 5.363202321487806, + 5.381610872428575, + 5.403713937048808, + 5.4290907078549795, + 5.457266217807493, + 5.487720170081493, + 5.519896492419682, + 5.553213441537415, + 5.587074074816534, + 5.62087690159165, + 5.654026524750087, + 5.685944085134395, + 5.7160773262945535, + 5.743910105368822, + 5.768971187105745, + 5.7908421720519385, + 5.8091644264502635, + 5.823644900108434, + 5.83406073906107, + 5.840262621879693, + 5.842176771585512, + 5.8398056188718, + 5.833227116322791, + 5.822592727099166, + 5.8081241347290895, + 5.790108742794909, + 5.768894054057341, + 5.744881037557054, + 5.718516609158148, + 5.690285365567832, + 5.660700723845293, + 5.63029562761035, + 5.599612987440736, + 5.569196026219753, + 5.539578700430703, + 5.511276365613374, + 5.4847768484742545, + 5.460532079602906, + 5.4389504295654545, + 5.420389877542364, + 5.405152125911712, + 5.393477756546993, + 5.3855425054269555, + 5.3814547117948806, + 5.381253976924982, + 5.384911045934573, + 5.3923289044071385, + 5.403345060245888, + 5.417734960533435, + 5.435216473588731, + 5.455455348223802, + 5.478071545718922, + 5.502646325531778, + 5.528729953473005, + 5.555849891214938, + 5.583519318706064, + 5.611245836447256, + 5.638540192706457, + 5.664924881615885, + 5.689942461671637, + 5.713163450353846, + 5.734193659275213, + 5.752680845272031, + 5.768320565961702, + 5.78086114325506, + 5.790107654851308, + 5.7959248915529145, + 5.798239236993176, + 5.797039445731276, + 5.792376315292349, + 5.784361267265311, + 5.77316387167497, + 5.759008367184617, + 5.742169246943593, + 5.722965995776369, + 5.701757078647137, + 5.678933292689372, + 5.654910605361907, + 5.630122609317581, + 5.605012730225618, + 5.58002632699446, + 5.555602824562042, + 5.532168017664009, + 5.510126679808442, + 5.489855605173122, + 5.4716972024321056, + 5.455953748784917, + 5.442882399909856, + 5.4326910374298985, + 5.425535020027304, + 5.4215148878554436, + 5.420675052672461, + 5.4230034884713225, + 5.4284324196191145, + 5.436839985959353, + 5.448052847282211, + 5.4618496733253465, + 5.477965450311893, + 5.496096521220038, + 5.515906264742888, + 5.537031307440096, + 5.559088155073583, + 5.581680122691942, + 5.604404438777882, + 5.626859396756485, + 5.648651427396086, + 5.669401968095138, + 5.6887540096751, + 5.706378207991517, + 5.72197845629784, + 5.735296824680215, + 5.746117784829433 + ], + "pressures_end": [ + 4.2, + 4.218232187563663, + 4.236464375127326, + 4.25469656269099, + 4.272928750254653, + 4.291160937818316, + 4.3093931253819795, + 4.327625312945643, + 4.345857500509306, + 4.364089688072969, + 4.382321875636633, + 4.400554063200296, + 4.418786250763959, + 4.437018438327622, + 4.455250625891286, + 4.4734828134549485, + 4.491715001018612, + 4.5099471885822755, + 4.528179376145939, + 4.5464115637096025, + 4.564643751273265, + 4.582875938836929, + 4.601108126400591, + 4.619340313964255, + 4.637572501527918, + 4.655804689091582, + 4.674036876655245, + 4.692269064218908, + 4.7105012517825715, + 4.728733439346234, + 4.746965626909898, + 4.765197814473561, + 4.783430002037225, + 4.801662189600888, + 4.819894377164551, + 4.838126564728214, + 4.856358752291878, + 4.8745909398555405, + 4.892823127419205, + 4.9110553149828675, + 4.929287502546531, + 4.947519690110194, + 4.965751877673857, + 4.983984065237521, + 5.002216252801183, + 5.020448440364848, + 5.03868062792851, + 5.056912815492174, + 5.0751450030558365, + 5.0933771906195, + 5.1116093781831635, + 5.129841565746826, + 5.1480737533104906, + 5.166305940874153, + 5.184538128437817, + 5.202770316001479, + 5.221002503565144, + 5.239234691128806, + 5.257466878692469, + 5.275699066256133, + 5.293931253819796, + 5.3121634413834595, + 5.330395628947122, + 5.348627816510787, + 5.366860004074449, + 5.385092191638113, + 5.403324379201776, + 5.421556566765439, + 5.439788754329102, + 5.458020941892765, + 5.476253129456429, + 5.494485317020092, + 5.5127175045837555, + 5.530949692147419, + 5.549181879711082, + 5.567414067274745, + 5.585646254838408, + 5.603878442402072, + 5.622110629965735, + 5.640342817529398, + 5.658575005093062, + 5.6768071926567245, + 5.695039380220388, + 5.713271567784052, + 5.731503755347715, + 5.749735942911378, + 5.767968130475041, + 5.786200318038705, + 5.804432505602367, + 5.822664693166031, + 5.840896880729695, + 5.859129068293358, + 5.8773612558570205, + 5.895593443420684, + 5.9138256309843475, + 5.932057818548011, + 5.950290006111674, + 5.968522193675338, + 5.986754381239001, + 6.004986568802663, + 6.023218756366327, + 6.04145094392999, + 6.059683131493654, + 6.0779153190573165, + 6.096147506620981, + 6.1143796941846436, + 6.132611881748306, + 6.15084406931197, + 6.169076256875633, + 6.187308444439297, + 6.205540632002959, + 6.223772819566624, + 6.242005007130286, + 6.26023719469395, + 6.2784693822576125, + 6.296701569821277, + 6.314933757384939, + 6.333165944948602, + 6.351398132512267, + 6.369630320075929, + 6.387862507639592, + 6.406094695203255, + 6.424326882766919, + 6.442559070330582, + 6.460791257894245, + 6.479023445457909, + 6.497255633021572, + 6.515487820585235, + 6.533720008148898, + 6.551952195712563, + 6.570184383276225, + 6.588416570839888, + 6.606648758403552, + 6.624880945967216, + 6.643113133530878, + 6.661345321094541, + 6.679577508658205, + 6.697809696221868, + 6.716041883785531, + 6.734274071349195, + 6.752506258912859, + 6.77073844647652, + 6.788970634040184, + 6.807202821603848, + 6.825435009167511, + 6.8436671967311735, + 6.861899384294838, + 6.880131571858501, + 6.898363759422163, + 6.916595946985827, + 6.934828134549491, + 6.953060322113154, + 6.971292509676816, + 6.989524697240481, + 7.007756884804144, + 7.025989072367807, + 7.0442212599314695, + 7.062453447495134, + 7.080685635058797, + 7.098917822622459, + 7.117150010186124, + 7.135382197749787, + 7.15361438531345, + 7.171846572877112, + 7.190078760440777, + 7.20831094800444, + 7.226543135568103, + 7.2447753231317655, + 7.26300751069543, + 7.281239698259093, + 7.299471885822755, + 7.31770407338642, + 7.335936260950082, + 7.354168448513745, + 7.372400636077408, + 7.390632823641073, + 7.408865011204735, + 7.427097198768398, + 7.445329386332062, + 7.463561573895726, + 7.481793761459389, + 7.500025949023051, + 7.518258136586716, + 7.536490324150378, + 7.554722511714041, + 7.572954699277705, + 7.591186886841369, + 7.609419074405031, + 7.627651261968694, + 7.645883449532358, + 7.664115637096022, + 7.682347824659685, + 7.700580012223348, + 7.718812199787012, + 7.737044387350674, + 7.755276574914337, + 7.773508762478001, + 7.791740950041664, + 7.8099731376053265, + 7.828205325168991, + 7.846437512732654, + 7.798915616620463, + 7.68835204576901, + 7.517227699065571, + 7.289070125805348, + 7.008382511006528, + 6.6805560610926396, + 6.311767474473787, + 5.908863430273566, + 5.479234240986606, + 5.030678987768536, + 4.57126458764578, + 4.109181328237328, + 3.652597446461848, + 3.209515322818388, + 2.787631812655076, + 2.394205141638984, + 2.0359306564487425, + 1.7188275462798048, + 1.4481384395088015, + 1.228243536829618, + 1.0625906719063274, + 0.9536423980774008, + 0.9028408902387914, + 0.9105911303249795, + 0.9762625185476608, + 1.098208726538281, + 1.273805288518867, + 1.4995041181862325, + 1.77090384747678, + 2.082834613779954, + 2.4294556790540396, + 2.8043640517327524, + 3.2007121037818274, + 3.6113320336341244, + 4.028864923183438, + 4.445892075029041, + 4.855066295487677, + 5.249240809539806, + 5.621593555143659, + 5.965744704807185, + 6.275865399857186, + 6.546775854744623, + 6.774031191659557, + 6.9539935958552075, + 7.083889635115574, + 7.16185185808811, + 7.186944070808419, + 7.159169983535995, + 7.0794652157703, + 6.949672940784774, + 6.772503737049612, + 6.551480487532613, + 6.290869424351777, + 5.995598651228129, + 5.671165685689913, + 5.323535743533692, + 4.959032636713021, + 4.5842242702521085, + 4.2058048022395855, + 3.830475572367859, + 3.464826908429663, + 3.1152228869093777, + 2.787691054216727, + 2.4878190107334883, + 2.220659622817681, + 1.9906464609212007, + 1.8015208682260724, + 1.65627184732981, + 1.5570897165323656, + 1.505334236514821, + 1.5015176472003364, + 1.5453027880367864, + 1.6355162075847691, + 1.7701759048533416, + 1.9465330899102038, + 2.1611271093250592, + 2.4098524571401447, + 2.688036588121259, + 2.9905270704429596, + 3.3117864626657116, + 3.6459931773226364, + 3.9871465025607584, + 4.329173895408639, + 4.666038636112749, + 4.991845942738674, + 5.30094568841172, + 5.588029939133966, + 5.848223636452569, + 6.077166884236667, + 6.271087459822939, + 6.426862353758282, + 6.542067345862148, + 6.615013844602057, + 6.644772447822266, + 6.631182921517649, + 6.574850535329601, + 6.477128934465452, + 6.340089963566091, + 6.166481084555214, + 5.959671243783649, + 5.723586240184749, + 5.462634822363205, + 5.1816268956123785, + 4.885685347293111, + 4.580153098777496, + 4.270497062741333, + 3.9622107249783616, + 3.660717079653521, + 3.371273626094938, + 3.098881084473314, + 2.848197408176993, + 2.6234585640083137, + 2.4284074196109553, + 2.2662319233211554, + 2.1395135878280698, + 2.0501870988571484, + 1.9995116670479967, + 1.9880545289704634, + 2.015686785630176, + 2.0815915477370845, + 2.1842841403231725, + 2.3216439087975633, + 2.4909569678772465, + 2.688969047484133, + 2.9119474188434746, + 3.1557507325290595, + 3.4159054705823944, + 3.6876876091886044, + 3.9662080083791365, + 4.246499992046808, + 4.5236075559115605, + 4.7926726431869735, + 5.049019957295066, + 5.288237837308601, + 5.5062538036449595, + 5.6994034872378, + 5.864491782906609, + 5.998845214497973, + 6.100354662835422, + 6.167507784563417, + 6.1994106373717415, + 6.1957982214464105, + 6.157033844829001, + 6.084097418159963, + 5.978562978547308, + 5.842565929645013, + 5.678760662201292, + 5.490269383308555, + 5.280623130574314, + 5.0536960769629795, + 4.813634341002973, + 4.5647806036671525, + 4.311595896176243, + 4.058579961337864, + 3.810191604345758, + 3.570770437204769, + 3.344461384532969, + 3.1351432582755314, + 2.9463626261053664, + 2.7812740946347168, + 2.6425880060213505, + 2.5325264074429206, + 2.452787999826273, + 2.404522607970002, + 2.388315541779531, + 2.40418204085154, + 2.451571815271089, + 2.529383517397577, + 2.6359888057436023, + 2.7692654958181473, + 2.92663913687961, + 3.1051322105874117, + 3.3014200199629014, + 3.51189222699167, + 3.7327189064113777, + 3.959919913171225, + 4.189436312779568, + 4.417202597944019, + 4.6392184118167785, + 4.8516185176526045, + 5.050739796230444, + 5.233184115067072, + 5.3958759959759055, + 5.536114108277148, + 5.651615732014071, + 5.740553466675767, + 5.801583603737175, + 5.833865733186836, + 5.837073312368787, + 5.811395087075491, + 5.75752741701618, + 5.676657717685175, + 5.570439385468296, + 5.440958719866397, + 5.2906944934563045, + 5.122470944328238, + 4.939405075152604, + 4.7448492359343595, + 4.542330042410034, + 4.335484737764284, + 4.127996141067159, + 3.9235273411010487, + 3.725657288958981, + 3.5378184172215694, + 3.363237368280564, + 3.2048798504342035, + 3.065400559021118, + 2.9470990026637938, + 2.8518819635092236, + 2.781233197258561, + 2.7361908460424735, + 2.7173328972435935, + 2.724770876721372, + 2.7581518181466023, + 2.816668403907562, + 2.8990770298811697, + 3.003723408768533, + 3.128575197053, + 3.2712610111690936, + 3.4291150911922945, + 3.599226777061151, + 3.7784938845508256, + 3.9636790071724697, + 4.151467726809347, + 4.338527690834776, + 4.521567506975169, + 4.697394419242296, + 4.862969758492336, + 5.015461208889973, + 5.152290995773554, + 5.271179179863212, + 5.370181335896083, + 5.447719998856656, + 5.50260937604, + 5.534072946130917, + 5.541753695067168, + 5.525716870366799, + 5.486445268484113, + 5.424827201265738, + 5.3421374154005, + 5.240011360672545, + 5.120413316736762, + 4.98559899209894, + 4.838073301251016, + 4.680544104956638, + 4.515872763222187, + 4.347022399508146, + 4.177004807501729, + 4.008826947843715, + 3.845437981438122, + 3.6896777685281936, + 3.544227729043778, + 3.411564910545588, + 3.2939200464066745, + 3.193240309928688, + 3.111157381354733, + 3.048961345879236, + 3.007580833593404, + 2.9875696988039464, + 2.9891004183753425, + 3.0119642687857926, + 3.055578221586497, + 3.1189983790290094, + 3.2009396578373237, + 3.299801321421238, + 3.4136978611017486, + 3.5404946368391146, + 3.6778476090257666, + 3.823246426427457, + 3.974060082392853, + 4.127584312825356, + 4.281089885678618, + 4.431870923195316, + 4.577292404776003, + 4.714836019998262, + 4.8421435773965245, + 4.957057224402513, + 5.057655796342076, + 5.142286686376602, + 5.209592712365298, + 5.258533549241622, + 5.288401394936826, + 5.298830642336962, + 5.289801437342177, + 5.261637111886354, + 5.214995588842862, + 5.150854961189602, + 5.070493548796797, + 4.975464830991547, + 4.8675677400251205, + 4.748812878255559, + 4.621385288967262, + 4.487604466188891, + 4.349882331759775, + 4.210679937585397, + 4.072463667100504, + 3.93766171225663, + 3.808621590944199, + 3.687569444965239, + 3.576571821040331, + 3.477500587635997, + 3.392001579611617, + 3.3214674919761453, + 3.2670154647422867, + 3.229469714441248, + 3.209349475897551, + 3.2068624220288835, + 3.2219036314526472, + 3.254060075293977, + 3.3026204975374416, + 3.3665904692459896, + 3.4447123076178494, + 3.5354894677005535, + 3.637214939044819, + 3.7480031129269333, + 3.865824529096341, + 3.9885428652307167, + 4.113953498118148, + 4.239822943540186, + 4.363928472186153, + 4.484097201754541, + 4.598243980534759, + 4.704407404843993, + 4.800783351138351, + 4.885755452653506, + 4.9579220091024965, + 5.0161188851526255, + 5.059438027862165, + 5.0872413136079855, + 5.099169519809866, + 5.095146304425879, + 5.0753771651845625, + 5.040343439254666, + 4.990791490969574, + 4.92771731880432, + 4.8523468916031485, + 4.766112596726081, + 4.67062624809469, + 4.567649158980805, + 4.459059831866024, + 4.346819855047406, + 4.232938622301198, + 4.119437507465076, + 4.00831413007676, + 3.9015073412353747, + 3.8008635408473093, + 3.708104908792513, + 3.624800093893209, + 3.5523378566520236, + 3.491904105472068, + 3.444462702541212, + 3.4107403459359844, + 3.391215760057957, + 3.3861133486087014, + 3.395401384341741, + 3.4187947292281087, + 3.4557619988625183, + 3.5055370073200427, + 3.567134254598009, + 3.639368149521042, + 3.7208755977283983, + 3.8101415281671063, + 3.905526883312421, + 4.005298558911437, + 4.10766074901724, + 4.210787131899437, + 4.312853322355648, + 4.412069016098777, + 4.50670926216858, + 4.5951443194458506, + 4.675867582896659, + 4.747521103540238, + 4.808918272569087, + 4.859063293664584, + 4.897167127341909, + 4.922659656017289, + 4.935197887232875, + 4.9346700838551385, + 4.921195782801025, + 4.895121736648492, + 4.857013884070709, + 4.807645524144282, + 4.747981935024095, + 4.679161738128085, + 4.602475363805619, + 4.519341022555662, + 4.431278626424815, + 4.339882137598967, + 4.246790844903666, + 4.153660083603096, + 4.062131919353282, + 3.973806313402344, + 3.890213273285245, + 3.81278647163316, + 3.7428387857660748, + 3.681540173057928, + 3.629898252387145, + 3.5887419111574457, + 3.558708201343219, + 3.54023272781092, + 3.5335436688910224, + 3.53865950396339, + 3.555390456840364, + 3.58334359815458, + 3.621931485935847, + 3.670384162208577, + 3.727764265817354, + 3.7929849687776542, + 3.8648303961442214, + 3.9419781484781176, + 4.023023512141911, + 4.106504916398345, + 4.19093017802946, + 4.2748030641854164, + 4.356649702521627, + 4.435044374347978, + 4.508634241307193, + 4.57616257869156, + 4.636490118434164, + 4.6886141414826605, + 4.731685001978214, + 4.765019813613604, + 4.788113080845702, + 4.800644113327452, + 4.802481119994536, + 4.793681938647495, + 4.7744914165529355, + 4.745335516493253, + 4.706812279790867, + 4.659679832129537, + 4.604841668557803, + 4.543329500028689, + 4.476283984433473, + 4.404933699655416, + 4.330572744143136, + 4.2545373714454175, + 4.178182078749862, + 4.102855575549063, + 4.0298770570760265, + 3.960513198195558, + 3.8959562672308836, + 3.837303736092187, + 3.785539733521148, + 3.741518652848795, + 3.705951185056585, + 3.6793930028921302, + 3.6622362731530673, + 3.6547041229025656, + 3.656848132246371, + 3.6685488723354975, + 3.68951945341924, + 3.71931199500799, + 3.75732687943555, + 3.8028246022144607, + 3.854939988375193, + 3.9126985042191453, + 3.975034359259625, + 4.040810064142146, + 4.108837087488537, + 4.17789723824966, + 4.246764390512333, + 4.314226164900998, + 4.379105184734994, + 4.440279535820136, + 4.496702075922839, + 4.547418263239217, + 4.591582202068976, + 4.628470637877608, + 4.657494672338555, + 4.678209011075124, + 4.690318601896278, + 4.693682568521028, + 4.688315393263614, + 4.674385351040156, + 4.65221024549195, + 4.622250545151016, + 4.585100062580083, + 4.541474361526396, + 4.492197115618714, + 4.4381846763619155, + 4.380429137575856, + 4.3199802075077285, + 4.257926218240097, + 4.19537461444382, + 4.133432269817674, + 4.073185979655181, + 4.015683471934681, + 3.9619152672994167, + 3.912797700542846, + 3.869157393101482, + 3.83171743803664, + 3.801085526592176, + 3.777744209255971, + 3.7620434449977567, + 3.754195550722793, + 3.7542726197241074, + 3.762206433811583, + 3.7777908496287624, + 3.800686596217106, + 3.8304283789123508, + 3.866434144886078, + 3.9080163287603593, + 3.954394863349774, + 4.00471171128261, + 4.058046648503067, + 4.113434010857275, + 4.16988010042494, + 4.226380939187437, + 4.281940054135796, + 4.335585980032937, + 4.386389173669111, + 4.433478046406756, + 4.476053839827462, + 4.513404092009917, + 4.544914468941846, + 4.570078766291674, + 4.588506920661998, + 4.599930905893598, + 4.604208428321441, + 4.601324374411066, + 4.591390004218262, + 4.574639923907517, + 4.55142690943555, + 4.52221469077823, + 4.487568841108332, + 4.448145947519826, + 4.404681268697706, + 4.357975109872184, + 4.308878166064671, + 4.2582761007026315, + 4.207073637906305, + 4.156178452975424, + 4.1064851467609875, + 4.058859585718249, + 4.01412388061338, + 3.973042263294837, + 3.9363081029207416, + 3.9045322809104084, + 3.8782331180863157, + 3.8578280184782203, + 3.843626962611809, + 3.835827949380554, + 3.834514450413151, + 3.8396549048330972, + 3.8511042461029112, + 3.868607416893608, + 3.8918047932462376, + 3.9202394062991144, + 3.9533658191089853, + 3.990560488119961, + 4.0311334141002435, + 4.074340866282239, + 4.119398946347625, + 4.165497746062507, + 4.211815843979878, + 4.257534882797372, + 4.3018539697163725, + 4.34400364744266, + 4.383259193166517, + 4.418953016754066, + 4.450485947190949, + 4.47733721769744, + 4.499072984473585, + 4.515353241274905, + 4.5259370214605195, + 4.530685810258515, + 4.5295651221959226, + 4.522644231365733, + 4.51009407486958, + 4.492183381806923, + 4.469273111020182, + 4.441809309916985, + 4.410314533576751, + 4.375377987554061, + 4.337644578911532, + 4.297803077704294, + 4.256573605113103, + 4.214694674469227, + 4.17291001738729, + 4.13195542905131, + 4.09254586438697, + 4.055363010475422, + 4.021043550267427, + 3.9901683186558916, + 3.9632525345377525, + 3.940737271979332, + 3.9229823103797403, + 3.9102604780374803, + 3.9027535762340655, + 3.9005499423517733, + 3.903643681155665, + 3.911935563717436, + 3.9252355640654333, + 3.9432669750273175, + 3.9656720173872806, + 3.992018830879681, + 4.021809712122121, + 4.05449044374771, + 4.08946054107416, + 4.126084227938015, + 4.163701942057544, + 4.201642162637405, + 4.239233348996476, + 4.275815778825058, + 4.310753078230348, + 4.343443242916018, + 4.373328960504662, + 4.39990705793472, + 4.422736914772035, + 4.44144770284826, + 4.455744334505723, + 4.465412025486475, + 4.470319403717494, + 4.470420121457207, + 4.465752955010525, + 4.4564404030143665, + 4.44268582067034, + 4.42476915279469, + 4.403041352725581, + 4.37791759655946, + 4.34986942250102, + 4.319415942964667, + 4.287114292165517, + 4.2535494840421695, + 4.219323864273091, + 4.1850463457536335, + 4.151321619120232, + 4.118739528731966, + 4.087864799996465, + 4.0592272961653055, + 4.033312971887644, + 4.01055567711696, + 3.991329948679575, + 3.975944908244509, + 3.964639364928647, + 3.957578198706619, + 3.9548500775740427, + 3.956466537454176, + 3.9623624295707485, + 3.972397715863824, + 3.986360569425775, + 4.003971714292182, + 4.0248899176288155, + 4.048718527774751, + 4.075012934063859, + 4.103288809144449, + 4.1330309818976545, + 4.163702779220547, + 4.1947556680388915, + 4.225639025044905, + 4.255809860858959, + 4.284742327579816, + 4.311936843949288, + 4.336928680496653, + 4.3592958578776715, + 4.378666224968558, + 4.39472359886051, + 4.407212866431784, + 4.415943966326285, + 4.420794690588812, + 4.421712266527139, + 4.418713701206171, + 4.411884892940477, + 4.401378535850384, + 4.387410864603051, + 4.370257306507921, + 4.350247126830717, + 4.3277571702135536, + 4.303204816154725, + 4.27704027936147, + 4.249738396234031, + 4.221790046606263, + 4.193693365039707, + 4.165944898376139, + 4.139030865878839, + 4.113418675165594, + 4.089548841334673, + 4.067827448333887, + 4.048619280890996, + 4.0322417424202746, + 4.018959659490929, + 4.008981056966027, + 4.002453970099684, + 3.99946434104129, + 4.0000350276790355, + 4.004125932910776, + 4.011635242610823, + 4.022401741115854, + 4.0362081543214305, + 4.052785452786606, + 4.071818030891234, + 4.092949663355619, + 4.1157901275611195, + 4.139922369314761, + 4.164910081153061, + 4.1903055561124, + 4.215657676193738, + 4.240519893562564, + 4.264458063850795, + 4.287057994720914, + 4.307932579026616, + 4.326728390329308, + 4.343131629038954, + 4.356873319837697, + 4.367733675081325, + 4.375545554295802, + 4.380196966409769, + 4.381632578689134, + 4.37985421415385, + 4.374920337242093, + 4.366944545324374, + 4.356093101046817, + 4.342581557096182, + 4.326670540543005, + 4.3086607781677895, + 4.28888745686861, + 4.2677140241758735, + 4.2455255428839695, + 4.222721720707762, + 4.199709740580551, + 4.176897019664814, + 4.154684025323027, + 4.13345727421003, + 4.113582636355691, + 4.09539905970218, + 4.079212822174091, + 4.065292408156773, + 4.053864094433784, + 4.045108317410244, + 4.039156879070216, + 4.03609103384616, + 4.035940482693736, + 4.038683284450929, + 4.0442466783053534, + 4.052508795184416, + 4.063301220400076, + 4.0764123551915485, + 4.091591511167851, + 4.108553659289192, + 4.126984744148833, + 4.146547465104753, + 4.166887418411203, + 4.187639489029547, + 4.208434377335442, + 4.2289051445298425, + 4.248693661211914, + 4.267456846253728, + 4.284872587765385, + 4.300645244456409, + 4.314510633954023, + 4.326240424471275, + 4.335645857441294, + 4.342580741138481, + 4.346943668664685, + 4.348679427744882, + 4.347779584298456, + 4.344282236469261, + 4.338270950448983, + 4.329872903756227, + 4.3192562753884625, + 4.306626935207694, + 4.292224496832277, + 4.276317808985353, + 4.259199969517028, + 4.24118295402143, + 4.222591956988185, + 4.203759547669213, + 4.185019745245844, + 4.166702118421531, + 4.149126013248006, + 4.132595009856331, + 4.117391703879841, + 4.103772901824079, + 4.091965311588687, + 4.082161799932392, + 4.074518278072423, + 4.069151265020478, + 4.066136165891582, + 4.065506289504345, + 4.067252616353492, + 4.071324314714335, + 4.077629989469514, + 4.086039635461658, + 4.09638725499401, + 4.108474087733919, + 4.1220723909150285, + 4.136929698557165, + 4.152773480580072, + 4.169316116305187, + 4.186260092018957, + 4.203303329083411, + 4.220144547567363, + 4.236488570547064, + 4.252051476071353, + 4.266565507256325, + 4.279783655993637, + 4.29148384222338, + 4.301472618510161, + 4.309588338622075 + ], + "flows": [ + 21999.999999999996, + 21889.999999999996, + 21780.0, + 21669.999999999996, + 21560.0, + 21450.0, + 21340.0, + 21229.999999999996, + 21119.999999999996, + 21009.999999999996, + 20900.0, + 20789.999999999996, + 20679.999999999996, + 20570.0, + 20459.999999999996, + 20349.999999999996, + 20240.0, + 20130.0, + 20019.999999999996, + 19909.999999999996, + 19799.999999999996, + 19690.0, + 19580.0, + 19470.0, + 19360.0, + 19250.0, + 19140.0, + 19029.999999999996, + 18919.999999999996, + 18810.0, + 18700.0, + 18589.999999999996, + 18479.999999999996, + 18369.999999999996, + 18259.999999999996, + 18149.999999999996, + 18040.0, + 17929.999999999996, + 17819.999999999996, + 17709.999999999996, + 17600.0, + 17490.0, + 17380.0, + 17270.0, + 17160.0, + 17050.0, + 16939.999999999996, + 16830.0, + 16720.0, + 16610.0, + 16500.0, + 16389.999999999996, + 16279.999999999998, + 16169.999999999998, + 16059.999999999998, + 15949.999999999998, + 15839.999999999998, + 15729.999999999998, + 15620.0, + 15510.0, + 15399.999999999996, + 15290.000000000002, + 15179.999999999998, + 15069.999999999998, + 14959.999999999998, + 14850.000000000002, + 14739.999999999998, + 14629.999999999998, + 14519.999999999996, + 14410.0, + 14299.999999999996, + 14189.999999999998, + 14079.999999999998, + 13969.999999999998, + 13860.0, + 13749.999999999998, + 13639.999999999998, + 13530.0, + 13419.999999999998, + 13309.999999999998, + 13199.999999999998, + 13089.999999999998, + 12979.999999999998, + 12870.0, + 12760.000000000002, + 12649.999999999998, + 12540.000000000002, + 12429.999999999998, + 12320.0, + 12209.999999999998, + 12100.0, + 11989.999999999998, + 11880.0, + 11769.999999999998, + 11660.0, + 11549.999999999996, + 11440.0, + 11329.999999999998, + 11219.999999999998, + 11109.999999999998, + 10999.999999999998, + 10890.0, + 10780.0, + 10670.0, + 10559.999999999998, + 10450.0, + 10339.999999999998, + 10229.999999999998, + 10119.999999999998, + 10009.999999999998, + 9899.999999999998, + 9790.0, + 9679.999999999998, + 9569.999999999998, + 9459.999999999998, + 9349.999999999998, + 9240.0, + 9129.999999999998, + 9020.0, + 8909.999999999998, + 8800.0, + 8690.0, + 8580.0, + 8469.999999999998, + 8360.0, + 8250.0, + 8139.999999999999, + 8029.999999999999, + 7919.999999999999, + 7810.0, + 7699.999999999998, + 7589.999999999999, + 7479.999999999999, + 7369.999999999999, + 7259.999999999998, + 7149.999999999998, + 7039.999999999998, + 6929.999999999998, + 6819.999999999997, + 6709.999999999997, + 6599.999999999999, + 6490.0, + 6380.000000000001, + 6270.000000000001, + 6160.0, + 6050.0, + 5940.0, + 5830.0, + 5720.0, + 5609.999999999999, + 5499.999999999999, + 5390.0, + 5279.999999999999, + 5169.999999999999, + 5059.999999999999, + 4949.999999999999, + 4839.999999999999, + 4729.999999999999, + 4619.999999999998, + 4509.999999999999, + 4399.999999999998, + 4289.999999999998, + 4179.999999999998, + 4069.9999999999977, + 3959.9999999999977, + 3849.9999999999986, + 3739.9999999999986, + 3630.000000000001, + 3520.0000000000005, + 3410.0000000000005, + 3300.0000000000005, + 3190.0000000000005, + 3080.0, + 2970.0, + 2860.0, + 2749.9999999999995, + 2639.9999999999995, + 2529.9999999999995, + 2419.9999999999995, + 2309.999999999999, + 2199.999999999999, + 2089.999999999999, + 1979.9999999999989, + 1869.9999999999993, + 1759.999999999999, + 1649.9999999999989, + 1539.9999999999989, + 1429.9999999999989, + 1319.9999999999986, + 1209.9999999999986, + 1099.9999999999984, + 989.9999999999983, + 880.0000000000007, + 770.0000000000006, + 660.0000000000005, + 550.0000000000005, + 440.00000000000034, + 330.0000000000002, + 220.00000000000017, + 110.00000000000009, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + "timestamp": "2025-09-13T14:54:58.150034", + "execution_id": "53da0d4b-eca1-4d2c-9df8-d940303f5c98", + "user_id": "unknown", + "project_id": "1" +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/Test Hammer Project/config.json b/data/script_groups/group_3/user_1/Test Hammer Project/config.json new file mode 100644 index 0000000..651ef55 --- /dev/null +++ b/data/script_groups/group_3/user_1/Test Hammer Project/config.json @@ -0,0 +1,6 @@ +{ + "created_at": "2025-09-13T14:35:54.726752", + "last_modified": "2025-09-13T14:35:54.726758", + "project_settings": {}, + "user_preferences": {} +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/Test Project 001/config.json b/data/script_groups/group_3/user_1/Test Project 001/config.json new file mode 100644 index 0000000..2fd2e7e --- /dev/null +++ b/data/script_groups/group_3/user_1/Test Project 001/config.json @@ -0,0 +1,6 @@ +{ + "created_at": "2025-09-13T14:13:18.131807", + "last_modified": "2025-09-13T14:13:18.131814", + "project_settings": {}, + "user_preferences": {} +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/project_default/hammer_config.json b/data/script_groups/group_3/user_1/project_default/hammer_config.json new file mode 100644 index 0000000..0f718a7 --- /dev/null +++ b/data/script_groups/group_3/user_1/project_default/hammer_config.json @@ -0,0 +1,19 @@ +{ + "pipe_length": 300, + "pipe_diameter": 0.065, + "wall_thickness": 0.003, + "roughness": 1.5e-06, + "flow_rate": 22000, + "pump_pressure": 7, + "fluid_density": 1100, + "fluid_temperature": 20, + "bulk_modulus": 2200000000, + "young_modulus": 200000000000, + "closure_time": 2, + "damper_volume": 50, + "damper_precharge": 4, + "damper_gas_percentage": 60, + "damper_position": 280, + "simulation_time": 10, + "damper_enabled": false +} \ No newline at end of file diff --git a/data/script_groups/group_3/user_1/project_default/hammer_results.json b/data/script_groups/group_3/user_1/project_default/hammer_results.json new file mode 100644 index 0000000..8f9f972 --- /dev/null +++ b/data/script_groups/group_3/user_1/project_default/hammer_results.json @@ -0,0 +1,5030 @@ +{ + "parameters": { + "fluid_velocity": 1.8416351074407347, + "wave_speed": 1270.8556268223824, + "critical_time": 0.47212286536451503, + "joukowsky_surge": 25.744975727291703, + "time_factor": 0.23606143268225752, + "damper_factor": 1.0, + "total_factor": 0.23606143268225752, + "real_surge": 6.077395854554424, + "damper_efficiency": 0.0, + "damper_effective_volume": 0.0 + }, + "simulation": { + "times": [ + 0.0, + 0.01, + 0.02, + 0.03, + 0.04, + 0.05, + 0.06, + 0.07, + 0.08, + 0.09, + 0.1, + 0.11, + 0.12, + 0.13, + 0.14, + 0.15, + 0.16, + 0.17, + 0.18, + 0.19, + 0.2, + 0.21, + 0.22, + 0.23, + 0.24, + 0.25, + 0.26, + 0.27, + 0.28, + 0.29, + 0.3, + 0.31, + 0.32, + 0.33, + 0.34, + 0.35000000000000003, + 0.36, + 0.37, + 0.38, + 0.39, + 0.4, + 0.41000000000000003, + 0.42, + 0.43, + 0.44, + 0.45, + 0.46, + 0.47000000000000003, + 0.48, + 0.49, + 0.5, + 0.51, + 0.52, + 0.53, + 0.54, + 0.55, + 0.56, + 0.5700000000000001, + 0.58, + 0.59, + 0.6, + 0.61, + 0.62, + 0.63, + 0.64, + 0.65, + 0.66, + 0.67, + 0.68, + 0.6900000000000001, + 0.7000000000000001, + 0.71, + 0.72, + 0.73, + 0.74, + 0.75, + 0.76, + 0.77, + 0.78, + 0.79, + 0.8, + 0.81, + 0.8200000000000001, + 0.8300000000000001, + 0.84, + 0.85, + 0.86, + 0.87, + 0.88, + 0.89, + 0.9, + 0.91, + 0.92, + 0.93, + 0.9400000000000001, + 0.9500000000000001, + 0.96, + 0.97, + 0.98, + 0.99, + 1.0, + 1.01, + 1.02, + 1.03, + 1.04, + 1.05, + 1.06, + 1.07, + 1.08, + 1.09, + 1.1, + 1.11, + 1.12, + 1.1300000000000001, + 1.1400000000000001, + 1.1500000000000001, + 1.16, + 1.17, + 1.18, + 1.19, + 1.2, + 1.21, + 1.22, + 1.23, + 1.24, + 1.25, + 1.26, + 1.27, + 1.28, + 1.29, + 1.3, + 1.31, + 1.32, + 1.33, + 1.34, + 1.35, + 1.36, + 1.37, + 1.3800000000000001, + 1.3900000000000001, + 1.4000000000000001, + 1.41, + 1.42, + 1.43, + 1.44, + 1.45, + 1.46, + 1.47, + 1.48, + 1.49, + 1.5, + 1.51, + 1.52, + 1.53, + 1.54, + 1.55, + 1.56, + 1.57, + 1.58, + 1.59, + 1.6, + 1.61, + 1.62, + 1.6300000000000001, + 1.6400000000000001, + 1.6500000000000001, + 1.6600000000000001, + 1.67, + 1.68, + 1.69, + 1.7, + 1.71, + 1.72, + 1.73, + 1.74, + 1.75, + 1.76, + 1.77, + 1.78, + 1.79, + 1.8, + 1.81, + 1.82, + 1.83, + 1.84, + 1.85, + 1.86, + 1.87, + 1.8800000000000001, + 1.8900000000000001, + 1.9000000000000001, + 1.9100000000000001, + 1.92, + 1.93, + 1.94, + 1.95, + 1.96, + 1.97, + 1.98, + 1.99, + 2.0, + 2.0100000000000002, + 2.02, + 2.0300000000000002, + 2.04, + 2.05, + 2.06, + 2.07, + 2.08, + 2.09, + 2.1, + 2.11, + 2.12, + 2.13, + 2.14, + 2.15, + 2.16, + 2.17, + 2.18, + 2.19, + 2.2, + 2.21, + 2.22, + 2.23, + 2.24, + 2.25, + 2.2600000000000002, + 2.27, + 2.2800000000000002, + 2.29, + 2.3000000000000003, + 2.31, + 2.32, + 2.33, + 2.34, + 2.35, + 2.36, + 2.37, + 2.38, + 2.39, + 2.4, + 2.41, + 2.42, + 2.43, + 2.44, + 2.45, + 2.46, + 2.47, + 2.48, + 2.49, + 2.5, + 2.5100000000000002, + 2.52, + 2.5300000000000002, + 2.54, + 2.5500000000000003, + 2.56, + 2.57, + 2.58, + 2.59, + 2.6, + 2.61, + 2.62, + 2.63, + 2.64, + 2.65, + 2.66, + 2.67, + 2.68, + 2.69, + 2.7, + 2.71, + 2.72, + 2.73, + 2.74, + 2.75, + 2.7600000000000002, + 2.77, + 2.7800000000000002, + 2.79, + 2.8000000000000003, + 2.81, + 2.82, + 2.83, + 2.84, + 2.85, + 2.86, + 2.87, + 2.88, + 2.89, + 2.9, + 2.91, + 2.92, + 2.93, + 2.94, + 2.95, + 2.96, + 2.97, + 2.98, + 2.99, + 3.0, + 3.0100000000000002, + 3.02, + 3.0300000000000002, + 3.04, + 3.0500000000000003, + 3.06, + 3.0700000000000003, + 3.08, + 3.09, + 3.1, + 3.11, + 3.12, + 3.13, + 3.14, + 3.15, + 3.16, + 3.17, + 3.18, + 3.19, + 3.2, + 3.21, + 3.22, + 3.23, + 3.24, + 3.25, + 3.2600000000000002, + 3.27, + 3.2800000000000002, + 3.29, + 3.3000000000000003, + 3.31, + 3.3200000000000003, + 3.33, + 3.34, + 3.35, + 3.36, + 3.37, + 3.38, + 3.39, + 3.4, + 3.41, + 3.42, + 3.43, + 3.44, + 3.45, + 3.46, + 3.47, + 3.48, + 3.49, + 3.5, + 3.5100000000000002, + 3.52, + 3.5300000000000002, + 3.54, + 3.5500000000000003, + 3.56, + 3.5700000000000003, + 3.58, + 3.59, + 3.6, + 3.61, + 3.62, + 3.63, + 3.64, + 3.65, + 3.66, + 3.67, + 3.68, + 3.69, + 3.7, + 3.71, + 3.72, + 3.73, + 3.74, + 3.75, + 3.7600000000000002, + 3.77, + 3.7800000000000002, + 3.79, + 3.8000000000000003, + 3.81, + 3.8200000000000003, + 3.83, + 3.84, + 3.85, + 3.86, + 3.87, + 3.88, + 3.89, + 3.9, + 3.91, + 3.92, + 3.93, + 3.94, + 3.95, + 3.96, + 3.97, + 3.98, + 3.99, + 4.0, + 4.01, + 4.0200000000000005, + 4.03, + 4.04, + 4.05, + 4.0600000000000005, + 4.07, + 4.08, + 4.09, + 4.1, + 4.11, + 4.12, + 4.13, + 4.14, + 4.15, + 4.16, + 4.17, + 4.18, + 4.19, + 4.2, + 4.21, + 4.22, + 4.23, + 4.24, + 4.25, + 4.26, + 4.2700000000000005, + 4.28, + 4.29, + 4.3, + 4.3100000000000005, + 4.32, + 4.33, + 4.34, + 4.3500000000000005, + 4.36, + 4.37, + 4.38, + 4.39, + 4.4, + 4.41, + 4.42, + 4.43, + 4.44, + 4.45, + 4.46, + 4.47, + 4.48, + 4.49, + 4.5, + 4.51, + 4.5200000000000005, + 4.53, + 4.54, + 4.55, + 4.5600000000000005, + 4.57, + 4.58, + 4.59, + 4.6000000000000005, + 4.61, + 4.62, + 4.63, + 4.64, + 4.65, + 4.66, + 4.67, + 4.68, + 4.69, + 4.7, + 4.71, + 4.72, + 4.73, + 4.74, + 4.75, + 4.76, + 4.7700000000000005, + 4.78, + 4.79, + 4.8, + 4.8100000000000005, + 4.82, + 4.83, + 4.84, + 4.8500000000000005, + 4.86, + 4.87, + 4.88, + 4.89, + 4.9, + 4.91, + 4.92, + 4.93, + 4.94, + 4.95, + 4.96, + 4.97, + 4.98, + 4.99, + 5.0, + 5.01, + 5.0200000000000005, + 5.03, + 5.04, + 5.05, + 5.0600000000000005, + 5.07, + 5.08, + 5.09, + 5.1000000000000005, + 5.11, + 5.12, + 5.13, + 5.14, + 5.15, + 5.16, + 5.17, + 5.18, + 5.19, + 5.2, + 5.21, + 5.22, + 5.23, + 5.24, + 5.25, + 5.26, + 5.2700000000000005, + 5.28, + 5.29, + 5.3, + 5.3100000000000005, + 5.32, + 5.33, + 5.34, + 5.3500000000000005, + 5.36, + 5.37, + 5.38, + 5.39, + 5.4, + 5.41, + 5.42, + 5.43, + 5.44, + 5.45, + 5.46, + 5.47, + 5.48, + 5.49, + 5.5, + 5.51, + 5.5200000000000005, + 5.53, + 5.54, + 5.55, + 5.5600000000000005, + 5.57, + 5.58, + 5.59, + 5.6000000000000005, + 5.61, + 5.62, + 5.63, + 5.64, + 5.65, + 5.66, + 5.67, + 5.68, + 5.69, + 5.7, + 5.71, + 5.72, + 5.73, + 5.74, + 5.75, + 5.76, + 5.7700000000000005, + 5.78, + 5.79, + 5.8, + 5.8100000000000005, + 5.82, + 5.83, + 5.84, + 5.8500000000000005, + 5.86, + 5.87, + 5.88, + 5.89, + 5.9, + 5.91, + 5.92, + 5.93, + 5.94, + 5.95, + 5.96, + 5.97, + 5.98, + 5.99, + 6.0, + 6.01, + 6.0200000000000005, + 6.03, + 6.04, + 6.05, + 6.0600000000000005, + 6.07, + 6.08, + 6.09, + 6.1000000000000005, + 6.11, + 6.12, + 6.13, + 6.140000000000001, + 6.15, + 6.16, + 6.17, + 6.18, + 6.19, + 6.2, + 6.21, + 6.22, + 6.23, + 6.24, + 6.25, + 6.26, + 6.2700000000000005, + 6.28, + 6.29, + 6.3, + 6.3100000000000005, + 6.32, + 6.33, + 6.34, + 6.3500000000000005, + 6.36, + 6.37, + 6.38, + 6.390000000000001, + 6.4, + 6.41, + 6.42, + 6.43, + 6.44, + 6.45, + 6.46, + 6.47, + 6.48, + 6.49, + 6.5, + 6.51, + 6.5200000000000005, + 6.53, + 6.54, + 6.55, + 6.5600000000000005, + 6.57, + 6.58, + 6.59, + 6.6000000000000005, + 6.61, + 6.62, + 6.63, + 6.640000000000001, + 6.65, + 6.66, + 6.67, + 6.68, + 6.69, + 6.7, + 6.71, + 6.72, + 6.73, + 6.74, + 6.75, + 6.76, + 6.7700000000000005, + 6.78, + 6.79, + 6.8, + 6.8100000000000005, + 6.82, + 6.83, + 6.84, + 6.8500000000000005, + 6.86, + 6.87, + 6.88, + 6.890000000000001, + 6.9, + 6.91, + 6.92, + 6.93, + 6.94, + 6.95, + 6.96, + 6.97, + 6.98, + 6.99, + 7.0, + 7.01, + 7.0200000000000005, + 7.03, + 7.04, + 7.05, + 7.0600000000000005, + 7.07, + 7.08, + 7.09, + 7.1000000000000005, + 7.11, + 7.12, + 7.13, + 7.140000000000001, + 7.15, + 7.16, + 7.17, + 7.18, + 7.19, + 7.2, + 7.21, + 7.22, + 7.23, + 7.24, + 7.25, + 7.26, + 7.2700000000000005, + 7.28, + 7.29, + 7.3, + 7.3100000000000005, + 7.32, + 7.33, + 7.34, + 7.3500000000000005, + 7.36, + 7.37, + 7.38, + 7.390000000000001, + 7.4, + 7.41, + 7.42, + 7.43, + 7.44, + 7.45, + 7.46, + 7.47, + 7.48, + 7.49, + 7.5, + 7.51, + 7.5200000000000005, + 7.53, + 7.54, + 7.55, + 7.5600000000000005, + 7.57, + 7.58, + 7.59, + 7.6000000000000005, + 7.61, + 7.62, + 7.63, + 7.640000000000001, + 7.65, + 7.66, + 7.67, + 7.68, + 7.69, + 7.7, + 7.71, + 7.72, + 7.73, + 7.74, + 7.75, + 7.76, + 7.7700000000000005, + 7.78, + 7.79, + 7.8, + 7.8100000000000005, + 7.82, + 7.83, + 7.84, + 7.8500000000000005, + 7.86, + 7.87, + 7.88, + 7.890000000000001, + 7.9, + 7.91, + 7.92, + 7.930000000000001, + 7.94, + 7.95, + 7.96, + 7.97, + 7.98, + 7.99, + 8.0, + 8.01, + 8.02, + 8.03, + 8.040000000000001, + 8.05, + 8.06, + 8.07, + 8.08, + 8.09, + 8.1, + 8.11, + 8.120000000000001, + 8.13, + 8.14, + 8.15, + 8.16, + 8.17, + 8.18, + 8.19, + 8.2, + 8.21, + 8.22, + 8.23, + 8.24, + 8.25, + 8.26, + 8.27, + 8.28, + 8.290000000000001, + 8.3, + 8.31, + 8.32, + 8.33, + 8.34, + 8.35, + 8.36, + 8.370000000000001, + 8.38, + 8.39, + 8.4, + 8.41, + 8.42, + 8.43, + 8.44, + 8.45, + 8.46, + 8.47, + 8.48, + 8.49, + 8.5, + 8.51, + 8.52, + 8.53, + 8.540000000000001, + 8.55, + 8.56, + 8.57, + 8.58, + 8.59, + 8.6, + 8.61, + 8.620000000000001, + 8.63, + 8.64, + 8.65, + 8.66, + 8.67, + 8.68, + 8.69, + 8.700000000000001, + 8.71, + 8.72, + 8.73, + 8.74, + 8.75, + 8.76, + 8.77, + 8.78, + 8.790000000000001, + 8.8, + 8.81, + 8.82, + 8.83, + 8.84, + 8.85, + 8.86, + 8.870000000000001, + 8.88, + 8.89, + 8.9, + 8.91, + 8.92, + 8.93, + 8.94, + 8.950000000000001, + 8.96, + 8.97, + 8.98, + 8.99, + 9.0, + 9.01, + 9.02, + 9.03, + 9.040000000000001, + 9.05, + 9.06, + 9.07, + 9.08, + 9.09, + 9.1, + 9.11, + 9.120000000000001, + 9.13, + 9.14, + 9.15, + 9.16, + 9.17, + 9.18, + 9.19, + 9.200000000000001, + 9.21, + 9.22, + 9.23, + 9.24, + 9.25, + 9.26, + 9.27, + 9.28, + 9.290000000000001, + 9.3, + 9.31, + 9.32, + 9.33, + 9.34, + 9.35, + 9.36, + 9.370000000000001, + 9.38, + 9.39, + 9.4, + 9.41, + 9.42, + 9.43, + 9.44, + 9.450000000000001, + 9.46, + 9.47, + 9.48, + 9.49, + 9.5, + 9.51, + 9.52, + 9.53, + 9.540000000000001, + 9.55, + 9.56, + 9.57, + 9.58, + 9.59, + 9.6, + 9.61, + 9.620000000000001, + 9.63, + 9.64, + 9.65, + 9.66, + 9.67, + 9.68, + 9.69, + 9.700000000000001, + 9.71, + 9.72, + 9.73, + 9.74, + 9.75, + 9.76, + 9.77, + 9.78, + 9.790000000000001, + 9.8, + 9.81, + 9.82, + 9.83, + 9.84, + 9.85, + 9.86, + 9.870000000000001, + 9.88, + 9.89, + 9.9, + 9.91, + 9.92, + 9.93, + 9.94, + 9.950000000000001, + 9.96, + 9.97, + 9.98, + 9.99 + ], + "pressures_start": [ + 7.0, + 7.030386979272772, + 7.0607739585455445, + 7.091160937818317, + 7.121547917091089, + 7.15193489636386, + 7.1823218756366325, + 7.212708854909405, + 7.243095834182177, + 7.273482813454949, + 7.303869792727721, + 7.334256772000494, + 7.364643751273265, + 7.395030730546037, + 7.425417709818809, + 7.455804689091582, + 7.486191668364354, + 7.516578647637126, + 7.546965626909898, + 7.577352606182671, + 7.607739585455443, + 7.638126564728214, + 7.668513544000986, + 7.698900523273759, + 7.729287502546531, + 7.759674481819303, + 7.790061461092075, + 7.8204484403648475, + 7.85083541963762, + 7.881222398910391, + 7.911609378183163, + 7.941996357455936, + 7.972383336728708, + 8.002770316001481, + 8.033157295274252, + 8.063544274547024, + 8.093931253819797, + 8.124318233092568, + 8.154705212365341, + 8.185092191638113, + 8.215479170910886, + 8.245866150183657, + 8.276253129456428, + 8.306640108729201, + 8.337027088001973, + 8.367414067274746, + 8.397801046547517, + 8.42818802582029, + 8.458575005093062, + 8.488961984365833, + 8.519348963638606, + 8.549735942911378, + 8.58012292218415, + 8.610509901456922, + 8.640896880729695, + 8.671283860002466, + 8.70167083927524, + 8.73205781854801, + 8.762444797820782, + 8.792831777093555, + 8.823218756366327, + 8.8536057356391, + 8.883992714911871, + 8.914379694184644, + 8.944766673457416, + 8.975153652730189, + 9.00554063200296, + 9.035927611275731, + 9.066314590548505, + 9.096701569821276, + 9.127088549094049, + 9.15747552836682, + 9.187862507639593, + 9.218249486912365, + 9.248636466185136, + 9.27902344545791, + 9.30941042473068, + 9.339797404003454, + 9.370184383276225, + 9.400571362548998, + 9.43095834182177, + 9.46134532109454, + 9.491732300367314, + 9.522119279640087, + 9.552506258912858, + 9.58289323818563, + 9.613280217458403, + 9.643667196731174, + 9.674054176003946, + 9.704441155276719, + 9.734828134549492, + 9.765215113822263, + 9.795602093095034, + 9.825989072367808, + 9.856376051640579, + 9.886763030913352, + 9.917150010186123, + 9.947536989458897, + 9.977923968731668, + 10.00831094800444, + 10.038697927277212, + 10.069084906549984, + 10.099471885822757, + 10.129858865095528, + 10.160245844368301, + 10.190632823641073, + 10.221019802913844, + 10.251406782186617, + 10.281793761459388, + 10.312180740732162, + 10.342567720004933, + 10.372954699277706, + 10.403341678550477, + 10.43372865782325, + 10.464115637096022, + 10.494502616368795, + 10.524889595641564, + 10.555276574914338, + 10.58566355418711, + 10.616050533459882, + 10.646437512732653, + 10.676824492005426, + 10.707211471278198, + 10.737598450550971, + 10.767985429823742, + 10.798372409096515, + 10.828759388369287, + 10.859146367642058, + 10.889533346914831, + 10.919920326187604, + 10.950307305460376, + 10.980694284733147, + 11.01108126400592, + 11.041468243278693, + 11.071855222551465, + 11.102242201824236, + 11.132629181097009, + 11.16301616036978, + 11.193403139642552, + 11.223790118915325, + 11.254177098188098, + 11.284564077460868, + 11.31495105673364, + 11.345338036006414, + 11.375725015279185, + 11.406111994551956, + 11.43649897382473, + 11.466885953097503, + 11.497272932370272, + 11.527659911643045, + 11.558046890915818, + 11.58843387018859, + 11.618820849461361, + 11.649207828734134, + 11.679594808006907, + 11.709981787279679, + 11.74036876655245, + 11.770755745825223, + 11.801142725097995, + 11.831529704370766, + 11.861916683643539, + 11.892303662916312, + 11.922690642189083, + 11.953077621461855, + 11.983464600734628, + 12.013851580007401, + 12.044238559280172, + 12.074625538552944, + 12.105012517825717, + 12.135399497098488, + 12.16578647637126, + 12.196173455644033, + 12.226560434916804, + 12.256947414189575, + 12.287334393462348, + 12.317721372735122, + 12.348108352007893, + 12.378495331280664, + 12.408882310553437, + 12.43926928982621, + 12.469656269098982, + 12.500043248371753, + 12.530430227644526, + 12.560817206917298, + 12.591204186190069, + 12.621591165462842, + 12.651978144735615, + 12.682365124008387, + 12.712752103281158, + 12.743139082553931, + 12.773526061826704, + 12.803913041099475, + 12.834300020372247, + 12.86468699964502, + 12.895073978917791, + 12.925460958190563, + 12.955847937463336, + 12.986234916736107, + 13.016621896008878, + 13.047008875281652, + 13.077395854554425, + 12.99819269436744, + 12.813920076281685, + 12.528712831775952, + 12.14845020967558, + 11.680637518344213, + 11.134260101821067, + 10.519612457456311, + 9.84810571712261, + 9.13205706831101, + 8.384464979614227, + 7.618774312742968, + 6.848635547062214, + 6.087662410769747, + 5.349192204697314, + 4.646053021091793, + 3.99034190273164, + 3.3932177607479046, + 2.864712577133008, + 2.4135640658480026, + 2.0470725613826968, + 1.7709844531772125, + 1.5894039967956681, + 1.5047348170646524, + 1.517651883874966, + 1.6271041975794347, + 1.8303478775638018, + 2.123008814198112, + 2.4991735303103875, + 2.9515064124613, + 3.4713910229665905, + 4.049092798423399, + 4.673940086221254, + 5.334520172969713, + 6.018886722723541, + 6.714774871972396, + 7.409820125048403, + 8.091777159146128, + 8.748734682566344, + 9.369322591906098, + 9.942907841345308, + 10.459775666428644, + 10.911293091241038, + 11.290051986099261, + 11.589989326425346, + 11.806482725192623, + 11.936419763480185, + 11.978240118014032, + 11.931949972559993, + 11.799108692950501, + 11.58278823464129, + 11.28750622841602, + 10.91913414588769, + 10.484782373919629, + 9.992664418713549, + 9.451942809483189, + 8.872559572556154, + 8.265054394521702, + 7.640373783753514, + 7.009674670399309, + 6.384125953946432, + 5.7747115140494385, + 5.192038144848963, + 4.646151757027878, + 4.146365017889147, + 3.7010993713628015, + 3.3177441015353346, + 3.0025347803767874, + 2.7604530788830166, + 2.595149527553943, + 2.5088903941913685, + 2.502529412000561, + 2.5755046467279774, + 2.725860345974615, + 2.9502931747555694, + 3.2442218165170065, + 3.601878515541766, + 4.016420761900242, + 4.480060980202099, + 4.9842117840716, + 5.519644104442853, + 6.076655295537727, + 6.645244170934598, + 7.215289825681064, + 7.776731060187915, + 8.319743237897791, + 8.8349094806862, + 9.313383231889944, + 9.747039394087615, + 10.128611473727778, + 10.451812433038233, + 10.711437256263803, + 10.903445576436914, + 11.025023074336762, + 11.074620746370444, + 11.051971535862748, + 10.958084225549335, + 10.795214890775753, + 10.566816605943485, + 10.27746847425869, + 9.932785406306083, + 9.539310400307915, + 9.104391370605342, + 8.636044826020632, + 8.142808912155186, + 7.633588497962493, + 7.117495104568888, + 6.603684541630603, + 6.101195132755869, + 5.618789376824897, + 5.1648018074555235, + 4.746995680294988, + 4.372430940013857, + 4.047345699351593, + 3.777053205535259, + 3.56585597971345, + 3.4169784980952476, + 3.3325194450799946, + 3.3134242149507727, + 3.359477976050294, + 3.4693192462284745, + 3.6404735672052877, + 3.869406514662606, + 4.151594946462078, + 4.481615079140221, + 4.853245698072458, + 5.259584554215099, + 5.693175784303991, + 6.146146015314341, + 6.610346680631895, + 7.07749998674468, + 7.539345926519268, + 7.987787738644957, + 8.415033262158444, + 8.813729728847669, + 9.1770896727416, + 9.499005812063, + 9.774152971511015, + 9.998075357496623, + 10.167257771392372, + 10.279179640939029, + 10.332351062286236, + 10.32633036907735, + 10.261723074715002, + 10.14016236359994, + 9.964271630912181, + 9.737609882741689, + 9.46460110366882, + 9.150448972180925, + 8.801038550957191, + 8.422826794938299, + 8.022723901671622, + 7.607967672778588, + 7.185993160293738, + 6.764299935563107, + 6.350319340576264, + 5.951284062007948, + 5.5741023075549485, + 5.225238763792553, + 4.910604376842278, + 4.635456824391195, + 4.404313343368917, + 4.220877345738201, + 4.087979999710456, + 4.007537679950003, + 3.980525902965885, + 4.0069700680859, + 4.085953025451815, + 4.215639195662629, + 4.393314676239338, + 4.615442493030246, + 4.87773189479935, + 5.17522035097902, + 5.502366699938169, + 5.853153711652784, + 6.221198177352297, + 6.599866521952042, + 6.9823938546326145, + 7.362004329906699, + 7.7320306863612975, + 8.086030862754342, + 8.417899660384075, + 8.721973525111787, + 8.993126659959843, + 9.22685684712858, + 9.419359553356786, + 9.567589111126278, + 9.669306006228625, + 9.723109555311394, + 9.728455520614645, + 9.685658478459152, + 9.5958790283603, + 9.461096196141959, + 9.28406564244716, + 9.068264533110662, + 8.817824155760508, + 8.537451573880396, + 8.232341791921007, + 7.908082059890599, + 7.570550070683391, + 7.225807896273806, + 6.879993568445266, + 6.5392122351684145, + 6.209428814931636, + 5.896364028702616, + 5.60539561380094, + 5.34146641739034, + 5.109000931701864, + 4.911831671106323, + 4.753136605848706, + 4.6353886620976015, + 4.560318076737456, + 4.528888162072656, + 4.54128479453562, + 4.596919696911004, + 4.6944473398459365, + 4.83179504980195, + 5.006205681280889, + 5.214291995088333, + 5.452101685281823, + 5.715191818653825, + 5.998711295101918, + 6.29748980758471, + 6.606131678620783, + 6.919112878015579, + 7.230879484724627, + 7.535945844958614, + 7.82899069873716, + 8.104949597487227, + 8.359102014816623, + 8.58715165962259, + 8.785298633105354, + 8.950302226493472, + 9.079533331427761, + 9.171015626733332, + 9.223454910218194, + 9.236256158445281, + 9.209528117278, + 9.144075447473522, + 9.04137866877623, + 8.903562359000833, + 8.733352267787575, + 8.53402219456127, + 8.309331653498234, + 8.063455502085027, + 7.800906841594397, + 7.526454605370311, + 7.245037332513577, + 6.9616746791695485, + 6.681378246406191, + 6.40906330239687, + 6.14946294754699, + 5.907046215072963, + 5.68594151757598, + 5.489866744011124, + 5.32206718321448, + 5.185262302257889, + 5.08160224313206, + 5.012634722655673, + 4.979282831339911, + 4.981834030625571, + 5.019940447976321, + 5.092630369310828, + 5.198330631715016, + 5.334899429728873, + 5.499668869035397, + 5.689496435169581, + 5.900824394731858, + 6.129746015042945, + 6.372077377379095, + 6.6234334706547555, + 6.879307188042262, + 7.135149809464364, + 7.38645153865886, + 7.628820674626672, + 7.858060033330437, + 8.070239295660874, + 8.261762040670856, + 8.429426327236794, + 8.57047781062767, + 8.68265452060883, + 8.76422258206937, + 8.81400232489471, + 8.831384403894937, + 8.81633572890363, + 8.769395186477256, + 8.691659314738104, + 8.584758268649338, + 8.450822581327996, + 8.292441384985912, + 8.112612900041867, + 7.914688130425932, + 7.702308814945437, + 7.479340776981486, + 7.249803886266292, + 7.017799895975661, + 6.787439445167506, + 6.562769520427717, + 6.347702651573665, + 6.145949074942066, + 5.960953035067218, + 5.795834312726662, + 5.653335966019362, + 5.535779153293576, + 5.445025774570478, + 5.382449524068747, + 5.348915793162585, + 5.344770703381473, + 5.369839385754412, + 5.423433458823295, + 5.504367495895736, + 5.610984115409983, + 5.741187179363083, + 5.892482446167589, + 6.062024898408032, + 6.2466718548782225, + 6.443040881827235, + 6.647571442051195, + 6.856589163530248, + 7.066371572566976, + 7.2732141203102545, + 7.473495336257569, + 7.663739967557932, + 7.840679008073321, + 8.001305585230586, + 8.14292575442251, + 8.263203348504161, + 8.360198141921042, + 8.432396713103609, + 8.478735522679976, + 8.498615866349777, + 8.491910507376465, + 8.458961941974271, + 8.400572398757777, + 8.317985818282624, + 8.212862198007201, + 8.087244819338581, + 7.9435209945434675, + 7.784377080157817, + 7.612748598301342, + 7.431766386443373, + 7.244699758412344, + 7.054897703835331, + 6.8657291791084605, + 6.680523550127934, + 6.502512235392292, + 6.334772568078849, + 6.180174847987522, + 6.041333489822015, + 5.920563094420039, + 5.81984017578678, + 5.74077117090202, + 5.684567243226641, + 5.6520262667632615, + 5.643522247681169, + 5.659002307236236, + 5.697991215380181, + 5.759603331437531, + 5.842561678866738, + 5.945223757663348, + 6.06561358253507, + 6.201459329547331, + 6.350235880278511, + 6.509211472187369, + 6.6754975981857285, + 6.846101248362068, + 7.017978553165729, + 7.188088870592747, + 7.353448360164629, + 7.5111821036143, + 7.658573865743084, + 7.793112638161099, + 7.912535172567063, + 8.014863787615145, + 8.098438822774307, + 8.161945212236516, + 8.204432760028816, + 8.225329812054792, + 8.224450139758565, + 8.201992971335041, + 8.158536227747486, + 8.09502314011785, + 8.01274254024047, + 7.913303225040158, + 7.798602896880141, + 7.670792273009365, + 7.532235037592771, + 7.385464377374692, + 7.233136895998279, + 7.07798474150611, + 6.922766806005161, + 6.770219865588804, + 6.62301052233724, + 6.483688788808742, + 6.354644119388601, + 6.238064642943458, + 6.13590028842988, + 6.049830420645241, + 5.981236518595743, + 5.931180335572032, + 5.9003878796848666, + 5.889239448151704, + 5.897765839938984, + 5.925650761400607, + 5.972239330257633, + 6.036552476559746, + 6.117306937014296, + 6.2129404430289235, + 6.321641614629424, + 6.4413839935737025, + 6.569963580796863, + 6.705039186903186, + 6.844174860663909, + 6.984883630049101, + 7.124671773642361, + 7.261082837536044, + 7.3917406239132974, + 7.514390402178655, + 7.626937631152599, + 7.727483530723607, + 7.814356902471101, + 7.88614166996369, + 7.941699689356006, + 7.98018846807617, + 8.001073522212419, + 8.004135199990895, + 7.989469897745826, + 7.957485694254893, + 7.908892527488756, + 7.844687132984779, + 7.76613305354923, + 7.6747361142630055, + 7.572215833381148, + 7.4604733073891225, + 7.341556166092361, + 7.21762124023856, + 7.090895619075696, + 6.963636797916437, + 6.838092625915106, + 6.7164617617933775, + 6.60085533032593, + 6.493260445384807, + 6.395506226820312, + 6.309232889201914, + 6.235864421414659, + 6.176585308427642, + 6.132321671486884, + 6.1037271219217795, + 6.091173538170943, + 6.094746887077285, + 6.114248120559163, + 6.149199089032067, + 6.198853325013317, + 6.262211465725917, + 6.338041003690768, + 6.424899980625322, + 6.521164173698576, + 6.625057265432709, + 6.734683440236911, + 6.8480618124808945, + 6.963162063749433, + 7.077940650853889, + 7.190376941501665, + 7.298508641224991, + 7.4004658930335605, + 7.494503459871398, + 7.579030438732028, + 7.652637003448293, + 7.714117729796014, + 7.76249112056426, + 7.79701501845854, + 7.817197669827131, + 7.822804280868381, + 7.81385898877269, + 7.790642251733594, + 7.753683742486583, + 7.703750908585027, + 7.641833437633472, + 7.569123935877327, + 7.486995192697857, + 7.396974460603193, + 7.300715229293093, + 7.1999670125128805, + 7.09654369706683, + 6.992291024073035, + 6.889053783029457, + 6.788643299425302, + 6.692805786557801, + 6.6031921121656945, + 6.521329500904743, + 6.448595655169137, + 6.386195730061067, + 6.335142544320294, + 6.296240348759952, + 6.270072408329595, + 6.256992584537988, + 6.2571210328735125, + 6.270344056352639, + 6.296318082714604, + 6.334477660361844, + 6.384047298187252, + 6.444056908143464, + 6.5133605479339325, + 6.590658105582957, + 6.674519518804351, + 6.763411080838446, + 6.855723351428791, + 6.949800167374901, + 7.043968231979061, + 7.136566756892993, + 7.225976633388228, + 7.310648622781853, + 7.389130077344593, + 7.46008973304577, + 7.522340153349862, + 7.5748574482364095, + 7.616797943819457, + 7.6475115344366635, + 7.666551509822664, + 7.67368071386907, + 7.668873957351776, + 7.652316673697103, + 7.624399873179195, + 7.585711515725917, + 7.537024484630384, + 7.479281401847221, + 7.413576579199711, + 7.34113544782951, + 7.263291849786974, + 7.1814636101077856, + 7.097126834504387, + 7.011789396510509, + 6.926964088292373, + 6.844141911268313, + 6.764765976197082, + 6.6902064676889665, + 6.621737105491396, + 6.560513504867903, + 6.507553801517347, + 6.463721863477193, + 6.429713364130367, + 6.406044937686349, + 6.393046582300923, + 6.390857417355252, + 6.3994248413884955, + 6.4185070768381856, + 6.4476790281560135, + 6.486341322077063, + 6.533732343831858, + 6.588943031848309, + 6.650934146866602, + 6.718555690167072, + 6.7905681104703985, + 6.865664910579375, + 6.942496243437512, + 7.019693073299796, + 7.095891471328953, + 7.169756616193955, + 7.2400060790711, + 7.305431988610862, + 7.364921694590111, + 7.417476578651582, + 7.4622286961624, + 7.498454974122643, + 7.525588735458175, + 7.5432283691008655, + 7.551143017097525, + 7.549275203659872, + 7.537740385609555, + 7.516823458115967, + 7.486972303011538, + 7.448788518366969, + 7.403015516528308, + 7.350524222627919, + 7.292296645923436, + 7.22940763151922, + 7.163005129507156, + 7.094289341855172, + 7.024491124115379, + 6.954850028978817, + 6.886592381752183, + 6.820909773978284, + 6.758938350792371, + 6.701739250445711, + 6.650280531093153, + 6.605420890896254, + 6.5678954532988865, + 6.538303850632901, + 6.517100796729134, + 6.504589293723443, + 6.5009165705862895, + 6.506072801926108, + 6.519892606195727, + 6.542059273442389, + 6.57211162504553, + 6.609453362312134, + 6.653364718132802, + 6.703016186870202, + 6.75748407291285, + 6.815767568456932, + 6.876807046563358, + 6.939503236762572, + 7.002736937729009, + 7.065388914994126, + 7.126359631375097, + 7.184588463717247, + 7.239072071526697, + 7.288881600841105, + 7.3331784298912, + 7.371228191286725, + 7.4024128380804335, + 7.426240557509538, + 7.442353375810791, + 7.450532339529158, + 7.450700202428678, + 7.442921591684209, + 7.427400671690611, + 7.404476367783899, + 7.374615254657818, + 7.338402254542636, + 7.2965293275990994, + 7.2497823708350335, + 7.199026571607778, + 7.145190486942529, + 7.089249140070283, + 7.032206440455151, + 6.975077242922723, + 6.918869365200386, + 6.864565881219944, + 6.813107999994109, + 6.765378826942176, + 6.7221882864794065, + 6.6842594618616, + 6.652216581132625, + 6.626574847074182, + 6.607732274881078, + 6.595963664511032, + 6.5914167959567385, + 6.594110895756961, + 6.603937382617914, + 6.620662859773041, + 6.643934282376292, + 6.673286190486969, + 6.708149862714692, + 6.747864212957919, + 6.791688223439766, + 6.838814681907416, + 6.888384969829424, + 6.939504632034247, + 6.991259446731486, + 7.042731708408175, + 7.093016434764932, + 7.141237212633028, + 7.186561406582147, + 7.228214467494422, + 7.2654930964627855, + 7.297777041614264, + 7.324539331434183, + 7.345354777386307, + 7.359906610543809, + 7.367991150981354, + 7.3695204442119, + 7.364522835343618, + 7.353141488234128, + 7.335630893083973, + 7.312351441005086, + 7.283762177513202, + 7.250411878051196, + 7.21292861702259, + 7.172008026924542, + 7.128400465602451, + 7.0828973270567195, + 7.036316744343773, + 6.989488941732844, + 6.943241497293566, + 6.898384776464732, + 6.8556977919426565, + 6.815914735557788, + 6.779712413889812, + 6.747698801484995, + 6.720402904033792, + 6.698266099151549, + 6.6816350949433785, + 6.670756616832807, + 6.665773901735483, + 6.666725046131726, + 6.673543221517961, + 6.686058737684705, + 6.704002901859758, + 6.7270135905357185, + 6.75464242131101, + 6.786363384818724, + 6.821582772259365, + 6.859650212601866, + 6.899870615524602, + 6.941516801921768, + 6.9838425935206665, + 7.026096126989563, + 7.067533155937608, + 7.1074301064179926, + 7.145096657868192, + 7.1798876317110265, + 7.21121398388218, + 7.238552715064923, + 7.261455533062829, + 7.279556125135542, + 7.2925759238263375, + 7.300328277349616, + 7.30272096448189, + 7.29975702358975, + 7.2915338954034885, + 7.278240908873957, + 7.260155168411361, + 7.237635928493636, + 7.211117567571676, + 7.181101296946316, + 7.148145761447685, + 7.11285670695979, + 7.075875904806616, + 7.037869534512937, + 6.999516234300919, + 6.961495032774691, + 6.924473375538379, + 6.889095457016717, + 6.855971060592818, + 6.825665099503633, + 6.7986880369568174, + 6.775487346927955, + 6.75644015738964, + 6.74184719568374, + 6.731928131783694, + 6.726818389743601, + 6.726567471156227, + 6.731138807418216, + 6.740411130508923, + 6.75418132530736, + 6.772168700666794, + 6.794020591985914, + 6.819319185279753, + 6.847589432148653, + 6.878307906914722, + 6.910912441841256, + 6.944812364018672, + 6.97939914838258, + 7.014057295559069, + 7.0481752408830705, + 7.081156102019857, + 7.112428077089546, + 7.141454312942308, + 7.167742074094016, + 7.190851056590038, + 7.210400707452126, + 7.226076429068825, + 7.237634568564135, + 7.244906114441142, + 7.24779904624147, + 7.246299307164094, + 7.240470394115436, + 7.230451584081639, + 7.216454839593712, + 7.198760458980771, + 7.177711558679491, + 7.153707494720461, + 7.127196348308922, + 7.098666615861714, + 7.068638256702384, + 7.037653261646976, + 7.006265912782022, + 6.975032908743074, + 6.944503530702552, + 6.915210022080011, + 6.887658349760552, + 6.8623195064664015, + 6.8396215030401315, + 6.819942185981145, + 6.80360299988732, + 6.790863796787373, + 6.78191877503413, + 6.776893609819304, + 6.775843815840576, + 6.7787543605891525, + 6.785540524523893, + 6.796049982449191, + 6.8100660591027635, + 6.827312091656683, + 6.847456812889866, + 6.870120651525047, + 6.894882830928609, + 6.92128913430012, + 6.948860193841979, + 6.977100153364928, + 7.005505548472352, + 7.033574245945606, + 7.060814284245107, + 7.086752460118922, + 7.1109425120938745, + 7.132972759989396, + 7.1524730703723005, + 7.169121030850268, + 7.182647231036792 + ], + "pressures_mid": [ + 5.6000000000000005, + 5.624309583418218, + 5.648619166836436, + 5.672928750254654, + 5.697238333672871, + 5.721547917091089, + 5.745857500509306, + 5.770167083927524, + 5.794476667345742, + 5.81878625076396, + 5.8430958341821775, + 5.867405417600395, + 5.891715001018612, + 5.91602458443683, + 5.940334167855048, + 5.9646437512732655, + 5.988953334691484, + 6.013262918109701, + 6.037572501527919, + 6.061882084946137, + 6.086191668364354, + 6.110501251782572, + 6.134810835200789, + 6.159120418619008, + 6.183430002037225, + 6.2077395854554425, + 6.232049168873661, + 6.256358752291878, + 6.2806683357100965, + 6.304977919128313, + 6.329287502546531, + 6.353597085964749, + 6.377906669382966, + 6.4022162528011854, + 6.426525836219402, + 6.450835419637619, + 6.475145003055838, + 6.499454586474055, + 6.5237641698922735, + 6.54807375331049, + 6.572383336728709, + 6.596692920146926, + 6.621002503565143, + 6.6453120869833615, + 6.669621670401579, + 6.693931253819797, + 6.718240837238014, + 6.742550420656233, + 6.7668600040744495, + 6.791169587492667, + 6.815479170910885, + 6.839788754329103, + 6.864098337747321, + 6.888407921165538, + 6.912717504583757, + 6.937027088001973, + 6.961336671420192, + 6.985646254838409, + 7.0099558382566265, + 7.034265421674845, + 7.058575005093061, + 7.0828845885112806, + 7.107194171929497, + 7.131503755347715, + 7.155813338765933, + 7.180122922184151, + 7.204432505602369, + 7.228742089020585, + 7.253051672438804, + 7.277361255857021, + 7.301670839275239, + 7.325980422693457, + 7.350290006111675, + 7.374599589529892, + 7.398909172948109, + 7.423218756366328, + 7.447528339784545, + 7.471837923202763, + 7.49614750662098, + 7.520457090039199, + 7.544766673457416, + 7.569076256875633, + 7.593385840293852, + 7.61769542371207, + 7.642005007130287, + 7.666314590548504, + 7.6906241739667225, + 7.71493375738494, + 7.7392433408031565, + 7.763552924221376, + 7.787862507639594, + 7.8121720910578105, + 7.836481674476028, + 7.860791257894246, + 7.885100841312464, + 7.909410424730682, + 7.933720008148899, + 7.958029591567118, + 7.982339174985334, + 8.006648758403552, + 8.030958341821771, + 8.055267925239987, + 8.079577508658206, + 8.103887092076423, + 8.12819667549464, + 8.152506258912858, + 8.176815842331076, + 8.201125425749295, + 8.22543500916751, + 8.24974459258573, + 8.274054176003947, + 8.298363759422164, + 8.322673342840382, + 8.346982926258601, + 8.371292509676818, + 8.395602093095036, + 8.419911676513252, + 8.44422125993147, + 8.468530843349688, + 8.492840426767906, + 8.517150010186123, + 8.541459593604342, + 8.565769177022558, + 8.590078760440777, + 8.614388343858995, + 8.638697927277212, + 8.66300751069543, + 8.687317094113647, + 8.711626677531866, + 8.735936260950083, + 8.760245844368301, + 8.784555427786518, + 8.808865011204736, + 8.833174594622955, + 8.857484178041172, + 8.88179376145939, + 8.906103344877607, + 8.930412928295825, + 8.954722511714042, + 8.97903209513226, + 9.003341678550479, + 9.027651261968694, + 9.051960845386914, + 9.076270428805131, + 9.100580012223348, + 9.124889595641566, + 9.149199179059783, + 9.173508762478003, + 9.197818345896218, + 9.222127929314437, + 9.246437512732655, + 9.270747096150872, + 9.29505667956909, + 9.319366262987307, + 9.343675846405526, + 9.367985429823744, + 9.392295013241961, + 9.416604596660179, + 9.440914180078396, + 9.465223763496613, + 9.48953334691483, + 9.51384293033305, + 9.538152513751267, + 9.562462097169485, + 9.586771680587702, + 9.611081264005922, + 9.635390847424139, + 9.659700430842356, + 9.684010014260574, + 9.708319597678791, + 9.732629181097009, + 9.756938764515226, + 9.781248347933444, + 9.805557931351661, + 9.82986751476988, + 9.854177098188098, + 9.878486681606315, + 9.902796265024532, + 9.92710584844275, + 9.951415431860969, + 9.975725015279187, + 10.000034598697404, + 10.024344182115621, + 10.048653765533839, + 10.072963348952056, + 10.097272932370274, + 10.121582515788493, + 10.14589209920671, + 10.170201682624928, + 10.194511266043145, + 10.218820849461364, + 10.243130432879582, + 10.267440016297797, + 10.291749599716017, + 10.316059183134234, + 10.340368766552452, + 10.364678349970669, + 10.388987933388886, + 10.413297516807104, + 10.437607100225321, + 10.46191668364354, + 10.398554155493953, + 10.251136061025349, + 10.022970265420762, + 9.718760167740465, + 9.34451001467537, + 8.907408081456854, + 8.415689965965049, + 7.878484573698088, + 7.305645654648808, + 6.707571983691382, + 6.095019450194375, + 5.478908437649771, + 4.870129928615798, + 4.279353763757851, + 3.716842416873435, + 3.192273522185312, + 2.7145742085983238, + 2.2917700617064063, + 1.9308512526784023, + 1.6376580491061574, + 1.41678756254177, + 1.2715231974365346, + 1.203787853651722, + 1.214121507099973, + 1.3016833580635478, + 1.4642783020510415, + 1.6984070513584897, + 1.99933882424831, + 2.36120512996904, + 2.7771128183732725, + 3.2392742387387194, + 3.7391520689770035, + 4.267616138375771, + 4.815109378178833, + 5.371819897577917, + 5.927856100038722, + 6.473421727316903, + 6.998987746053075, + 7.495458073524879, + 7.954326273076247, + 8.367820533142917, + 8.729034472992831, + 9.032041588879409, + 9.271991461140278, + 9.4451861801541, + 9.549135810784149, + 9.582592094411226, + 9.545559978047995, + 9.439286954360401, + 9.266230587713032, + 9.030004982732818, + 8.735307316710152, + 8.387825899135704, + 7.9941315349708395, + 7.561554247586551, + 7.098047658044924, + 6.612043515617362, + 6.112299027002812, + 5.607739736319448, + 5.107300763157146, + 4.619769211239551, + 4.153630515879171, + 3.716921405622303, + 3.317092014311318, + 2.9608794970902412, + 2.654195281228268, + 2.40202782430143, + 2.2083624631064134, + 2.0761196220431546, + 2.007112315353095, + 2.0020235296004487, + 2.060403717382382, + 2.180688276779692, + 2.3602345398044555, + 2.5953774532136054, + 2.8815028124334128, + 3.2131366095201934, + 3.5840487841616793, + 3.98736942725728, + 4.415715283554283, + 4.861324236430182, + 5.316195336747679, + 5.772231860544852, + 6.221384848150333, + 6.655794590318234, + 7.06792758454896, + 7.450706585511956, + 7.797631515270092, + 8.102889178982222, + 8.361449946430588, + 8.569149805011042, + 8.722756461149531, + 8.82001845946941, + 8.859696597096356, + 8.841577228690198, + 8.766467380439469, + 8.636171912620602, + 8.453453284754788, + 8.221974779406953, + 7.946228325044867, + 7.631448320246332, + 7.283513096484274, + 6.908835860816506, + 6.514247129724149, + 6.106870798369995, + 5.693996083655111, + 5.282947633304483, + 4.880956106204696, + 4.495031501459918, + 4.131841445964419, + 3.797596544235991, + 3.4979447520110853, + 3.237876559481274, + 3.0216425644282072, + 2.8526847837707603, + 2.7335827984761982, + 2.666015556063996, + 2.6507393719606185, + 2.6875823808402353, + 2.77545539698278, + 2.9123788537642303, + 3.095525211730085, + 3.3212759571696626, + 3.585292063312177, + 3.8825965584579665, + 4.207667643372079, + 4.554540627443193, + 4.916916812251473, + 5.2882773445055165, + 5.661999989395745, + 6.031476741215415, + 6.390230190915966, + 6.732026609726756, + 7.050983783078135, + 7.341671738193281, + 7.5992046496504, + 7.819322377208812, + 7.998460285997298, + 8.133806217113898, + 8.223343712751223, + 8.265880849828989, + 8.26106429526188, + 8.209378459772003, + 8.112129890879952, + 7.971417304729745, + 7.790087906193351, + 7.5716808829350555, + 7.3203591777447405, + 7.040830840765754, + 6.73826143595064, + 6.418179121337298, + 6.086374138222871, + 5.748794528234991, + 5.411439948450486, + 5.080255472461012, + 4.761027249606359, + 4.459281846043959, + 4.180191011034043, + 3.9284835014738224, + 3.7083654595129563, + 3.523450674695134, + 3.376701876590561, + 3.270383999768365, + 3.2060301439600027, + 3.184420722372708, + 3.2055760544687204, + 3.268762420361452, + 3.372511356530103, + 3.51465174099147, + 3.692353994424197, + 3.9021855158394803, + 4.140176280783216, + 4.401893359950535, + 4.6825229693222274, + 4.976958541881838, + 5.279893217561634, + 5.585915083706092, + 5.88960346392536, + 6.185624549089038, + 6.468824690203474, + 6.73431972830726, + 6.97757882008943, + 7.194501327967875, + 7.3814854777028645, + 7.535487642685429, + 7.654071288901022, + 7.735444804982901, + 7.7784876442491155, + 7.782764416491716, + 7.748526782767321, + 7.676703222688241, + 7.568876956913567, + 7.427252513957729, + 7.25461162648853, + 7.054259324608407, + 6.8299612591043175, + 6.585873433536806, + 6.32646564791248, + 6.0564400565467125, + 5.780646317019045, + 5.503994854756213, + 5.231369788134732, + 4.967543051945309, + 4.717091222962092, + 4.484316491040753, + 4.273173133912272, + 4.087200745361492, + 3.9294653368850585, + 3.802509284678965, + 3.708310929678081, + 3.648254461389965, + 3.623110529658125, + 3.633027835628496, + 3.6775357575288035, + 3.7555578718767495, + 3.86543603984156, + 4.004964545024712, + 4.171433596070666, + 4.361681348225459, + 4.57215345492306, + 4.798969036081535, + 5.037991846067769, + 5.284905342896627, + 5.535290302412463, + 5.784703587779703, + 6.028756675966892, + 6.263192558989728, + 6.483959677989782, + 6.687281611853298, + 6.869721327698072, + 7.028238906484283, + 7.160241781194777, + 7.263626665142209, + 7.3368125013866665, + 7.378763928174556, + 7.3890049267562254, + 7.3676224938224, + 7.3152603579788185, + 7.233102935020985, + 7.122849887200667, + 6.98668181423006, + 6.827217755649016, + 6.647465322798587, + 6.450764401668022, + 6.240725473275518, + 6.0211636842962495, + 5.796029866010862, + 5.5693397433356395, + 5.345102597124953, + 5.127250641917496, + 4.919570358037593, + 4.72563697205837, + 4.548753214060784, + 4.391893395208899, + 4.257653746571584, + 4.148209841806311, + 4.0652817945056485, + 4.010107778124539, + 3.983426265071929, + 3.9854672245004568, + 4.015952358381057, + 4.074104295448662, + 4.158664505372013, + 4.267919543783099, + 4.399735095228318, + 4.551597148135666, + 4.720659515785487, + 4.903796812034356, + 5.097661901903276, + 5.298746776523805, + 5.5034457504338095, + 5.708119847571492, + 5.909161230927088, + 6.103056539701338, + 6.28644802666435, + 6.4561914365287, + 6.609409632536686, + 6.743541061789435, + 6.856382248502136, + 6.946123616487064, + 7.011378065655497, + 7.051201859915769, + 7.06510752311595, + 7.053068583122904, + 7.015516149181805, + 6.953327451790483, + 6.867806614919471, + 6.7606580650623975, + 6.63395310798873, + 6.490090320033494, + 6.3317505043407465, + 6.16184705195635, + 5.983472621585189, + 5.799843109013034, + 5.614239916780529, + 5.4299515561340055, + 5.2502156163421745, + 5.0781621212589325, + 4.916759259953653, + 4.768762428053775, + 4.63666745018133, + 4.522668772815489, + 4.428623322634861, + 4.356020619656383, + 4.305959619254998, + 4.279132634530068, + 4.275816562705178, + 4.29587150860353, + 4.338746767058637, + 4.403493996716589, + 4.488787292327987, + 4.5929497434904665, + 4.713985956934072, + 4.849619918726425, + 4.997337483902578, + 5.1544327054617884, + 5.318057153640956, + 5.485271330824198, + 5.653097258053581, + 5.818571296248204, + 5.978796269006056, + 6.130991974046346, + 6.272543206458657, + 6.40104446818447, + 6.514340603538009, + 6.61056267880333, + 6.688158513536834, + 6.745917370482887, + 6.782988418143981, + 6.7988926930798215, + 6.7935284059011725, + 6.767169553579418, + 6.720457919006222, + 6.6543886546261, + 6.570289758405761, + 6.469795855470865, + 6.3548167956347745, + 6.227501664126255, + 6.090198878641074, + 5.945413109154699, + 5.795759806729876, + 5.643918163068265, + 5.492583343286769, + 5.344418840102348, + 5.202009788313834, + 5.067818054463079, + 4.944139878390018, + 4.833066791857612, + 4.7364504755360315, + 4.655872140629424, + 4.592616936721616, + 4.547653794581313, + 4.521621013410609, + 4.514817798144935, + 4.527201845788989, + 4.558392972304145, + 4.607682665150025, + 4.67404934309339, + 4.756179006130679, + 4.852490866028056, + 4.961167463637865, + 5.0801887042228095, + 5.207369177749896, + 5.340398078548583, + 5.476880998689655, + 5.614382842532583, + 5.750471096474198, + 5.8827586881317036, + 6.00894568289144, + 6.126859092594468, + 6.2344901105288795, + 6.330028138053651, + 6.411891030092116, + 6.478751058219446, + 6.529556169789213, + 6.563546208023053, + 6.580263849643834, + 6.5795601118068525, + 6.561594377068033, + 6.52682898219799, + 6.47601851209428, + 6.4101940321923765, + 6.330642580032126, + 6.238882317504113, + 6.136633818407493, + 6.025788030074217, + 5.9083715018997545, + 5.786509516798624, + 5.662387793204888, + 5.5382134448041285, + 5.416175892471044, + 5.298408417869792, + 5.186951031046994, + 5.083715295510881, + 4.990451714354767, + 4.908720230743905, + 4.839864336516193, + 4.784989214876595, + 4.744944268457625, + 4.720310303747893, + 4.711391558521363, + 4.718212671951187, + 4.740520609120486, + 4.777791464206106, + 4.829241981247797, + 4.893845549611437, + 4.970352354423139, + 5.05731329170354, + 5.153107194858962, + 5.25597086463749, + 5.3640313495225485, + 5.475339888531128, + 5.587906904039281, + 5.699737418913889, + 5.808866270028836, + 5.913392499130638, + 6.0115123217429245, + 6.1015501049220795, + 6.181986824578885, + 6.251485521976881, + 6.308913335970953, + 6.353359751484805, + 6.384150774460936, + 6.400858817769936, + 6.403308159992716, + 6.391575918196661, + 6.365988555403915, + 6.3271140219910045, + 6.275749706387824, + 6.212906442839384, + 6.139788891410404, + 6.057772666704919, + 5.968378645911298, + 5.873244932873889, + 5.774096992190849, + 5.672716495260557, + 5.57090943833315, + 5.470474100732085, + 5.373169409434702, + 5.280684264260745, + 5.194608356307846, + 5.11640498145625, + 5.047386311361532, + 4.988691537131728, + 4.941268246742114, + 4.905857337189508, + 4.882981697537424, + 4.8729388305367545, + 4.875797509661829, + 4.89139849644733, + 4.919359271225654, + 4.959082660010655, + 5.009769172580734, + 5.070432802952615, + 5.139919984500258, + 5.216931338958862, + 5.300045812346167, + 5.387746752189529, + 5.478449449984716, + 5.570529650999546, + 5.662352520683111, + 5.752301553201332, + 5.838806912979994, + 5.920372714426849, + 5.995602767897118, + 6.063224350985623, + 6.122109602758634, + 6.171294183836811, + 6.209992896451408, + 6.237612014766832, + 6.253758135861705, + 6.2582434246947045, + 6.2510871910181525, + 6.232513801386876, + 6.202946993989267, + 6.163000726868022, + 6.113466750106777, + 6.055299148701862, + 5.989596154158286, + 5.917579568482555, + 5.840572183434475, + 5.759973610010305, + 5.677234957653464, + 5.593832819258428, + 5.511243026423566, + 5.430914639540242, + 5.354244629246241, + 5.282553689732556, + 5.217063600723795, + 5.15887652413531, + 5.108956584048855, + 5.068114035456236, + 5.036992279007961, + 5.0160579266636764, + 5.0055940676303905, + 5.00569682629881, + 5.016275245082111, + 5.037054466171684, + 5.067582128289476, + 5.107237838549802, + 5.155245526514772, + 5.210688438347146, + 5.272526484466366, + 5.339615615043481, + 5.410728864670757, + 5.4845786811430335, + 5.559840133899922, + 5.63517458558325, + 5.709253405514395, + 5.780781306710583, + 5.848518898225483, + 5.911304061875675, + 5.968071786436616, + 6.01787212267989, + 6.059885958589128, + 6.093438355055566, + 6.118009227549331, + 6.1332412078581315, + 6.138944571095256, + 6.135099165881421, + 6.121853338957683, + 6.099519898543356, + 6.068569212580734, + 6.029619587704308, + 5.983425121477777, + 5.93086126335977, + 5.872908358263608, + 5.81063347982958, + 5.7451708880862284, + 5.67770146760351, + 5.6094315172084075, + 5.541571270633899, + 5.475313529014651, + 5.411812780957666, + 5.352165174151174, + 5.297389684393117, + 5.248410803894323, + 5.206043041213878, + 5.170977490781755, + 5.143770691304294, + 5.1248359501490794, + 5.114437265840738, + 5.112685933884202, + 5.119539873110797, + 5.134805661470549, + 5.158143222524811, + 5.189073057661651, + 5.226985875065487, + 5.271154425478648, + 5.320747317493282, + 5.374844552133658, + 5.432454488376319, + 5.4925319284635, + 5.55399699475001, + 5.615754458639837, + 5.676713177063163, + 5.735805292955164, + 5.792004863256881, + 5.84434559088869, + 5.891937355672089, + 5.933981262921266, + 5.969782956929921, + 5.998763979298115, + 6.02047098836654, + 6.034582695280693, + 6.040914413678021, + 6.039420162927898, + 6.030192308487645, + 6.013458766492774, + 5.989577842409231, + 5.959030814693576, + 5.922412413222647, + 5.880419378102335, + 5.833837316738749, + 5.783526105215376, + 5.730404103605725, + 5.675431473484138, + 5.619592899292304, + 5.563880023183054, + 5.509273905401747, + 5.456727819182627, + 5.407150680633897, + 5.3613914003565695, + 5.320224424874523, + 5.284336712717003, + 5.254316362639109, + 5.230643080506321, + 5.213680637383308, + 5.203671434978755, + 5.200733256469032, + 5.204858241540887, + 5.215914084956582, + 5.233647418753911, + 5.257689300036424, + 5.2875626898497075, + 5.322691774506242, + 5.362412949496162, + 5.40598725833028, + 5.452614054765546, + 5.501445637250686, + 5.5516025894100585, + 5.6021895501832075, + 5.652311131995301, + 5.701087705100078, + 5.747670770973798, + 5.791257657221358, + 5.831105280672884, + 5.8665427439129605, + 5.89698255302938, + 5.9219302704643475, + 5.94099244600763, + 5.9538827006486335, + 5.960425871623326, + 5.960560161942943, + 5.954337273347368, + 5.941920537352489, + 5.92358109422712, + 5.8996922037262545, + 5.870721803634109, + 5.83722346207928, + 5.799825896668027, + 5.759221257286223, + 5.716152389554024, + 5.671399312056227, + 5.625765152364121, + 5.580061794338178, + 5.535095492160309, + 5.491652704975955, + 5.450486399995288, + 5.412303061553741, + 5.3777506291835255, + 5.34740756948928, + 5.3217732649061, + 5.301259877659346, + 5.286185819904863, + 5.2767709316088265, + 5.2731334367653915, + 5.275288716605569, + 5.283149906094332, + 5.296530287818433, + 5.315147425901034, + 5.338628952389576, + 5.366519890171754, + 5.398291370366335, + 5.4333505787518135, + 5.4710517455259335, + 5.510707975863539, + 5.5516037056273975, + 5.593007557385189, + 5.63418536672654, + 5.674413147811946, + 5.7129897701064225, + 5.749249125265718, + 5.782571573995538, + 5.812394477170229, + 5.838221633291411, + 5.859631465147347, + 5.876283821909046, + 5.8879252884350475, + 5.894392920785084, + 5.89561635536952, + 5.891618268274895, + 5.882513190587303, + 5.8685047144671785, + 5.84988115280407, + 5.827009742010562, + 5.800329502440957, + 5.770342893618072, + 5.737606421539634, + 5.702720372481961, + 5.666317861645376, + 5.629053395475019, + 5.591591153386275, + 5.554593197834853, + 5.518707821171786, + 5.484558233554125, + 5.452731788446231, + 5.42376993111185, + 5.398159041187996, + 5.376322323227034, + 5.358612879321239, + 5.345308075954703, + 5.336605293466246, + 5.332619121388387, + 5.333380036905381, + 5.338834577214369, + 5.348846990147765, + 5.363202321487806, + 5.381610872428575, + 5.403713937048808, + 5.4290907078549795, + 5.457266217807493, + 5.487720170081493, + 5.519896492419682, + 5.553213441537415, + 5.587074074816534, + 5.62087690159165, + 5.654026524750087, + 5.685944085134395, + 5.7160773262945535, + 5.743910105368822, + 5.768971187105745, + 5.7908421720519385, + 5.8091644264502635, + 5.823644900108434, + 5.83406073906107, + 5.840262621879693, + 5.842176771585512, + 5.8398056188718, + 5.833227116322791, + 5.822592727099166, + 5.8081241347290895, + 5.790108742794909, + 5.768894054057341, + 5.744881037557054, + 5.718516609158148, + 5.690285365567832, + 5.660700723845293, + 5.63029562761035, + 5.599612987440736, + 5.569196026219753, + 5.539578700430703, + 5.511276365613374, + 5.4847768484742545, + 5.460532079602906, + 5.4389504295654545, + 5.420389877542364, + 5.405152125911712, + 5.393477756546993, + 5.3855425054269555, + 5.3814547117948806, + 5.381253976924982, + 5.384911045934573, + 5.3923289044071385, + 5.403345060245888, + 5.417734960533435, + 5.435216473588731, + 5.455455348223802, + 5.478071545718922, + 5.502646325531778, + 5.528729953473005, + 5.555849891214938, + 5.583519318706064, + 5.611245836447256, + 5.638540192706457, + 5.664924881615885, + 5.689942461671637, + 5.713163450353846, + 5.734193659275213, + 5.752680845272031, + 5.768320565961702, + 5.78086114325506, + 5.790107654851308, + 5.7959248915529145, + 5.798239236993176, + 5.797039445731276, + 5.792376315292349, + 5.784361267265311, + 5.77316387167497, + 5.759008367184617, + 5.742169246943593, + 5.722965995776369, + 5.701757078647137, + 5.678933292689372, + 5.654910605361907, + 5.630122609317581, + 5.605012730225618, + 5.58002632699446, + 5.555602824562042, + 5.532168017664009, + 5.510126679808442, + 5.489855605173122, + 5.4716972024321056, + 5.455953748784917, + 5.442882399909856, + 5.4326910374298985, + 5.425535020027304, + 5.4215148878554436, + 5.420675052672461, + 5.4230034884713225, + 5.4284324196191145, + 5.436839985959353, + 5.448052847282211, + 5.4618496733253465, + 5.477965450311893, + 5.496096521220038, + 5.515906264742888, + 5.537031307440096, + 5.559088155073583, + 5.581680122691942, + 5.604404438777882, + 5.626859396756485, + 5.648651427396086, + 5.669401968095138, + 5.6887540096751, + 5.706378207991517, + 5.72197845629784, + 5.735296824680215, + 5.746117784829433 + ], + "pressures_end": [ + 4.2, + 4.218232187563663, + 4.236464375127326, + 4.25469656269099, + 4.272928750254653, + 4.291160937818316, + 4.3093931253819795, + 4.327625312945643, + 4.345857500509306, + 4.364089688072969, + 4.382321875636633, + 4.400554063200296, + 4.418786250763959, + 4.437018438327622, + 4.455250625891286, + 4.4734828134549485, + 4.491715001018612, + 4.5099471885822755, + 4.528179376145939, + 4.5464115637096025, + 4.564643751273265, + 4.582875938836929, + 4.601108126400591, + 4.619340313964255, + 4.637572501527918, + 4.655804689091582, + 4.674036876655245, + 4.692269064218908, + 4.7105012517825715, + 4.728733439346234, + 4.746965626909898, + 4.765197814473561, + 4.783430002037225, + 4.801662189600888, + 4.819894377164551, + 4.838126564728214, + 4.856358752291878, + 4.8745909398555405, + 4.892823127419205, + 4.9110553149828675, + 4.929287502546531, + 4.947519690110194, + 4.965751877673857, + 4.983984065237521, + 5.002216252801183, + 5.020448440364848, + 5.03868062792851, + 5.056912815492174, + 5.0751450030558365, + 5.0933771906195, + 5.1116093781831635, + 5.129841565746826, + 5.1480737533104906, + 5.166305940874153, + 5.184538128437817, + 5.202770316001479, + 5.221002503565144, + 5.239234691128806, + 5.257466878692469, + 5.275699066256133, + 5.293931253819796, + 5.3121634413834595, + 5.330395628947122, + 5.348627816510787, + 5.366860004074449, + 5.385092191638113, + 5.403324379201776, + 5.421556566765439, + 5.439788754329102, + 5.458020941892765, + 5.476253129456429, + 5.494485317020092, + 5.5127175045837555, + 5.530949692147419, + 5.549181879711082, + 5.567414067274745, + 5.585646254838408, + 5.603878442402072, + 5.622110629965735, + 5.640342817529398, + 5.658575005093062, + 5.6768071926567245, + 5.695039380220388, + 5.713271567784052, + 5.731503755347715, + 5.749735942911378, + 5.767968130475041, + 5.786200318038705, + 5.804432505602367, + 5.822664693166031, + 5.840896880729695, + 5.859129068293358, + 5.8773612558570205, + 5.895593443420684, + 5.9138256309843475, + 5.932057818548011, + 5.950290006111674, + 5.968522193675338, + 5.986754381239001, + 6.004986568802663, + 6.023218756366327, + 6.04145094392999, + 6.059683131493654, + 6.0779153190573165, + 6.096147506620981, + 6.1143796941846436, + 6.132611881748306, + 6.15084406931197, + 6.169076256875633, + 6.187308444439297, + 6.205540632002959, + 6.223772819566624, + 6.242005007130286, + 6.26023719469395, + 6.2784693822576125, + 6.296701569821277, + 6.314933757384939, + 6.333165944948602, + 6.351398132512267, + 6.369630320075929, + 6.387862507639592, + 6.406094695203255, + 6.424326882766919, + 6.442559070330582, + 6.460791257894245, + 6.479023445457909, + 6.497255633021572, + 6.515487820585235, + 6.533720008148898, + 6.551952195712563, + 6.570184383276225, + 6.588416570839888, + 6.606648758403552, + 6.624880945967216, + 6.643113133530878, + 6.661345321094541, + 6.679577508658205, + 6.697809696221868, + 6.716041883785531, + 6.734274071349195, + 6.752506258912859, + 6.77073844647652, + 6.788970634040184, + 6.807202821603848, + 6.825435009167511, + 6.8436671967311735, + 6.861899384294838, + 6.880131571858501, + 6.898363759422163, + 6.916595946985827, + 6.934828134549491, + 6.953060322113154, + 6.971292509676816, + 6.989524697240481, + 7.007756884804144, + 7.025989072367807, + 7.0442212599314695, + 7.062453447495134, + 7.080685635058797, + 7.098917822622459, + 7.117150010186124, + 7.135382197749787, + 7.15361438531345, + 7.171846572877112, + 7.190078760440777, + 7.20831094800444, + 7.226543135568103, + 7.2447753231317655, + 7.26300751069543, + 7.281239698259093, + 7.299471885822755, + 7.31770407338642, + 7.335936260950082, + 7.354168448513745, + 7.372400636077408, + 7.390632823641073, + 7.408865011204735, + 7.427097198768398, + 7.445329386332062, + 7.463561573895726, + 7.481793761459389, + 7.500025949023051, + 7.518258136586716, + 7.536490324150378, + 7.554722511714041, + 7.572954699277705, + 7.591186886841369, + 7.609419074405031, + 7.627651261968694, + 7.645883449532358, + 7.664115637096022, + 7.682347824659685, + 7.700580012223348, + 7.718812199787012, + 7.737044387350674, + 7.755276574914337, + 7.773508762478001, + 7.791740950041664, + 7.8099731376053265, + 7.828205325168991, + 7.846437512732654, + 7.798915616620463, + 7.68835204576901, + 7.517227699065571, + 7.289070125805348, + 7.008382511006528, + 6.6805560610926396, + 6.311767474473787, + 5.908863430273566, + 5.479234240986606, + 5.030678987768536, + 4.57126458764578, + 4.109181328237328, + 3.652597446461848, + 3.209515322818388, + 2.787631812655076, + 2.394205141638984, + 2.0359306564487425, + 1.7188275462798048, + 1.4481384395088015, + 1.228243536829618, + 1.0625906719063274, + 0.9536423980774008, + 0.9028408902387914, + 0.9105911303249795, + 0.9762625185476608, + 1.098208726538281, + 1.273805288518867, + 1.4995041181862325, + 1.77090384747678, + 2.082834613779954, + 2.4294556790540396, + 2.8043640517327524, + 3.2007121037818274, + 3.6113320336341244, + 4.028864923183438, + 4.445892075029041, + 4.855066295487677, + 5.249240809539806, + 5.621593555143659, + 5.965744704807185, + 6.275865399857186, + 6.546775854744623, + 6.774031191659557, + 6.9539935958552075, + 7.083889635115574, + 7.16185185808811, + 7.186944070808419, + 7.159169983535995, + 7.0794652157703, + 6.949672940784774, + 6.772503737049612, + 6.551480487532613, + 6.290869424351777, + 5.995598651228129, + 5.671165685689913, + 5.323535743533692, + 4.959032636713021, + 4.5842242702521085, + 4.2058048022395855, + 3.830475572367859, + 3.464826908429663, + 3.1152228869093777, + 2.787691054216727, + 2.4878190107334883, + 2.220659622817681, + 1.9906464609212007, + 1.8015208682260724, + 1.65627184732981, + 1.5570897165323656, + 1.505334236514821, + 1.5015176472003364, + 1.5453027880367864, + 1.6355162075847691, + 1.7701759048533416, + 1.9465330899102038, + 2.1611271093250592, + 2.4098524571401447, + 2.688036588121259, + 2.9905270704429596, + 3.3117864626657116, + 3.6459931773226364, + 3.9871465025607584, + 4.329173895408639, + 4.666038636112749, + 4.991845942738674, + 5.30094568841172, + 5.588029939133966, + 5.848223636452569, + 6.077166884236667, + 6.271087459822939, + 6.426862353758282, + 6.542067345862148, + 6.615013844602057, + 6.644772447822266, + 6.631182921517649, + 6.574850535329601, + 6.477128934465452, + 6.340089963566091, + 6.166481084555214, + 5.959671243783649, + 5.723586240184749, + 5.462634822363205, + 5.1816268956123785, + 4.885685347293111, + 4.580153098777496, + 4.270497062741333, + 3.9622107249783616, + 3.660717079653521, + 3.371273626094938, + 3.098881084473314, + 2.848197408176993, + 2.6234585640083137, + 2.4284074196109553, + 2.2662319233211554, + 2.1395135878280698, + 2.0501870988571484, + 1.9995116670479967, + 1.9880545289704634, + 2.015686785630176, + 2.0815915477370845, + 2.1842841403231725, + 2.3216439087975633, + 2.4909569678772465, + 2.688969047484133, + 2.9119474188434746, + 3.1557507325290595, + 3.4159054705823944, + 3.6876876091886044, + 3.9662080083791365, + 4.246499992046808, + 4.5236075559115605, + 4.7926726431869735, + 5.049019957295066, + 5.288237837308601, + 5.5062538036449595, + 5.6994034872378, + 5.864491782906609, + 5.998845214497973, + 6.100354662835422, + 6.167507784563417, + 6.1994106373717415, + 6.1957982214464105, + 6.157033844829001, + 6.084097418159963, + 5.978562978547308, + 5.842565929645013, + 5.678760662201292, + 5.490269383308555, + 5.280623130574314, + 5.0536960769629795, + 4.813634341002973, + 4.5647806036671525, + 4.311595896176243, + 4.058579961337864, + 3.810191604345758, + 3.570770437204769, + 3.344461384532969, + 3.1351432582755314, + 2.9463626261053664, + 2.7812740946347168, + 2.6425880060213505, + 2.5325264074429206, + 2.452787999826273, + 2.404522607970002, + 2.388315541779531, + 2.40418204085154, + 2.451571815271089, + 2.529383517397577, + 2.6359888057436023, + 2.7692654958181473, + 2.92663913687961, + 3.1051322105874117, + 3.3014200199629014, + 3.51189222699167, + 3.7327189064113777, + 3.959919913171225, + 4.189436312779568, + 4.417202597944019, + 4.6392184118167785, + 4.8516185176526045, + 5.050739796230444, + 5.233184115067072, + 5.3958759959759055, + 5.536114108277148, + 5.651615732014071, + 5.740553466675767, + 5.801583603737175, + 5.833865733186836, + 5.837073312368787, + 5.811395087075491, + 5.75752741701618, + 5.676657717685175, + 5.570439385468296, + 5.440958719866397, + 5.2906944934563045, + 5.122470944328238, + 4.939405075152604, + 4.7448492359343595, + 4.542330042410034, + 4.335484737764284, + 4.127996141067159, + 3.9235273411010487, + 3.725657288958981, + 3.5378184172215694, + 3.363237368280564, + 3.2048798504342035, + 3.065400559021118, + 2.9470990026637938, + 2.8518819635092236, + 2.781233197258561, + 2.7361908460424735, + 2.7173328972435935, + 2.724770876721372, + 2.7581518181466023, + 2.816668403907562, + 2.8990770298811697, + 3.003723408768533, + 3.128575197053, + 3.2712610111690936, + 3.4291150911922945, + 3.599226777061151, + 3.7784938845508256, + 3.9636790071724697, + 4.151467726809347, + 4.338527690834776, + 4.521567506975169, + 4.697394419242296, + 4.862969758492336, + 5.015461208889973, + 5.152290995773554, + 5.271179179863212, + 5.370181335896083, + 5.447719998856656, + 5.50260937604, + 5.534072946130917, + 5.541753695067168, + 5.525716870366799, + 5.486445268484113, + 5.424827201265738, + 5.3421374154005, + 5.240011360672545, + 5.120413316736762, + 4.98559899209894, + 4.838073301251016, + 4.680544104956638, + 4.515872763222187, + 4.347022399508146, + 4.177004807501729, + 4.008826947843715, + 3.845437981438122, + 3.6896777685281936, + 3.544227729043778, + 3.411564910545588, + 3.2939200464066745, + 3.193240309928688, + 3.111157381354733, + 3.048961345879236, + 3.007580833593404, + 2.9875696988039464, + 2.9891004183753425, + 3.0119642687857926, + 3.055578221586497, + 3.1189983790290094, + 3.2009396578373237, + 3.299801321421238, + 3.4136978611017486, + 3.5404946368391146, + 3.6778476090257666, + 3.823246426427457, + 3.974060082392853, + 4.127584312825356, + 4.281089885678618, + 4.431870923195316, + 4.577292404776003, + 4.714836019998262, + 4.8421435773965245, + 4.957057224402513, + 5.057655796342076, + 5.142286686376602, + 5.209592712365298, + 5.258533549241622, + 5.288401394936826, + 5.298830642336962, + 5.289801437342177, + 5.261637111886354, + 5.214995588842862, + 5.150854961189602, + 5.070493548796797, + 4.975464830991547, + 4.8675677400251205, + 4.748812878255559, + 4.621385288967262, + 4.487604466188891, + 4.349882331759775, + 4.210679937585397, + 4.072463667100504, + 3.93766171225663, + 3.808621590944199, + 3.687569444965239, + 3.576571821040331, + 3.477500587635997, + 3.392001579611617, + 3.3214674919761453, + 3.2670154647422867, + 3.229469714441248, + 3.209349475897551, + 3.2068624220288835, + 3.2219036314526472, + 3.254060075293977, + 3.3026204975374416, + 3.3665904692459896, + 3.4447123076178494, + 3.5354894677005535, + 3.637214939044819, + 3.7480031129269333, + 3.865824529096341, + 3.9885428652307167, + 4.113953498118148, + 4.239822943540186, + 4.363928472186153, + 4.484097201754541, + 4.598243980534759, + 4.704407404843993, + 4.800783351138351, + 4.885755452653506, + 4.9579220091024965, + 5.0161188851526255, + 5.059438027862165, + 5.0872413136079855, + 5.099169519809866, + 5.095146304425879, + 5.0753771651845625, + 5.040343439254666, + 4.990791490969574, + 4.92771731880432, + 4.8523468916031485, + 4.766112596726081, + 4.67062624809469, + 4.567649158980805, + 4.459059831866024, + 4.346819855047406, + 4.232938622301198, + 4.119437507465076, + 4.00831413007676, + 3.9015073412353747, + 3.8008635408473093, + 3.708104908792513, + 3.624800093893209, + 3.5523378566520236, + 3.491904105472068, + 3.444462702541212, + 3.4107403459359844, + 3.391215760057957, + 3.3861133486087014, + 3.395401384341741, + 3.4187947292281087, + 3.4557619988625183, + 3.5055370073200427, + 3.567134254598009, + 3.639368149521042, + 3.7208755977283983, + 3.8101415281671063, + 3.905526883312421, + 4.005298558911437, + 4.10766074901724, + 4.210787131899437, + 4.312853322355648, + 4.412069016098777, + 4.50670926216858, + 4.5951443194458506, + 4.675867582896659, + 4.747521103540238, + 4.808918272569087, + 4.859063293664584, + 4.897167127341909, + 4.922659656017289, + 4.935197887232875, + 4.9346700838551385, + 4.921195782801025, + 4.895121736648492, + 4.857013884070709, + 4.807645524144282, + 4.747981935024095, + 4.679161738128085, + 4.602475363805619, + 4.519341022555662, + 4.431278626424815, + 4.339882137598967, + 4.246790844903666, + 4.153660083603096, + 4.062131919353282, + 3.973806313402344, + 3.890213273285245, + 3.81278647163316, + 3.7428387857660748, + 3.681540173057928, + 3.629898252387145, + 3.5887419111574457, + 3.558708201343219, + 3.54023272781092, + 3.5335436688910224, + 3.53865950396339, + 3.555390456840364, + 3.58334359815458, + 3.621931485935847, + 3.670384162208577, + 3.727764265817354, + 3.7929849687776542, + 3.8648303961442214, + 3.9419781484781176, + 4.023023512141911, + 4.106504916398345, + 4.19093017802946, + 4.2748030641854164, + 4.356649702521627, + 4.435044374347978, + 4.508634241307193, + 4.57616257869156, + 4.636490118434164, + 4.6886141414826605, + 4.731685001978214, + 4.765019813613604, + 4.788113080845702, + 4.800644113327452, + 4.802481119994536, + 4.793681938647495, + 4.7744914165529355, + 4.745335516493253, + 4.706812279790867, + 4.659679832129537, + 4.604841668557803, + 4.543329500028689, + 4.476283984433473, + 4.404933699655416, + 4.330572744143136, + 4.2545373714454175, + 4.178182078749862, + 4.102855575549063, + 4.0298770570760265, + 3.960513198195558, + 3.8959562672308836, + 3.837303736092187, + 3.785539733521148, + 3.741518652848795, + 3.705951185056585, + 3.6793930028921302, + 3.6622362731530673, + 3.6547041229025656, + 3.656848132246371, + 3.6685488723354975, + 3.68951945341924, + 3.71931199500799, + 3.75732687943555, + 3.8028246022144607, + 3.854939988375193, + 3.9126985042191453, + 3.975034359259625, + 4.040810064142146, + 4.108837087488537, + 4.17789723824966, + 4.246764390512333, + 4.314226164900998, + 4.379105184734994, + 4.440279535820136, + 4.496702075922839, + 4.547418263239217, + 4.591582202068976, + 4.628470637877608, + 4.657494672338555, + 4.678209011075124, + 4.690318601896278, + 4.693682568521028, + 4.688315393263614, + 4.674385351040156, + 4.65221024549195, + 4.622250545151016, + 4.585100062580083, + 4.541474361526396, + 4.492197115618714, + 4.4381846763619155, + 4.380429137575856, + 4.3199802075077285, + 4.257926218240097, + 4.19537461444382, + 4.133432269817674, + 4.073185979655181, + 4.015683471934681, + 3.9619152672994167, + 3.912797700542846, + 3.869157393101482, + 3.83171743803664, + 3.801085526592176, + 3.777744209255971, + 3.7620434449977567, + 3.754195550722793, + 3.7542726197241074, + 3.762206433811583, + 3.7777908496287624, + 3.800686596217106, + 3.8304283789123508, + 3.866434144886078, + 3.9080163287603593, + 3.954394863349774, + 4.00471171128261, + 4.058046648503067, + 4.113434010857275, + 4.16988010042494, + 4.226380939187437, + 4.281940054135796, + 4.335585980032937, + 4.386389173669111, + 4.433478046406756, + 4.476053839827462, + 4.513404092009917, + 4.544914468941846, + 4.570078766291674, + 4.588506920661998, + 4.599930905893598, + 4.604208428321441, + 4.601324374411066, + 4.591390004218262, + 4.574639923907517, + 4.55142690943555, + 4.52221469077823, + 4.487568841108332, + 4.448145947519826, + 4.404681268697706, + 4.357975109872184, + 4.308878166064671, + 4.2582761007026315, + 4.207073637906305, + 4.156178452975424, + 4.1064851467609875, + 4.058859585718249, + 4.01412388061338, + 3.973042263294837, + 3.9363081029207416, + 3.9045322809104084, + 3.8782331180863157, + 3.8578280184782203, + 3.843626962611809, + 3.835827949380554, + 3.834514450413151, + 3.8396549048330972, + 3.8511042461029112, + 3.868607416893608, + 3.8918047932462376, + 3.9202394062991144, + 3.9533658191089853, + 3.990560488119961, + 4.0311334141002435, + 4.074340866282239, + 4.119398946347625, + 4.165497746062507, + 4.211815843979878, + 4.257534882797372, + 4.3018539697163725, + 4.34400364744266, + 4.383259193166517, + 4.418953016754066, + 4.450485947190949, + 4.47733721769744, + 4.499072984473585, + 4.515353241274905, + 4.5259370214605195, + 4.530685810258515, + 4.5295651221959226, + 4.522644231365733, + 4.51009407486958, + 4.492183381806923, + 4.469273111020182, + 4.441809309916985, + 4.410314533576751, + 4.375377987554061, + 4.337644578911532, + 4.297803077704294, + 4.256573605113103, + 4.214694674469227, + 4.17291001738729, + 4.13195542905131, + 4.09254586438697, + 4.055363010475422, + 4.021043550267427, + 3.9901683186558916, + 3.9632525345377525, + 3.940737271979332, + 3.9229823103797403, + 3.9102604780374803, + 3.9027535762340655, + 3.9005499423517733, + 3.903643681155665, + 3.911935563717436, + 3.9252355640654333, + 3.9432669750273175, + 3.9656720173872806, + 3.992018830879681, + 4.021809712122121, + 4.05449044374771, + 4.08946054107416, + 4.126084227938015, + 4.163701942057544, + 4.201642162637405, + 4.239233348996476, + 4.275815778825058, + 4.310753078230348, + 4.343443242916018, + 4.373328960504662, + 4.39990705793472, + 4.422736914772035, + 4.44144770284826, + 4.455744334505723, + 4.465412025486475, + 4.470319403717494, + 4.470420121457207, + 4.465752955010525, + 4.4564404030143665, + 4.44268582067034, + 4.42476915279469, + 4.403041352725581, + 4.37791759655946, + 4.34986942250102, + 4.319415942964667, + 4.287114292165517, + 4.2535494840421695, + 4.219323864273091, + 4.1850463457536335, + 4.151321619120232, + 4.118739528731966, + 4.087864799996465, + 4.0592272961653055, + 4.033312971887644, + 4.01055567711696, + 3.991329948679575, + 3.975944908244509, + 3.964639364928647, + 3.957578198706619, + 3.9548500775740427, + 3.956466537454176, + 3.9623624295707485, + 3.972397715863824, + 3.986360569425775, + 4.003971714292182, + 4.0248899176288155, + 4.048718527774751, + 4.075012934063859, + 4.103288809144449, + 4.1330309818976545, + 4.163702779220547, + 4.1947556680388915, + 4.225639025044905, + 4.255809860858959, + 4.284742327579816, + 4.311936843949288, + 4.336928680496653, + 4.3592958578776715, + 4.378666224968558, + 4.39472359886051, + 4.407212866431784, + 4.415943966326285, + 4.420794690588812, + 4.421712266527139, + 4.418713701206171, + 4.411884892940477, + 4.401378535850384, + 4.387410864603051, + 4.370257306507921, + 4.350247126830717, + 4.3277571702135536, + 4.303204816154725, + 4.27704027936147, + 4.249738396234031, + 4.221790046606263, + 4.193693365039707, + 4.165944898376139, + 4.139030865878839, + 4.113418675165594, + 4.089548841334673, + 4.067827448333887, + 4.048619280890996, + 4.0322417424202746, + 4.018959659490929, + 4.008981056966027, + 4.002453970099684, + 3.99946434104129, + 4.0000350276790355, + 4.004125932910776, + 4.011635242610823, + 4.022401741115854, + 4.0362081543214305, + 4.052785452786606, + 4.071818030891234, + 4.092949663355619, + 4.1157901275611195, + 4.139922369314761, + 4.164910081153061, + 4.1903055561124, + 4.215657676193738, + 4.240519893562564, + 4.264458063850795, + 4.287057994720914, + 4.307932579026616, + 4.326728390329308, + 4.343131629038954, + 4.356873319837697, + 4.367733675081325, + 4.375545554295802, + 4.380196966409769, + 4.381632578689134, + 4.37985421415385, + 4.374920337242093, + 4.366944545324374, + 4.356093101046817, + 4.342581557096182, + 4.326670540543005, + 4.3086607781677895, + 4.28888745686861, + 4.2677140241758735, + 4.2455255428839695, + 4.222721720707762, + 4.199709740580551, + 4.176897019664814, + 4.154684025323027, + 4.13345727421003, + 4.113582636355691, + 4.09539905970218, + 4.079212822174091, + 4.065292408156773, + 4.053864094433784, + 4.045108317410244, + 4.039156879070216, + 4.03609103384616, + 4.035940482693736, + 4.038683284450929, + 4.0442466783053534, + 4.052508795184416, + 4.063301220400076, + 4.0764123551915485, + 4.091591511167851, + 4.108553659289192, + 4.126984744148833, + 4.146547465104753, + 4.166887418411203, + 4.187639489029547, + 4.208434377335442, + 4.2289051445298425, + 4.248693661211914, + 4.267456846253728, + 4.284872587765385, + 4.300645244456409, + 4.314510633954023, + 4.326240424471275, + 4.335645857441294, + 4.342580741138481, + 4.346943668664685, + 4.348679427744882, + 4.347779584298456, + 4.344282236469261, + 4.338270950448983, + 4.329872903756227, + 4.3192562753884625, + 4.306626935207694, + 4.292224496832277, + 4.276317808985353, + 4.259199969517028, + 4.24118295402143, + 4.222591956988185, + 4.203759547669213, + 4.185019745245844, + 4.166702118421531, + 4.149126013248006, + 4.132595009856331, + 4.117391703879841, + 4.103772901824079, + 4.091965311588687, + 4.082161799932392, + 4.074518278072423, + 4.069151265020478, + 4.066136165891582, + 4.065506289504345, + 4.067252616353492, + 4.071324314714335, + 4.077629989469514, + 4.086039635461658, + 4.09638725499401, + 4.108474087733919, + 4.1220723909150285, + 4.136929698557165, + 4.152773480580072, + 4.169316116305187, + 4.186260092018957, + 4.203303329083411, + 4.220144547567363, + 4.236488570547064, + 4.252051476071353, + 4.266565507256325, + 4.279783655993637, + 4.29148384222338, + 4.301472618510161, + 4.309588338622075 + ], + "flows": [ + 21999.999999999996, + 21889.999999999996, + 21780.0, + 21669.999999999996, + 21560.0, + 21450.0, + 21340.0, + 21229.999999999996, + 21119.999999999996, + 21009.999999999996, + 20900.0, + 20789.999999999996, + 20679.999999999996, + 20570.0, + 20459.999999999996, + 20349.999999999996, + 20240.0, + 20130.0, + 20019.999999999996, + 19909.999999999996, + 19799.999999999996, + 19690.0, + 19580.0, + 19470.0, + 19360.0, + 19250.0, + 19140.0, + 19029.999999999996, + 18919.999999999996, + 18810.0, + 18700.0, + 18589.999999999996, + 18479.999999999996, + 18369.999999999996, + 18259.999999999996, + 18149.999999999996, + 18040.0, + 17929.999999999996, + 17819.999999999996, + 17709.999999999996, + 17600.0, + 17490.0, + 17380.0, + 17270.0, + 17160.0, + 17050.0, + 16939.999999999996, + 16830.0, + 16720.0, + 16610.0, + 16500.0, + 16389.999999999996, + 16279.999999999998, + 16169.999999999998, + 16059.999999999998, + 15949.999999999998, + 15839.999999999998, + 15729.999999999998, + 15620.0, + 15510.0, + 15399.999999999996, + 15290.000000000002, + 15179.999999999998, + 15069.999999999998, + 14959.999999999998, + 14850.000000000002, + 14739.999999999998, + 14629.999999999998, + 14519.999999999996, + 14410.0, + 14299.999999999996, + 14189.999999999998, + 14079.999999999998, + 13969.999999999998, + 13860.0, + 13749.999999999998, + 13639.999999999998, + 13530.0, + 13419.999999999998, + 13309.999999999998, + 13199.999999999998, + 13089.999999999998, + 12979.999999999998, + 12870.0, + 12760.000000000002, + 12649.999999999998, + 12540.000000000002, + 12429.999999999998, + 12320.0, + 12209.999999999998, + 12100.0, + 11989.999999999998, + 11880.0, + 11769.999999999998, + 11660.0, + 11549.999999999996, + 11440.0, + 11329.999999999998, + 11219.999999999998, + 11109.999999999998, + 10999.999999999998, + 10890.0, + 10780.0, + 10670.0, + 10559.999999999998, + 10450.0, + 10339.999999999998, + 10229.999999999998, + 10119.999999999998, + 10009.999999999998, + 9899.999999999998, + 9790.0, + 9679.999999999998, + 9569.999999999998, + 9459.999999999998, + 9349.999999999998, + 9240.0, + 9129.999999999998, + 9020.0, + 8909.999999999998, + 8800.0, + 8690.0, + 8580.0, + 8469.999999999998, + 8360.0, + 8250.0, + 8139.999999999999, + 8029.999999999999, + 7919.999999999999, + 7810.0, + 7699.999999999998, + 7589.999999999999, + 7479.999999999999, + 7369.999999999999, + 7259.999999999998, + 7149.999999999998, + 7039.999999999998, + 6929.999999999998, + 6819.999999999997, + 6709.999999999997, + 6599.999999999999, + 6490.0, + 6380.000000000001, + 6270.000000000001, + 6160.0, + 6050.0, + 5940.0, + 5830.0, + 5720.0, + 5609.999999999999, + 5499.999999999999, + 5390.0, + 5279.999999999999, + 5169.999999999999, + 5059.999999999999, + 4949.999999999999, + 4839.999999999999, + 4729.999999999999, + 4619.999999999998, + 4509.999999999999, + 4399.999999999998, + 4289.999999999998, + 4179.999999999998, + 4069.9999999999977, + 3959.9999999999977, + 3849.9999999999986, + 3739.9999999999986, + 3630.000000000001, + 3520.0000000000005, + 3410.0000000000005, + 3300.0000000000005, + 3190.0000000000005, + 3080.0, + 2970.0, + 2860.0, + 2749.9999999999995, + 2639.9999999999995, + 2529.9999999999995, + 2419.9999999999995, + 2309.999999999999, + 2199.999999999999, + 2089.999999999999, + 1979.9999999999989, + 1869.9999999999993, + 1759.999999999999, + 1649.9999999999989, + 1539.9999999999989, + 1429.9999999999989, + 1319.9999999999986, + 1209.9999999999986, + 1099.9999999999984, + 989.9999999999983, + 880.0000000000007, + 770.0000000000006, + 660.0000000000005, + 550.0000000000005, + 440.00000000000034, + 330.0000000000002, + 220.00000000000017, + 110.00000000000009, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + "timestamp": "2025-09-13T16:28:39.528848", + "execution_id": "d30d35a1-fa78-4c5a-8fc5-0757d3a64a5a", + "user_id": "unknown", + "project_id": "1" +} \ No newline at end of file diff --git a/data/scriptsmanager.db b/data/scriptsmanager.db deleted file mode 100755 index 9458c52f67006bf25395cf33048ae1cba75b0f1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90112 zcmeHQU2GiJb)F?9a(DT&k|~*1WW{6J4#{|DJ^w!&D={NcmSS0yNy?66%In#gS#qW2 z?rLY266LswXxXjfrcH{Zc}NWej$c|JLC_{`ADRRxiXuSKrbr$VplK1fDDqGPMG~M* z&_49s`PrS>-ywG?iPl|6yWE+(_niBkbMKvV?mg!&J##j18Dy?hSywHRBMuOe2=N3- z5=7)pf*|gN|K95*_+y{<1wJFbzuWu?b)+`l983I$7}>W;j2}+?W8&@6AB}u+^z*U5 zjDBe74~G8(F5?$Q03&d>A#n4ak>SbN*~sr^EHzs&jBAEgweqE6rchcngWpC^EY8m@ z&y&k@A3r-!2JewG@mO9b&zxJHe{z12Jh!k+p1W}NY?6$}Os$eHTbVX@tEN$Dch9s` zt7?+Z&MlreJ-0Z+(zC&eEwy50to*t`o&>&@&pbVk=ov-5`C_SRm8%xHJpajMyG*50 zs$?23Udvkl8f`F<`?JBotR%DovUWcU$~$L%A;#e>GiFmw79p%rcy z&YgMY!aOb&IqCY5PKm&weaEG`U1YhV_jz7+q?j%bOY9$f?zWMSgr?;q3g}IRtDQffiH~x`>9l4)l<2qV{)@?a9(> zML_hfKHB%Ze)8%A!^4wDk49cUY|FzbV!9vEfDGJ=9nklvw$%4rzF>5QUeBB5g1Xr( zAOvVD=zZ5SY_WpsZFvODr^=cmpoT zS=FrkhT#{pEzk9mp3mjCDNhfpt`gc}_YY4pOyp+5mQd5cZ8l#S3dpVbeg_eDmQWME zf!@2xHndPzIB3055%E78pFJ@& zH2ECUZk%dHB*Qdc8{T?ipFLLH{FtwAWSs63=u7(pcn5Cn80y-@+pN?9(0zTNrm7*8 zys61GkvY!*j?9{L9=fSk0>N~juHv(=#v{X%larCx;6VuFjs`J%m^TLkklEKeK!xrH zG*f8kuf{rPR)GBgNM+SD;fY4itf^*jfCv<`$Jj0dL&eA$6?*_ti>p<2wLXi~vReBY+XW2w(&-0vG{|07l?_gTU6- zXk?U_oZEV4^5EgQxtOZ2=Zp5+6RxKe)?L6qP)VT$kpf)XEL&-gl|(r$r z@>Fqi>GUTUI=lWbpQQzvGdNzMbE1$ll&qm^LRQIfB5i28#;aL2Co+;Qvl_?pGR@@V z9M7<c^0gM1f03(1AzzARjFaj6>i~vU9{e?huaME#oIQIX$MB?4|R|9ctFaj6> zi~vReBY+XW2w(&-0vG{|07d{KaCaeaY|!21&~k&rSnS)x&~TJUe0=Pl(dS0KHyn*k z++FzK)?x%O0vG{|z}<+z%>(=6#PO$JzZrEtpE@=fn>)R!S0FSzuaR>_wXkXCA)dHY zDwt}yypmP5%dp*UB@i#VvZk)D8S%=~(_prQm9B;<8~ z|8Bh&su!i-At4yQYFd@NS|D?UDkLW`H%-e}H>Z;1lwqQ3PeTZ!x}Jx$52{H*RBrLQ zs>5H9H^Ql1%db>vI>!~sO(1~&Hkd*lale+=E6#V+suGC;rQt`YeyE^M*|2M~$(L-x zc?%I%LN;Y&VSvD#z4Y*osoc&XqLLRj&S3v|8 zAoT~pfZC+ld@8bsHpaG7wGN>VT z$tm}z_Wn#j8Yp|hhp5-01yS{&B3`zPDZ7}JS2K=YK@yLa46+=pC+Dm<4r5(K zUFChOt69}FT55u$s`u`T5szln!=S1sRZAt$I|*JuecF#zIuy)6S`C!W0t!wo*?DrD zK?vO=>-Pd<)f5Uc?y91)BGbHlLmrG1)Qv~ABcP&qylb`c{ux(okD-Ppv&hpl1qSw}l6U%jQ%UZ5J3` zX2ymWiTn1?M23Eq_)6m8@xK^9H}vw@zl@bfe>?hnqeq6KBkzo)<3EY(v0v=}O6;?- ziRfEVarn>o&)kjAinz@f0gS-iiNN}OQR0D%M`Lr`)ip?X1%^caM0(`{%8awJo?opR z@LmMd3IegX6-dx$uGGqLDTYolobM@)5!1Ak7UYy9h@!yO?%2^;ypU$O(mhe)!3-j2 zuBjEH45`|zF7)aJfgqb=>Oo&D=_AOCLY}t zT1x^XSrOvhyx6ol$?8y)m^Khe<65~;ssNN07}s5h2Fe0irX94r(wgjx5rFn%M^H;^ z5^GD-CLq+9_cx0dM4^7C-Yn=JFWH(x)HI-N_1o1HsC(ay$Yhk@uJ}}u((`I1f891P z!;$j;!Vz6vC;V+}r=G^WQDX7}V!^hhyAZX@0Gakm2~gGm0EISGFCU5$$6i2m5mOt^4`fc$7H$JW|e*R-sIFy$cz)6qk}yOdH{~p=6FliAOZl7*vOA zICUGG{Y5(ptABy--`pgb|lM)0$&?;>O)#SinIpFa@8opQ$(RlBi&LRCD?}4 z6MPl?b+pL0dThz=j}nKMP@jO(Qj${B4x> zd8(4Fl&-=P82F{Skg691g6*FeAQ->ZgUXdb4@i_W7dfS>Ohn@ z@*GkV6+FlJZenu^btEK;Jl#Sc(f^0gM1f03(1AzzARjFaj8X zJ|ZwS_&}uQN55}!kn_IzUD%Vc!O4j2Wxn^|;B+M5EIvFscr4<1Xb+)+_LqtA!3QJt zC6jv&4N?)a!Pj{(G5Ao#=ZHKoJU9^ne_~=}@My$!=Zzm2e8m3SbIXmPANf{BMo|lD zuCWnBw(jAIBX$Emr5LK)b^1h6RX&f*Fe)8b{}_r69*!VC%6?RD-OI5L{nF=x7>o}d zi8xMzfw92{WA&AfvDmMPL~NNzd?#@!ab$d9?BB<}I5s!>>(M_Q&5ZoRNF@H{*mC^I z=$E2j>Z4F`RTu$`07d{KfDyn5U<4Wv_|(KG5&4J!M-v?*VsrZ~15V$ABj$=$b-j>* zP=|8CNWrOPEiQXI{A&vxEXlHImPxa)14m*xfrrN(J#ylB>$=f7c2_I;)itZB{`#%f zG$7kD1Q5^?OAFkM`wu_^sOirTbCb}3A!o%X;pRU6Iup`F*^lG zrxH z$YZks2;A_LQpIa{?Lv#@(kx0Y&2lMP<^+a?`WDX~v|Ajg(-WCjrT4u>jV$cHmeM?( zLaDA9{?ZuK_SC#ro5PC^2d6sQrZXsfqGBKGSAxnr-EKh(xaa9K%clfIp=svElcQrq zgrjckCtk7D&81NT04OwGI#Z)>kk7#hpcV489sffvIZ-|k&4VI(mNqNZGI_qbUWR=Z z@XZeAsf7fY$*bt6Zkv*2r&!WNKT5))U(rOHurl5j-=>zpnli|NPty#f@)jgfxN&gA z7J^AAhe7T3*}I4BpI?V`=H<=6_c;`RbRB|aPAol3qC56hf5-5Eo<*V~aA8F}55@(F z_Mbt}jAm|thPju`qyNj+SA2@##3Q^yniX$s@qhAe@!vG|1t||JB*7?61kz zGCPI20%_Av#{xCMadww8TES3@)iP?E?`yZ3&PJgoTmNmI+}`M=eXn&-_d>VY&JBCD zA?+EkMVpq7)f@NRk*ZCNVp@<= z_6~3H(tfD1)|&=8br-0<)9of&G|9l&Dx?KAMY9})e%yF+U!XS)G5(ls)724||wwywpiiP**rJ02NZxZiRu)h!hwF<#?U7YgKTB zLA@&ImtHuJ%~;@jx2nbxe?tt8|Bx8}A*}NMQ^Q1zzhVS10vG{|07d{KfDyn5U<5D% z7y*m`M&QmwU?mbGVvj~1jm^zL$jT*1F_F=Y93-T%_MdbE1V^sO&@_nP9;dN{+bDVvn*T^- z%wx}E%3lYxR8DhrN?{~MRKOiU5C`r|VPdW@0vG{|07d{KfDyn5U<5D%7y*m`MgSv# z5$F#BDE=SY|NX%d*Mbqi2w(&-0vG{|07d{KfDyn5U<5D%7=b$#f&IW(Eb(K+-o1(c zP5gJ_mx=cv7vQ^ze@*-}@#C?dj{Vu#r^n8Xk)yvF{kzdW9$gzvkB*M~+sLa`fE35Y5X%OODF(8)m zN;O|G^mJnj<`)+i79q|T4iHE|{{0k+>&<`$q>XEaR<(>7hLvX1&Di56(Co($VjOSq$8wZv-KcePC3*Lli^ArX=rz{xTU z2a1`T>{c2=&lxGjaSAKY$$LAOwok30Wq9~NX&RD;yOtKwrfNlkjmCWPQ0LMxj&o^7 zPVu6m2y$|wb7{yv0qG*d6wmTBqa^R?S{h>P;Yb1r_B^x6gPlvWX$~3+$t?syk)-5- z&ZXh`3N}>3p$>w?N?bD0xik$$QJM=zrWH|0j(04L5(6lZ7XvsE;guWH24+}zNEKCxiQwp5Q#3%~K3rRQ-xWl736y@O1 zSO^WESx6+3+!vxWBo|<5o{_{PoQ~P0ZXP|j!+De}JZ#whZ(161y#?6*_pN9l=hoe4|3|uc3!G#J0u2i)BC`J@0~d*bivy3{ z4ig5`+)D^h$q#l^F3>DkpXNk3lUsmX$X_Lod21-&S%|e*akh)sma~05*QqFQXgaJ- zqqT1?$?!5skv#s&{=j^}6|esJd8sRj6$ zx0h2<9%aa7Td@q?UW_!gO1^BhT-uKN*z)n9^uWUfSXWJx)#BwMoN}8a-7FnxlGz1X z_4b}QnI^+vwF^uvxv8sR6F?DAcGuK1nw|Sv2P9vf_O9ji=`=Y_OR}hf|Cr)gm7#cA z;waTnc#76laJTY8R+QE0Bsp!bP&+?y;Y3%x1#9O9GyTdgH0dPDne65WCgC7?ICQ3v zzi#NQNl9W4>T;@}nwQZ!e<82ghrEZNC-p#Y2_<>f&=v+A>FLSz3TWsic%ny^gwCgF;mnW#hda<>zuy@W~L_K#g)XVH0@C1FsmZ6nzQG7Y1UuR~?r zxuBm!oeez{Ip^!Q?gpXh=jIom`qcb|Co`}g>RH$lb?W4FKS?)Db>7hedWt+*t=MBo znxs=S2SYL1P}D}bd(yG_Yk3RyGwHBltj)aEQ}qqP^rjD^sKbAE0Ceu0EB+L}$nX0lVTt&W`P-=NuI zr`c4JEaZy@$?%ergvo$>e7&Ss3&uz7y=-Xb*v#y$<^-0r5hsYa&4pRgE*p@V4QVWOG5W8&%j zMZ}!%^*goKi!EO@h#${YO4kiI_r(0DCpxsD1hJBVjQkdeeLa(jKV@vrJNqwN4zKUm z{guA$mS`ocaklQZ{Sw>%d&&O3-MmuC2SV8YyprNXhUJB?k{=9V|JU3FK117eB*?x? zj_u9KNgf_s{PsTsyL)oF!BAN(r&GMB^OUU0B9${(M#@R>kksdd0wITtV&aAjyI?*qpCSk z;0>DV&HnGXN#X5(M2ZXA|6#;XSJ`GWv7^7CXL`5X{_mON+hhORYzOWCUIpv*h|czZ z&xAq3eYF33W@j;!{oga0hEWKfzCDLpd;5RqM0>XXcTT!#s%vNe^X={bK2Yyu|My&d zgD^dNzN`Ju^9-0-4fcPi=?2^X_92IXKr+uDV|Z-;uU3tf`oZceU<;co9laCS{&!pe zEzSQIvHfp{%yx^f?1TM35E+5>e|WpAUt3!Xq99PBrgIdp7&$5{X2BC6sER5=JekC!wX&v% zq8;1+HV?t&%I)#64g0@mTEX@IFnl)K|2;F&=3&jVcAD*fLsuAqlNbu(z0vx=4&EJE zrYSlnb399PIU$$pY5l+FCWW{E5vhhPD`CV?SJ`da|2Dm#S-L%Xx7_~knd94I|0A{q z$amoL&210pX2E(rqO<*P6J~oL++X{@XLiEb|2>mw7==RF|2rqzv;Dtw(oIv{4($Iv zQ14{__gsC0Fhkq_C`Cz={U2(&!S+A4|MB`iUjMf;c77z&4XnJ)@s(X{wovQ;k>dpX z!>{ck@YWL#9t4j8%Bc38Gcng?(41FIK^a9@KE=?G-9+@6v|#0;JN`>x<=U5$5+8ho zXN{aDaXAI7Tv4ESPN6A9guT%@Fpy|g=Oo$4)=h@G)weS%*X2P7ZZh2-4`Hp`e$cA7 z7p-!K;j_WY?FSQW9!b1s`erLvQw?5MSs83wo`=W<@O8+lpinZ)>KZR+4OU`yZsqo) zNg=IVmy{edhQf%UuCmR>Q2SNxe$czMR&GByz71Bc$98ZBO0RY8kNk;uj{~u=oE*6axO?*LDzi>*Q3;_Fu4V|G|Nl5$?PIS*lYC z&&Yfrr#hq!g*%eZ9RRk!eJKg483NB@iXriGPKDrhl|^qk79!kPjxtzS2;~fxH5BA5 zXnG*pneE>X9>UuG{h$@J{lj3@VEgxji8c>vo~6@l`zwO3aXN%4Xd0tIn7fgs6xt9e zE-U1+Ia)+2{{3JlgzeuCG7Y0pciX=wqP^MvJ&|sj>bASW-5=_0ZGW%&pigCceWyW~ zp>2POlcgr}Kh$({2b%vPY!pC|zPCTZUE}~&9N~_4xZ?eOa)9Th#-5}nf0|2qrBM+e+0DYiU zZ!cQ>4}(>s1E3E~w0T2SB?NckV>X^`hJzQrz{U`UYW!b^vg#wz!9yZtg$_ zfP}*J?+gckB4Y;t4spjR?r!y=7}x<&x&+ym?Q?6oV6m+b?St1G`+tBqLPQGi=6h{z zoqr@44G+uPm8MfC;4nrWR;}S|O;Lti>)6-Q&e!slA56UQ*1?B8kHNR|ZMO^nr08%{ z$f2ijXm@}w0^YtO_|F<%1!uSBAXr|^ za{cod^oNIV9)teS3VIB}U={Ef^oNNyk9VGZ)a)@}d5PB*nWeHh8Is~LIhD!^EI1Gp zh!fygh=~_>94^qGCWZ1C)JVy_sBE)g*)Ck5KlE;;$DltP-*S&Zo$X+PjxhbJCyzm$ za4;*!_6YaQW6&RVx_S)yL#AOA>gF-%k!UX-gC0ru=rQOQ^)_1u`cr*_FhhF`SOLzv zZcK_7YPz`-JqE0k9Q^ig8IWj)lh#S`YYEPJ$svz3+(XX2?PT7=8Sd*wT6xo2gELoP z%wIvLT0rj173UzV_fv#>y}39;Tj0DV;%(Wn|3`@_V*DFpFO0_Ge-+cC_Y8f1|N6cU z4E!Kcg&W`qV8S>8ASa%ZX1Nr{$q>i9r$L8>Ov*j|sP8@(;WtrplcE5*{I(7|G z{$~?!ZkE-Rj9Bymq8x|`iT_bv2DIvoa4SV4sqJSoL7u-vz|5#7yh zzwvW4+kYsCXzPL0MwFLRoXpF6JVX0#_Il!L?@fFT#s7~)rit-yj;)Nw<9{8?MGp=A z?f%lffq^f>W&E-c*xI`McwO^u9-X|{Li0G1reSDIv+$fLivqour*M{r%zxW?a);8^ zngQoe>T2aOd?~2K)hZmsO2PrTX3?<19veWs{m!BDTbDi(M7zc8Zlle}X)rxGMdFmb z{0Isu9B&WW bash -c "source activate scriptsmanager && + echo '=== SIDEL ScriptsManager Development Environment ===' && + echo 'Hot reload enabled - code changes will be reflected automatically' && + echo 'Application will be available at: http://localhost:5003' && + echo 'Debug port available at: 5678' && python scripts/init_db.py && python scripts/run_app.py" profiles: - dev - # Servicio para backup automático según especificaciones SIDEL + # Backup Service backup: build: . - container_name: sidel_backup_service + container_name: scriptsmanager_backup + network_mode: host + environment: + - DATABASE_URL=postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager + - BACKUP_ENABLED=true + - BACKUP_RETENTION_DAYS=30 + - PYTHONPATH=/app volumes: - ./data:/app/data - ./backup:/app/backup - ./logs:/app/logs - environment: - - BACKUP_ENABLED=true - - BACKUP_RETENTION_DAYS=30 - - DATABASE_URL=sqlite:///app/data/scriptsmanager.db - - PYTHONPATH=/app + depends_on: + postgres: + condition: service_healthy command: > bash -c "source activate scriptsmanager && + echo '=== Starting SIDEL ScriptsManager Backup Service ===' && while true; do - echo '=== Starting daily backup ===' + echo '[BACKUP] Starting daily backup process...' python -c 'from app.services.backup_service import BackupService; BackupService().create_backup()' - echo '=== Backup completed ===' - sleep 86400 # Backup diario (24 horas) + echo '[BACKUP] Backup completed successfully' + sleep 86400 # Daily backup (24 hours) done" profiles: - backup - # Servicio de monitoreo de logs (opcional) + # Log Monitor Service log-monitor: build: . - container_name: sidel_log_monitor + container_name: scriptsmanager_monitor + network_mode: host + environment: + - DATABASE_URL=postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager + - PYTHONPATH=/app volumes: - ./logs:/app/logs - ./data:/app/data - environment: - - DATABASE_URL=sqlite:///app/data/scriptsmanager.db - - PYTHONPATH=/app + depends_on: + postgres: + condition: service_healthy command: > bash -c "source activate scriptsmanager && + echo '=== Starting SIDEL ScriptsManager Log Monitor ===' && python -c ' import time - from app.services.log_service import LogService - print(\"Starting log monitor service...\") + from app.services.data_manager import DataManager + print(\"Log monitor service started - cleanup every hour\") while True: try: - # Cleanup de logs antiguos según políticas de retención - LogService().cleanup_old_logs() - time.sleep(3600) # Cleanup cada hora + # Log cleanup according to retention policies + # TODO: Implement log cleanup service + print(f\"[MONITOR] Log cleanup check at {time.strftime(\"%Y-%m-%d %H:%M:%S\")}\") + time.sleep(3600) # Cleanup every hour except Exception as e: - print(f\"Log monitor error: {e}\") + print(f\"[MONITOR] Error: {e}\") time.sleep(60) '" profiles: - monitoring - # Base de datos separada (opcional, si quieres usar PostgreSQL en lugar de SQLite) - postgres: - image: postgres:15 - container_name: sidel_postgres - environment: - - POSTGRES_DB=scriptsmanager - - POSTGRES_USER=scriptsmanager - - POSTGRES_PASSWORD=scriptsmanager_password - volumes: - - postgres_data:/var/lib/postgresql/data - ports: - - "5432:5432" - profiles: - - postgres - - # Servicio para backup automático - backup: - build: . - container_name: sidel_backup - volumes: - - ./data:/app/data - - ./backup:/app/backup - environment: - - BACKUP_ENABLED=true - - PYTHONPATH=/app - command: > - bash -c "source activate scriptsmanager && - while true; do - python -c 'from app.services.backup_service import BackupService; BackupService().create_backup()' - sleep 86400 # Backup diario - done" - profiles: - - backup - +# Named volumes for data persistence volumes: - postgres_data: \ No newline at end of file + postgres_data: + driver: local + name: scriptsmanager_postgres_data \ No newline at end of file diff --git a/docker-entrypoint-debug.sh b/docker-entrypoint-debug.sh new file mode 100755 index 0000000..1f0c75b --- /dev/null +++ b/docker-entrypoint-debug.sh @@ -0,0 +1,89 @@ +#!/bin/bash +set -e + +echo "=== SIDEL ScriptsManager Docker Entrypoint ===" +echo "Working directory: $(pwd)" +echo "User: $(whoami)" +echo "Database URL: ${DATABASE_URL:-'Not set'}" + +# Activar conda environment +source /opt/conda/etc/profile.d/conda.sh +conda activate scriptsmanager +cd /app + +echo "Available conda environments:" +conda env list + +echo "Python path:" +which python + +echo "Testing python modules:" +python -c "import flask; print(f'Flask: {flask.__version__}')" +python -c "import sqlalchemy; print(f'SQLAlchemy: {sqlalchemy.__version__}')" + +# Verificar psycopg2 específicamente +echo "Testing psycopg2 module:" +python -c " +try: + import psycopg2 + print(f'psycopg2 version: {psycopg2.__version__}') + print('psycopg2 imported successfully') +except ImportError as e: + print(f'psycopg2 import error: {e}') + print('Available packages in scriptsmanager environment:') + import subprocess + result = subprocess.run(['/opt/conda/bin/conda', 'list', '-n', 'scriptsmanager'], + capture_output=True, text=True) + print(result.stdout) + exit(1) +" + +# Verificar que los directorios necesarios existen +echo "Checking data directories..." +ls -la data/ instance/ logs/ || echo "Creating missing directories..." + +# Database setup based on DATABASE_URL +if [[ "${DATABASE_URL}" == postgresql* ]]; then + echo "=== PostgreSQL Database Setup ===" + + # Extract database connection info + DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\).*/\1/p') + DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p') + DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p') + + echo "Database Host: ${DB_HOST}" + echo "Database Port: ${DB_PORT}" + echo "Database Name: ${DB_NAME}" + + # Wait for PostgreSQL to be ready + echo "Waiting for PostgreSQL to be ready..." + + # Simple wait to ensure PostgreSQL has time to start + sleep 15 + echo "PostgreSQL should be ready - proceeding..." + +else + echo "=== SQLite Database Setup ===" + # Asegurar que la base de datos SQLite puede ser creada + echo "Setting up SQLite database permissions..." + touch data/scriptsmanager.db || echo "Database file already exists or created" + chmod 664 data/scriptsmanager.db || true +fi + +# Inicializar base de datos +echo "Initializing database schema..." +python scripts/init_db.py + +# Verificar entornos conda +echo "ScriptsManager environment packages:" +conda list -n scriptsmanager | grep -E "(flask|sqlalchemy|psycopg2)" || true + +echo "TSNet environment packages:" +conda list -n tsnet | grep -E "(tsnet|numpy|matplotlib)" || true + +# Database health check +echo "Performing database health check..." +echo "Skipping health check for now - starting application" + +echo "=== SIDEL ScriptsManager Ready ===" +exec "$@" \ No newline at end of file diff --git a/docker-entrypoint-simple.sh b/docker-entrypoint-simple.sh new file mode 100755 index 0000000..85b71f6 --- /dev/null +++ b/docker-entrypoint-simple.sh @@ -0,0 +1,72 @@ +#!/bin/bash +set -e + +echo "=== SIDEL ScriptsManager Docker Entrypoint ===" +echo "Working directory: $(pwd)" +echo "User: $(whoami)" +echo "Database URL: ${DATABASE_URL:-'Not set'}" + +# Activar conda environment +source /opt/conda/etc/profile.d/conda.sh +conda activate scriptsmanager +cd /app + +echo "Available conda environments:" +conda env list + +echo "Python path:" +which python + +echo "Testing python modules:" +python -c "import flask; print(f'Flask: {flask.__version__}')" +python -c "import sqlalchemy; print(f'SQLAlchemy: {sqlalchemy.__version__}')" + +# Verificar que los directorios necesarios existen +echo "Checking data directories..." +ls -la data/ instance/ logs/ || echo "Creating missing directories..." + +# Database setup based on DATABASE_URL +if [[ "${DATABASE_URL}" == postgresql* ]]; then + echo "=== PostgreSQL Database Setup ===" + + # Extract database connection info + DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\).*/\1/p') + DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p') + DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p') + + echo "Database Host: ${DB_HOST}" + echo "Database Port: ${DB_PORT}" + echo "Database Name: ${DB_NAME}" + + # Wait for PostgreSQL to be ready + echo "Waiting for PostgreSQL to be ready..." + + # Simple wait to ensure PostgreSQL has time to start + sleep 15 + echo "PostgreSQL should be ready - proceeding..." + +else + echo "=== SQLite Database Setup ===" + # Asegurar que la base de datos SQLite puede ser creada + echo "Setting up SQLite database permissions..." + touch data/scriptsmanager.db || echo "Database file already exists or created" + chmod 664 data/scriptsmanager.db || true +fi + +# Inicializar base de datos +echo "Initializing database schema..." +python scripts/init_db.py + +# Verificar entornos conda +echo "ScriptsManager environment packages:" +conda list -n scriptsmanager | grep -E "(flask|sqlalchemy|psycopg2)" || true + +echo "TSNet environment packages:" +conda list -n tsnet | grep -E "(tsnet|numpy|matplotlib)" || true + +# Database health check +echo "Performing database health check..." +echo "Skipping health check for now - starting application" + +echo "=== SIDEL ScriptsManager Ready ===" +exec "$@" \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..43a2ed0 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,71 @@ +#!/bin/bash +set -e + +echo "=== SIDEL ScriptsManager Docker Entrypoint ===" +echo "Working directory: $(pwd)" +echo "User: $(whoami)" +echo "Database URL: ${DATABASE_URL:-'Not set'}" + +# Activar conda environment +source /opt/conda/etc/profile.d/conda.sh +conda activate scriptsmanager +cd /app + +echo "Available conda environments:" +conda env list + +echo "Checking directory structure..." +if [ ! -d "app/backend/script_groups" ]; then + echo "ERROR: app/backend/script_groups directory not found!" + exit 1 +fi + +# Verificar que los directorios necesarios existen +echo "Checking data directories..." +ls -la data/ instance/ logs/ || echo "Creating missing directories..." + +# Database setup based on DATABASE_URL +if [[ "${DATABASE_URL}" == postgresql* ]]; then + echo "=== PostgreSQL Database Setup ===" + + # Extract database connection info + DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\).*/\1/p') + DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p') + DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p') + + echo "Database Host: ${DB_HOST}" + echo "Database Port: ${DB_PORT}" + echo "Database Name: ${DB_NAME}" + + # Wait for PostgreSQL to be ready + echo "Waiting for PostgreSQL to be ready..." + + # Simple wait to ensure PostgreSQL has time to start + sleep 10 + echo "PostgreSQL should be ready - proceeding..." + +else + echo "=== SQLite Database Setup ===" + # Asegurar que la base de datos SQLite puede ser creada + echo "Setting up SQLite database permissions..." + touch data/scriptsmanager.db || echo "Database file already exists or created" + chmod 664 data/scriptsmanager.db || true +fi + +# Inicializar base de datos +echo "Initializing database schema..." +python scripts/init_db.py + +# Verificar entornos conda +echo "ScriptsManager environment packages:" +conda list -n scriptsmanager | grep -E "(flask|sqlalchemy|psycopg2)" || true + +echo "TSNet environment packages:" +conda list -n tsnet | grep -E "(tsnet|numpy|matplotlib)" || true + +# Database health check +echo "Performing database health check..." +echo "Skipping health check for now - starting application" + +echo "=== SIDEL ScriptsManager Ready ===" +exec "$@" \ No newline at end of file diff --git a/docker-manage.sh b/docker-manage.sh index 22c577c..1409c72 100755 --- a/docker-manage.sh +++ b/docker-manage.sh @@ -72,7 +72,7 @@ rebuild_quick() { echo -e "${BLUE}⚡ Rebuild rápido de SIDEL ScriptsManager...${NC}" echo -e "${YELLOW}Paso 1/3: Deteniendo contenedor...${NC}" - stop_services + stop_containers echo -e "${YELLOW}Paso 2/3: Reconstruyendo imagen...${NC}" build_image @@ -113,9 +113,15 @@ show_help() { echo -e " ${GREEN}verify${NC} Verificar configuración y entornos" echo -e " ${GREEN}ports${NC} Mostrar puertos en uso" echo -e " ${GREEN}users${NC} Gestionar usuarios (requiere shell activo)" + echo -e " ${GREEN}db-status${NC} Verificar estado de la base de datos" + echo -e " ${GREEN}db-migrate${NC} Migrar desde SQLite a PostgreSQL" + echo -e " ${GREEN}db-backup${NC} Crear backup de la base de datos" + echo -e " ${GREEN}start-postgres${NC} Iniciar solo el servicio PostgreSQL" + echo -e " ${GREEN}stop-postgres${NC} Detener solo el servicio PostgreSQL" echo "" echo "Servicios opcionales (perfiles):" echo -e " ${YELLOW}--profile dev${NC} Modo desarrollo" + echo -e " ${YELLOW}--profile production${NC} Modo producción" echo -e " ${YELLOW}--profile backup${NC} Backup automático" echo -e " ${YELLOW}--profile monitoring${NC} Monitoreo de logs" echo "" @@ -210,10 +216,22 @@ start_production() { echo -e "${YELLOW}¡IMPORTANTE: Edita el archivo .env con tus configuraciones de producción!${NC}" fi - $DOCKER_COMPOSE up -d scriptsmanager + # Iniciar PostgreSQL primero + echo -e "${BLUE}🐘 Iniciando PostgreSQL...${NC}" + $DOCKER_COMPOSE up -d postgres + + # Esperar que PostgreSQL esté listo + echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" + sleep 10 + + # Iniciar aplicación + echo -e "${BLUE}🚀 Iniciando aplicación...${NC}" + $DOCKER_COMPOSE --profile production up -d scriptsmanager + echo -e "${GREEN}✅ SIDEL ScriptsManager iniciado en http://localhost:${SIDEL_APP_PORT}${NC}" echo -e "${BLUE}📊 Dashboard multiusuario disponible${NC}" echo -e "${BLUE}🔧 Scripts TSNet en puertos ${SIDEL_SCRIPT_PORT_RANGE}${NC}" + echo -e "${BLUE}🐘 PostgreSQL en puerto 5432${NC}" } # Función para iniciar en desarrollo @@ -230,9 +248,21 @@ start_development() { cp .env.example .env fi + # Iniciar PostgreSQL primero + echo -e "${BLUE}🐘 Iniciando PostgreSQL...${NC}" + $DOCKER_COMPOSE up -d postgres + + # Esperar que PostgreSQL esté listo + echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" + sleep 10 + + # Iniciar aplicación en modo desarrollo + echo -e "${BLUE}🚀 Iniciando aplicación en modo desarrollo...${NC}" $DOCKER_COMPOSE --profile dev up -d scriptsmanager-dev + echo -e "${GREEN}✅ SIDEL ScriptsManager (desarrollo) iniciado en http://localhost:${SIDEL_DEV_PORT}${NC}" echo -e "${BLUE}🔄 Hot-reload activado para desarrollo${NC}" + echo -e "${BLUE}🐘 PostgreSQL en puerto 5432${NC}" } # Función para iniciar backup automático @@ -474,6 +504,158 @@ manage_users() { $DOCKER_COMPOSE exec scriptsmanager bash -c "source activate scriptsmanager && bash" } +# Función para verificar estado de la base de datos +check_database_status() { + show_banner + echo -e "${BLUE}Verificando estado de la base de datos...${NC}" + check_docker_compose + + # Verificar si PostgreSQL está ejecutándose + if docker ps | grep -q "scriptsmanager_postgres"; then + echo -e "${GREEN}✅ PostgreSQL container is running${NC}" + + # Verificar conectividad + if $DOCKER_COMPOSE exec postgres pg_isready -U scriptsmanager -d scriptsmanager > /dev/null 2>&1; then + echo -e "${GREEN}✅ PostgreSQL is accepting connections${NC}" + + # Obtener información de la base de datos + echo -e "${BLUE}📊 Database Information:${NC}" + $DOCKER_COMPOSE exec postgres psql -U scriptsmanager -d scriptsmanager -c " + SELECT + 'PostgreSQL Version' as info, + version() as value + UNION ALL + SELECT + 'Database Size' as info, + pg_size_pretty(pg_database_size('scriptsmanager')) as value + UNION ALL + SELECT + 'Active Connections' as info, + count(*)::text as value + FROM pg_stat_activity + WHERE datname = 'scriptsmanager';" 2>/dev/null || echo "Could not retrieve database info" + else + echo -e "${RED}❌ PostgreSQL is not accepting connections${NC}" + fi + else + echo -e "${YELLOW}⚠️ PostgreSQL container is not running${NC}" + echo -e "${BLUE}💡 Start with: $0 start-postgres${NC}" + fi + + # Verificar si la aplicación puede conectarse + if docker ps | grep -q $SIDEL_CONTAINER_NAME; then + echo -e "${BLUE}🔗 Testing application database connection...${NC}" + $DOCKER_COMPOSE exec scriptsmanager bash -c " + source activate scriptsmanager && + python -c 'from app.config.database import check_db_health; import json; print(json.dumps(check_db_health(), indent=2))' + " 2>/dev/null || echo -e "${YELLOW}⚠️ Application container not available${NC}" + fi +} + +# Función para migrar de SQLite a PostgreSQL +migrate_to_postgresql() { + show_banner + echo -e "${BLUE}Migrando desde SQLite a PostgreSQL...${NC}" + check_docker_compose + + # Verificar que PostgreSQL esté ejecutándose + if ! docker ps | grep -q "scriptsmanager_postgres"; then + echo -e "${YELLOW}Iniciando PostgreSQL...${NC}" + $DOCKER_COMPOSE up -d postgres + sleep 10 + fi + + # Verificar si existe la base de datos SQLite + if [ ! -f "data/scriptsmanager.db" ]; then + echo -e "${RED}❌ No se encontró la base de datos SQLite en data/scriptsmanager.db${NC}" + echo -e "${BLUE}💡 ¿Quizás ya se migró o no tienes datos existentes?${NC}" + return 1 + fi + + echo -e "${BLUE}🔄 Ejecutando migración...${NC}" + echo -e "${YELLOW}Esto puede tomar varios minutos dependiendo del tamaño de los datos${NC}" + + # Ejecutar el script de migración + python migrate_sqlite_to_postgresql.py \ + --source "data/scriptsmanager.db" \ + --target "${DATABASE_URL:-postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager}" \ + --backup + + if [ $? -eq 0 ]; then + echo -e "${GREEN}✅ Migración completada exitosamente${NC}" + echo -e "${BLUE}💡 La base de datos SQLite original se mantiene como backup${NC}" + echo -e "${BLUE}💡 Ahora puedes usar PostgreSQL configurando DATABASE_URL en docker-compose.yml${NC}" + else + echo -e "${RED}❌ La migración falló${NC}" + return 1 + fi +} + +# Función para backup de base de datos +backup_database() { + show_banner + echo -e "${BLUE}Creando backup de la base de datos...${NC}" + check_docker_compose + + if docker ps | grep -q "scriptsmanager_postgres"; then + # Backup PostgreSQL + echo -e "${BLUE}📦 Creando backup de PostgreSQL...${NC}" + timestamp=$(date +"%Y%m%d_%H%M%S") + backup_file="backup/postgres_backup_${timestamp}.sql" + + mkdir -p backup + + $DOCKER_COMPOSE exec postgres pg_dump -U scriptsmanager -d scriptsmanager > "$backup_file" + + if [ $? -eq 0 ]; then + echo -e "${GREEN}✅ Backup PostgreSQL creado: ${backup_file}${NC}" + else + echo -e "${RED}❌ Error creando backup PostgreSQL${NC}" + fi + elif [ -f "data/scriptsmanager.db" ]; then + # Backup SQLite + echo -e "${BLUE}📦 Creando backup de SQLite...${NC}" + timestamp=$(date +"%Y%m%d_%H%M%S") + backup_file="backup/sqlite_backup_${timestamp}.db" + + mkdir -p backup + cp "data/scriptsmanager.db" "$backup_file" + + echo -e "${GREEN}✅ Backup SQLite creado: ${backup_file}${NC}" + else + echo -e "${RED}❌ No se encontró ninguna base de datos para hacer backup${NC}" + fi +} + +# Función para iniciar solo PostgreSQL +start_postgres() { + show_banner + echo -e "${BLUE}Iniciando servicio PostgreSQL...${NC}" + check_docker_compose + + $DOCKER_COMPOSE up -d postgres + + echo -e "${BLUE}⏳ Esperando que PostgreSQL esté listo...${NC}" + sleep 5 + + if $DOCKER_COMPOSE exec postgres pg_isready -U scriptsmanager -d scriptsmanager > /dev/null 2>&1; then + echo -e "${GREEN}✅ PostgreSQL iniciado y listo en puerto 5432${NC}" + echo -e "${BLUE}🔗 Connection: postgresql://scriptsmanager:scriptsmanager_dev_password@localhost:5432/scriptsmanager${NC}" + else + echo -e "${YELLOW}⚠️ PostgreSQL iniciado pero aún no está listo${NC}" + echo -e "${BLUE}💡 Usa: $0 db-status para verificar${NC}" + fi +} + +# Función para detener solo PostgreSQL +stop_postgres() { + echo -e "${BLUE}Deteniendo servicio PostgreSQL...${NC}" + check_docker_compose + + $DOCKER_COMPOSE stop postgres + echo -e "${GREEN}✅ PostgreSQL detenido${NC}" +} + # Script principal case "${1:-help}" in build) @@ -545,6 +727,21 @@ case "${1:-help}" in users) manage_users ;; + db-status) + check_database_status + ;; + db-migrate) + migrate_to_postgresql + ;; + db-backup) + backup_database + ;; + start-postgres) + start_postgres + ;; + stop-postgres) + stop_postgres + ;; help|--help|-h) show_help ;; diff --git a/migrate_sqlite_to_postgresql.py b/migrate_sqlite_to_postgresql.py new file mode 100644 index 0000000..4d623fa --- /dev/null +++ b/migrate_sqlite_to_postgresql.py @@ -0,0 +1,377 @@ +#!/usr/bin/env python3 +""" +SIDEL ScriptsManager - SQLite to PostgreSQL Migration Script + +This script migrates data from SQLite to PostgreSQL while maintaining +referential integrity and data consistency. + +Usage: + python migrate_sqlite_to_postgresql.py [--source SOURCE_DB] [--target TARGET_URL] [--dry-run] + +Arguments: + --source: SQLite database file path (default: data/scriptsmanager.db) + --target: PostgreSQL connection URL (default: from DATABASE_URL env var) + --dry-run: Perform a dry run without making changes + --backup: Create backup before migration +""" + +import argparse +import os +import sys +import json +import shutil +from datetime import datetime +from pathlib import Path +from typing import Dict, List, Any, Optional + +# Add the app directory to Python path +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) + +import sqlite3 +from sqlalchemy import create_engine, MetaData, Table, select, insert +from sqlalchemy.orm import sessionmaker +from sqlalchemy.exc import SQLAlchemyError + +# Import application modules +from app.config.config import Config +from app.config.database import db + + +class DatabaseMigrator: + """Handles migration from SQLite to PostgreSQL.""" + + def __init__(self, sqlite_path: str, postgresql_url: str, dry_run: bool = False): + self.sqlite_path = sqlite_path + self.postgresql_url = postgresql_url + self.dry_run = dry_run + + # Database connections + self.sqlite_engine = None + self.postgres_engine = None + self.sqlite_metadata = None + self.postgres_metadata = None + + # Migration statistics + self.stats = { + 'tables_migrated': 0, + 'total_records': 0, + 'start_time': None, + 'end_time': None, + 'errors': [] + } + + def connect_databases(self): + """Establish connections to both databases.""" + try: + # Connect to SQLite + print(f"Connecting to SQLite database: {self.sqlite_path}") + self.sqlite_engine = create_engine(f"sqlite:///{self.sqlite_path}") + self.sqlite_metadata = MetaData() + self.sqlite_metadata.reflect(bind=self.sqlite_engine) + + # Connect to PostgreSQL + print(f"Connecting to PostgreSQL database...") + self.postgres_engine = create_engine(self.postgresql_url) + self.postgres_metadata = MetaData() + + # Test connections + with self.sqlite_engine.connect() as conn: + result = conn.execute("SELECT name FROM sqlite_master WHERE type='table'") + sqlite_tables = [row[0] for row in result.fetchall()] + print(f"Found {len(sqlite_tables)} tables in SQLite: {sqlite_tables}") + + with self.postgres_engine.connect() as conn: + result = conn.execute("SELECT version()") + pg_version = result.fetchone()[0] + print(f"PostgreSQL version: {pg_version.split()[1]}") + + return True + + except Exception as e: + print(f"Error connecting to databases: {e}") + self.stats['errors'].append(f"Connection error: {e}") + return False + + def create_backup(self): + """Create backup of SQLite database before migration.""" + try: + backup_dir = Path("backup") / datetime.now().strftime("%Y-%m-%d") + backup_dir.mkdir(parents=True, exist_ok=True) + + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_path = backup_dir / f"sqlite_backup_{timestamp}.db" + + print(f"Creating backup: {backup_path}") + shutil.copy2(self.sqlite_path, backup_path) + + return str(backup_path) + except Exception as e: + print(f"Error creating backup: {e}") + return None + + def get_table_dependencies(self) -> List[str]: + """Get tables in dependency order for migration.""" + # Define table migration order based on foreign key dependencies + # This should be updated based on your actual schema + dependency_order = [ + 'users', # Independent table + 'scripts', # Depends on users + 'execution_logs', # Depends on scripts + 'script_tags', # Depends on scripts + 'user_preferences', # Depends on users + 'backup_logs', # Independent + 'system_settings', # Independent + ] + + # Get actual tables from SQLite + available_tables = list(self.sqlite_metadata.tables.keys()) + + # Return only tables that exist, in dependency order + ordered_tables = [] + for table in dependency_order: + if table in available_tables: + ordered_tables.append(table) + + # Add any remaining tables not in dependency list + for table in available_tables: + if table not in ordered_tables and not table.startswith('sqlite_'): + ordered_tables.append(table) + + return ordered_tables + + def migrate_table_data(self, table_name: str) -> Dict[str, Any]: + """Migrate data from a specific table.""" + print(f"\\nMigrating table: {table_name}") + + try: + # Get table schema from SQLite + sqlite_table = self.sqlite_metadata.tables[table_name] + + # Reflect PostgreSQL schema (should already be created by SQLAlchemy) + self.postgres_metadata.reflect(bind=self.postgres_engine) + + if table_name not in self.postgres_metadata.tables: + print(f"Warning: Table {table_name} does not exist in PostgreSQL, skipping...") + return {'status': 'skipped', 'reason': 'table_not_found', 'records': 0} + + postgres_table = self.postgres_metadata.tables[table_name] + + # Read data from SQLite + with self.sqlite_engine.connect() as sqlite_conn: + result = sqlite_conn.execute(select(sqlite_table)) + rows = result.fetchall() + columns = result.keys() + + if not rows: + print(f"Table {table_name} is empty, skipping...") + return {'status': 'empty', 'records': 0} + + print(f"Found {len(rows)} records in {table_name}") + + if self.dry_run: + print(f"DRY RUN: Would migrate {len(rows)} records to {table_name}") + return {'status': 'dry_run', 'records': len(rows)} + + # Prepare data for PostgreSQL + data_to_insert = [] + for row in rows: + row_dict = dict(zip(columns, row)) + + # Handle data type conversions if needed + converted_row = self.convert_row_data(table_name, row_dict) + data_to_insert.append(converted_row) + + # Insert data into PostgreSQL + with self.postgres_engine.connect() as postgres_conn: + # Clear existing data (if any) + postgres_conn.execute(postgres_table.delete()) + + # Insert new data + if data_to_insert: + postgres_conn.execute(postgres_table.insert(), data_to_insert) + postgres_conn.commit() + + print(f"Successfully migrated {len(data_to_insert)} records to {table_name}") + return {'status': 'success', 'records': len(data_to_insert)} + + except Exception as e: + print(f"Error migrating table {table_name}: {e}") + self.stats['errors'].append(f"Table {table_name}: {e}") + return {'status': 'error', 'error': str(e), 'records': 0} + + def convert_row_data(self, table_name: str, row_data: Dict[str, Any]) -> Dict[str, Any]: + """Convert SQLite data types to PostgreSQL compatible format.""" + converted = {} + + for column, value in row_data.items(): + if value is None: + converted[column] = None + elif isinstance(value, str): + # Handle string data + converted[column] = value + elif isinstance(value, (int, float)): + # Handle numeric data + converted[column] = value + elif isinstance(value, bytes): + # Handle binary data + converted[column] = value + else: + # Convert other types to string + converted[column] = str(value) + + return converted + + def verify_migration(self) -> bool: + """Verify that migration was successful by comparing record counts.""" + print("\\nVerifying migration...") + + verification_passed = True + + for table_name in self.get_table_dependencies(): + try: + # Count records in SQLite + with self.sqlite_engine.connect() as sqlite_conn: + sqlite_table = self.sqlite_metadata.tables[table_name] + result = sqlite_conn.execute(f"SELECT COUNT(*) FROM {table_name}") + sqlite_count = result.scalar() + + # Count records in PostgreSQL + with self.postgres_engine.connect() as postgres_conn: + result = postgres_conn.execute(f"SELECT COUNT(*) FROM {table_name}") + postgres_count = result.scalar() + + print(f"{table_name}: SQLite={sqlite_count}, PostgreSQL={postgres_count}") + + if sqlite_count != postgres_count: + print(f"❌ Record count mismatch in {table_name}") + verification_passed = False + else: + print(f"✅ {table_name} verified successfully") + + except Exception as e: + print(f"❌ Error verifying {table_name}: {e}") + verification_passed = False + + return verification_passed + + def run_migration(self, create_backup: bool = True) -> bool: + """Run the complete migration process.""" + print("=== SIDEL ScriptsManager: SQLite to PostgreSQL Migration ===") + self.stats['start_time'] = datetime.now() + + try: + # Create backup if requested + if create_backup and not self.dry_run: + backup_path = self.create_backup() + if backup_path: + print(f"Backup created: {backup_path}") + else: + print("Warning: Could not create backup") + + # Connect to databases + if not self.connect_databases(): + return False + + # Get migration order + tables_to_migrate = self.get_table_dependencies() + print(f"\\nTables to migrate: {tables_to_migrate}") + + # Migrate each table + for table_name in tables_to_migrate: + result = self.migrate_table_data(table_name) + if result['status'] == 'success': + self.stats['tables_migrated'] += 1 + self.stats['total_records'] += result['records'] + + # Verify migration (skip for dry run) + if not self.dry_run: + verification_passed = self.verify_migration() + if not verification_passed: + print("\\n❌ Migration verification failed!") + return False + + self.stats['end_time'] = datetime.now() + duration = self.stats['end_time'] - self.stats['start_time'] + + print(f"\\n=== Migration Summary ===") + print(f"Duration: {duration}") + print(f"Tables migrated: {self.stats['tables_migrated']}") + print(f"Total records: {self.stats['total_records']}") + print(f"Errors: {len(self.stats['errors'])}") + + if self.stats['errors']: + print("\\nErrors encountered:") + for error in self.stats['errors']: + print(f" - {error}") + + if self.dry_run: + print("\\n✅ DRY RUN completed successfully") + else: + print("\\n✅ Migration completed successfully") + + return True + + except Exception as e: + print(f"\\n❌ Migration failed: {e}") + return False + + finally: + # Close connections + if self.sqlite_engine: + self.sqlite_engine.dispose() + if self.postgres_engine: + self.postgres_engine.dispose() + + +def main(): + """Main migration script entry point.""" + parser = argparse.ArgumentParser(description="Migrate SIDEL ScriptsManager from SQLite to PostgreSQL") + + parser.add_argument( + '--source', + default='data/scriptsmanager.db', + help='SQLite database file path (default: data/scriptsmanager.db)' + ) + + parser.add_argument( + '--target', + default=os.getenv('DATABASE_URL'), + help='PostgreSQL connection URL (default: from DATABASE_URL env var)' + ) + + parser.add_argument( + '--dry-run', + action='store_true', + help='Perform a dry run without making changes' + ) + + parser.add_argument( + '--no-backup', + action='store_true', + help='Skip creating backup before migration' + ) + + args = parser.parse_args() + + # Validate arguments + if not args.target: + print("Error: PostgreSQL target URL must be specified via --target or DATABASE_URL environment variable") + sys.exit(1) + + if not args.target.startswith('postgresql://'): + print("Error: Target URL must be a PostgreSQL connection string") + sys.exit(1) + + if not Path(args.source).exists(): + print(f"Error: SQLite database file not found: {args.source}") + sys.exit(1) + + # Run migration + migrator = DatabaseMigrator(args.source, args.target, args.dry_run) + success = migrator.run_migration(create_backup=not args.no_backup) + + sys.exit(0 if success else 1) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b507db4..bdfb234 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ eventlet>=0.30.0 # Database # sqlite3 is built-in with Python 3.12+ +psycopg2-binary>=2.9.0 # PostgreSQL adapter # Conda Environment Management psutil>=5.9.0 diff --git a/scripts/run_app.py b/scripts/run_app.py old mode 100644 new mode 100755 index ccaa82d..781c995 --- a/scripts/run_app.py +++ b/scripts/run_app.py @@ -26,7 +26,8 @@ def run_app(): if __name__ == "__main__": print("Starting ScriptsManager...") - print("Application will be available at: http://localhost:5002") + print("🚀 Application will be available at: http://localhost:5002") + print("🔄 HOT-RELOAD ENABLED - Modify files and they will update automatically!") print("Press Ctrl+C to stop the server") print("-" * 50) run_app() diff --git a/sql/01_init_database.sql b/sql/01_init_database.sql new file mode 100644 index 0000000..d8a6a2c --- /dev/null +++ b/sql/01_init_database.sql @@ -0,0 +1,25 @@ +-- SIDEL ScriptsManager PostgreSQL Database Initialization +-- This script creates the initial database structure for PostgreSQL + +-- Enable necessary extensions +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- For text search capabilities + +-- Create application schema (optional, can use public schema) +-- CREATE SCHEMA IF NOT EXISTS scriptsmanager; +-- SET search_path TO scriptsmanager, public; + +-- Database configuration for better performance +ALTER DATABASE scriptsmanager SET timezone TO 'UTC'; +ALTER DATABASE scriptsmanager SET log_statement TO 'all'; +ALTER DATABASE scriptsmanager SET log_min_duration_statement TO 1000; -- Log slow queries + +-- Grant necessary permissions to the application user +GRANT CONNECT ON DATABASE scriptsmanager TO scriptsmanager; +GRANT USAGE ON SCHEMA public TO scriptsmanager; +GRANT CREATE ON SCHEMA public TO scriptsmanager; + +-- Create sequences for auto-incrementing IDs (SQLAlchemy will handle this automatically, but good to have) +-- Note: SQLAlchemy will create these automatically when creating tables + +COMMENT ON DATABASE scriptsmanager IS 'SIDEL ScriptsManager Application Database'; \ No newline at end of file diff --git a/sql/02_indexes.sql b/sql/02_indexes.sql new file mode 100644 index 0000000..791c119 --- /dev/null +++ b/sql/02_indexes.sql @@ -0,0 +1,27 @@ +-- SIDEL ScriptsManager PostgreSQL Indexes and Performance Optimization +-- This script creates indexes and performance optimizations + +-- Performance settings for the database +SET shared_preload_libraries = 'pg_stat_statements'; +SET log_statement = 'ddl'; +SET log_checkpoints = on; +SET log_connections = on; +SET log_disconnections = on; + +-- Note: The following indexes will be created by SQLAlchemy when tables are created +-- This file serves as documentation and can be used for manual optimization + +-- Indexes for common queries (will be created automatically by SQLAlchemy) +-- CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); +-- CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); +-- CREATE INDEX IF NOT EXISTS idx_scripts_user_id ON scripts(user_id); +-- CREATE INDEX IF NOT EXISTS idx_scripts_created_at ON scripts(created_at); +-- CREATE INDEX IF NOT EXISTS idx_execution_logs_script_id ON execution_logs(script_id); +-- CREATE INDEX IF NOT EXISTS idx_execution_logs_timestamp ON execution_logs(timestamp); + +-- Full-text search indexes (if needed) +-- CREATE INDEX IF NOT EXISTS idx_scripts_name_search ON scripts USING gin(to_tsvector('english', name)); +-- CREATE INDEX IF NOT EXISTS idx_scripts_description_search ON scripts USING gin(to_tsvector('english', description)); + +-- Comment for documentation +COMMENT ON SCHEMA public IS 'SIDEL ScriptsManager main schema with performance optimizations'; \ No newline at end of file diff --git a/sql/03_default_data.sql b/sql/03_default_data.sql new file mode 100644 index 0000000..4bf5ee4 --- /dev/null +++ b/sql/03_default_data.sql @@ -0,0 +1,64 @@ +-- SIDEL ScriptsManager PostgreSQL Default Data +-- This script inserts default data for the application + +-- Default admin user (password should be changed after first login) +-- Note: This will be handled by the application's init_db.py script +-- The password hash below corresponds to 'admin123' - CHANGE IN PRODUCTION + +-- Default application settings +-- INSERT INTO settings (key, value, description) VALUES +-- ('app_version', '1.0.0', 'Application version'), +-- ('backup_enabled', 'true', 'Enable automatic backups'), +-- ('max_projects_per_user', '50', 'Maximum projects per user'), +-- ('default_theme', 'light', 'Default UI theme'), +-- ('default_language', 'en', 'Default interface language') +-- ON CONFLICT (key) DO NOTHING; + +-- Default script categories/tags +-- INSERT INTO script_categories (name, description) VALUES +-- ('analysis', 'Data analysis scripts'), +-- ('automation', 'Process automation scripts'), +-- ('reporting', 'Report generation scripts'), +-- ('maintenance', 'System maintenance scripts'), +-- ('development', 'Development and testing scripts') +-- ON CONFLICT (name) DO NOTHING; + +-- PostgreSQL-specific maintenance tasks +-- Create a function to clean up old execution logs +CREATE OR REPLACE FUNCTION cleanup_old_execution_logs(retention_days INTEGER DEFAULT 30) +RETURNS INTEGER AS $$ +DECLARE + deleted_count INTEGER; +BEGIN + DELETE FROM execution_logs + WHERE timestamp < (CURRENT_DATE - INTERVAL '1 day' * retention_days); + + GET DIAGNOSTICS deleted_count = ROW_COUNT; + + RETURN deleted_count; +END; +$$ LANGUAGE plpgsql; + +-- Comment the function +COMMENT ON FUNCTION cleanup_old_execution_logs(INTEGER) IS 'Cleans up execution logs older than specified days'; + +-- Create a function to get database statistics +CREATE OR REPLACE FUNCTION get_database_stats() +RETURNS TABLE ( + table_name TEXT, + row_count BIGINT, + table_size TEXT +) AS $$ +BEGIN + RETURN QUERY + SELECT + schemaname||'.'||tablename as table_name, + n_tup_ins - n_tup_del as row_count, + pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as table_size + FROM pg_stat_user_tables + ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC; +END; +$$ LANGUAGE plpgsql; + +-- Comment the function +COMMENT ON FUNCTION get_database_stats() IS 'Returns statistics about database tables and sizes'; \ No newline at end of file