* feat(static-image): Add static image manager with web interface
- Create StaticImageManager class with image scaling and transparency support
- Add configuration options for display duration, zoom scale, and background color
- Integrate with display controller and web interface
- Add image upload functionality to web interface
- Support for various image formats with proper scaling
- Efficient image processing with aspect ratio preservation
- Ready for future scrolling feature implementation
* fix(static-image): Move display duration to main display_durations block
- Remove display_duration from static_image config section
- Update StaticImageManager to read duration from display.display_durations.static_image
- Remove display duration field from web interface form
- Update web interface JavaScript to not include display_duration in payload
- Follows same pattern as all other managers in the project
* feat(static-image): Add fit to display option
- Add fit_to_display checkbox to automatically scale images to fit display
- When enabled, images are scaled to fit display dimensions while preserving aspect ratio
- When disabled, manual zoom_scale control is available
- Update web interface with smart form controls (zoom scale disabled when fit to display is on)
- Prevents stretching or cropping - images are always properly fitted
- Default to fit_to_display=true for better user experience
* refactor(static-image): Remove zoom_scale and simplify to fit_to_display only
- Remove zoom_scale option entirely as it was confusing and redundant
- Simplify image processing to always fit to display dimensions
- Remove zoom_scale field from web interface
- Clean up JavaScript to remove zoom scale logic
- Images are now always properly fitted without stretching or cropping
- Much simpler and more intuitive user experience
- Add willReadFrequently: true to all getContext('2d') calls in templates/index_v2.html
- Fixes Canvas2D performance warning for multiple readback operations using getImageData
- Improves performance for LED matrix preview rendering with frequent pixel sampling
* fix(web-ui): Use config display dimensions instead of hardcoded 128x32 in Live Display Preview
- Updated /api/display/current endpoint to calculate display dimensions from config
- Modified HTML template to use config dimensions as fallbacks instead of hardcoded 128x32
- Display preview now shows correct resolution based on cols*chain_length x rows*parallel
- Maintains backward compatibility with existing API responses
* feat(web-ui): Add missing NCAAM Hockey sports manager to web interface
- Added NCAAM Hockey import and OnDemandRunner support
- Updated sports configuration UI to include NCAAM Hockey
- Fixed MLB and MiLB config keys to match template (_scoreboard suffix)
- All sports managers now properly represented in web interface:
- NFL, MLB, MiLB, NHL, NBA, NCAA FB, NCAA Baseball, NCAAM Basketball, NCAAM Hockey, Soccer
- Maintains backward compatibility with existing configurations
* fix(web-ui): Improve on-demand button error handling and prevent crashes
- Enhanced error handling in OnDemandRunner with better logging and fallback modes
- Added robust display manager initialization with fallback support
- Improved error reporting via WebSocket to client for real-time feedback
- Added input validation for on-demand mode parameters
- Enhanced client-side error handling with better user notifications
- Added safety checks to prevent multiple on-demand instances
- Fixed display manager initialization issues that caused crashes
- Improved error recovery and graceful degradation
* Fix leaderboard gap to use display width instead of hardcoded values
- Replace hardcoded spacing (40px) with display_manager.matrix.width
- Update gap calculation to use display width for blank screen simulation
- Fix display width logging to show correct value
- Ensures gap between league rotations matches actual display width
* Add display width gap to news manager
- Add display width gap at the beginning of news content
- Update total_scroll_width calculation to include display width gap
- Modify create_scrolling_image to draw text after display width gap
- Ensures news starts with blank screen period matching display width
- Removed duplicate create_scrolling_image method
* add Live, Recent, Upcoming toggles to display modes on website
- Added config_type='main' to FormData when submitting display form
- Added proper HTTP error handling to catch non-JSON responses
- This fixes the 'Unexpected token <' JSON parsing error when saving display settings