SYMBOL INDEX (13751 symbols across 535 files) FILE: backend/app/api/routes/ams_history.py class AMSHistoryPoint (line 19) | class AMSHistoryPoint(BaseModel): class AMSHistoryResponse (line 26) | class AMSHistoryResponse(BaseModel): function get_ams_history (line 39) | async def get_ams_history( function delete_old_history (line 104) | async def delete_old_history( FILE: backend/app/api/routes/api_keys.py function list_api_keys (line 25) | async def list_api_keys( function create_api_key (line 35) | async def create_api_key( function get_api_key (line 80) | async def get_api_key( function update_api_key (line 96) | async def update_api_key( function delete_api_key (line 132) | async def delete_api_key( FILE: backend/app/api/routes/archives.py function _safe_filename (line 36) | def _safe_filename(filename: str) -> str: function _validate_user_filter_permission (line 45) | def _validate_user_filter_permission(current_user: User | None, created_... function _apply_user_filter (line 55) | def _apply_user_filter(conditions: list, created_by_id: int | None): function compute_time_accuracy (line 64) | def compute_time_accuracy(archive: PrintArchive) -> dict: function archive_to_response (line 91) | def archive_to_response( function list_archives (line 157) | async def list_archives( function list_archives_slim (line 275) | async def list_archives_slim( function search_archives (line 350) | async def search_archives( function rebuild_search_index (line 458) | async def rebuild_search_index( function analyze_failures (line 500) | async def analyze_failures( function compare_archives (line 535) | async def compare_archives( function export_archives (line 569) | async def export_archives( function export_stats (line 636) | async def export_stats( function get_archive_stats (line 675) | async def get_archive_stats( function _sum_live_plug_totals (line 843) | async def _sum_live_plug_totals(db: AsyncSession) -> float: function _sum_snapshot_deltas (line 886) | async def _sum_snapshot_deltas( function get_all_tags (line 964) | async def get_all_tags( function rename_tag (line 993) | async def rename_tag( function delete_tag (line 1040) | async def delete_tag( function get_archive (line 1069) | async def get_archive( function find_similar_archives (line 1092) | async def find_similar_archives( function update_archive (line 1115) | async def update_archive( function toggle_favorite (line 1162) | async def toggle_favorite( function rescan_archive (line 1180) | async def rescan_archive( function recalculate_all_costs (line 1259) | async def recalculate_all_costs( function rescan_all_archives (line 1316) | async def rescan_all_archives( function get_archive_duplicates (line 1366) | async def get_archive_duplicates( function backfill_content_hashes (line 1388) | async def backfill_content_hashes( function delete_archive (line 1417) | async def delete_archive( function download_archive (line 1448) | async def download_archive( function download_archive_with_filename (line 1476) | async def download_archive_with_filename( function create_archive_slicer_token (line 1500) | async def create_archive_slicer_token( function download_archive_for_slicer (line 1522) | async def download_archive_for_slicer( function get_thumbnail (line 1556) | async def get_thumbnail( function get_timelapse (line 1588) | async def get_timelapse( function delete_timelapse (line 1626) | async def delete_timelapse( function scan_timelapse (line 1653) | async def scan_timelapse( function select_timelapse (line 1885) | async def select_timelapse( function upload_timelapse (line 1972) | async def upload_timelapse( function get_timelapse_info (line 1998) | async def get_timelapse_info( function get_timelapse_thumbnails (line 2026) | async def get_timelapse_thumbnails( function process_timelapse (line 2062) | async def process_timelapse( function upload_photo (line 2177) | async def upload_photo( function get_photo (line 2220) | async def get_photo( function delete_photo (line 2255) | async def delete_photo( function get_qrcode (line 2291) | async def get_qrcode( function get_archive_capabilities (line 2349) | async def get_archive_capabilities( function get_gcode (line 2569) | async def get_gcode( function get_plate_preview (line 2606) | async def get_plate_preview( function upload_archive (line 2675) | async def upload_archive( function upload_archives_bulk (line 2711) | async def upload_archives_bulk( function get_archive_plates (line 2767) | async def get_archive_plates( function get_plate_thumbnail (line 3040) | async def get_plate_thumbnail( function get_filament_requirements (line 3072) | async def get_filament_requirements( function reprint_archive (line 3199) | async def reprint_archive( function get_project_page (line 3300) | async def get_project_page( function update_project_page (line 3325) | async def update_project_page( function get_project_image (line 3355) | async def get_project_image( function upload_source_3mf (line 3396) | async def upload_source_3mf( function download_source_3mf (line 3444) | async def download_source_3mf( function download_source_3mf_for_slicer (line 3473) | async def download_source_3mf_for_slicer( function create_source_slicer_token (line 3500) | async def create_source_slicer_token( function download_source_3mf_for_slicer_with_token (line 3520) | async def download_source_3mf_for_slicer_with_token( function upload_source_3mf_by_name (line 3556) | async def upload_source_3mf_by_name( function delete_source_3mf (line 3646) | async def delete_source_3mf( function upload_f3d (line 3678) | async def upload_f3d( function download_f3d (line 3726) | async def download_f3d( function delete_f3d (line 3755) | async def delete_f3d( FILE: backend/app/api/routes/auth.py function _user_to_response (line 67) | def _user_to_response(user: User) -> UserResponse: function _api_key_to_user_response (line 83) | def _api_key_to_user_response(api_key) -> UserResponse: function _get_client_ip (line 108) | def _get_client_ip(request: Request) -> str: function is_auth_enabled (line 145) | async def is_auth_enabled(db: AsyncSession) -> bool: function is_advanced_auth_enabled (line 154) | async def is_advanced_auth_enabled(db: AsyncSession) -> bool: function set_advanced_auth_enabled (line 163) | async def set_advanced_auth_enabled(db: AsyncSession, enabled: bool) -> ... function set_auth_enabled (line 170) | async def set_auth_enabled(db: AsyncSession, enabled: bool) -> None: function is_setup_completed (line 178) | async def is_setup_completed(db: AsyncSession) -> bool: function set_setup_completed (line 185) | async def set_setup_completed(db: AsyncSession, completed: bool) -> None: function setup_auth (line 194) | async def setup_auth(request: SetupRequest, db: AsyncSession = Depends(g... function get_auth_status (line 290) | async def get_auth_status(db: AsyncSession = Depends(get_db)): function disable_auth (line 300) | async def disable_auth( function login (line 335) | async def login(raw_request: Request, request: LoginRequest, response: R... function get_current_user_info (line 492) | async def get_current_user_info( function logout (line 579) | async def logout( function test_smtp_connection (line 624) | async def test_smtp_connection( function get_smtp_config (line 656) | async def get_smtp_config( function save_smtp_config (line 669) | async def save_smtp_config( function enable_advanced_auth (line 694) | async def enable_advanced_auth( function disable_advanced_auth (line 739) | async def disable_advanced_auth( function get_advanced_auth_status (line 773) | async def get_advanced_auth_status(db: AsyncSession = Depends(get_db)): function _send_reset_email_or_delete_token (line 793) | async def _send_reset_email_or_delete_token( function forgot_password (line 833) | async def forgot_password( function forgot_password_confirm (line 963) | async def forgot_password_confirm(request: ForgotPasswordConfirmRequest,... function reset_user_password (line 1005) | async def reset_user_password( function _get_ldap_settings (line 1112) | async def _get_ldap_settings(db: AsyncSession) -> dict[str, str] | None: function _provision_ldap_user (line 1134) | async def _provision_ldap_user(db: AsyncSession, ldap_user, ldap_config)... function _sync_ldap_user (line 1172) | async def _sync_ldap_user(db: AsyncSession, user: User, ldap_user, ldap_... function test_ldap (line 1215) | async def test_ldap( function get_ldap_status (line 1258) | async def get_ldap_status(db: AsyncSession = Depends(get_db)): FILE: backend/app/api/routes/background_dispatch.py function cancel_dispatch_job (line 12) | async def cancel_dispatch_job( FILE: backend/app/api/routes/bug_report.py class BugReportRequest (line 26) | class BugReportRequest(BaseModel): class BugReportResponse (line 34) | class BugReportResponse(BaseModel): class StartLoggingResponse (line 41) | class StartLoggingResponse(BaseModel): class StopLoggingResponse (line 46) | class StopLoggingResponse(BaseModel): function start_logging (line 51) | async def start_logging( function stop_logging (line 74) | async def stop_logging( function submit_bug_report (line 91) | async def submit_bug_report( FILE: backend/app/api/routes/camera.py function get_buffered_frame (line 68) | def get_buffered_frame(printer_id: int) -> bytes | None: function get_printer_or_404 (line 76) | async def get_printer_or_404(printer_id: int, db: AsyncSession) -> Printer: function generate_chamber_mjpeg_stream (line 85) | async def generate_chamber_mjpeg_stream( function _terminate_ffmpeg (line 185) | async def _terminate_ffmpeg(process: asyncio.subprocess.Process, stream_... function _summarize_ffmpeg_stderr (line 204) | def _summarize_ffmpeg_stderr(text: str | None) -> str: function _read_ffmpeg_stderr (line 231) | async def _read_ffmpeg_stderr(process: asyncio.subprocess.Process) -> st... function generate_rtsp_mjpeg_stream (line 255) | async def generate_rtsp_mjpeg_stream( function create_stream_token (line 520) | async def create_stream_token( function camera_stream (line 532) | async def camera_stream( function stop_camera_stream (line 703) | async def stop_camera_stream( function camera_snapshot (line 771) | async def camera_snapshot( function test_camera (line 846) | async def test_camera( function camera_status (line 867) | async def camera_status( function test_external_camera (line 932) | async def test_external_camera( function check_plate_empty (line 958) | async def check_plate_empty( function calibrate_plate_detection (line 1067) | async def calibrate_plate_detection( function delete_plate_calibration (line 1132) | async def delete_plate_calibration( function get_plate_detection_status (line 1173) | async def get_plate_detection_status( function get_plate_references (line 1218) | async def get_plate_references( function get_reference_thumbnail (line 1251) | async def get_reference_thumbnail( function update_reference_label (line 1281) | async def update_reference_label( function delete_reference (line 1307) | async def delete_reference( function _scan_bambu_ffmpeg_pids (line 1331) | def _scan_bambu_ffmpeg_pids() -> list[int]: function cleanup_orphaned_streams (line 1357) | async def cleanup_orphaned_streams(): FILE: backend/app/api/routes/cloud.py function _normalise_region (line 54) | def _normalise_region(region: str | None) -> str: function get_stored_token (line 59) | async def get_stored_token(db: AsyncSession, user: User | None = None) -... function store_token (line 82) | async def store_token(db: AsyncSession, token: str, email: str, region: ... function clear_token (line 111) | async def clear_token(db: AsyncSession, user: User | None = None) -> None: function build_authenticated_cloud (line 135) | async def build_authenticated_cloud(db: AsyncSession, user: User | None)... function get_auth_status (line 150) | async def get_auth_status( function login (line 179) | async def login( function verify_code (line 219) | async def verify_code( function set_token (line 264) | async def set_token( function logout (line 291) | async def logout( function get_slicer_settings (line 301) | async def get_slicer_settings( function get_setting_detail (line 372) | async def get_setting_detail( function get_filament_presets (line 399) | async def get_filament_presets( function _enrich_from_local_presets (line 511) | async def _enrich_from_local_presets( function get_filament_info (line 594) | async def get_filament_info( function get_devices (line 674) | async def get_devices( function get_firmware_updates (line 711) | async def get_firmware_updates( function create_setting (line 786) | async def create_setting( function update_setting (line 822) | async def update_setting( function delete_setting (line 854) | async def delete_setting( function _load_fields (line 890) | def _load_fields(preset_type: str) -> dict: function get_builtin_filaments (line 919) | async def get_builtin_filaments( function get_filament_id_map (line 938) | async def get_filament_id_map( function get_preset_fields (line 993) | async def get_preset_fields( function get_all_preset_fields (line 1015) | async def get_all_preset_fields( FILE: backend/app/api/routes/discovery.py class DiscoveryStatus (line 27) | class DiscoveryStatus(BaseModel): class DiscoveryInfo (line 33) | class DiscoveryInfo(BaseModel): class SubnetScanRequest (line 42) | class SubnetScanRequest(BaseModel): class SubnetScanStatus (line 49) | class SubnetScanStatus(BaseModel): class DiscoveredPrinterResponse (line 57) | class DiscoveredPrinterResponse(BaseModel): function get_discovery_info (line 68) | async def get_discovery_info( function get_discovery_status (line 82) | async def get_discovery_status( function start_discovery (line 90) | async def start_discovery( function stop_discovery (line 104) | async def stop_discovery( function get_discovered_printers (line 113) | async def get_discovered_printers( function start_subnet_scan (line 145) | async def start_subnet_scan( function get_scan_status (line 171) | async def get_scan_status( function stop_subnet_scan (line 184) | async def stop_subnet_scan( FILE: backend/app/api/routes/external_links.py function list_external_links (line 35) | async def list_external_links( function create_external_link (line 46) | async def create_external_link( function get_external_link (line 74) | async def get_external_link( function update_external_link (line 90) | async def update_external_link( function delete_external_link (line 117) | async def delete_external_link( function reorder_external_links (line 139) | async def reorder_external_links( function upload_icon (line 164) | async def upload_icon( function delete_icon (line 214) | async def delete_icon( function get_icon (line 239) | async def get_icon( FILE: backend/app/api/routes/filaments.py function list_filaments (line 21) | async def list_filaments( function create_filament (line 31) | async def create_filament( function get_filament (line 45) | async def get_filament( function update_filament (line 59) | async def update_filament( function delete_filament (line 80) | async def delete_filament( function calculate_cost (line 97) | async def calculate_cost( function get_filaments_by_type (line 121) | async def get_filaments_by_type( function seed_default_filaments (line 132) | async def seed_default_filaments( FILE: backend/app/api/routes/firmware.py class AvailableFirmwareVersion (line 33) | class AvailableFirmwareVersion(BaseModel): class FirmwareUpdateInfo (line 43) | class FirmwareUpdateInfo(BaseModel): class FirmwareUpdatesResponse (line 57) | class FirmwareUpdatesResponse(BaseModel): class LatestFirmwareInfo (line 64) | class LatestFirmwareInfo(BaseModel): function check_firmware_updates (line 74) | async def check_firmware_updates( function check_printer_firmware (line 128) | async def check_printer_firmware( function get_all_latest_firmware (line 169) | async def get_all_latest_firmware( class FirmwareUploadPrepareResponse (line 197) | class FirmwareUploadPrepareResponse(BaseModel): class FirmwareUploadStatusResponse (line 213) | class FirmwareUploadStatusResponse(BaseModel): class FirmwareUploadStartResponse (line 224) | class FirmwareUploadStartResponse(BaseModel): function prepare_firmware_upload (line 232) | async def prepare_firmware_upload( function start_firmware_upload (line 255) | async def start_firmware_upload( function get_firmware_upload_status (line 307) | async def get_firmware_upload_status( FILE: backend/app/api/routes/github_backup.py function _config_to_response (line 30) | def _config_to_response(config: GitHubBackupConfig) -> dict: function get_config (line 56) | async def get_config( function save_config (line 71) | async def save_config( function update_config (line 134) | async def update_config( function delete_config (line 170) | async def delete_config( function test_connection (line 190) | async def test_connection( function test_stored_connection (line 201) | async def test_stored_connection( function trigger_backup (line 220) | async def trigger_backup( function get_status (line 240) | async def get_status( function get_logs (line 271) | async def get_logs( function clear_logs (line 310) | async def clear_logs( FILE: backend/app/api/routes/groups.py function _permission_label (line 31) | def _permission_label(perm: Permission) -> str: function list_permissions (line 44) | async def list_permissions( function list_groups (line 64) | async def list_groups( function create_group (line 88) | async def create_group( function get_group (line 133) | async def get_group( function update_group (line 161) | async def update_group( function delete_group (line 221) | async def delete_group( function add_user_to_group (line 246) | async def add_user_to_group( function remove_user_from_group (line 283) | async def remove_user_from_group( FILE: backend/app/api/routes/inventory.py class CatalogEntryResponse (line 64) | class CatalogEntryResponse(BaseModel): class Config (line 70) | class Config: class CatalogEntryCreate (line 74) | class CatalogEntryCreate(BaseModel): class CatalogEntryUpdate (line 79) | class CatalogEntryUpdate(BaseModel): class BulkDeleteIdsRequest (line 84) | class BulkDeleteIdsRequest(BaseModel): class ColorEntryResponse (line 91) | class ColorEntryResponse(BaseModel): class Config (line 99) | class Config: class ColorEntryCreate (line 103) | class ColorEntryCreate(BaseModel): class ColorEntryUpdate (line 110) | class ColorEntryUpdate(BaseModel): class ColorLookupResult (line 117) | class ColorLookupResult(BaseModel): function get_spool_catalog (line 127) | async def get_spool_catalog( function add_catalog_entry (line 137) | async def add_catalog_entry( function update_catalog_entry (line 151) | async def update_catalog_entry( function delete_catalog_entry (line 170) | async def delete_catalog_entry( function bulk_delete_catalog_entries (line 186) | async def bulk_delete_catalog_entries( function reset_spool_catalog (line 203) | async def reset_spool_catalog( function get_color_catalog (line 224) | async def get_color_catalog( function get_color_name_map (line 238) | async def get_color_name_map( function add_color_entry (line 277) | async def add_color_entry( function update_color_entry (line 297) | async def update_color_entry( function delete_color_entry (line 318) | async def delete_color_entry( function bulk_delete_color_entries (line 334) | async def bulk_delete_color_entries( function reset_color_catalog (line 351) | async def reset_color_catalog( function lookup_color (line 374) | async def lookup_color( function search_colors (line 397) | async def search_colors( function sync_from_filamentcolors (line 415) | async def sync_from_filamentcolors( function list_spools (line 524) | async def list_spools( function get_spool (line 539) | async def get_spool( function create_spool (line 553) | async def create_spool( function bulk_create_spools (line 569) | async def bulk_create_spools( function update_spool (line 588) | async def update_spool( function delete_spool (line 615) | async def delete_spool( function archive_spool (line 633) | async def archive_spool( function restore_spool (line 654) | async def restore_spool( function list_k_profiles (line 676) | async def list_k_profiles( function replace_k_profiles (line 687) | async def replace_k_profiles( function list_assignments (line 721) | async def list_assignments( function assign_spool (line 786) | async def assign_spool( function unassign_spool (line 1168) | async def unassign_spool( class LinkTagRequest (line 1205) | class LinkTagRequest(BaseModel): function _validate_tag_input (line 1212) | def _validate_tag_input( function link_tag_to_spool (line 1229) | async def link_tag_to_spool( function get_spool_usage_history (line 1309) | async def get_spool_usage_history( function get_all_usage_history (line 1333) | async def get_all_usage_history( function clear_spool_usage_history (line 1350) | async def clear_spool_usage_history( function sync_weights_from_ams (line 1369) | async def sync_weights_from_ams( function _find_tray_in_ams_data (line 1466) | def _find_tray_in_ams_data(ams_data: list, ams_id: int, tray_id: int) ->... FILE: backend/app/api/routes/kprofiles.py function get_kprofiles (line 32) | async def get_kprofiles( function set_kprofile (line 81) | async def set_kprofile( function set_kprofiles_batch (line 183) | async def set_kprofiles_batch( function delete_kprofile (line 242) | async def delete_kprofile( function get_kprofile_notes (line 289) | async def get_kprofile_notes( function set_kprofile_note (line 316) | async def set_kprofile_note( function delete_kprofile_note (line 365) | async def delete_kprofile_note( FILE: backend/app/api/routes/library.py function get_library_dir (line 68) | def get_library_dir() -> Path: function get_library_files_dir (line 76) | def get_library_files_dir() -> Path: function get_library_thumbnails_dir (line 83) | def get_library_thumbnails_dir() -> Path: function to_relative_path (line 90) | def to_relative_path(absolute_path: Path | str) -> str: function to_absolute_path (line 103) | def to_absolute_path(relative_path: str | None) -> Path | None: function calculate_file_hash (line 114) | def calculate_file_hash(file_path: Path) -> str: function extract_gcode_thumbnail (line 123) | def extract_gcode_thumbnail(file_path: Path) -> bytes | None: function create_image_thumbnail (line 186) | def create_image_thumbnail(file_path: Path, thumbnails_dir: Path, max_si... function list_folders (line 244) | async def list_folders( function get_folders_by_project (line 303) | async def get_folders_by_project( function get_folders_by_archive (line 348) | async def get_folders_by_archive( function create_folder (line 394) | async def create_folder( function get_folder (line 453) | async def get_folder( function update_folder (line 495) | async def update_folder( function delete_folder (line 591) | async def delete_folder( function _validate_external_path (line 684) | def _validate_external_path(path_str: str) -> Path: function create_external_folder (line 709) | async def create_external_folder( function scan_external_folder (line 762) | async def scan_external_folder( function list_files (line 1044) | async def list_files( function upload_file (line 1129) | async def upload_file( function extract_zip_file (line 1266) | async def extract_zip_file( function batch_generate_stl_thumbnails (line 1531) | async def batch_generate_stl_thumbnails( function is_sliced_file (line 1647) | def is_sliced_file(filename: str) -> bool: function add_files_to_queue (line 1659) | async def add_files_to_queue( function get_library_file_plates (line 1738) | async def get_library_file_plates( function get_library_file_plate_thumbnail (line 2002) | async def get_library_file_plate_thumbnail( function get_library_file_filament_requirements (line 2034) | async def get_library_file_filament_requirements( function print_library_file (line 2167) | async def print_library_file( function get_file (line 2262) | async def get_file( function update_file (line 2350) | async def update_file( function delete_file (line 2415) | async def delete_file( function download_file (line 2462) | async def download_file( function create_library_slicer_token (line 2486) | async def create_library_slicer_token( function download_library_file_for_slicer (line 2508) | async def download_library_file_for_slicer( function get_thumbnail (line 2542) | async def get_thumbnail( function get_gcode (line 2573) | async def get_gcode( function move_files (line 2613) | async def move_files( function bulk_delete (line 2660) | async def bulk_delete( function get_library_stats (line 2729) | async def get_library_stats( FILE: backend/app/api/routes/local_backup.py function get_status (line 19) | async def get_status( function trigger_backup (line 37) | async def trigger_backup( function list_backups (line 46) | async def list_backups( function download_backup (line 55) | async def download_backup( function restore_backup (line 72) | async def restore_backup( function delete_backup (line 98) | async def delete_backup( FILE: backend/app/api/routes/local_presets.py function list_local_presets (line 38) | async def list_local_presets( function get_local_preset (line 60) | async def get_local_preset( function import_presets (line 81) | async def import_presets( function create_local_preset (line 99) | async def create_local_preset( function update_local_preset (line 125) | async def update_local_preset( function delete_local_preset (line 161) | async def delete_local_preset( function base_cache_status (line 177) | async def base_cache_status( function refresh_cache (line 186) | async def refresh_cache( function reclassify (line 195) | async def reclassify( FILE: backend/app/api/routes/maintenance.py function _should_apply_to_printer (line 111) | def _should_apply_to_printer(type_name: str, printer_model: str | None) ... function get_printer_total_hours (line 125) | async def get_printer_total_hours(db: AsyncSession, printer_id: int) -> ... function ensure_default_types (line 146) | async def ensure_default_types(db: AsyncSession) -> None: function get_maintenance_types (line 184) | async def get_maintenance_types( function create_maintenance_type (line 199) | async def create_maintenance_type( function update_maintenance_type (line 220) | async def update_maintenance_type( function delete_maintenance_type (line 242) | async def delete_maintenance_type( function restore_default_maintenance_types (line 264) | async def restore_default_maintenance_types( function _get_printer_maintenance_internal (line 284) | async def _get_printer_maintenance_internal( function get_printer_maintenance (line 438) | async def get_printer_maintenance( function get_all_maintenance_overview (line 448) | async def get_all_maintenance_overview( function update_printer_maintenance (line 471) | async def update_printer_maintenance( function assign_maintenance_type (line 497) | async def assign_maintenance_type( function remove_maintenance_item (line 551) | async def remove_maintenance_item( function perform_maintenance (line 577) | async def perform_maintenance( function get_maintenance_history (line 656) | async def get_maintenance_history( function get_maintenance_summary (line 671) | async def get_maintenance_summary( function set_printer_hours (line 707) | async def set_printer_hours( FILE: backend/app/api/routes/metrics.py function get_prometheus_settings (line 20) | async def get_prometheus_settings(db: AsyncSession) -> tuple[bool, str]: function format_labels (line 30) | def format_labels(**labels: str) -> str: function state_to_numeric (line 38) | def state_to_numeric(state: str) -> int: function get_metrics (line 54) | async def get_metrics( FILE: backend/app/api/routes/mfa.py function _as_utc (line 89) | def _as_utc(dt: datetime) -> datetime: function _user_to_response (line 125) | def _user_to_response(user: User) -> UserResponse: function _generate_totp_qr_b64 (line 142) | def _generate_totp_qr_b64(provisioning_uri: str) -> str: function _generate_backup_codes (line 158) | def _generate_backup_codes() -> tuple[list[str], list[str]]: function create_pre_auth_token (line 169) | async def create_pre_auth_token(db: AsyncSession, username: str, challen... function consume_pre_auth_token (line 198) | async def consume_pre_auth_token(db: AsyncSession, token: str, challenge... function peek_pre_auth_token (line 230) | async def peek_pre_auth_token(db: AsyncSession, token: str, challenge_id... function check_rate_limit (line 258) | async def check_rate_limit( function record_failed_attempt (line 296) | async def record_failed_attempt(db: AsyncSession, username: str, event_t... function clear_failed_attempts (line 302) | async def clear_failed_attempts(db: AsyncSession, username: str, event_t... function check_email_otp_send_rate (line 313) | async def check_email_otp_send_rate(db: AsyncSession, username: str) -> ... function record_email_otp_send (line 340) | async def record_email_otp_send(db: AsyncSession, username: str) -> None: function _assert_totp_not_replayed (line 353) | def _assert_totp_not_replayed(totp_obj: pyotp.TOTP, totp_record: UserTOT... function _get_email_2fa_enabled (line 379) | async def _get_email_2fa_enabled(db: AsyncSession, user_id: int) -> bool: function _set_email_2fa_enabled (line 384) | async def _set_email_2fa_enabled(db: AsyncSession, user_id: int, enabled... function get_2fa_status (line 394) | async def get_2fa_status( function setup_totp (line 414) | async def setup_totp( function enable_totp (line 466) | async def enable_totp( function disable_totp (line 504) | async def disable_totp( function regenerate_backup_codes (line 544) | async def regenerate_backup_codes( function enable_email_otp (line 591) | async def enable_email_otp( function confirm_enable_email_otp (line 668) | async def confirm_enable_email_otp( function disable_email_otp (line 725) | async def disable_email_otp( function send_email_otp (line 748) | async def send_email_otp( function verify_2fa (line 837) | async def verify_2fa( function admin_disable_2fa (line 976) | async def admin_disable_2fa( function list_oidc_providers (line 1024) | async def list_oidc_providers( function list_all_oidc_providers (line 1034) | async def list_all_oidc_providers( function create_oidc_provider (line 1045) | async def create_oidc_provider( function update_oidc_provider (line 1068) | async def update_oidc_provider( function delete_oidc_provider (line 1091) | async def delete_oidc_provider( function oidc_authorize (line 1108) | async def oidc_authorize( function oidc_callback (line 1191) | async def oidc_callback( function oidc_exchange (line 1557) | async def oidc_exchange( function list_oidc_links (line 1643) | async def list_oidc_links( function remove_oidc_link (line 1665) | async def remove_oidc_link( function _get_base_external_url (line 1688) | async def _get_base_external_url(db: AsyncSession) -> str: FILE: backend/app/api/routes/notification_templates.py function get_templates (line 59) | async def get_templates( function get_variables (line 69) | async def get_variables( function get_template (line 84) | async def get_template( function update_template (line 98) | async def update_template( function reset_template (line 125) | async def reset_template( function preview_template (line 157) | async def preview_template( FILE: backend/app/api/routes/notifications.py function _provider_to_dict (line 32) | def _provider_to_dict(provider: NotificationProvider) -> dict: function list_notification_providers (line 97) | async def list_notification_providers( function create_notification_provider (line 109) | async def create_notification_provider( function test_notification_config (line 178) | async def test_notification_config( function test_all_notification_providers (line 192) | async def test_all_notification_providers( function get_notification_logs (line 246) | async def get_notification_logs( function get_notification_log_stats (line 308) | async def get_notification_log_stats( function clear_notification_logs (line 354) | async def clear_notification_logs( function get_notification_provider (line 377) | async def get_notification_provider( function update_notification_provider (line 393) | async def update_notification_provider( function delete_notification_provider (line 426) | async def delete_notification_provider( function test_notification_provider (line 448) | async def test_notification_provider( FILE: backend/app/api/routes/obico.py class TestConnectionRequest (line 18) | class TestConnectionRequest(BaseModel): function get_status (line 23) | async def get_status( function test_connection (line 41) | async def test_connection( function cached_frame (line 52) | async def cached_frame(nonce: str): FILE: backend/app/api/routes/pending_uploads.py class ArchiveRequest (line 21) | class ArchiveRequest(BaseModel): class PendingUploadResponse (line 29) | class PendingUploadResponse(BaseModel): class Config (line 42) | class Config: function list_pending_uploads (line 47) | async def list_pending_uploads( function get_pending_count (line 60) | async def get_pending_count( function archive_all_pending (line 76) | async def archive_all_pending( function discard_all_pending (line 132) | async def discard_all_pending( function get_pending_upload (line 159) | async def get_pending_upload( function archive_pending_upload (line 175) | async def archive_pending_upload( function discard_pending_upload (line 244) | async def discard_pending_upload( FILE: backend/app/api/routes/print_log.py function get_print_log (line 23) | async def get_print_log( function get_print_log_thumbnail (line 92) | async def get_print_log_thumbnail( function clear_print_log (line 117) | async def clear_print_log( FILE: backend/app/api/routes/print_queue.py function _extract_filament_types_from_3mf (line 44) | def _extract_filament_types_from_3mf(file_path: Path, plate_id: int | No... function _extract_print_time_from_3mf (line 105) | def _extract_print_time_from_3mf(file_path: Path, plate_id: int | None =... function _enrich_response (line 157) | def _enrich_response(item: PrintQueueItem) -> PrintQueueItemResponse: function list_queue (line 277) | async def list_queue( function add_to_queue (line 338) | async def add_to_queue( function bulk_update_queue_items (line 582) | async def bulk_update_queue_items( function list_batches (line 649) | async def list_batches( function get_batch (line 668) | async def get_batch( function cancel_batch (line 682) | async def cancel_batch( function _build_batch_response (line 709) | async def _build_batch_response(db: AsyncSession, batch: PrintBatch) -> ... function get_queue_item (line 746) | async def get_queue_item( function update_queue_item (line 770) | async def update_queue_item( function delete_queue_item (line 848) | async def delete_queue_item( function reorder_queue (line 882) | async def reorder_queue( function cancel_queue_item (line 900) | async def cancel_queue_item( function stop_queue_item (line 935) | async def stop_queue_item( function start_queue_item (line 1017) | async def start_queue_item( FILE: backend/app/api/routes/printers.py function list_printers (line 53) | async def list_printers( function create_printer (line 63) | async def create_printer( function list_usb_cameras (line 87) | async def list_usb_cameras( function get_available_filaments (line 105) | async def get_available_filaments( function get_developer_mode_warnings (line 203) | async def get_developer_mode_warnings( function get_printer (line 226) | async def get_printer( function update_printer (line 240) | async def update_printer( function delete_printer (line 285) | async def delete_printer( function get_printer_status (line 339) | async def get_printer_status( function get_current_print_user (line 642) | async def get_current_print_user( function refresh_printer_status (line 663) | async def refresh_printer_status( function connect_printer (line 682) | async def connect_printer( function disconnect_printer (line 698) | async def disconnect_printer( function test_printer_connection (line 714) | async def test_printer_connection( function clear_cover_cache (line 733) | def clear_cover_cache(printer_id: int) -> None: function get_printer_cover (line 739) | async def get_printer_cover( function list_printer_files (line 960) | async def list_printer_files( function download_printer_file (line 985) | async def download_printer_file( function get_printer_file_gcode (line 1026) | async def get_printer_file_gcode( function get_printer_file_plates (line 1065) | async def get_printer_file_plates( function get_printer_file_plate_thumbnail (line 1309) | async def get_printer_file_plate_thumbnail( function download_printer_files_as_zip (line 1341) | async def download_printer_files_as_zip( function delete_printer_file (line 1388) | async def delete_printer_file( function get_printer_storage (line 1408) | async def get_printer_storage( function enable_mqtt_logging (line 1430) | async def enable_mqtt_logging( function disable_mqtt_logging (line 1449) | async def disable_mqtt_logging( function get_mqtt_logs (line 1468) | async def get_mqtt_logs( function clear_mqtt_logs (line 1495) | async def clear_mqtt_logs( function start_drying (line 1516) | async def start_drying( function stop_drying (line 1595) | async def stop_drying( function set_print_option (line 1619) | async def set_print_option( function start_calibration (line 1691) | async def start_calibration( function _slot_preset_key (line 1751) | def _slot_preset_key(ams_id: int, tray_id: int) -> int: function get_slot_presets (line 1761) | async def get_slot_presets( function get_slot_preset (line 1782) | async def get_slot_preset( function save_slot_preset (line 1811) | async def save_slot_preset( function delete_slot_preset (line 1867) | async def delete_slot_preset( function configure_ams_slot (line 1892) | async def configure_ams_slot( function reset_ams_slot (line 2097) | async def reset_ams_slot( function get_ams_labels (line 2142) | async def get_ams_labels( function save_ams_label (line 2195) | async def save_ams_label( function delete_ams_label (line 2232) | async def delete_ams_label( function debug_simulate_print_complete (line 2254) | async def debug_simulate_print_complete( function stop_print (line 2307) | async def stop_print( function clear_plate (line 2330) | async def clear_plate( function pause_print (line 2366) | async def pause_print( function resume_print (line 2389) | async def resume_print( function set_print_speed (line 2412) | async def set_print_speed( function set_airduct_mode (line 2437) | async def set_airduct_mode( function set_chamber_light (line 2464) | async def set_chamber_light( function bed_jog (line 2488) | async def bed_jog( function home_axes (line 2530) | async def home_axes( function clear_hms_errors (line 2574) | async def clear_hms_errors( function get_printable_objects (line 2597) | async def get_printable_objects( function skip_objects (line 2708) | async def skip_objects( function refresh_ams_slot (line 2762) | async def refresh_ams_slot( function _apply_pa_after_refresh (line 2789) | async def _apply_pa_after_refresh(printer_id: int, ams_id: int, slot_id:... function get_runtime_debug (line 2911) | async def get_runtime_debug( FILE: backend/app/api/routes/projects.py function compute_project_stats (line 49) | async def compute_project_stats( function list_projects (line 159) | async def list_projects( function create_project (line 265) | async def create_project( function list_templates (line 328) | async def list_templates( function create_project_from_template (line 365) | async def create_project_from_template( function get_child_previews (line 449) | async def get_child_previews(db: AsyncSession, parent_id: int) -> list[P... function get_project (line 481) | async def get_project( function update_project (line 530) | async def update_project( function delete_project (line 622) | async def delete_project( function list_project_archives (line 640) | async def list_project_archives( function list_project_queue (line 672) | async def list_project_queue( function add_archives_to_project (line 692) | async def add_archives_to_project( function add_queue_items_to_project (line 717) | async def add_queue_items_to_project( function remove_archives_from_project (line 742) | async def remove_archives_from_project( function get_project_attachments_dir (line 765) | def get_project_attachments_dir(project_id: int) -> Path: function upload_attachment (line 829) | async def upload_attachment( function download_attachment (line 907) | async def download_attachment( function delete_attachment (line 943) | async def delete_attachment( function list_bom_items (line 992) | async def list_bom_items( function create_bom_item (line 1043) | async def create_bom_item( function update_bom_item (line 1102) | async def update_bom_item( function delete_bom_item (line 1167) | async def delete_bom_item( function create_template_from_project (line 1191) | async def create_template_from_project( function get_project_timeline (line 1272) | async def get_project_timeline( function export_project (line 1373) | async def export_project( function import_project (line 1495) | async def import_project( function import_project_file (line 1589) | async def import_project_file( FILE: backend/app/api/routes/settings.py function get_setting (line 29) | async def get_setting(db: AsyncSession, key: str) -> str | None: function get_external_login_url (line 36) | async def get_external_login_url(db: AsyncSession) -> str: function set_setting (line 57) | async def set_setting(db: AsyncSession, key: str, value: str) -> None: function get_settings (line 66) | async def get_settings( function update_settings (line 152) | async def update_settings( function patch_settings (line 210) | async def patch_settings( function reset_settings (line 220) | async def reset_settings( function get_default_sidebar_order (line 236) | async def get_default_sidebar_order( function check_ffmpeg (line 250) | async def check_ffmpeg(): function get_spoolman_settings (line 263) | async def get_spoolman_settings( function update_spoolman_settings (line 284) | async def update_spoolman_settings( function get_homeassistant_settings (line 317) | async def get_homeassistant_settings(db: AsyncSession) -> dict: function create_backup_zip (line 354) | async def create_backup_zip(output_path: Path | None = None) -> tuple[Pa... function create_backup (line 475) | async def create_backup( function _import_sqlite_to_postgres (line 498) | async def _import_sqlite_to_postgres(sqlite_path: Path, postgres_url: str): function restore_backup (line 673) | async def restore_backup( function get_network_interfaces (line 804) | async def get_network_interfaces( function get_virtual_printer_models (line 815) | async def get_virtual_printer_models( function get_virtual_printer_settings (line 831) | async def get_virtual_printer_settings( function update_virtual_printer_settings (line 860) | async def update_virtual_printer_settings( function get_mqtt_status (line 1015) | async def get_mqtt_status( FILE: backend/app/api/routes/smart_plugs.py function list_smart_plugs (line 48) | async def list_smart_plugs( function create_smart_plug (line 58) | async def create_smart_plug( function get_smart_plug_by_printer (line 139) | async def get_smart_plug_by_printer( function get_script_plugs_by_printer (line 166) | async def get_script_plugs_by_printer( class TasmotaScanRequest (line 191) | class TasmotaScanRequest(BaseModel): function get_local_network_range (line 199) | def get_local_network_range() -> tuple[str, str]: class TasmotaScanStatus (line 225) | class TasmotaScanStatus(BaseModel): class DiscoveredTasmotaDevice (line 233) | class DiscoveredTasmotaDevice(BaseModel): function start_tasmota_scan (line 244) | async def start_tasmota_scan( function get_tasmota_scan_status (line 271) | async def get_tasmota_scan_status( function stop_tasmota_scan (line 284) | async def stop_tasmota_scan( function get_discovered_tasmota_devices (line 298) | async def get_discovered_tasmota_devices( function test_ha_connection (line 318) | async def test_ha_connection( function test_rest_connection (line 328) | async def test_rest_connection( function list_ha_entities (line 338) | async def list_ha_entities( function list_ha_sensor_entities (line 366) | async def list_ha_sensor_entities( function get_smart_plug (line 391) | async def get_smart_plug( function update_smart_plug (line 405) | async def update_smart_plug( function delete_smart_plug (line 497) | async def delete_smart_plug( function _get_service_for_plug (line 522) | async def _get_service_for_plug(plug: SmartPlug, db: AsyncSession): function control_smart_plug (line 540) | async def control_smart_plug( function trigger_associated_scripts (line 619) | async def trigger_associated_scripts(printer_id: int, plug_state: str, d... function get_plug_status (line 651) | async def get_plug_status( function check_power_alerts (line 727) | async def check_power_alerts(plug: SmartPlug, current_power: float | Non... function test_connection (line 786) | async def test_connection( FILE: backend/app/api/routes/spoolbuddy.py function _is_online (line 52) | def _is_online(device: SpoolBuddyDevice) -> bool: function _device_to_response (line 60) | def _device_to_response(device: SpoolBuddyDevice) -> DeviceResponse: function _should_broadcast_online (line 92) | def _should_broadcast_online(device_id: str, force: bool = False) -> bool: function register_device (line 109) | async def register_device( function list_devices (line 181) | async def list_devices( function unregister_device (line 192) | async def unregister_device( function device_heartbeat (line 212) | async def device_heartbeat( function nfc_tag_scanned (line 297) | async def nfc_tag_scanned( function nfc_tag_removed (line 349) | async def nfc_tag_removed( function nfc_write_tag (line 365) | async def nfc_write_tag( function nfc_write_result (line 406) | async def nfc_write_result( function cancel_write (line 459) | async def cancel_write( function scale_reading (line 483) | async def scale_reading( function update_spool_weight (line 501) | async def update_spool_weight( function tare_scale (line 534) | async def tare_scale( function set_tare_offset (line 551) | async def set_tare_offset( function set_calibration_factor (line 575) | async def set_calibration_factor( function get_calibration (line 613) | async def get_calibration( function get_display_settings (line 634) | async def get_display_settings( function update_display_settings (line 656) | async def update_display_settings( function queue_system_config_update (line 682) | async def queue_system_config_update( function queue_system_command (line 719) | async def queue_system_command( function system_command_result (line 748) | async def system_command_result( function queue_diagnostic (line 789) | async def queue_diagnostic( function get_diagnostic_result (line 821) | async def get_diagnostic_result( function report_diagnostic_result (line 851) | async def report_diagnostic_result( function check_daemon_update (line 884) | async def check_daemon_update( function trigger_daemon_update (line 908) | async def trigger_daemon_update( function get_ssh_public_key (line 952) | async def get_ssh_public_key( function report_update_status (line 966) | async def report_update_status( function spoolbuddy_watchdog (line 1004) | async def spoolbuddy_watchdog(): FILE: backend/app/api/routes/spoolman.py class SpoolmanStatus (line 31) | class SpoolmanStatus(BaseModel): class SkippedSpool (line 39) | class SkippedSpool(BaseModel): class SyncResult (line 48) | class SyncResult(BaseModel): function get_spoolman_settings (line 58) | async def get_spoolman_settings(db: AsyncSession) -> dict: function get_spoolman_status (line 86) | async def get_spoolman_status( function connect_spoolman (line 107) | async def connect_spoolman( function disconnect_spoolman (line 141) | async def disconnect_spoolman( function sync_printer_ams (line 150) | async def sync_printer_ams( function sync_all_printers (line 341) | async def sync_all_printers( function get_spools (line 520) | async def get_spools( function get_filaments (line 545) | async def get_filaments( class UnlinkedSpool (line 569) | class UnlinkedSpool(BaseModel): function get_unlinked_spools (line 582) | async def get_unlinked_spools( function get_linked_spools (line 629) | async def get_linked_spools( class LinkSpoolRequest (line 670) | class LinkSpoolRequest(BaseModel): function link_spool (line 682) | async def link_spool( function unlink_spool (line 746) | async def unlink_spool( FILE: backend/app/api/routes/support.py class DebugLoggingState (line 43) | class DebugLoggingState(BaseModel): class DebugLoggingToggle (line 49) | class DebugLoggingToggle(BaseModel): function _get_debug_setting (line 53) | async def _get_debug_setting(db: AsyncSession) -> tuple[bool, datetime |... function _set_debug_setting (line 74) | async def _set_debug_setting(db: AsyncSession, enabled: bool) -> datetim... function _apply_log_level (line 97) | def _apply_log_level(debug: bool): function get_debug_logging_state (line 119) | async def get_debug_logging_state( function toggle_debug_logging (line 138) | async def toggle_debug_logging( class LogEntry (line 159) | class LogEntry(BaseModel): class LogsResponse (line 168) | class LogsResponse(BaseModel): function _parse_log_line (line 180) | def _parse_log_line(line: str) -> LogEntry | None: function _read_log_entries (line 193) | def _read_log_entries( function get_logs (line 278) | async def get_logs( function clear_logs (line 295) | async def clear_logs( function _sanitize_path (line 315) | def _sanitize_path(path: str) -> str: function _detect_docker_network_mode (line 326) | def _detect_docker_network_mode() -> str: function _mask_subnet (line 344) | def _mask_subnet(subnet: str) -> str: function _anonymize_mqtt_broker (line 357) | def _anonymize_mqtt_broker(broker: str) -> str: function _check_port (line 372) | async def _check_port(ip: str, port: int, timeout: float = 2.0) -> bool: function _get_container_memory_limit (line 383) | def _get_container_memory_limit() -> int | None: function _format_bytes (line 407) | def _format_bytes(size_bytes: int) -> str: function _collect_support_info (line 418) | async def _collect_support_info() -> dict: function _sanitize_log_content (line 783) | def _sanitize_log_content(content: str, sensitive_strings: dict[str, str... function _get_log_content (line 819) | def _get_log_content(max_bytes: int = 10 * 1024 * 1024, sensitive_string... function _get_recent_sanitized_logs (line 841) | async def _get_recent_sanitized_logs(max_lines: int = 200) -> str: function generate_support_bundle (line 883) | async def generate_support_bundle( function init_debug_logging (line 950) | async def init_debug_logging(): FILE: backend/app/api/routes/system.py function get_directory_size (line 36) | def get_directory_size(path: Path) -> int: function format_bytes (line 48) | def format_bytes(bytes_value: int) -> str: function format_uptime (line 57) | def format_uptime(seconds: float) -> str: function _is_under (line 74) | def _is_under(path: Path, root: Path) -> bool: function _get_database_paths (line 82) | def _get_database_paths() -> list[Path]: function _get_database_items (line 91) | def _get_database_items() -> list[dict]: function _get_app_dir (line 110) | def _get_app_dir() -> Path: function _get_data_dirs (line 114) | def _get_data_dirs() -> list[Path]: function _is_system_path (line 124) | def _is_system_path(path: Path) -> bool: function _get_storage_rules (line 131) | def _get_storage_rules() -> list[tuple[str, str, Callable]]: function _classify_file (line 214) | def _classify_file(path: Path, rules: list[tuple[str, str, Callable]]) -... function _format_percentage (line 224) | def _format_percentage(part: int, total: int) -> float: function _get_other_bucket (line 230) | def _get_other_bucket(path: Path, base_dir: Path) -> str: function _walk_files (line 240) | def _walk_files(roots: list[Path]) -> list[Path]: function _scan_storage_usage (line 262) | def _scan_storage_usage() -> dict: function _get_storage_usage_cached (line 351) | async def _get_storage_usage_cached(refresh: bool, max_age_seconds: int)... function get_system_info (line 399) | async def get_system_info( function get_storage_usage (line 569) | async def get_storage_usage( FILE: backend/app/api/routes/updates.py function _is_docker_environment (line 35) | def _is_docker_environment() -> bool: function _find_executable (line 57) | def _find_executable(name: str) -> str | None: function parse_version (line 81) | def parse_version(version: str) -> tuple: function is_newer_version (line 127) | def is_newer_version(latest: str, current: str) -> bool: function get_version (line 173) | async def get_version(): function check_for_updates (line 185) | async def check_for_updates( function _perform_update (line 314) | async def _perform_update(): function apply_update (line 504) | async def apply_update( function get_update_status (line 548) | async def get_update_status( FILE: backend/app/api/routes/user_notifications.py function get_user_email_preferences (line 22) | async def get_user_email_preferences( function update_user_email_preferences (line 55) | async def update_user_email_preferences( FILE: backend/app/api/routes/users.py function _user_to_response (line 41) | def _user_to_response(user: User) -> UserResponse: function list_users (line 59) | async def list_users( function create_user (line 71) | async def create_user( function get_user (line 177) | async def get_user( function update_user (line 195) | async def update_user( function get_user_items_count (line 303) | async def get_user_items_count( function delete_user (line 339) | async def delete_user( function change_own_password (line 408) | async def change_own_password( FILE: backend/app/api/routes/virtual_printers.py class VirtualPrinterCreate (line 19) | class VirtualPrinterCreate(BaseModel): class VirtualPrinterUpdate (line 31) | class VirtualPrinterUpdate(BaseModel): function _resolve_printer_model (line 43) | def _resolve_printer_model(printer_model: str | None) -> str | None: function _vp_to_dict (line 60) | def _vp_to_dict(vp, status: dict | None = None) -> dict: function list_virtual_printers (line 87) | async def list_virtual_printers( function create_virtual_printer (line 111) | async def create_virtual_printer( function get_virtual_printer (line 219) | async def get_virtual_printer( function update_virtual_printer (line 240) | async def update_virtual_printer( function delete_virtual_printer (line 387) | async def delete_virtual_printer( FILE: backend/app/api/routes/webhook.py class QueueAddRequest (line 22) | class QueueAddRequest(BaseModel): class QueueAddResponse (line 31) | class QueueAddResponse(BaseModel): class PrinterStatusResponse (line 40) | class PrinterStatusResponse(BaseModel): class QueueStatusResponse (line 50) | class QueueStatusResponse(BaseModel): function webhook_add_to_queue (line 62) | async def webhook_add_to_queue( function webhook_start_print (line 134) | async def webhook_start_print( function webhook_stop_print (line 189) | async def webhook_stop_print( function webhook_cancel_print (line 217) | async def webhook_cancel_print( function webhook_get_printer_status (line 245) | async def webhook_get_printer_status( function webhook_get_queue_status (line 277) | async def webhook_get_queue_status( FILE: backend/app/api/routes/websocket.py function websocket_endpoint (line 14) | async def websocket_endpoint(websocket: WebSocket): FILE: backend/app/cli.py class KioskBootstrapError (line 27) | class KioskBootstrapError(RuntimeError): function kiosk_bootstrap (line 31) | async def kiosk_bootstrap( function main (line 86) | def main(argv: list[str] | None = None) -> int: FILE: backend/app/core/auth.py function _get_jwt_secret (line 34) | def _get_jwt_secret() -> str: function create_slicer_download_token (line 109) | async def create_slicer_download_token(resource_type: str, resource_id: ... function verify_slicer_download_token (line 135) | async def verify_slicer_download_token(token: str, resource_type: str, r... function create_camera_stream_token (line 173) | async def create_camera_stream_token() -> str: function verify_camera_stream_token (line 197) | async def verify_camera_stream_token(token: str) -> bool: function verify_password (line 211) | def verify_password(plain_password: str, hashed_password: str) -> bool: function get_password_hash (line 219) | def get_password_hash(password: str) -> str: function create_access_token (line 227) | def create_access_token(data: dict, expires_delta: timedelta | None = No... function _is_token_fresh (line 241) | def _is_token_fresh(iat: int | float | None, user: User) -> bool: function revoke_jti (line 262) | async def revoke_jti(jti: str, expires_at: datetime, username: str | Non... function is_jti_revoked (line 283) | async def is_jti_revoked(jti: str) -> bool: function get_user_by_username (line 295) | async def get_user_by_username(db: AsyncSession, username: str) -> User ... function get_user_by_email (line 303) | async def get_user_by_email(db: AsyncSession, email: str) -> User | None: function authenticate_user (line 311) | async def authenticate_user(db: AsyncSession, username: str, password: s... function authenticate_user_by_email (line 329) | async def authenticate_user_by_email(db: AsyncSession, email: str, passw... function is_auth_enabled (line 347) | async def is_auth_enabled(db: AsyncSession) -> bool: function _validate_api_key (line 360) | async def _validate_api_key(db: AsyncSession, api_key_value: str) -> API... function get_current_user_optional (line 400) | async def get_current_user_optional( function get_current_user (line 440) | async def get_current_user( function get_current_active_user (line 478) | async def get_current_active_user(current_user: Annotated[User, Depends(... function require_auth_if_enabled (line 483) | async def require_auth_if_enabled( function require_role (line 565) | def require_role(required_role: str): function require_admin_if_auth_enabled (line 579) | def require_admin_if_auth_enabled(): function generate_api_key (line 597) | def generate_api_key() -> tuple[str, str, str]: function get_api_key (line 613) | async def get_api_key( function check_permission (line 672) | def check_permission(api_key: APIKey, permission: str) -> None: function check_printer_access (line 702) | def check_printer_access(api_key: APIKey, printer_id: int) -> None: function RequireAdmin (line 725) | def RequireAdmin(): function RequireAdminIfAuthEnabled (line 730) | def RequireAdminIfAuthEnabled(): function require_permission (line 735) | def require_permission(*permissions: str | Permission): function require_permission_if_auth_enabled (line 811) | def require_permission_if_auth_enabled(*permissions: str | Permission): function RequirePermission (line 912) | def RequirePermission(*permissions: str | Permission): function RequirePermissionIfAuthEnabled (line 917) | def RequirePermissionIfAuthEnabled(*permissions: str | Permission): function require_camera_stream_token_if_auth_enabled (line 922) | def require_camera_stream_token_if_auth_enabled(): function require_ownership_permission (line 946) | def require_ownership_permission( FILE: backend/app/core/compat.py class StrEnum (line 10) | class StrEnum(str, Enum): FILE: backend/app/core/config.py function _migrate_database (line 30) | def _migrate_database() -> Path: class Settings (line 57) | class Settings(BaseSettings): class Config (line 76) | class Config: FILE: backend/app/core/database.py function _set_sqlite_pragmas (line 15) | def _set_sqlite_pragmas(dbapi_conn, connection_record): function _create_engine (line 26) | def _create_engine(): function run_with_retry (line 82) | async def run_with_retry(fn, *, max_attempts: int = 3, label: str = ""): function close_all_connections (line 118) | async def close_all_connections(): function reinitialize_database (line 124) | async def reinitialize_database(): class Base (line 135) | class Base(DeclarativeBase): function get_db (line 139) | async def get_db() -> AsyncSession: function init_db (line 151) | async def init_db(): function _safe_execute (line 215) | async def _safe_execute(conn, sql): function run_migrations (line 230) | async def run_migrations(conn): function seed_notification_templates (line 1519) | async def seed_notification_templates(): function seed_default_groups (line 1557) | async def seed_default_groups(): function seed_spool_catalog (line 1701) | async def seed_spool_catalog(): function seed_color_catalog (line 1724) | async def seed_color_catalog(): FILE: backend/app/core/db_dialect.py function is_postgres (line 10) | def is_postgres() -> bool: function is_sqlite (line 17) | def is_sqlite() -> bool: function upsert_setting (line 24) | async def upsert_setting(db, model, key: str, value: str): function run_pragma (line 45) | async def run_pragma(conn, pragma_sql: str): FILE: backend/app/core/encryption.py function _get_fernet (line 24) | def _get_fernet(): function mfa_encrypt (line 47) | def mfa_encrypt(plaintext: str) -> str: function mfa_decrypt (line 56) | def mfa_decrypt(value: str) -> str: FILE: backend/app/core/permissions.py class Permission (line 10) | class Permission(StrEnum): FILE: backend/app/core/websocket.py class ConnectionManager (line 8) | class ConnectionManager: method __init__ (line 11) | def __init__(self): method connect (line 15) | async def connect(self, websocket: WebSocket): method disconnect (line 21) | async def disconnect(self, websocket: WebSocket): method broadcast (line 27) | async def broadcast(self, message: dict[str, Any]): method send_printer_status (line 46) | async def send_printer_status(self, printer_id: int, status: dict): method send_print_start (line 56) | async def send_print_start(self, printer_id: int, data: dict): method send_print_complete (line 66) | async def send_print_complete(self, printer_id: int, data: dict): method send_archive_created (line 76) | async def send_archive_created(self, archive: dict): method send_archive_updated (line 85) | async def send_archive_updated(self, archive: dict): method send_missing_spool_assignment (line 94) | async def send_missing_spool_assignment( FILE: backend/app/i18n/__init__.py function get_translation (line 76) | def get_translation(lang: str, key: str, **kwargs: Any) -> str: class Translator (line 117) | class Translator: method __init__ (line 120) | def __init__(self, lang: str = "en"): method t (line 123) | def t(self, key: str, **kwargs: Any) -> str: FILE: backend/app/main.py function _start_error_server (line 105) | def _start_error_server(missing_packages: list): function check_dependencies (line 185) | def check_dependencies(): function _get_plug_energy (line 323) | async def _get_plug_energy(plug, db) -> dict | None: function _record_energy_start (line 355) | async def _record_energy_start(archive, printer_id: int, db, *, context:... function register_expected_print (line 388) | def register_expected_print( function _get_start_ams_mapping (line 426) | def _get_start_ams_mapping(data: dict, archive_id: int | None) -> list[i... function _bump_library_file_usage_if_completed (line 434) | async def _bump_library_file_usage_if_completed(db, item, queue_status: ... function mark_printer_stopped_by_user (line 451) | def mark_printer_stopped_by_user(printer_id: int) -> None: function on_printer_status_change (line 467) | async def on_printer_status_change(printer_id: int, state: PrinterState): function _is_bambu_uuid (line 698) | def _is_bambu_uuid(tray_uuid: str) -> bool: function on_ams_change (line 703) | async def on_ams_change(printer_id: int, ams_data: list): function _capture_snapshot_for_notification (line 1132) | async def _capture_snapshot_for_notification(printer_id: int, printer, l... function _apply_camera_rotation (line 1189) | def _apply_camera_rotation(image_data: bytes, printer, logger) -> bytes: function _send_print_start_notification (line 1213) | async def _send_print_start_notification( function _dispatch_user_print_email (line 1253) | async def _dispatch_user_print_email( function _load_objects_from_archive (line 1288) | def _load_objects_from_archive(archive, printer_id: int, logger) -> None: function on_print_start (line 1310) | async def on_print_start(printer_id: int, data: dict): function _list_timelapse_videos (line 2194) | async def _list_timelapse_videos(printer) -> tuple[list[dict], str | None]: function _scan_for_timelapse_with_retries (line 2225) | async def _scan_for_timelapse_with_retries(archive_id: int, baseline_nam... function on_print_complete (line 2416) | async def on_print_complete(printer_id: int, data: dict): function record_ams_history (line 3448) | async def record_ams_history(): function start_ams_history_recording (line 3631) | def start_ams_history_recording(): function stop_ams_history_recording (line 3639) | def stop_ams_history_recording(): function track_printer_runtime (line 3653) | async def track_printer_runtime(): function start_runtime_tracking (line 3738) | def start_runtime_tracking(): function stop_runtime_tracking (line 3746) | def stop_runtime_tracking(): function _spoolbuddy_watchdog_loop (line 3760) | async def _spoolbuddy_watchdog_loop(): function start_spoolbuddy_watchdog (line 3774) | def start_spoolbuddy_watchdog(): function stop_spoolbuddy_watchdog (line 3781) | def stop_spoolbuddy_watchdog(): function _camera_cleanup_loop (line 3794) | async def _camera_cleanup_loop(): function start_camera_cleanup (line 3808) | def start_camera_cleanup(): function stop_camera_cleanup (line 3815) | def stop_camera_cleanup(): function _evict_stale_expected_prints (line 3828) | def _evict_stale_expected_prints() -> None: function _expected_prints_cleanup_loop (line 3864) | async def _expected_prints_cleanup_loop() -> None: function start_expected_prints_cleanup (line 3876) | def start_expected_prints_cleanup() -> None: function stop_expected_prints_cleanup (line 3883) | def stop_expected_prints_cleanup() -> None: function _run_auth_cleanup (line 3899) | async def _run_auth_cleanup() -> None: function _auth_cleanup_loop (line 3959) | async def _auth_cleanup_loop() -> None: function start_auth_cleanup (line 3971) | def start_auth_cleanup() -> None: function stop_auth_cleanup (line 3978) | def stop_auth_cleanup() -> None: function lifespan (line 3987) | async def lifespan(app: FastAPI): function security_headers_middleware (line 4321) | async def security_headers_middleware(request, call_next): function auth_middleware (line 4353) | async def auth_middleware(request, call_next): function serve_frontend (line 4541) | async def serve_frontend(): function health_check (line 4554) | async def health_check(): function serve_manifest (line 4560) | async def serve_manifest(): function serve_service_worker (line 4569) | async def serve_service_worker(): function serve_sw_register (line 4582) | async def serve_sw_register(): function serve_spa (line 4596) | async def serve_spa(full_path: str): FILE: backend/app/models/active_print_spoolman.py class ActivePrintSpoolman (line 9) | class ActivePrintSpoolman(Base): FILE: backend/app/models/ams_history.py class AMSSensorHistory (line 9) | class AMSSensorHistory(Base): FILE: backend/app/models/ams_label.py class AmsLabel (line 19) | class AmsLabel(Base): FILE: backend/app/models/api_key.py class APIKey (line 9) | class APIKey(Base): FILE: backend/app/models/archive.py class PrintArchive (line 9) | class PrintArchive(Base): FILE: backend/app/models/auth_ephemeral.py class TokenType (line 32) | class TokenType(str, Enum): class EventType (line 47) | class EventType(str, Enum): class AuthEphemeralToken (line 62) | class AuthEphemeralToken(Base): method new_pre_auth (line 100) | def new_pre_auth( method new_oidc_state (line 117) | def new_oidc_state( method new_oidc_exchange (line 136) | def new_oidc_exchange( method new_password_reset (line 151) | def new_password_reset( method new_email_otp_setup (line 166) | def new_email_otp_setup( class AuthRateLimitEvent (line 187) | class AuthRateLimitEvent(Base): FILE: backend/app/models/bug_report.py class BugReport (line 9) | class BugReport(Base): FILE: backend/app/models/color_catalog.py class ColorCatalogEntry (line 9) | class ColorCatalogEntry(Base): FILE: backend/app/models/external_link.py class ExternalLink (line 9) | class ExternalLink(Base): FILE: backend/app/models/filament.py class Filament (line 9) | class Filament(Base): FILE: backend/app/models/github_backup.py class GitHubBackupConfig (line 11) | class GitHubBackupConfig(Base): class GitHubBackupLog (line 49) | class GitHubBackupLog(Base): FILE: backend/app/models/group.py class Group (line 27) | class Group(Base): method __repr__ (line 53) | def __repr__(self) -> str: FILE: backend/app/models/kprofile_note.py class KProfileNote (line 11) | class KProfileNote(Base): FILE: backend/app/models/library.py class LibraryFolder (line 11) | class LibraryFolder(Base): class LibraryFile (line 55) | class LibraryFile(Base): FILE: backend/app/models/local_preset.py class LocalPreset (line 11) | class LocalPreset(Base): FILE: backend/app/models/maintenance.py class MaintenanceType (line 11) | class MaintenanceType(Base): class PrinterMaintenance (line 34) | class PrinterMaintenance(Base): class MaintenanceHistory (line 64) | class MaintenanceHistory(Base): FILE: backend/app/models/notification.py class NotificationDigestQueue (line 11) | class NotificationDigestQueue(Base): class NotificationLog (line 29) | class NotificationLog(Base): class NotificationProvider (line 49) | class NotificationProvider(Base): FILE: backend/app/models/notification_template.py class NotificationTemplate (line 11) | class NotificationTemplate(Base): FILE: backend/app/models/oidc_provider.py class OIDCProvider (line 12) | class OIDCProvider(Base): method client_secret (line 36) | def client_secret(self) -> str: method client_secret (line 40) | def client_secret(self, value: str) -> None: method __repr__ (line 65) | def __repr__(self) -> str: class UserOIDCLink (line 69) | class UserOIDCLink(Base): method __repr__ (line 92) | def __repr__(self) -> str: FILE: backend/app/models/orca_base_cache.py class OrcaBaseProfile (line 11) | class OrcaBaseProfile(Base): FILE: backend/app/models/pending_upload.py class PendingUpload (line 11) | class PendingUpload(Base): FILE: backend/app/models/print_batch.py class PrintBatch (line 9) | class PrintBatch(Base): FILE: backend/app/models/print_log.py class PrintLogEntry (line 9) | class PrintLogEntry(Base): FILE: backend/app/models/print_queue.py class PrintQueueItem (line 9) | class PrintQueueItem(Base): FILE: backend/app/models/printer.py class Printer (line 9) | class Printer(Base): FILE: backend/app/models/project.py class Project (line 9) | class Project(Base): FILE: backend/app/models/project_bom.py class ProjectBOMItem (line 9) | class ProjectBOMItem(Base): FILE: backend/app/models/settings.py class Settings (line 9) | class Settings(Base): FILE: backend/app/models/slot_preset.py class SlotPresetMapping (line 15) | class SlotPresetMapping(Base): FILE: backend/app/models/smart_plug.py class SmartPlug (line 9) | class SmartPlug(Base): FILE: backend/app/models/smart_plug_energy_snapshot.py class SmartPlugEnergySnapshot (line 9) | class SmartPlugEnergySnapshot(Base): FILE: backend/app/models/spool.py class Spool (line 9) | class Spool(Base): FILE: backend/app/models/spool_assignment.py class SpoolAssignment (line 9) | class SpoolAssignment(Base): method printer_name (line 29) | def printer_name(self) -> str | None: FILE: backend/app/models/spool_catalog.py class SpoolCatalogEntry (line 9) | class SpoolCatalogEntry(Base): FILE: backend/app/models/spool_k_profile.py class SpoolKProfile (line 9) | class SpoolKProfile(Base): FILE: backend/app/models/spool_usage_history.py class SpoolUsageHistory (line 9) | class SpoolUsageHistory(Base): FILE: backend/app/models/spoolbuddy_device.py class SpoolBuddyDevice (line 9) | class SpoolBuddyDevice(Base): FILE: backend/app/models/user.py class User (line 16) | class User(Base): method is_admin (line 66) | def is_admin(self) -> bool: method get_permissions (line 77) | def get_permissions(self) -> set[str]: method has_permission (line 88) | def has_permission(self, permission: str) -> bool: method has_all_permissions (line 98) | def has_all_permissions(self, *permissions: str) -> bool: method has_any_permission (line 109) | def has_any_permission(self, *permissions: str) -> bool: method __repr__ (line 120) | def __repr__(self) -> str: FILE: backend/app/models/user_email_pref.py class UserEmailPreference (line 17) | class UserEmailPreference(Base): FILE: backend/app/models/user_otp_code.py class UserOTPCode (line 11) | class UserOTPCode(Base): method consume (line 35) | def consume(self) -> None: method __repr__ (line 54) | def __repr__(self) -> str: FILE: backend/app/models/user_totp.py class UserTOTP (line 14) | class UserTOTP(Base): method secret (line 40) | def secret(self) -> str: method secret (line 45) | def secret(self, value: str) -> None: method backup_code_hashes (line 50) | def backup_code_hashes(self) -> list[str]: method backup_code_hashes (line 62) | def backup_code_hashes(self, hashes: list[str]) -> None: method accept_counter (line 66) | def accept_counter(self, new_counter: int) -> None: method __repr__ (line 83) | def __repr__(self) -> str: FILE: backend/app/models/virtual_printer.py class VirtualPrinter (line 9) | class VirtualPrinter(Base): FILE: backend/app/schemas/api_key.py class APIKeyCreate (line 6) | class APIKeyCreate(BaseModel): class APIKeyUpdate (line 17) | class APIKeyUpdate(BaseModel): class APIKeyResponse (line 29) | class APIKeyResponse(BaseModel): class Config (line 44) | class Config: class APIKeyCreateResponse (line 48) | class APIKeyCreateResponse(APIKeyResponse): FILE: backend/app/schemas/archive.py class ArchiveBase (line 6) | class ArchiveBase(BaseModel): class ArchiveUpdate (line 18) | class ArchiveUpdate(ArchiveBase): class ArchiveDuplicate (line 25) | class ArchiveDuplicate(BaseModel): class ArchiveResponse (line 34) | class ArchiveResponse(BaseModel): method compute_object_count (line 103) | def compute_object_count(self) -> "ArchiveResponse": class Config (line 111) | class Config: class ArchiveSlim (line 115) | class ArchiveSlim(BaseModel): class Config (line 132) | class Config: class ArchiveStats (line 136) | class ArchiveStats(BaseModel): class ProjectPageImage (line 158) | class ProjectPageImage(BaseModel): class ProjectPageResponse (line 166) | class ProjectPageResponse(BaseModel): class ProjectPageUpdate (line 198) | class ProjectPageUpdate(BaseModel): class ReprintRequest (line 210) | class ReprintRequest(BaseModel): FILE: backend/app/schemas/auth.py function _validate_password_complexity (line 7) | def _validate_password_complexity(v: str) -> str: class GroupBrief (line 24) | class GroupBrief(BaseModel): class Config (line 30) | class Config: class LoginRequest (line 34) | class LoginRequest(BaseModel): class LoginResponse (line 39) | class LoginResponse(BaseModel): class UserCreate (line 49) | class UserCreate(BaseModel): method validate_password (line 58) | def validate_password(cls, v: str | None) -> str | None: class UserUpdate (line 64) | class UserUpdate(BaseModel): method validate_password (line 74) | def validate_password(cls, v: str | None) -> str | None: class UserResponse (line 80) | class UserResponse(BaseModel): class Config (line 92) | class Config: class ChangePasswordRequest (line 96) | class ChangePasswordRequest(BaseModel): method validate_new_password (line 102) | def validate_new_password(cls, v: str) -> str: class SetupRequest (line 106) | class SetupRequest(BaseModel): method validate_admin_password (line 113) | def validate_admin_password(cls, v: str | None) -> str | None: class SetupResponse (line 119) | class SetupResponse(BaseModel): class ForgotPasswordRequest (line 124) | class ForgotPasswordRequest(BaseModel): class ForgotPasswordConfirmRequest (line 128) | class ForgotPasswordConfirmRequest(BaseModel): method validate_new_password (line 134) | def validate_new_password(cls, v: str) -> str: class ForgotPasswordResponse (line 138) | class ForgotPasswordResponse(BaseModel): class ResetPasswordRequest (line 142) | class ResetPasswordRequest(BaseModel): class ResetPasswordResponse (line 146) | class ResetPasswordResponse(BaseModel): class SMTPSettings (line 150) | class SMTPSettings(BaseModel): class TestSMTPRequest (line 163) | class TestSMTPRequest(BaseModel): class TestSMTPResponse (line 167) | class TestSMTPResponse(BaseModel): class TwoFAStatusResponse (line 177) | class TwoFAStatusResponse(BaseModel): class TOTPSetupResponse (line 183) | class TOTPSetupResponse(BaseModel): class TOTPSetupRequest (line 193) | class TOTPSetupRequest(BaseModel): class TOTPEnableRequest (line 204) | class TOTPEnableRequest(BaseModel): method validate_code (line 209) | def validate_code(cls, v: str) -> str: class TOTPEnableResponse (line 216) | class TOTPEnableResponse(BaseModel): class TOTPDisableRequest (line 221) | class TOTPDisableRequest(BaseModel): class BackupCodesResponse (line 227) | class BackupCodesResponse(BaseModel): class EmailOTPEnableRequest (line 232) | class EmailOTPEnableRequest(BaseModel): class TwoFAVerifyRequest (line 238) | class TwoFAVerifyRequest(BaseModel): method validate_code_format (line 247) | def validate_code_format(cls, v: str) -> str: class TwoFAVerifyResponse (line 254) | class TwoFAVerifyResponse(BaseModel): class EmailOTPSendRequest (line 260) | class EmailOTPSendRequest(BaseModel): class EmailOTPEnableConfirmRequest (line 264) | class EmailOTPEnableConfirmRequest(BaseModel): method validate_code_digits (line 273) | def validate_code_digits(cls, v: str) -> str: class EmailOTPDisableRequest (line 280) | class EmailOTPDisableRequest(BaseModel): class AdminDisable2FARequest (line 286) | class AdminDisable2FARequest(BaseModel): function _validate_icon_url (line 300) | def _validate_icon_url(v: str | None) -> str | None: function _validate_issuer_url (line 309) | def _validate_issuer_url(v: str | None) -> str | None: function _validate_scopes (line 335) | def _validate_scopes(v: str | None) -> str | None: class OIDCProviderCreate (line 350) | class OIDCProviderCreate(BaseModel): method validate_issuer_url (line 363) | def validate_issuer_url(cls, v: str) -> str: method validate_scopes (line 370) | def validate_scopes(cls, v: str) -> str: method validate_icon_url (line 377) | def validate_icon_url(cls, v: str | None) -> str | None: class OIDCProviderUpdate (line 381) | class OIDCProviderUpdate(BaseModel): method validate_issuer_url (line 387) | def validate_issuer_url(cls, v: str | None) -> str | None: method validate_scopes (line 400) | def validate_scopes(cls, v: str | None) -> str | None: method validate_icon_url (line 405) | def validate_icon_url(cls, v: str | None) -> str | None: class OIDCProviderResponse (line 409) | class OIDCProviderResponse(BaseModel): class Config (line 420) | class Config: class OIDCAuthorizeResponse (line 424) | class OIDCAuthorizeResponse(BaseModel): class OIDCExchangeRequest (line 428) | class OIDCExchangeRequest(BaseModel): class OIDCLinkResponse (line 432) | class OIDCLinkResponse(BaseModel): FILE: backend/app/schemas/cloud.py class CloudLoginRequest (line 8) | class CloudLoginRequest(BaseModel): class CloudVerifyRequest (line 16) | class CloudVerifyRequest(BaseModel): class CloudLoginResponse (line 25) | class CloudLoginResponse(BaseModel): class CloudAuthStatus (line 35) | class CloudAuthStatus(BaseModel): class CloudTokenRequest (line 43) | class CloudTokenRequest(BaseModel): class SlicerSetting (line 50) | class SlicerSetting(BaseModel): class SlicerSettingsResponse (line 62) | class SlicerSettingsResponse(BaseModel): class CloudDevice (line 70) | class CloudDevice(BaseModel): class SlicerSettingCreate (line 80) | class SlicerSettingCreate(BaseModel): class SlicerSettingUpdate (line 90) | class SlicerSettingUpdate(BaseModel): class SlicerSettingDetail (line 97) | class SlicerSettingDetail(BaseModel): class SlicerSettingDeleteResponse (line 115) | class SlicerSettingDeleteResponse(BaseModel): class FirmwareUpdateInfo (line 122) | class FirmwareUpdateInfo(BaseModel): class FirmwareUpdatesResponse (line 133) | class FirmwareUpdatesResponse(BaseModel): FILE: backend/app/schemas/external_link.py class ExternalLinkBase (line 6) | class ExternalLinkBase(BaseModel): method validate_url (line 16) | def validate_url(cls, v: str) -> str: class ExternalLinkCreate (line 23) | class ExternalLinkCreate(ExternalLinkBase): class ExternalLinkUpdate (line 29) | class ExternalLinkUpdate(BaseModel): method validate_url (line 39) | def validate_url(cls, v: str | None) -> str | None: class ExternalLinkResponse (line 46) | class ExternalLinkResponse(ExternalLinkBase): class ExternalLinkReorder (line 59) | class ExternalLinkReorder(BaseModel): FILE: backend/app/schemas/filament.py class FilamentBase (line 6) | class FilamentBase(BaseModel): class FilamentCreate (line 22) | class FilamentCreate(FilamentBase): class FilamentUpdate (line 26) | class FilamentUpdate(BaseModel): class FilamentResponse (line 42) | class FilamentResponse(FilamentBase): class Config (line 47) | class Config: class FilamentCostCalculation (line 51) | class FilamentCostCalculation(BaseModel): FILE: backend/app/schemas/github_backup.py class ScheduleType (line 11) | class ScheduleType(StrEnum): class GitHubBackupConfigCreate (line 19) | class GitHubBackupConfigCreate(BaseModel): method validate_repo_url (line 39) | def validate_repo_url(cls, v: str) -> str: class GitHubBackupConfigUpdate (line 52) | class GitHubBackupConfigUpdate(BaseModel): method validate_repo_url (line 72) | def validate_repo_url(cls, v: str | None) -> str | None: class GitHubBackupConfigResponse (line 85) | class GitHubBackupConfigResponse(BaseModel): class Config (line 112) | class Config: class GitHubBackupLogResponse (line 116) | class GitHubBackupLogResponse(BaseModel): class Config (line 129) | class Config: class GitHubBackupStatus (line 133) | class GitHubBackupStatus(BaseModel): class GitHubTestConnectionResponse (line 145) | class GitHubTestConnectionResponse(BaseModel): class GitHubBackupTriggerResponse (line 154) | class GitHubBackupTriggerResponse(BaseModel): FILE: backend/app/schemas/group.py class GroupBrief (line 8) | class GroupBrief(BaseModel): class Config (line 14) | class Config: class GroupCreate (line 18) | class GroupCreate(BaseModel): class GroupUpdate (line 26) | class GroupUpdate(BaseModel): class GroupResponse (line 34) | class GroupResponse(BaseModel): class Config (line 46) | class Config: class GroupDetailResponse (line 50) | class GroupDetailResponse(GroupResponse): class UserBrief (line 56) | class UserBrief(BaseModel): class Config (line 63) | class Config: class PermissionInfo (line 67) | class PermissionInfo(BaseModel): class PermissionCategory (line 74) | class PermissionCategory(BaseModel): class PermissionsListResponse (line 81) | class PermissionsListResponse(BaseModel): FILE: backend/app/schemas/kprofile.py class KProfile (line 6) | class KProfile(BaseModel): class KProfileCreate (line 22) | class KProfileCreate(BaseModel): class KProfilesResponse (line 38) | class KProfilesResponse(BaseModel): class KProfileDelete (line 45) | class KProfileDelete(BaseModel): class KProfileNote (line 56) | class KProfileNote(BaseModel): class KProfileNoteResponse (line 63) | class KProfileNoteResponse(BaseModel): FILE: backend/app/schemas/library.py class FolderCreate (line 10) | class FolderCreate(BaseModel): class ExternalFolderCreate (line 19) | class ExternalFolderCreate(BaseModel): class FolderUpdate (line 29) | class FolderUpdate(BaseModel): class FolderResponse (line 38) | class FolderResponse(BaseModel): class Config (line 56) | class Config: class FolderTreeItem (line 60) | class FolderTreeItem(BaseModel): class Config (line 76) | class Config: class FileCreate (line 83) | class FileCreate(BaseModel): class FileUpdate (line 97) | class FileUpdate(BaseModel): class FileDuplicate (line 106) | class FileDuplicate(BaseModel): class FileResponse (line 116) | class FileResponse(BaseModel): class Config (line 157) | class Config: class FileListResponse (line 161) | class FileListResponse(BaseModel): class Config (line 184) | class Config: class FileMoveRequest (line 188) | class FileMoveRequest(BaseModel): class FilePrintRequest (line 195) | class FilePrintRequest(BaseModel): class FileUploadResponse (line 221) | class FileUploadResponse(BaseModel): class BulkDeleteRequest (line 236) | class BulkDeleteRequest(BaseModel): class BulkDeleteResponse (line 243) | class BulkDeleteResponse(BaseModel): class AddToQueueRequest (line 253) | class AddToQueueRequest(BaseModel): class AddToQueueResult (line 259) | class AddToQueueResult(BaseModel): class AddToQueueError (line 267) | class AddToQueueError(BaseModel): class AddToQueueResponse (line 275) | class AddToQueueResponse(BaseModel): class ZipExtractResult (line 285) | class ZipExtractResult(BaseModel): class ZipExtractError (line 293) | class ZipExtractError(BaseModel): class ZipExtractResponse (line 300) | class ZipExtractResponse(BaseModel): class BatchThumbnailRequest (line 312) | class BatchThumbnailRequest(BaseModel): class BatchThumbnailResult (line 320) | class BatchThumbnailResult(BaseModel): class BatchThumbnailResponse (line 329) | class BatchThumbnailResponse(BaseModel): FILE: backend/app/schemas/local_preset.py class LocalPresetResponse (line 8) | class LocalPresetResponse(BaseModel): class LocalPresetDetail (line 32) | class LocalPresetDetail(LocalPresetResponse): class LocalPresetCreate (line 38) | class LocalPresetCreate(BaseModel): class LocalPresetUpdate (line 46) | class LocalPresetUpdate(BaseModel): class LocalPresetsResponse (line 53) | class LocalPresetsResponse(BaseModel): class ImportResponse (line 61) | class ImportResponse(BaseModel): FILE: backend/app/schemas/maintenance.py class MaintenanceTypeBase (line 9) | class MaintenanceTypeBase(BaseModel): class MaintenanceTypeCreate (line 19) | class MaintenanceTypeCreate(MaintenanceTypeBase): class MaintenanceTypeUpdate (line 23) | class MaintenanceTypeUpdate(BaseModel): class MaintenanceTypeResponse (line 32) | class MaintenanceTypeResponse(MaintenanceTypeBase): class Config (line 37) | class Config: class PrinterMaintenanceBase (line 42) | class PrinterMaintenanceBase(BaseModel): class PrinterMaintenanceCreate (line 49) | class PrinterMaintenanceCreate(PrinterMaintenanceBase): class PrinterMaintenanceUpdate (line 53) | class PrinterMaintenanceUpdate(BaseModel): class PrinterMaintenanceResponse (line 59) | class PrinterMaintenanceResponse(BaseModel): class Config (line 71) | class Config: class MaintenanceHistoryBase (line 76) | class MaintenanceHistoryBase(BaseModel): class MaintenanceHistoryCreate (line 80) | class MaintenanceHistoryCreate(MaintenanceHistoryBase): class MaintenanceHistoryResponse (line 84) | class MaintenanceHistoryResponse(MaintenanceHistoryBase): class Config (line 90) | class Config: class MaintenanceStatus (line 95) | class MaintenanceStatus(BaseModel): class PrinterMaintenanceOverview (line 123) | class PrinterMaintenanceOverview(BaseModel): class PerformMaintenanceRequest (line 135) | class PerformMaintenanceRequest(BaseModel): FILE: backend/app/schemas/notification.py class ProviderType (line 11) | class ProviderType(StrEnum): class NotificationProviderBase (line 24) | class NotificationProviderBase(BaseModel): method validate_time_format (line 91) | def validate_time_format(cls, v: str | None) -> str | None: class NotificationProviderCreate (line 106) | class NotificationProviderCreate(NotificationProviderBase): class NotificationProviderUpdate (line 112) | class NotificationProviderUpdate(BaseModel): class NotificationProviderResponse (line 173) | class NotificationProviderResponse(NotificationProviderBase): class Config (line 183) | class Config: class NotificationTestRequest (line 187) | class NotificationTestRequest(BaseModel): class NotificationTestResponse (line 194) | class NotificationTestResponse(BaseModel): class CallMeBotConfig (line 202) | class CallMeBotConfig(BaseModel): class NtfyConfig (line 209) | class NtfyConfig(BaseModel): class PushoverConfig (line 217) | class PushoverConfig(BaseModel): class TelegramConfig (line 225) | class TelegramConfig(BaseModel): class EmailConfig (line 232) | class EmailConfig(BaseModel): class NotificationLogResponse (line 245) | class NotificationLogResponse(BaseModel): class Config (line 261) | class Config: class NotificationLogStats (line 265) | class NotificationLogStats(BaseModel): FILE: backend/app/schemas/notification_template.py class EventType (line 10) | class EventType(StrEnum): class NotificationTemplateBase (line 307) | class NotificationTemplateBase(BaseModel): class NotificationTemplateUpdate (line 314) | class NotificationTemplateUpdate(BaseModel): class NotificationTemplateResponse (line 321) | class NotificationTemplateResponse(NotificationTemplateBase): class Config (line 331) | class Config: class TemplateVariableInfo (line 335) | class TemplateVariableInfo(BaseModel): class EventVariablesResponse (line 342) | class EventVariablesResponse(BaseModel): class TemplatePreviewRequest (line 350) | class TemplatePreviewRequest(BaseModel): class TemplatePreviewResponse (line 358) | class TemplatePreviewResponse(BaseModel): FILE: backend/app/schemas/print_log.py class PrintLogEntrySchema (line 6) | class PrintLogEntrySchema(BaseModel): class PrintLogResponse (line 23) | class PrintLogResponse(BaseModel): FILE: backend/app/schemas/print_queue.py function serialize_utc_datetime (line 8) | def serialize_utc_datetime(dt: datetime | None) -> str | None: class PrintQueueItemCreate (line 18) | class PrintQueueItemCreate(BaseModel): class PrintQueueItemUpdate (line 51) | class PrintQueueItemUpdate(BaseModel): class PrintQueueItemResponse (line 74) | class PrintQueueItemResponse(BaseModel): class Config (line 132) | class Config: class PrintQueueReorderItem (line 136) | class PrintQueueReorderItem(BaseModel): class PrintQueueReorder (line 141) | class PrintQueueReorder(BaseModel): class PrintQueueBulkUpdate (line 145) | class PrintQueueBulkUpdate(BaseModel): class PrintQueueBulkUpdateResponse (line 166) | class PrintQueueBulkUpdateResponse(BaseModel): class PrintBatchResponse (line 174) | class PrintBatchResponse(BaseModel): class Config (line 193) | class Config: FILE: backend/app/schemas/printer.py class PrinterBase (line 6) | class PrinterBase(BaseModel): class PrinterCreate (line 24) | class PrinterCreate(PrinterBase): class PlateDetectionROI (line 28) | class PlateDetectionROI(BaseModel): class PrinterUpdate (line 37) | class PrinterUpdate(BaseModel): class PrinterResponse (line 58) | class PrinterResponse(PrinterBase): class Config (line 72) | class Config: method from_orm_with_roi (line 76) | def from_orm_with_roi(cls, printer) -> "PrinterResponse": class HMSErrorResponse (line 116) | class HMSErrorResponse(BaseModel): class AMSTray (line 123) | class AMSTray(BaseModel): class AMSUnit (line 142) | class AMSUnit(BaseModel): class NozzleInfoResponse (line 157) | class NozzleInfoResponse(BaseModel): class NozzleRackSlot (line 162) | class NozzleRackSlot(BaseModel): class AmsLabelBody (line 177) | class AmsLabelBody(BaseModel): class PrintOptionsResponse (line 182) | class PrintOptionsResponse(BaseModel): class PrinterStatus (line 204) | class PrinterStatus(BaseModel): FILE: backend/app/schemas/project.py class ProjectCreate (line 6) | class ProjectCreate(BaseModel): class ProjectUpdate (line 22) | class ProjectUpdate(BaseModel): class ProjectStats (line 39) | class ProjectStats(BaseModel): class ProjectChildPreview (line 64) | class ProjectChildPreview(BaseModel): class ProjectResponse (line 74) | class ProjectResponse(BaseModel): class Config (line 99) | class Config: class ArchivePreview (line 103) | class ArchivePreview(BaseModel): class ProjectListResponse (line 114) | class ProjectListResponse(BaseModel): class Config (line 136) | class Config: class BatchAddArchives (line 140) | class BatchAddArchives(BaseModel): class BatchAddQueueItems (line 146) | class BatchAddQueueItems(BaseModel): class BOMItemCreate (line 153) | class BOMItemCreate(BaseModel): class BOMItemUpdate (line 165) | class BOMItemUpdate(BaseModel): class BOMItemResponse (line 178) | class BOMItemResponse(BaseModel): class Config (line 197) | class Config: class TimelineEvent (line 202) | class TimelineEvent(BaseModel): class BOMItemExport (line 213) | class BOMItemExport(BaseModel): class LinkedFolderExport (line 225) | class LinkedFolderExport(BaseModel): class ProjectExport (line 231) | class ProjectExport(BaseModel): class ProjectImport (line 249) | class ProjectImport(BaseModel): FILE: backend/app/schemas/settings.py class AppSettings (line 6) | class AppSettings(BaseModel): class AppSettingsUpdate (line 291) | class AppSettingsUpdate(BaseModel): method validate_gcode_snippets (line 394) | def validate_gcode_snippets(cls, v: str | None) -> str | None: method validate_ldap_group_mapping (line 407) | def validate_ldap_group_mapping(cls, v: str | None) -> str | None: method validate_obico_enabled_printers (line 420) | def validate_obico_enabled_printers(cls, v: str | None) -> str | None: method validate_obico_sensitivity (line 433) | def validate_obico_sensitivity(cls, v: str | None) -> str | None: method validate_obico_action (line 442) | def validate_obico_action(cls, v: str | None) -> str | None: method validate_default_sidebar_order (line 451) | def validate_default_sidebar_order(cls, v: str | None) -> str | None: FILE: backend/app/schemas/smart_plug.py class SmartPlugBase (line 7) | class SmartPlugBase(BaseModel): method validate_plug_type_fields (line 85) | def validate_plug_type_fields(self) -> "SmartPlugBase": class SmartPlugCreate (line 107) | class SmartPlugCreate(SmartPlugBase): class SmartPlugUpdate (line 111) | class SmartPlugUpdate(BaseModel): class SmartPlugResponse (line 174) | class SmartPlugResponse(SmartPlugBase): class Config (line 183) | class Config: class SmartPlugControl (line 187) | class SmartPlugControl(BaseModel): class SmartPlugEnergy (line 191) | class SmartPlugEnergy(BaseModel): class SmartPlugStatus (line 205) | class SmartPlugStatus(BaseModel): class SmartPlugTestConnection (line 212) | class SmartPlugTestConnection(BaseModel): class HATestConnectionRequest (line 219) | class HATestConnectionRequest(BaseModel): class HATestConnectionResponse (line 226) | class HATestConnectionResponse(BaseModel): class HAEntity (line 234) | class HAEntity(BaseModel): class HASensorEntity (line 243) | class HASensorEntity(BaseModel): class RESTTestConnectionRequest (line 252) | class RESTTestConnectionRequest(BaseModel): class RESTTestConnectionResponse (line 260) | class RESTTestConnectionResponse(BaseModel): FILE: backend/app/schemas/spool.py class SpoolBase (line 6) | class SpoolBase(BaseModel): class SpoolCreate (line 31) | class SpoolCreate(SpoolBase): class SpoolBulkCreate (line 35) | class SpoolBulkCreate(BaseModel): class SpoolUpdate (line 40) | class SpoolUpdate(BaseModel): class SpoolKProfileBase (line 63) | class SpoolKProfileBase(BaseModel): class SpoolKProfileResponse (line 74) | class SpoolKProfileResponse(SpoolKProfileBase): class Config (line 79) | class Config: class SpoolResponse (line 83) | class SpoolResponse(SpoolBase): class Config (line 102) | class Config: class SpoolAssignmentCreate (line 106) | class SpoolAssignmentCreate(BaseModel): class SpoolAssignmentResponse (line 113) | class SpoolAssignmentResponse(BaseModel): class Config (line 127) | class Config: FILE: backend/app/schemas/spool_usage.py class SpoolUsageHistoryResponse (line 6) | class SpoolUsageHistoryResponse(BaseModel): class Config (line 17) | class Config: FILE: backend/app/schemas/spoolbuddy.py class DeviceRegisterRequest (line 8) | class DeviceRegisterRequest(BaseModel): class DeviceResponse (line 23) | class DeviceResponse(BaseModel): class Config (line 53) | class Config: class HeartbeatRequest (line 57) | class HeartbeatRequest(BaseModel): class HeartbeatResponse (line 69) | class HeartbeatResponse(BaseModel): class TagScannedRequest (line 82) | class TagScannedRequest(BaseModel): class TagRemovedRequest (line 91) | class TagRemovedRequest(BaseModel): class ScaleReadingRequest (line 99) | class ScaleReadingRequest(BaseModel): class UpdateSpoolWeightRequest (line 106) | class UpdateSpoolWeightRequest(BaseModel): class SetTareRequest (line 114) | class SetTareRequest(BaseModel): class SetCalibrationFactorRequest (line 118) | class SetCalibrationFactorRequest(BaseModel): class CalibrationResponse (line 124) | class CalibrationResponse(BaseModel): class WriteTagRequest (line 132) | class WriteTagRequest(BaseModel): class WriteTagResultRequest (line 137) | class WriteTagResultRequest(BaseModel): class DisplaySettingsRequest (line 145) | class DisplaySettingsRequest(BaseModel): class SystemConfigRequest (line 150) | class SystemConfigRequest(BaseModel): class SystemCommandRequest (line 155) | class SystemCommandRequest(BaseModel): class SystemCommandResultRequest (line 159) | class SystemCommandResultRequest(BaseModel): class DiagnosticResultRequest (line 168) | class DiagnosticResultRequest(BaseModel): FILE: backend/app/schemas/timelapse.py class TimelapseInfoResponse (line 6) | class TimelapseInfoResponse(BaseModel): class ThumbnailResponse (line 18) | class ThumbnailResponse(BaseModel): class ProcessResponse (line 25) | class ProcessResponse(BaseModel): FILE: backend/app/schemas/user_notifications.py class UserEmailPreferenceResponse (line 6) | class UserEmailPreferenceResponse(BaseModel): class Config (line 14) | class Config: class UserEmailPreferenceUpdate (line 18) | class UserEmailPreferenceUpdate(BaseModel): FILE: backend/app/services/archive.py function _copy_and_fsync (line 23) | def _copy_and_fsync(src: Path, dst: Path, chunk_size: int = 1024 * 1024)... class ThreeMFParser (line 44) | class ThreeMFParser: method __init__ (line 47) | def __init__(self, file_path: Path, plate_number: int | None = None): method parse (line 52) | def parse(self) -> dict: method _parse_slice_info (line 93) | def _parse_slice_info(self, zf: zipfile.ZipFile): method _parse_project_settings (line 208) | def _parse_project_settings(self, zf: zipfile.ZipFile): method _parse_gcode_header (line 222) | def _parse_gcode_header(self, zf: zipfile.ZipFile): method _extract_filament_info (line 252) | def _extract_filament_info(self, data: dict): method _extract_print_settings (line 293) | def _extract_print_settings(self, data: dict): method _extract_settings_from_content (line 340) | def _extract_settings_from_content(self, content: str): method _parse_3dmodel (line 364) | def _parse_3dmodel(self, zf: zipfile.ZipFile): method _extract_thumbnail (line 409) | def _extract_thumbnail(self, zf: zipfile.ZipFile): function extract_printable_objects_from_3mf (line 436) | def extract_printable_objects_from_3mf( class ProjectPageParser (line 539) | class ProjectPageParser: method __init__ (line 542) | def __init__(self, file_path: Path): method parse (line 545) | def parse(self, archive_id: int) -> dict: method get_image (line 656) | def get_image(self, image_path: str) -> tuple[bytes, str] | None: method update_metadata (line 680) | def update_metadata(self, updates: dict) -> bool: class ArchiveService (line 744) | class ArchiveService: method __init__ (line 747) | def __init__(self, db: AsyncSession): method compute_file_hash (line 751) | def compute_file_hash(file_path: Path) -> str: method get_duplicate_hashes_and_names (line 760) | async def get_duplicate_hashes_and_names(self) -> tuple[set[str], set[... method find_duplicates (line 791) | async def find_duplicates( method archive_print (line 880) | async def archive_print( method get_archive (line 1061) | async def get_archive(self, archive_id: int) -> PrintArchive | None: method update_archive_status (line 1072) | async def update_archive_status( method list_archives (line 1093) | async def list_archives( method delete_archive (line 1129) | async def delete_archive(self, archive_id: int) -> bool: method attach_timelapse (line 1187) | async def attach_timelapse( function _convert_timelapse_to_mp4 (line 1227) | async def _convert_timelapse_to_mp4(archive_id: int, source_path: Path) ... FILE: backend/app/services/archive_comparison.py class ArchiveComparisonService (line 8) | class ArchiveComparisonService: method __init__ (line 24) | def __init__(self, db: AsyncSession): method compare_archives (line 27) | async def compare_archives(self, archive_ids: list[int]) -> dict: method _analyze_success_correlation (line 117) | def _analyze_success_correlation(self, archives: list[PrintArchive]) -... method find_similar_archives (line 180) | async def find_similar_archives( FILE: backend/app/services/background_dispatch.py class DispatchJobCancelled (line 38) | class DispatchJobCancelled(Exception): class DispatchEnqueueRejected (line 42) | class DispatchEnqueueRejected(Exception): class PrintDispatchJob (line 47) | class PrintDispatchJob: class ActiveDispatchState (line 62) | class ActiveDispatchState: class BackgroundDispatchService (line 69) | class BackgroundDispatchService: method __init__ (line 70) | def __init__(self): method _printer_is_busy_printing (line 86) | def _printer_is_busy_printing(printer_id: int) -> bool: method start (line 92) | async def start(self): method stop (line 99) | async def stop(self): method dispatch_reprint_archive (line 128) | async def dispatch_reprint_archive( method get_state (line 150) | async def get_state(self) -> dict[str, Any]: method dispatch_print_library_file (line 155) | async def dispatch_print_library_file( method cancel_job (line 181) | async def cancel_job(self, job_id: int) -> dict[str, Any]: method _dispatch (line 255) | async def _dispatch( method _dispatcher_loop (line 320) | async def _dispatcher_loop(self): method _run_active_job (line 368) | async def _run_active_job(self, job: PrintDispatchJob): method _set_active_message (line 382) | async def _set_active_message(self, job: PrintDispatchJob, message: str): method _set_active_upload_progress (line 400) | async def _set_active_upload_progress(self, job: PrintDispatchJob, upl... method _mark_job_finished (line 420) | async def _mark_job_finished(self, job: PrintDispatchJob, *, failed: b... method _mark_job_cancelled (line 452) | async def _mark_job_cancelled(self, job: PrintDispatchJob): method _is_cancel_requested (line 476) | def _is_cancel_requested(self, job_id: int) -> bool: method _raise_if_cancel_requested (line 479) | def _raise_if_cancel_requested(self, job: PrintDispatchJob): method _build_state_payload_unlocked (line 483) | def _build_state_payload_unlocked(self, recent_event: dict[str, Any] |... method _process_job (line 537) | async def _process_job(self, job: PrintDispatchJob): method _run_reprint_archive (line 546) | async def _run_reprint_archive(self, job: PrintDispatchJob): method _run_print_library_file (line 701) | async def _run_print_library_file(self, job: PrintDispatchJob): method _verify_print_response (line 898) | async def _verify_print_response( method _cleanup_sd_card_file (line 936) | async def _cleanup_sd_card_file( method _resolve_plate_id (line 949) | def _resolve_plate_id(file_path: Path, requested_plate_id: int | None)... method _is_sliced_file (line 966) | def _is_sliced_file(filename: str) -> bool: FILE: backend/app/services/bambu_cloud.py class BambuCloudError (line 18) | class BambuCloudError(Exception): class BambuCloudAuthError (line 24) | class BambuCloudAuthError(BambuCloudError): function set_shared_http_client (line 33) | def set_shared_http_client(client: httpx.AsyncClient | None) -> None: class BambuCloudService (line 45) | class BambuCloudService: method __init__ (line 48) | def __init__(self, region: str = "global", client: httpx.AsyncClient |... method is_authenticated (line 67) | def is_authenticated(self) -> bool: method _get_headers (line 73) | def _get_headers(self) -> dict: method login_request (line 83) | async def login_request(self, email: str, password: str) -> dict: method verify_code (line 141) | async def verify_code(self, email: str, code: str) -> dict: method verify_totp (line 168) | async def verify_totp(self, tfa_key: str, code: str) -> dict: method _set_tokens (line 248) | def _set_tokens(self, data: dict): method set_token (line 255) | def set_token(self, access_token: str): method logout (line 260) | def logout(self): method get_user_profile (line 266) | async def get_user_profile(self) -> dict: method get_slicer_settings (line 284) | async def get_slicer_settings(self, version: str = "02.04.00.70") -> d... method get_setting_detail (line 311) | async def get_setting_detail(self, setting_id: str) -> dict: method create_setting (line 329) | async def create_setting( method update_setting (line 378) | async def update_setting(self, setting_id: str, name: str | None = Non... method delete_setting (line 463) | async def delete_setting(self, setting_id: str) -> dict: method get_devices (line 491) | async def get_devices(self) -> dict: method get_firmware_version (line 509) | async def get_firmware_version(self, device_id: str) -> dict: method close (line 539) | async def close(self): FILE: backend/app/services/bambu_ftp.py class FileNotOnPrinterError (line 20) | class FileNotOnPrinterError(Exception): class ImplicitFTP_TLS (line 31) | class ImplicitFTP_TLS(FTP_TLS): method __init__ (line 40) | def __init__(self, *args, skip_session_reuse: bool = False, **kwargs): method connect (line 48) | def connect(self, host="", port=990, timeout=-999, source_address=None): method ntransfercmd (line 67) | def ntransfercmd(self, cmd, rest=None): class BambuFTPClient (line 88) | class BambuFTPClient: method __init__ (line 106) | def __init__( method _is_a1_model (line 121) | def _is_a1_model(self) -> bool: method _get_cached_mode (line 127) | def _get_cached_mode(self) -> str | None: method cache_mode (line 132) | def cache_mode(cls, ip_address: str, mode: str): method _should_use_prot_c (line 137) | def _should_use_prot_c(self) -> bool: method connect (line 149) | def connect(self) -> bool: method disconnect (line 194) | def disconnect(self): method list_files (line 203) | def list_files(self, path: str = "/") -> list[dict]: method download_file (line 262) | def download_file(self, remote_path: str) -> bytes | None: method download_to_file (line 274) | def download_to_file(self, remote_path: str, local_path: Path) -> bool: method diagnose_storage (line 312) | def diagnose_storage(self) -> dict: method upload_file (line 368) | def upload_file( method upload_bytes (line 504) | def upload_bytes(self, data: bytes, remote_path: str) -> bool: method delete_file (line 544) | def delete_file(self, remote_path: str) -> bool: method get_file_size (line 556) | def get_file_size(self, remote_path: str) -> int | None: method get_storage_info (line 566) | def get_storage_info(self) -> dict | None: function normalize_3mf_name (line 634) | def normalize_3mf_name(name: str) -> str: function cache_3mf_download (line 649) | def cache_3mf_download(printer_id: int, name: str, local_path: Path) -> ... function get_cached_3mf (line 654) | def get_cached_3mf(printer_id: int, name: str) -> Path | None: function clear_3mf_cache (line 667) | def clear_3mf_cache(printer_id: int | None = None, delete_files: bool = ... function download_file_async (line 692) | async def download_file_async( function download_file_try_paths_async (line 806) | async def download_file_try_paths_async( function upload_file_async (line 844) | async def upload_file_async( function list_files_async (line 922) | async def list_files_async( function delete_file_async (line 954) | async def delete_file_async( function download_file_bytes_async (line 981) | async def download_file_bytes_async( function get_storage_info_async (line 1008) | async def get_storage_info_async( function get_ftp_retry_settings (line 1034) | async def get_ftp_retry_settings() -> tuple[bool, int, float, float]: function with_ftp_retry (line 1051) | async def with_ftp_retry( FILE: backend/app/services/bambu_mqtt.py class MQTTLogEntry (line 35) | class MQTTLogEntry: class HMSError (line 45) | class HMSError: class KProfile (line 56) | class KProfile: class NozzleInfo (line 73) | class NozzleInfo: class PrintOptions (line 81) | class PrintOptions: class PrinterState (line 104) | class PrinterState: function get_stage_name (line 260) | def get_stage_name(stage: int) -> str: class BambuMQTTClient (line 265) | class BambuMQTTClient: method __init__ (line 276) | def __init__( method topic_subscribe (line 377) | def topic_subscribe(self) -> str: method topic_publish (line 381) | def topic_publish(self) -> str: method is_stale (line 387) | def is_stale(self) -> bool: method check_staleness (line 399) | def check_staleness(self) -> bool: method force_reconnect_stale_session (line 431) | def force_reconnect_stale_session(self, reason: str) -> None: method _on_connect (line 448) | def _on_connect(self, client, userdata, flags, rc, properties=None): method _on_subscribe (line 497) | def _on_subscribe(self, client, userdata, mid, reason_code_list, prope... method _on_disconnect (line 522) | def _on_disconnect(self, client, userdata, disconnect_flags=None, rc=N... method _on_message (line 575) | def _on_message(self, client, userdata, msg): method _handle_request_message (line 613) | def _handle_request_message(self, data: dict) -> None: method _process_message (line 627) | def _process_message(self, payload: dict): method _handle_system_response (line 791) | def _handle_system_response(self, data: dict): method _handle_version_info (line 807) | def _handle_version_info(self, data: dict): method _apply_ams_version_cache (line 929) | def _apply_ams_version_cache(self, ams_list: list) -> None: method _parse_xcam_data (line 965) | def _parse_xcam_data(self, xcam_data): method _resolve_local_slot_from_mapping (line 1176) | def _resolve_local_slot_from_mapping(local_slot: int, mapping_raw: lis... method _handle_ams_data (line 1203) | def _handle_ams_data(self, ams_data): method _update_state (line 1688) | def _update_state(self, data: dict): method _request_push_all (line 2747) | def _request_push_all(self): method _probe_developer_mode (line 2753) | def _probe_developer_mode(self): method _handle_dev_mode_probe_response (line 2800) | def _handle_dev_mode_probe_response(self, data: dict): method _request_version (line 2821) | def _request_version(self): method request_status_update (line 2834) | def request_status_update(self) -> bool: method _request_accessories (line 2852) | def _request_accessories(self): method _prime_kprofile_request (line 2866) | def _prime_kprofile_request(self): method connect (line 2885) | def connect(self, loop: asyncio.AbstractEventLoop | None = None): method start_print (line 2925) | def start_print( method stop_print (line 3091) | def stop_print(self) -> bool: method set_xcam_option (line 3100) | def set_xcam_option( method _set_print_option (line 3196) | def _set_print_option(self, option_name: str, enabled: bool) -> bool: method start_calibration (line 3240) | def start_calibration( method disconnect (line 3308) | def disconnect(self, timeout: float = 0): method send_command (line 3318) | def send_command(self, command: dict): method enable_logging (line 3333) | def enable_logging(self, enabled: bool = True): method get_logs (line 3338) | def get_logs(self) -> list[MQTTLogEntry]: method clear_logs (line 3342) | def clear_logs(self): method logging_enabled (line 3347) | def logging_enabled(self) -> bool: method send_drying_command (line 3351) | def send_drying_command( method _handle_kprofile_response (line 3393) | def _handle_kprofile_response(self, data: dict): method get_kprofiles (line 3486) | async def get_kprofiles( method set_kprofile (line 3558) | def set_kprofile( method set_kprofiles_batch (line 3638) | def set_kprofiles_batch( method delete_kprofile (line 3706) | def delete_kprofile( method pause_print (line 3782) | def pause_print(self) -> bool: method resume_print (line 3793) | def resume_print(self) -> bool: method clear_hms_errors (line 3804) | def clear_hms_errors(self) -> bool: method skip_objects (line 3816) | def skip_objects(self, object_ids: list[int]) -> bool: method send_gcode (line 3861) | def send_gcode(self, gcode: str) -> bool: method set_bed_temperature (line 3883) | def set_bed_temperature(self, target: int) -> bool: method set_nozzle_temperature (line 3894) | def set_nozzle_temperature(self, target: int, nozzle: int = 0) -> bool: method set_chamber_temperature (line 3915) | def set_chamber_temperature(self, target: int) -> bool: method set_print_speed (line 3938) | def set_print_speed(self, mode: int) -> bool: method set_fan_speed (line 3960) | def set_fan_speed(self, fan: int, speed: int) -> bool: method set_part_fan (line 3977) | def set_part_fan(self, speed: int) -> bool: method set_aux_fan (line 3981) | def set_aux_fan(self, speed: int) -> bool: method set_chamber_fan (line 3985) | def set_chamber_fan(self, speed: int) -> bool: method set_airduct_mode (line 3989) | def set_airduct_mode(self, mode: str) -> bool: method set_chamber_light (line 4017) | def set_chamber_light(self, on: bool) -> bool: method select_extruder (line 4050) | def select_extruder(self, extruder: int) -> bool: method home_axes (line 4081) | def home_axes(self, axes: str = "XYZ") -> bool: method move_axis (line 4092) | def move_axis(self, axis: str, distance: float, speed: int = 3000) -> ... method disable_motors (line 4112) | def disable_motors(self) -> bool: method enable_motors (line 4123) | def enable_motors(self) -> bool: method ams_load_filament (line 4131) | def ams_load_filament(self, tray_id: int, extruder_id: int | None = No... method ams_unload_filament (line 4182) | def ams_unload_filament(self) -> bool: method ams_control (line 4236) | def ams_control(self, action: str) -> bool: method ams_refresh_tray (line 4258) | def ams_refresh_tray(self, ams_id: int, tray_id: int) -> tuple[bool, s... method ams_set_filament_setting (line 4296) | def ams_set_filament_setting( method reset_ams_slot (line 4381) | def reset_ams_slot(self, ams_id: int, tray_id: int) -> bool: method extrusion_cali_sel (line 4439) | def extrusion_cali_sel( method extrusion_cali_set (line 4520) | def extrusion_cali_set( method set_timelapse (line 4583) | def set_timelapse(self, enable: bool) -> bool: method set_liveview (line 4607) | def set_liveview(self, enable: bool) -> bool: FILE: backend/app/services/bug_report.py function _check_rate_limit (line 20) | def _check_rate_limit() -> bool: function submit_report (line 30) | async def submit_report( FILE: backend/app/services/camera.py function get_ffmpeg_path (line 32) | def get_ffmpeg_path() -> str | None: function supports_rtsp (line 69) | def supports_rtsp(model: str | None) -> bool: function get_camera_port (line 98) | def get_camera_port(model: str | None) -> int: function rewrite_rtsp_request_url (line 109) | def rewrite_rtsp_request_url(data: bytes, proxy_url: bytes, real_url: by... function create_tls_proxy (line 127) | async def create_tls_proxy(target_host: str, target_port: int) -> tuple[... function is_chamber_image_model (line 222) | def is_chamber_image_model(model: str | None) -> bool: function build_camera_url (line 230) | def build_camera_url(ip_address: str, access_code: str, model: str | Non... function _create_chamber_auth_payload (line 236) | def _create_chamber_auth_payload(access_code: str) -> bytes: function _create_ssl_context (line 261) | def _create_ssl_context() -> ssl.SSLContext: function read_chamber_image_frame (line 272) | async def read_chamber_image_frame( function generate_chamber_image_stream (line 353) | async def generate_chamber_image_stream( function read_next_chamber_frame (line 384) | async def read_next_chamber_frame(reader: asyncio.StreamReader, timeout:... function capture_camera_frame (line 416) | async def capture_camera_frame( function capture_camera_frame_bytes (line 453) | async def capture_camera_frame_bytes( function capture_finish_photo (line 551) | async def capture_finish_photo( function test_camera_connection (line 595) | async def test_camera_connection( FILE: backend/app/services/discovery.py function is_running_in_docker (line 26) | def is_running_in_docker() -> bool: class DiscoveredPrinter (line 68) | class DiscoveredPrinter: method to_dict (line 77) | def to_dict(self) -> dict: class PrinterDiscoveryService (line 87) | class PrinterDiscoveryService: method __init__ (line 90) | def __init__(self): method is_running (line 96) | def is_running(self) -> bool: method discovered_printers (line 100) | def discovered_printers(self) -> list[DiscoveredPrinter]: method clear (line 103) | def clear(self): method start (line 107) | async def start(self, duration: float = 10.0): method stop (line 116) | async def stop(self): method _discover (line 127) | async def _discover(self, duration: float): method _discover_alternative (line 211) | async def _discover_alternative(self, duration: float): method _handle_response (line 259) | def _handle_response(self, response: str, ip_address: str): class SubnetScanner (line 314) | class SubnetScanner: method __init__ (line 321) | def __init__(self): method is_running (line 328) | def is_running(self) -> bool: method discovered_printers (line 332) | def discovered_printers(self) -> list[DiscoveredPrinter]: method progress (line 336) | def progress(self) -> tuple[int, int]: method scan_subnet (line 340) | async def scan_subnet(self, subnet: str, timeout: float = 1.0) -> list... method _probe_host (line 389) | async def _probe_host(self, ip: str, timeout: float): method _get_printer_info_ssdp (line 421) | async def _get_printer_info_ssdp(self, ip: str, timeout: float) -> tup... method _check_port (line 473) | async def _check_port(self, ip: str, port: int, timeout: float) -> bool: method stop (line 491) | def stop(self): class TasmotaScanner (line 496) | class TasmotaScanner: method __init__ (line 501) | def __init__(self): method is_running (line 508) | def is_running(self) -> bool: method discovered_devices (line 512) | def discovered_devices(self) -> list[dict]: method progress (line 516) | def progress(self) -> tuple[int, int]: method scan_range (line 520) | async def scan_range(self, from_ip: str, to_ip: str, timeout: float = ... method _probe_host (line 582) | async def _probe_host(self, ip: str): method _do_probe (line 592) | async def _do_probe(self, ip: str): method stop (line 684) | def stop(self): FILE: backend/app/services/email_service.py function generate_secure_password (line 26) | def generate_secure_password(length: int = 16) -> str: function get_notification_template (line 59) | async def get_notification_template(db: AsyncSession, event_type: str) -... function render_template (line 73) | def render_template(template_str: str, variables: dict[str, Any]) -> str: function get_smtp_settings (line 91) | async def get_smtp_settings(db: AsyncSession) -> SMTPSettings | None: function save_smtp_settings (line 146) | async def save_smtp_settings(db: AsyncSession, smtp_settings: SMTPSettin... function send_email (line 176) | def send_email( function create_welcome_email (line 242) | def create_welcome_email(username: str, password: str, login_url: str) -... function create_password_reset_email (line 308) | def create_password_reset_email(username: str, password: str, login_url:... function create_password_reset_link_email (line 382) | def create_password_reset_link_email(username: str, reset_url: str) -> t... function create_password_reset_link_email_from_template (line 430) | async def create_password_reset_link_email_from_template( function create_welcome_email_from_template (line 447) | async def create_welcome_email_from_template( function create_password_reset_email_from_template (line 509) | async def create_password_reset_email_from_template( function send_user_print_notification (line 577) | async def send_user_print_notification( FILE: backend/app/services/export.py class ExportService (line 13) | class ExportService: method __init__ (line 70) | def __init__(self, db: AsyncSession): method export_archives (line 73) | async def export_archives( method export_stats (line 155) | async def export_stats( method _archive_to_row (line 239) | def _archive_to_row(self, archive: PrintArchive, fields: list[str]) ->... method _generate_csv (line 254) | def _generate_csv(self, headers: list[str], rows: list[list]) -> bytes: method _generate_csv_simple (line 262) | def _generate_csv_simple(self, rows: list[list]) -> bytes: method _generate_xlsx (line 269) | def _generate_xlsx(self, headers: list[str], rows: list[list], fields:... method _generate_xlsx_simple (line 316) | def _generate_xlsx_simple(self, rows: list[list]) -> bytes: FILE: backend/app/services/external_camera.py function _sanitize_camera_url (line 23) | def _sanitize_camera_url(url: str, allowed_schemes: tuple[str, ...] = ("... function _validate_camera_url (line 87) | def _validate_camera_url(url: str, allowed_schemes: tuple[str, ...] = ("... function list_usb_cameras (line 100) | def list_usb_cameras() -> list[dict]: function get_ffmpeg_path (line 163) | def get_ffmpeg_path() -> str | None: function capture_frame (line 176) | async def capture_frame(url: str, camera_type: str, timeout: int = 15) -... function _capture_usb_frame (line 201) | async def _capture_usb_frame(device: str, timeout: int) -> bytes | None: function _capture_mjpeg_frame (line 282) | async def _capture_mjpeg_frame(url: str, timeout: int) -> bytes | None: function _capture_rtsp_frame (line 338) | async def _capture_rtsp_frame(url: str, timeout: int) -> bytes | None: function _capture_snapshot (line 430) | async def _capture_snapshot(url: str, timeout: int) -> bytes | None: function test_connection (line 469) | async def test_connection(url: str, camera_type: str) -> dict: function generate_mjpeg_stream (line 508) | async def generate_mjpeg_stream(url: str, camera_type: str, fps: int = 1... function _format_mjpeg_frame (line 579) | def _format_mjpeg_frame(frame: bytes) -> bytes: function _stream_mjpeg (line 589) | async def _stream_mjpeg(url: str) -> AsyncGenerator[bytes, None]: function _stream_rtsp (line 640) | async def _stream_rtsp(url: str, fps: int) -> AsyncGenerator[bytes, None]: function _stream_usb (line 777) | async def _stream_usb(device: str, fps: int) -> AsyncGenerator[bytes, No... FILE: backend/app/services/failure_analysis.py class FailureAnalysisService (line 11) | class FailureAnalysisService: method __init__ (line 14) | def __init__(self, db: AsyncSession): method analyze_failures (line 17) | async def analyze_failures( FILE: backend/app/services/firmware_check.py class FirmwareVersion (line 104) | class FirmwareVersion: class FirmwareCheckService (line 113) | class FirmwareCheckService: method __init__ (line 116) | def __init__(self): method _get_build_id (line 129) | async def _get_build_id(self) -> str | None: method _fetch_version_from_wiki (line 151) | async def _fetch_version_from_wiki(self, api_key: str) -> str | None: method _fetch_all_versions_from_wiki (line 159) | async def _fetch_all_versions_from_wiki(self, api_key: str) -> list[tu... method _fetch_all_versions_from_download_page (line 214) | async def _fetch_all_versions_from_download_page(self, api_key: str) -... method _fetch_from_download_page (line 246) | async def _fetch_from_download_page(self, api_key: str) -> FirmwareVer... method _fetch_firmware_versions (line 251) | async def _fetch_firmware_versions(self, api_key: str) -> FirmwareVers... method get_latest_version (line 278) | async def get_latest_version(self, model: str) -> FirmwareVersion | None: method _resolve_api_key (line 319) | def _resolve_api_key(self, model: str) -> str | None: method _version_tuple (line 328) | def _version_tuple(v: str) -> tuple[int, ...]: method get_available_versions (line 334) | async def get_available_versions(self, model: str) -> list[FirmwareVer... method get_version_info (line 378) | async def get_version_info(self, model: str, version: str) -> Firmware... method check_for_update (line 385) | async def check_for_update(self, model: str, current_version: str) -> ... method get_all_latest_versions (line 450) | async def get_all_latest_versions(self) -> dict[str, FirmwareVersion]: method _get_firmware_cache_dir (line 466) | def _get_firmware_cache_dir(self) -> Path: method get_firmware_file_info (line 472) | async def get_firmware_file_info(self, model: str, version: str | None... method download_firmware (line 496) | async def download_firmware( method close (line 571) | async def close(self): function get_firmware_service (line 580) | def get_firmware_service() -> FirmwareCheckService: FILE: backend/app/services/firmware_update.py class FirmwareUploadStatus (line 33) | class FirmwareUploadStatus(StrEnum): class FirmwareUploadState (line 45) | class FirmwareUploadState: function get_upload_state (line 60) | def get_upload_state(printer_id: int) -> FirmwareUploadState: function reset_upload_state (line 67) | def reset_upload_state(printer_id: int): class FirmwareUpdateService (line 72) | class FirmwareUpdateService: method prepare_update (line 78) | async def prepare_update( method start_upload (line 209) | async def start_upload( method _do_upload (line 261) | async def _do_upload( method _broadcast_progress (line 369) | async def _broadcast_progress(self, printer_id: int, state: FirmwareUp... function get_firmware_update_service (line 389) | def get_firmware_update_service() -> FirmwareUpdateService: FILE: backend/app/services/github_backup.py class GitHubBackupService (line 37) | class GitHubBackupService: method __init__ (line 40) | def __init__(self): method _get_client (line 47) | async def _get_client(self) -> httpx.AsyncClient: method start_scheduler (line 53) | async def start_scheduler(self): method stop_scheduler (line 60) | def stop_scheduler(self): method _scheduler_loop (line 67) | async def _scheduler_loop(self): method _check_scheduled_backups (line 79) | async def _check_scheduled_backups(self): method _calculate_next_run (line 100) | def _calculate_next_run(self, schedule_type: str, from_time: datetime ... method test_connection (line 106) | async def test_connection(self, repo_url: str, token: str) -> dict: method _parse_repo_url (line 179) | def _parse_repo_url(self, url: str) -> tuple[str, str]: method run_backup (line 199) | async def run_backup(self, config_id: int, trigger: str = "manual") ->... method _collect_backup_data (line 313) | async def _collect_backup_data(self, db: AsyncSession, config: GitHubB... method _collect_kprofiles (line 369) | async def _collect_kprofiles(self, db: AsyncSession, files: dict): method _collect_cloud_profiles (line 415) | async def _collect_cloud_profiles(self, db: AsyncSession, files: dict): method _collect_settings (line 476) | async def _collect_settings(self, db: AsyncSession, files: dict): method _collect_spools (line 490) | async def _collect_spools(self, db: AsyncSession, files: dict): method _collect_archives (line 559) | async def _collect_archives(self, db: AsyncSession, files: dict): method _push_to_github (line 612) | async def _push_to_github(self, config: GitHubBackupConfig, files: dic... method _create_branch_and_push (line 747) | async def _create_branch_and_push( method _create_initial_commit (line 796) | async def _create_initial_commit( method is_running (line 860) | def is_running(self) -> bool: method progress (line 865) | def progress(self) -> str | None: method get_logs (line 869) | async def get_logs(self, config_id: int, limit: int = 50, offset: int ... FILE: backend/app/services/hms_errors.py function get_error_description (line 866) | def get_error_description(error_code: str) -> str | None: FILE: backend/app/services/homeassistant.py class HomeAssistantService (line 15) | class HomeAssistantService: method __init__ (line 18) | def __init__(self, timeout: float = 10.0): method configure (line 23) | def configure(self, url: str, token: str): method _headers (line 28) | def _headers(self) -> dict: method get_status (line 34) | async def get_status(self, plug: "SmartPlug") -> dict: method turn_on (line 72) | async def turn_on(self, plug: "SmartPlug") -> bool: method turn_off (line 79) | async def turn_off(self, plug: "SmartPlug") -> bool: method toggle (line 86) | async def toggle(self, plug: "SmartPlug") -> bool: method _call_service (line 93) | async def _call_service(self, plug: "SmartPlug", action: str) -> bool: method get_energy (line 113) | async def get_energy(self, plug: "SmartPlug") -> dict | None: method _get_sensor_value (line 173) | async def _get_sensor_value(self, client: httpx.AsyncClient, entity_id... method _validate_url (line 189) | def _validate_url(url: str) -> str | None: method test_connection (line 202) | async def test_connection(self, url: str, token: str) -> dict: method list_entities (line 237) | async def list_entities(self, url: str, token: str, search: str | None... method list_sensor_entities (line 291) | async def list_sensor_entities(self, url: str, token: str) -> list[dict]: FILE: backend/app/services/layer_timelapse.py function get_ffmpeg_path (line 22) | def get_ffmpeg_path() -> str | None: class TimelapseSession (line 36) | class TimelapseSession: method __post_init__ (line 48) | def __post_init__(self): method capture_layer (line 53) | async def capture_layer(self, layer_num: int) -> bool: method stitch (line 85) | async def stitch(self, output_path: Path, fps: int = 30) -> bool: method cleanup (line 173) | def cleanup(self): function start_session (line 183) | def start_session(printer_id: int, archive_id: int | None, url: str, cam... function get_session (line 209) | def get_session(printer_id: int) -> TimelapseSession | None: function on_layer_change (line 214) | async def on_layer_change(printer_id: int, layer_num: int): function on_print_complete (line 226) | async def on_print_complete(printer_id: int) -> Path | None: function cancel_session (line 262) | def cancel_session(printer_id: int): function get_active_sessions (line 274) | def get_active_sessions() -> dict[int, TimelapseSession]: FILE: backend/app/services/ldap_service.py class LDAPUserInfo (line 22) | class LDAPUserInfo: class LDAPConfig (line 32) | class LDAPConfig: function parse_ldap_config (line 47) | def parse_ldap_config(settings: dict[str, str]) -> LDAPConfig | None: function _create_server (line 76) | def _create_server(config: LDAPConfig) -> Server: function authenticate_ldap_user (line 94) | def authenticate_ldap_user(config: LDAPConfig, username: str, password: ... function resolve_group_mapping (line 230) | def resolve_group_mapping(ldap_groups: list[str], group_mapping: dict[st... function test_ldap_connection (line 249) | def test_ldap_connection(config: LDAPConfig) -> tuple[bool, str]: function _ldap_escape (line 282) | def _ldap_escape(value: str) -> str: FILE: backend/app/services/local_backup.py function _default_backup_dir (line 27) | def _default_backup_dir() -> Path: class LocalBackupService (line 31) | class LocalBackupService: method __init__ (line 34) | def __init__(self): method start_scheduler (line 43) | async def start_scheduler(self): method stop_scheduler (line 52) | def stop_scheduler(self): method _scheduler_loop (line 59) | async def _scheduler_loop(self): method _seed_next_run (line 71) | async def _seed_next_run(self): method _load_settings (line 83) | async def _load_settings(self) -> dict: method _check_scheduled_backup (line 103) | async def _check_scheduled_backup(self): method _calculate_next_run (line 122) | def _calculate_next_run(self, schedule_type: str, time_str: str = "03:... method _resolve_backup_dir (line 153) | def _resolve_backup_dir(self, path_setting: str) -> Path: method run_backup (line 159) | async def run_backup(self, settings: dict | None = None) -> dict: method _prune_backups (line 195) | def _prune_backups(self, backup_dir: Path, retention: int): method get_status (line 209) | def get_status(self) -> dict: method resolve_backup_file (line 219) | def resolve_backup_file(self, path_setting: str, filename: str) -> Pat... method list_backups (line 231) | def list_backups(self, path_setting: str) -> list[dict]: method delete_backup (line 249) | def delete_backup(self, path_setting: str, filename: str) -> dict: FILE: backend/app/services/mqtt_relay.py class MQTTRelayService (line 21) | class MQTTRelayService: method __init__ (line 27) | def __init__(self): method configure (line 41) | async def configure(self, settings: dict) -> bool: method _configure_smart_plug_service (line 83) | async def _configure_smart_plug_service(self, settings: dict): method smart_plug_service (line 96) | def smart_plug_service(self): method _connect (line 104) | async def _connect(self, broker: str, port: int, username: str, passwo... method _on_connect (line 154) | def _on_connect( method _on_disconnect (line 174) | def _on_disconnect( method disconnect (line 194) | async def disconnect(self, timeout: float = 0): method _publish_status (line 210) | def _publish_status(self, status: str): method _publish (line 218) | def _publish(self, topic: str, payload: dict, retain: bool = False): method get_status (line 229) | def get_status(self) -> dict: method on_printer_status (line 243) | async def on_printer_status(self, printer_id: int, state: Any, printer... method on_printer_online (line 286) | async def on_printer_online(self, printer_id: int, printer_name: str, ... method on_printer_offline (line 301) | async def on_printer_offline(self, printer_id: int, printer_name: str,... method on_print_start (line 316) | async def on_print_start( method on_print_complete (line 340) | async def on_print_complete( method on_ams_change (line 372) | async def on_ams_change( method on_printer_error (line 394) | async def on_printer_error( method on_queue_job_added (line 420) | async def on_queue_job_added( method on_queue_job_started (line 442) | async def on_queue_job_started( method on_queue_job_completed (line 466) | async def on_queue_job_completed( method on_maintenance_alert (line 500) | async def on_maintenance_alert( method on_maintenance_acknowledged (line 524) | async def on_maintenance_acknowledged( method on_maintenance_reset (line 544) | async def on_maintenance_reset( method on_archive_created (line 568) | async def on_archive_created( method on_archive_updated (line 590) | async def on_archive_updated( method on_filament_low (line 614) | async def on_filament_low( method on_smart_plug_state (line 640) | async def on_smart_plug_state( method on_smart_plug_energy (line 666) | async def on_smart_plug_energy( FILE: backend/app/services/mqtt_smart_plug.py class SmartPlugMQTTData (line 20) | class SmartPlugMQTTData: class MQTTDataSourceConfig (line 31) | class MQTTDataSourceConfig: class MQTTSmartPlugService (line 40) | class MQTTSmartPlugService: method __init__ (line 46) | def __init__(self): method is_configured (line 64) | def is_configured(self) -> bool: method has_broker_settings (line 68) | def has_broker_settings(self) -> bool: method configure (line 72) | async def configure(self, settings: dict) -> bool: method _connect (line 123) | async def _connect(self) -> bool: method _on_connect (line 179) | def _on_connect( method _on_disconnect (line 198) | def _on_disconnect( method _on_message (line 217) | def _on_message(self, client: mqtt.Client, userdata: Any, msg: mqtt.MQ... method _extract_json_path (line 302) | def _extract_json_path(self, data: dict, path: str) -> Any: method _resubscribe_all (line 321) | def _resubscribe_all(self): method subscribe (line 335) | def subscribe( method _add_subscription (line 414) | def _add_subscription(self, plug_id: int, topic: str, data_type: str): method unsubscribe (line 430) | def unsubscribe(self, plug_id: int): method get_plug_data (line 464) | def get_plug_data(self, plug_id: int) -> SmartPlugMQTTData | None: method is_reachable (line 469) | def is_reachable(self, plug_id: int) -> bool: method disconnect (line 478) | async def disconnect(self, timeout: float = 0): function subscribe_plug_to_mqtt (line 493) | def subscribe_plug_to_mqtt(service: "MQTTSmartPlugService", plug: Any) -... FILE: backend/app/services/network_utils.py function _is_excluded (line 20) | def _is_excluded(name: str) -> bool: function get_network_interfaces (line 25) | def get_network_interfaces() -> list[dict]: function get_all_interface_ips (line 90) | def get_all_interface_ips() -> list[dict]: function _fallback_get_all_ips (line 160) | def _fallback_get_all_ips() -> list[dict]: function find_interface_for_ip (line 172) | def find_interface_for_ip(target_ip: str) -> dict | None: function get_other_interfaces (line 204) | def get_other_interfaces(exclude_ip: str) -> list[dict]: FILE: backend/app/services/notification_service.py class NotificationService (line 24) | class NotificationService: method __init__ (line 27) | def __init__(self): method _get_client (line 33) | async def _get_client(self) -> httpx.AsyncClient: method close (line 39) | async def close(self): method _is_in_quiet_hours (line 44) | def _is_in_quiet_hours(self, provider: NotificationProvider) -> bool: method _get_template (line 73) | async def _get_template(self, db: AsyncSession, event_type: str) -> No... method _render_template (line 87) | def _render_template(self, template_str: str, variables: dict[str, Any... method _format_eta (line 96) | async def _format_eta(self, seconds: int | None, db: AsyncSession) -> ... method _format_duration (line 111) | def _format_duration(self, seconds: int | None) -> str: method _clean_filename (line 121) | def _clean_filename(self, filename: str) -> str: method _build_message_from_template (line 136) | async def _build_message_from_template( method send_test_notification (line 155) | async def send_test_notification( method _send_callmebot (line 188) | async def _send_callmebot(self, config: dict, message: str) -> tuple[b... method _send_ntfy (line 208) | async def _send_ntfy( method _send_pushover (line 252) | async def _send_pushover( method _send_telegram (line 298) | async def _send_telegram(self, config: dict, message: str, image_data:... method _send_email (line 343) | async def _send_email(self, config: dict, subject: str, body: str) -> ... method _send_discord (line 394) | async def _send_discord( method _send_webhook (line 432) | async def _send_webhook( method _send_homeassistant (line 503) | async def _send_homeassistant( method _send_to_provider (line 584) | async def _send_to_provider( method _update_provider_status (line 627) | async def _update_provider_status( method _get_providers_for_event (line 641) | async def _get_providers_for_event( method _log_notification (line 662) | async def _log_notification( method _send_to_providers (line 692) | async def _send_to_providers( method on_print_start (line 759) | async def on_print_start( method on_print_complete (line 843) | async def on_print_complete( method on_print_progress (line 945) | async def on_print_progress( method on_print_missing_spool_assignment (line 983) | async def on_print_missing_spool_assignment( method on_printer_offline (line 1025) | async def on_printer_offline(self, printer_id: int, printer_name: str,... method on_printer_error (line 1038) | async def on_printer_error( method on_plate_not_empty (line 1071) | async def on_plate_not_empty( method on_filament_low (line 1101) | async def on_filament_low( method on_maintenance_due (line 1127) | async def on_maintenance_due( method on_ams_humidity_high (line 1161) | async def on_ams_humidity_high( method on_ams_temperature_high (line 1196) | async def on_ams_temperature_high( method on_ams_ht_humidity_high (line 1231) | async def on_ams_ht_humidity_high( method on_ams_ht_temperature_high (line 1267) | async def on_ams_ht_temperature_high( method on_bed_cooled (line 1303) | async def on_bed_cooled( method on_first_layer_complete (line 1329) | async def on_first_layer_complete( method clear_template_cache (line 1362) | def clear_template_cache(self): method send_user_print_email (line 1366) | async def send_user_print_email( method on_queue_job_added (line 1482) | async def on_queue_job_added( method on_queue_job_assigned (line 1506) | async def on_queue_job_assigned( method on_queue_job_started (line 1530) | async def on_queue_job_started( method on_queue_job_waiting (line 1557) | async def on_queue_job_waiting( method on_queue_job_skipped (line 1578) | async def on_queue_job_skipped( method on_queue_job_failed (line 1602) | async def on_queue_job_failed( method on_queue_completed (line 1626) | async def on_queue_completed( method _queue_for_digest (line 1643) | async def _queue_for_digest( method send_digest (line 1669) | async def send_digest(self, provider_id: int): method check_and_send_digests (line 1740) | async def check_and_send_digests(self): method start_digest_scheduler (line 1768) | def start_digest_scheduler(self): method stop_digest_scheduler (line 1774) | def stop_digest_scheduler(self): method _digest_scheduler_loop (line 1781) | async def _digest_scheduler_loop(self): FILE: backend/app/services/obico_actions.py function execute_action (line 16) | async def execute_action(printer_id: int, action: str, task_name: str, s... function _get_printer_name (line 32) | async def _get_printer_name(printer_id: int) -> str: function _pause_print (line 39) | def _pause_print(printer_id: int) -> None: function _turn_off_linked_plugs (line 50) | async def _turn_off_linked_plugs(printer_id: int) -> None: function _notify (line 66) | async def _notify(printer_id: int, printer_name: str, task_name: str, sc... FILE: backend/app/services/obico_detection.py function _prune_frame_cache (line 47) | def _prune_frame_cache() -> None: function stash_frame (line 55) | async def stash_frame(data: bytes) -> str: function pop_frame (line 64) | async def pop_frame(nonce: str) -> bytes | None: class ObicoDetectionService (line 77) | class ObicoDetectionService: method __init__ (line 80) | def __init__(self): method start (line 96) | async def start(self): method stop (line 102) | def stop(self): method _load_settings (line 110) | async def _load_settings(self) -> dict: method _loop (line 145) | async def _loop(self): method _poll_once (line 164) | async def _poll_once(self, settings: dict): method _capture_frame (line 183) | async def _capture_frame(self, printer_id: int) -> bytes | None: method _check_printer (line 208) | async def _check_printer(self, printer_id: int, status, settings: dict): method _dispatch_action (line 279) | async def _dispatch_action(self, printer_id: int, action: str, task_na... method get_status (line 297) | def get_status(self) -> dict: method test_connection (line 314) | async def test_connection(self, url: str) -> dict: FILE: backend/app/services/obico_smoothing.py function thresholds (line 34) | def thresholds(sensitivity: str) -> tuple[float, float]: class PrintState (line 40) | class PrintState: method update (line 50) | def update(self, current_p: float) -> float: function classify (line 80) | def classify(score: float, sensitivity: str) -> str: function score_from_detections (line 90) | def score_from_detections(detections: list) -> float: FILE: backend/app/services/opentag3d.py function _build_payload (line 24) | def _build_payload(spool: Spool) -> bytes: function encode_opentag3d (line 76) | def encode_opentag3d(spool: Spool) -> bytes: FILE: backend/app/services/orca_profiles.py function get_cached_base_profile (line 30) | async def get_cached_base_profile(name: str, db: AsyncSession) -> dict |... function fetch_and_cache_base_profile (line 51) | async def fetch_and_cache_base_profile(name: str, profile_type: str, db:... function resolve_preset (line 110) | async def resolve_preset(preset_data: dict, profile_type: str, db: Async... function extract_core_fields (line 137) | def extract_core_fields(data: dict) -> dict: function _parse_material_from_name (line 232) | def _parse_material_from_name(name: str) -> str | None: function _parse_vendor_from_name (line 256) | def _parse_vendor_from_name(name: str) -> str | None: function _type_from_path (line 272) | def _type_from_path(zip_entry: str) -> str | None: function _guess_profile_type (line 285) | def _guess_profile_type(data: dict, path_hint: str | None = None) -> str: function import_orca_file (line 345) | async def import_orca_file(filename: str, content: bytes, db: AsyncSessi... function _import_single_preset (line 403) | async def _import_single_preset(data: dict, db: AsyncSession, path_hint:... function refresh_base_cache (line 452) | async def refresh_base_cache(db: AsyncSession) -> dict: function get_cache_status (line 475) | async def get_cache_status(db: AsyncSession) -> dict: function reclassify_presets (line 501) | async def reclassify_presets(db: AsyncSession) -> dict: FILE: backend/app/services/plate_detection.py function _get_calibration_dir (line 27) | def _get_calibration_dir() -> Path: class PlateDetectionResult (line 34) | class PlateDetectionResult: method __init__ (line 37) | def __init__( method to_dict (line 53) | def to_dict(self) -> dict: class PlateDetector (line 64) | class PlateDetector: method __init__ (line 78) | def __init__( method _get_metadata_path (line 101) | def _get_metadata_path(self, printer_id: int) -> Path: method _load_metadata (line 106) | def _load_metadata(self, printer_id: int) -> dict: method _save_metadata (line 119) | def _save_metadata(self, printer_id: int, metadata: dict) -> None: method _get_reference_paths (line 127) | def _get_reference_paths(self, printer_id: int) -> list[Path]: method _get_next_reference_slot (line 137) | def _get_next_reference_slot(self, printer_id: int) -> Path: method _rotate_references (line 148) | def _rotate_references(self, printer_id: int) -> None: method get_references (line 172) | def get_references(self, printer_id: int) -> list[dict]: method update_reference_label (line 197) | def update_reference_label(self, printer_id: int, index: int, label: s... method delete_reference (line 216) | def delete_reference(self, printer_id: int, index: int) -> bool: method get_reference_thumbnail (line 252) | def get_reference_thumbnail(self, printer_id: int, index: int, max_siz... method _extract_roi (line 282) | def _extract_roi(self, frame: np.ndarray) -> tuple[np.ndarray, int, in... method _preprocess_for_comparison (line 296) | def _preprocess_for_comparison(self, frame: np.ndarray) -> np.ndarray: method calibrate (line 310) | def calibrate(self, image_data: bytes, printer_id: int, label: str | N... method get_calibration_count (line 386) | def get_calibration_count(self, printer_id: int) -> int: method has_calibration (line 390) | def has_calibration(self, printer_id: int, plate_type: str | None = No... method delete_calibration (line 394) | def delete_calibration(self, printer_id: int, plate_type: str | None =... method analyze_frame (line 404) | def analyze_frame( function capture_camera_image (line 583) | async def capture_camera_image( function check_plate_empty (line 657) | async def check_plate_empty( function calibrate_plate (line 716) | async def calibrate_plate( function get_calibration_status (line 760) | def get_calibration_status(printer_id: int, plate_type: str | None = Non... function delete_calibration (line 793) | def delete_calibration(printer_id: int, plate_type: str | None = None) -... function is_plate_detection_available (line 802) | def is_plate_detection_available() -> bool: FILE: backend/app/services/print_log.py function write_log_entry (line 16) | async def write_log_entry( FILE: backend/app/services/print_scheduler.py function _canonical_filament_type (line 44) | def _canonical_filament_type(ftype: str) -> str: class PrintScheduler (line 50) | class PrintScheduler: method __init__ (line 66) | def __init__(self): method run (line 75) | async def run(self): method stop (line 88) | def stop(self): method check_queue (line 93) | async def check_queue(self): method _find_idle_printer_for_model (line 427) | async def _find_idle_printer_for_model( method _is_busy_only (line 607) | def _is_busy_only(waiting_reason: str) -> bool: method _get_missing_force_color_slots (line 617) | def _get_missing_force_color_slots(self, printer_id: int, force_overri... method _get_missing_filament_types (line 655) | def _get_missing_filament_types(self, printer_id: int, required_types:... method _count_override_color_matches (line 696) | def _count_override_color_matches(self, printer_id: int, overrides: li... method _compute_ams_mapping_for_printer (line 728) | async def _compute_ams_mapping_for_printer( method _get_filament_requirements (line 791) | async def _get_filament_requirements(self, db: AsyncSession, item: Pri... method _build_loaded_filaments (line 896) | def _build_loaded_filaments(self, status) -> list[dict]: method _normalize_color (line 967) | def _normalize_color(self, color: str | None) -> str: method _normalize_color_for_compare (line 974) | def _normalize_color_for_compare(self, color: str | None) -> str: method _colors_are_similar (line 980) | def _colors_are_similar(self, color1: str | None, color2: str | None, ... method _match_filaments_to_slots (line 998) | def _match_filaments_to_slots( method _is_printer_idle (line 1121) | def _is_printer_idle(self, printer_id: int, require_plate_clear: bool ... method _get_setting (line 1150) | async def _get_setting(self, db: AsyncSession, key: str) -> str | None: method _get_bool_setting (line 1156) | async def _get_bool_setting(self, db: AsyncSession, key: str, default:... method _get_drying_presets (line 1164) | async def _get_drying_presets(self, db: AsyncSession) -> dict[str, dic... method _get_conservative_drying_params (line 1177) | def _get_conservative_drying_params( method _check_auto_drying (line 1216) | async def _check_auto_drying( method _sync_drying_state (line 1415) | def _sync_drying_state(self): method _stop_drying (line 1435) | async def _stop_drying(self, printer_id: int): method _get_smart_plugs (line 1455) | async def _get_smart_plugs(self, db: AsyncSession, printer_id: int) ->... method _power_on_and_wait (line 1460) | async def _power_on_and_wait(self, plug: SmartPlug, printer_id: int, d... method _check_previous_success (line 1515) | async def _check_previous_success(self, db: AsyncSession, item: PrintQ... method _power_off_if_needed (line 1534) | async def _power_off_if_needed(self, db: AsyncSession, item: PrintQueu... method _get_job_name (line 1560) | async def _get_job_name(self, db: AsyncSession, item: PrintQueueItem) ... method _get_printer (line 1574) | async def _get_printer(self, db: AsyncSession, printer_id: int) -> Pri... method _start_print (line 1579) | async def _start_print(self, db: AsyncSession, item: PrintQueueItem): method _watchdog_print_start (line 1955) | async def _watchdog_print_start( FILE: backend/app/services/printer_manager.py function supports_chamber_temp (line 75) | def supports_chamber_temp(model: str | None) -> bool: function has_stg_cur_idle_bug (line 88) | def has_stg_cur_idle_bug(model: str | None) -> bool: function supports_drying (line 118) | def supports_drying(model: str | None, firmware: str | None) -> bool: class PrinterInfo (line 137) | class PrinterInfo: method __init__ (line 140) | def __init__(self, name: str, serial_number: str): class PrinterManager (line 145) | class PrinterManager: method __init__ (line 148) | def __init__(self): method get_printer (line 166) | def get_printer(self, printer_id: int) -> PrinterInfo | None: method set_current_print_user (line 170) | def set_current_print_user(self, printer_id: int, user_id: int, userna... method get_current_print_user (line 174) | def get_current_print_user(self, printer_id: int) -> dict | None: method clear_current_print_user (line 178) | def clear_current_print_user(self, printer_id: int): method is_awaiting_plate_clear (line 182) | def is_awaiting_plate_clear(self, printer_id: int) -> bool: method set_awaiting_plate_clear (line 188) | def set_awaiting_plate_clear(self, printer_id: int, awaiting: bool): method _persist_awaiting_plate_clear (line 204) | async def _persist_awaiting_plate_clear(self, printer_id: int, awaitin... method load_awaiting_plate_clear_from_db (line 216) | async def load_awaiting_plate_clear_from_db(self): method set_event_loop (line 230) | def set_event_loop(self, loop: asyncio.AbstractEventLoop): method set_print_start_callback (line 234) | def set_print_start_callback(self, callback: Callable[[int, dict], Non... method set_print_complete_callback (line 238) | def set_print_complete_callback(self, callback: Callable[[int, dict], ... method set_status_change_callback (line 242) | def set_status_change_callback(self, callback: Callable[[int, PrinterS... method set_ams_change_callback (line 246) | def set_ams_change_callback(self, callback: Callable[[int, list], None]): method set_layer_change_callback (line 250) | def set_layer_change_callback(self, callback: Callable[[int, int], Non... method set_bed_temp_update_callback (line 254) | def set_bed_temp_update_callback(self, callback: Callable[[int, float]... method _schedule_async (line 258) | def _schedule_async(self, coro): method connect_printer (line 278) | async def connect_printer(self, printer: Printer) -> bool: method disconnect_printer (line 331) | def disconnect_printer(self, printer_id: int, timeout: float = 0): method disconnect_all (line 339) | def disconnect_all(self, timeout: float = 0): method get_status (line 344) | def get_status(self, printer_id: int) -> PrinterState | None: method get_model (line 353) | def get_model(self, printer_id: int) -> str | None: method get_all_statuses (line 357) | def get_all_statuses(self) -> dict[int, PrinterState]: method is_connected (line 366) | def is_connected(self, printer_id: int) -> bool: method get_client (line 374) | def get_client(self, printer_id: int) -> BambuMQTTClient | None: method mark_printer_offline (line 378) | def mark_printer_offline(self, printer_id: int): method start_print (line 398) | def start_print( method stop_print (line 435) | def stop_print(self, printer_id: int) -> bool: method wait_for_cooldown (line 441) | async def wait_for_cooldown( method enable_logging (line 486) | def enable_logging(self, printer_id: int, enabled: bool = True) -> bool: method get_logs (line 493) | def get_logs(self, printer_id: int) -> list[MQTTLogEntry]: method clear_logs (line 499) | def clear_logs(self, printer_id: int) -> bool: method is_logging_enabled (line 506) | def is_logging_enabled(self, printer_id: int) -> bool: method send_drying_command (line 512) | def send_drying_command( method request_status_update (line 527) | def request_status_update(self, printer_id: int) -> bool: method test_connection (line 536) | async def test_connection( function get_derived_status_name (line 564) | def get_derived_status_name(state: PrinterState, model: str | None = Non... function parse_plate_id (line 629) | def parse_plate_id(gcode_file: str | None) -> int | None: function printer_state_to_dict (line 642) | def printer_state_to_dict(state: PrinterState, printer_id: int | None = ... function init_printer_connections (line 882) | async def init_printer_connections(db: AsyncSession): FILE: backend/app/services/rest_smart_plug.py class RESTSmartPlugService (line 17) | class RESTSmartPlugService: method __init__ (line 23) | def __init__(self, timeout: float = 10.0): method _validate_url (line 27) | def _validate_url(url: str) -> bool: method _parse_headers (line 40) | def _parse_headers(self, headers_json: str | None) -> dict[str, str]: method _extract_json_path (line 53) | def _extract_json_path(data: Any, path: str) -> Any: method _send_request (line 69) | async def _send_request( method turn_on (line 110) | async def turn_on(self, plug: "SmartPlug") -> bool: method turn_off (line 127) | async def turn_off(self, plug: "SmartPlug") -> bool: method toggle (line 144) | async def toggle(self, plug: "SmartPlug") -> bool: method get_status (line 152) | async def get_status(self, plug: "SmartPlug") -> dict: method get_energy (line 193) | async def get_energy(self, plug: "SmartPlug") -> dict | None: method _fetch_json (line 236) | async def _fetch_json(self, url: str, headers: dict[str, str]) -> Any: method test_connection (line 246) | async def test_connection(self, url: str, method: str = "GET", headers... FILE: backend/app/services/smart_plug_manager.py class SmartPlugManager (line 22) | class SmartPlugManager: method __init__ (line 25) | def __init__(self): method get_service_for_plug (line 32) | async def get_service_for_plug(self, plug: "SmartPlug", db: AsyncSessi... method _configure_ha_service (line 45) | async def _configure_ha_service(self, db: AsyncSession | None = None): method set_event_loop (line 64) | def set_event_loop(self, loop: asyncio.AbstractEventLoop): method start_scheduler (line 68) | def start_scheduler(self): method stop_scheduler (line 77) | def stop_scheduler(self): method _schedule_loop (line 88) | async def _schedule_loop(self): method _snapshot_loop (line 99) | async def _snapshot_loop(self): method _capture_energy_snapshots (line 116) | async def _capture_energy_snapshots(self): method _check_schedules (line 164) | async def _check_schedules(self): method _get_plugs_for_printer (line 210) | async def _get_plugs_for_printer(self, printer_id: int, db: AsyncSessi... method on_print_start (line 217) | async def on_print_start(self, printer_id: int, db: AsyncSession): method on_print_complete (line 251) | async def on_print_complete(self, printer_id: int, status: str, db: As... method _schedule_delayed_off (line 296) | def _schedule_delayed_off(self, plug: "SmartPlug", printer_id: int, de... method _delayed_off (line 324) | async def _delayed_off( method _schedule_temp_based_off (line 375) | def _schedule_temp_based_off(self, plug: "SmartPlug", printer_id: int,... method _temp_based_off (line 403) | async def _temp_based_off( method _mark_auto_off_pending (line 494) | async def _mark_auto_off_pending(self, plug_id: int, pending: bool): method _mark_auto_off_executed (line 511) | async def _mark_auto_off_executed(self, plug_id: int): method _cancel_pending_off (line 536) | def _cancel_pending_off(self, plug_id: int): method cancel_all_pending (line 545) | def cancel_all_pending(self): method resume_pending_auto_offs (line 550) | async def resume_pending_auto_offs(self): FILE: backend/app/services/spool_assignment_notifications.py function _global_tray_from_assignment (line 12) | def _global_tray_from_assignment(ams_id: int, tray_id: int) -> int: function _slot_label_from_global_tray (line 21) | def _slot_label_from_global_tray(global_tray_id: int) -> str: function _tray_profile_and_color_for_global_id (line 34) | def _tray_profile_and_color_for_global_id(state: PrinterState | None, gl... function _decode_mqtt_mapping_to_global_trays (line 74) | def _decode_mqtt_mapping_to_global_trays(mapping_raw: object) -> list[int]: function notify_missing_spool_assignments_on_print_start (line 107) | async def notify_missing_spool_assignments_on_print_start( FILE: backend/app/services/spool_tag_matcher.py function is_valid_tag (line 23) | def is_valid_tag(tag_uid: str, tray_uuid: str) -> bool: function is_bambu_tag (line 32) | def is_bambu_tag(tag_uid: str, tray_uuid: str, tray_info_idx: str) -> bool: function create_spool_from_tray (line 40) | async def create_spool_from_tray(db: AsyncSession, tray_data: dict) -> S... function find_matching_untagged_spool (line 193) | async def find_matching_untagged_spool(db: AsyncSession, tray_data: dict... function link_tag_to_inventory_spool (line 270) | async def link_tag_to_inventory_spool(db: AsyncSession, spool: Spool, tr... function get_spool_by_tag (line 304) | async def get_spool_by_tag(db: AsyncSession, tag_uid: str, tray_uuid: st... function auto_assign_spool (line 399) | async def auto_assign_spool( FILE: backend/app/services/spoolbuddy_ssh.py function _get_ssh_key_dir (line 45) | def _get_ssh_key_dir() -> Path: function get_or_create_keypair (line 53) | async def get_or_create_keypair() -> tuple[Path, Path]: function get_public_key (line 94) | async def get_public_key() -> str: function detect_current_branch (line 100) | def detect_current_branch() -> str: function _run_ssh_command (line 138) | async def _run_ssh_command( function perform_ssh_update (line 176) | async def perform_ssh_update(device_id: str, ip_address: str, install_pa... FILE: backend/app/services/spoolman.py class SpoolmanSpool (line 16) | class SpoolmanSpool: class SpoolmanFilament (line 32) | class SpoolmanFilament: class AMSTray (line 44) | class AMSTray: class SpoolmanClient (line 59) | class SpoolmanClient: method __init__ (line 62) | def __init__(self, base_url: str): method _get_client (line 73) | async def _get_client(self) -> httpx.AsyncClient: method close (line 92) | async def close(self): method health_check (line 98) | async def health_check(self) -> bool: method is_connected (line 115) | def is_connected(self) -> bool: method get_spools (line 119) | async def get_spools(self) -> list[dict]: method get_filaments (line 174) | async def get_filaments(self) -> list[dict]: method get_external_filaments (line 189) | async def get_external_filaments(self) -> list[dict]: method get_vendors (line 204) | async def get_vendors(self) -> list[dict]: method create_vendor (line 219) | async def create_vendor(self, name: str) -> dict | None: method _get_material_density (line 237) | def _get_material_density(self, material: str | None) -> float: method create_filament (line 271) | async def create_filament( method create_spool (line 333) | async def create_spool( method update_spool (line 382) | async def update_spool( method use_spool (line 424) | async def use_spool(self, spool_id: int, used_weight: float) -> dict |... method find_spool_by_tag (line 446) | async def find_spool_by_tag(self, tag_uid: str, cached_spools: list[di... method _find_spool_by_location (line 473) | def _find_spool_by_location(self, location: str, cached_spools: list[d... method find_spools_by_location_prefix (line 493) | async def find_spools_by_location_prefix( method clear_location_for_removed_spools (line 514) | async def clear_location_for_removed_spools( method ensure_bambu_vendor (line 574) | async def ensure_bambu_vendor(self) -> int | None: method ensure_tag_extra_field (line 589) | async def ensure_tag_extra_field(self) -> bool: method parse_ams_tray (line 625) | def parse_ams_tray(self, ams_id: int, tray_data: dict) -> AMSTray | None: method convert_ams_slot_to_location (line 683) | def convert_ams_slot_to_location(self, ams_id: int, tray_id: int) -> str: method is_bambu_lab_spool (line 704) | def is_bambu_lab_spool(self, tray_uuid: str, tag_uid: str = "", tray_i... method calculate_remaining_weight (line 747) | def calculate_remaining_weight(self, remain_percent: int, spool_weight... method sync_ams_tray (line 759) | async def sync_ams_tray( method _find_or_create_filament (line 885) | async def _find_or_create_filament(self, tray: AMSTray) -> dict | None: method _create_filament_from_external (line 934) | async def _create_filament_from_external(self, external: dict, tray: A... function get_spoolman_client (line 958) | async def get_spoolman_client() -> SpoolmanClient | None: function init_spoolman_client (line 967) | async def init_spoolman_client(url: str) -> SpoolmanClient: function close_spoolman_client (line 984) | async def close_spoolman_client(): FILE: backend/app/services/spoolman_tracking.py function _is_non_zero_identifier (line 24) | def _is_non_zero_identifier(value: str) -> bool: function _to_fixed_hex (line 31) | def _to_fixed_hex(value: int, width: int) -> str: function _hash_serial_to_hex32 (line 37) | def _hash_serial_to_hex32(serial: str) -> str: function _global_tray_id_to_ams_slot (line 47) | def _global_tray_id_to_ams_slot(global_tray_id: int) -> tuple[int, int]: function _get_fallback_spool_tag (line 59) | def _get_fallback_spool_tag(printer_serial: str, global_tray_id: int) ->... function _resolve_spool_tag (line 67) | def _resolve_spool_tag(tray_info: dict, printer_serial: str = "", global... function _get_printer_serial (line 83) | async def _get_printer_serial(printer_id: int) -> str: function _resolve_global_tray_id (line 98) | def _resolve_global_tray_id(slot_id: int, slot_to_tray: list | None, ams... function build_ams_tray_lookup (line 120) | def build_ams_tray_lookup(raw_data: dict) -> dict[int, dict]: function store_print_data (line 152) | async def store_print_data( function cleanup_tracking (line 260) | async def cleanup_tracking( function _get_spoolman_client_with_fallback (line 303) | async def _get_spoolman_client_with_fallback(): function _report_spool_usage_for_slots (line 323) | async def _report_spool_usage_for_slots( function _report_partial_usage (line 374) | async def _report_partial_usage( function report_usage (line 530) | async def report_usage(printer_id: int, archive_id: int): FILE: backend/app/services/stl_thumbnail.py function generate_stl_thumbnail (line 20) | def generate_stl_thumbnail( FILE: backend/app/services/tasmota.py class TasmotaService (line 15) | class TasmotaService: method __init__ (line 18) | def __init__(self, timeout: float = 5.0): method _build_url (line 21) | def _build_url(self, ip: str, command: str) -> str: method _validate_ip (line 28) | def _validate_ip(ip: str) -> bool: method _send_command (line 36) | async def _send_command( method get_status (line 68) | async def get_status(self, plug: "SmartPlug") -> dict: method turn_on (line 91) | async def turn_on(self, plug: "SmartPlug") -> bool: method turn_off (line 109) | async def turn_off(self, plug: "SmartPlug") -> bool: method toggle (line 127) | async def toggle(self, plug: "SmartPlug") -> bool: method get_energy (line 142) | async def get_energy(self, plug: "SmartPlug") -> dict | None: method test_connection (line 178) | async def test_connection( FILE: backend/app/services/timelapse_processor.py class TimelapseProcessor (line 14) | class TimelapseProcessor: method __init__ (line 17) | def __init__(self, input_path: Path): method get_info (line 25) | async def get_info(self) -> dict: method generate_thumbnails (line 81) | async def generate_thumbnails( method process (line 129) | async def process( method _build_atempo_chain (line 238) | def _build_atempo_chain(self, speed: float) -> str: FILE: backend/app/services/usage_tracker.py function _decode_mqtt_mapping (line 25) | def _decode_mqtt_mapping(mapping_raw: list | None) -> list[int] | None: function _match_slots_by_color (line 66) | def _match_slots_by_color( class PrintSession (line 151) | class PrintSession: function _to_epoch_seconds (line 169) | def _to_epoch_seconds(value: datetime | None) -> float | None: function _resolve_spool_id_for_tray (line 179) | async def _resolve_spool_id_for_tray( function on_print_start (line 233) | async def on_print_start(printer_id: int, data: dict, printer_manager, d... function on_print_complete (line 353) | async def on_print_complete( function _resolve_3mf_fallback (line 590) | async def _resolve_3mf_fallback(archive, db: AsyncSession, base_dir): function _find_3mf_by_filename (line 658) | async def _find_3mf_by_filename( function _track_from_3mf (line 725) | async def _track_from_3mf( FILE: backend/app/services/virtual_printer/bind_server.py class BindServer (line 37) | class BindServer: method __init__ (line 47) | def __init__( method _create_tls_context (line 68) | def _create_tls_context(self) -> ssl.SSLContext | None: method start (line 78) | async def start(self) -> None: method stop (line 136) | async def stop(self) -> None: method _handle_client (line 149) | async def _handle_client( method _parse_frame (line 212) | def _parse_frame(self, data: bytes) -> dict | None: method _build_frame (line 236) | def _build_frame(self, payload: dict) -> bytes: FILE: backend/app/services/virtual_printer/certificate.py function _get_local_ip (line 31) | def _get_local_ip() -> str: class CertificateService (line 43) | class CertificateService: method __init__ (line 51) | def __init__(self, cert_dir: Path, serial: str = DEFAULT_SERIAL, share... method ensure_certificates (line 68) | def ensure_certificates(self) -> tuple[Path, Path]: method _load_existing_ca (line 79) | def _load_existing_ca(self) -> tuple[rsa.RSAPrivateKey, x509.Certifica... method _get_or_create_ca (line 112) | def _get_or_create_ca(self) -> tuple[rsa.RSAPrivateKey, x509.Certifica... method _generate_ca_certificate (line 141) | def _generate_ca_certificate(self) -> tuple[rsa.RSAPrivateKey, x509.Ce... method _build_san_entries (line 199) | def _build_san_entries(self, local_ip: str, additional_ips: list[str] ... method generate_certificates (line 220) | def generate_certificates(self, additional_ips: list[str] | None = Non... method delete_printer_certificate (line 327) | def delete_printer_certificate(self) -> None: method delete_certificates (line 334) | def delete_certificates(self, include_ca: bool = False) -> None: FILE: backend/app/services/virtual_printer/ftp_server.py class FTPSession (line 28) | class FTPSession: method __init__ (line 31) | def __init__( method send (line 72) | async def send(self, code: int, message: str) -> None: method handle (line 79) | async def handle(self) -> None: method _cleanup (line 133) | async def _cleanup(self) -> None: method cmd_USER (line 154) | async def cmd_USER(self, arg: str) -> None: method cmd_PASS (line 162) | async def cmd_PASS(self, arg: str) -> None: method cmd_SYST (line 175) | async def cmd_SYST(self, arg: str) -> None: method cmd_FEAT (line 179) | async def cmd_FEAT(self, arg: str) -> None: method cmd_PWD (line 195) | async def cmd_PWD(self, arg: str) -> None: method cmd_CWD (line 202) | async def cmd_CWD(self, arg: str) -> None: method cmd_TYPE (line 210) | async def cmd_TYPE(self, arg: str) -> None: method _bind_passive_port (line 222) | async def _bind_passive_port(self) -> bool: method cmd_EPSV (line 244) | async def cmd_EPSV(self, arg: str) -> None: method cmd_PASV (line 267) | async def cmd_PASV(self, arg: str) -> None: method _handle_data_connection (line 309) | async def _handle_data_connection(self, reader: asyncio.StreamReader, ... method _close_data_connection (line 353) | async def _close_data_connection(self) -> None: method cmd_STOR (line 382) | async def cmd_STOR(self, arg: str) -> None: method cmd_SIZE (line 464) | async def cmd_SIZE(self, arg: str) -> None: method cmd_QUIT (line 472) | async def cmd_QUIT(self, arg: str) -> None: method cmd_NOOP (line 477) | async def cmd_NOOP(self, arg: str) -> None: method cmd_OPTS (line 481) | async def cmd_OPTS(self, arg: str) -> None: method cmd_PBSZ (line 488) | async def cmd_PBSZ(self, arg: str) -> None: method cmd_PROT (line 495) | async def cmd_PROT(self, arg: str) -> None: method cmd_MKD (line 508) | async def cmd_MKD(self, arg: str) -> None: method cmd_LIST (line 516) | async def cmd_LIST(self, arg: str) -> None: class VirtualPrinterFTPServer (line 526) | class VirtualPrinterFTPServer: method __init__ (line 532) | def __init__( method start (line 570) | async def start(self) -> None: method _handle_client (line 627) | async def _handle_client(self, reader: asyncio.StreamReader, writer: a... method stop (line 656) | async def stop(self) -> None: FILE: backend/app/services/virtual_printer/manager.py function _get_serial_for_model (line 87) | def _get_serial_for_model(model: str, serial_suffix: str) -> str: class VirtualPrinterInstance (line 93) | class VirtualPrinterInstance: method __init__ (line 100) | def __init__( method serial (line 162) | def serial(self) -> str: method cert_path (line 167) | def cert_path(self) -> Path: method key_path (line 171) | def key_path(self) -> Path: method is_proxy (line 175) | def is_proxy(self) -> bool: method is_running (line 179) | def is_running(self) -> bool: method generate_certificates (line 182) | def generate_certificates(self) -> tuple[Path, Path]: method on_file_received (line 194) | async def on_file_received(self, file_path: Path, source_ip: str) -> N... method on_print_command (line 211) | async def on_print_command(self, filename: str, data: dict) -> None: method _archive_file (line 215) | async def _archive_file(self, file_path: Path, source_ip: str) -> None: method _queue_file (line 256) | async def _queue_file(self, file_path: Path, source_ip: str) -> None: method _add_to_print_queue (line 289) | async def _add_to_print_queue(self, file_path: Path, source_ip: str) -... method _extract_plate_id (line 348) | def _extract_plate_id(file_path: Path) -> int | None: method start_server (line 369) | async def start_server(self) -> None: method stop_server (line 452) | async def stop_server(self) -> None: method start_proxy (line 468) | async def start_proxy(self) -> None: method _start_fallback_ssdp (line 527) | def _start_fallback_ssdp(self, proxy_serial: str, run_with_logging) ->... method stop_proxy (line 543) | async def stop_proxy(self) -> None: method _cancel_tasks (line 556) | async def _cancel_tasks(self) -> None: method get_status (line 567) | def get_status(self) -> dict: class VirtualPrinterManager (line 578) | class VirtualPrinterManager: method __init__ (line 584) | def __init__(self): method _ensure_base_directories (line 594) | def _ensure_base_directories(self) -> None: method set_session_factory (line 606) | def set_session_factory(self, session_factory: Callable) -> None: method is_enabled (line 611) | def is_enabled(self) -> bool: method sync_from_db (line 615) | async def sync_from_db(self) -> None: method remove_instance (line 723) | async def remove_instance(self, vp_id: int) -> None: method stop_all (line 733) | async def stop_all(self) -> None: method get_instance (line 742) | def get_instance(self, vp_id: int) -> VirtualPrinterInstance | None: method get_all_status (line 746) | def get_all_status(self) -> list[dict]: method get_status (line 760) | def get_status(self) -> dict: method configure (line 790) | async def configure( FILE: backend/app/services/virtual_printer/mqtt_server.py class VirtualPrinterMQTTServer (line 37) | class VirtualPrinterMQTTServer: method __init__ (line 47) | def __init__( method start (line 76) | async def start(self) -> None: method _authenticate (line 139) | async def _authenticate(self, session) -> bool: method stop (line 159) | async def stop(self) -> None: class SimpleMQTTServer (line 172) | class SimpleMQTTServer: method __init__ (line 180) | def __init__( method start (line 221) | async def start(self) -> None: method stop (line 301) | async def stop(self) -> None: method _extract_serial_from_topic (line 334) | def _extract_serial_from_topic(topic: str) -> str | None: method _periodic_status_push (line 349) | async def _periodic_status_push(self) -> None: method _handle_client (line 381) | async def _handle_client(self, reader: asyncio.StreamReader, writer: a... method _read_remaining_length (line 447) | async def _read_remaining_length(self, reader: asyncio.StreamReader) -... method _handle_connect (line 467) | async def _handle_connect(self, payload: bytes, writer: asyncio.Stream... method _handle_subscribe (line 527) | async def _handle_subscribe(self, payload: bytes, writer: asyncio.Stre... method _send_status_report (line 577) | async def _send_status_report(self, writer: asyncio.StreamWriter, seri... method _send_version_response (line 660) | async def _send_version_response( method set_gcode_state (line 733) | def set_gcode_state(self, state: str, filename: str = "", prepare_perc... method _publish_to_report (line 742) | async def _publish_to_report(self, writer: asyncio.StreamWriter, paylo... method _send_print_response (line 772) | async def _send_print_response( method _handle_publish (line 803) | async def _handle_publish(self, header: int, payload: bytes, writer: a... method _notify_print_command (line 905) | async def _notify_print_command(self, filename: str, data: dict) -> None: FILE: backend/app/services/virtual_printer/ssdp_server.py class VirtualPrinterSSDPServer (line 28) | class VirtualPrinterSSDPServer: method __init__ (line 31) | def __init__( method _get_local_ip (line 63) | def _get_local_ip(self) -> str: method _build_notify_message (line 79) | def _build_notify_message(self) -> bytes: method _build_response_message (line 104) | def _build_response_message(self) -> bytes: method start (line 127) | async def start(self) -> None: method stop (line 248) | async def stop(self) -> None: method _cleanup (line 254) | async def _cleanup(self) -> None: method _send_notify (line 276) | async def _send_notify(self) -> None: method _send_byebye (line 299) | async def _send_byebye(self) -> None: method _handle_message (line 319) | async def _handle_message( class SSDPProxy (line 356) | class SSDPProxy: method __init__ (line 366) | def __init__( method _parse_ssdp_message (line 391) | def _parse_ssdp_message(self, data: bytes) -> dict[str, str]: method _rewrite_ssdp (line 404) | def _rewrite_ssdp(self, data: bytes) -> bytes: method start (line 453) | async def start(self) -> None: method stop (line 538) | async def stop(self) -> None: method _cleanup (line 544) | async def _cleanup(self) -> None: method _handle_local_packet (line 555) | async def _handle_local_packet(self, data: bytes, addr: tuple[str, int... method _respond_to_msearch (line 594) | async def _respond_to_msearch(self, data: bytes, addr: tuple[str, int]... method _broadcast_to_remote (line 632) | async def _broadcast_to_remote(self) -> None: FILE: backend/app/services/virtual_printer/tcp_proxy.py class _SessionReuseSSLContext (line 27) | class _SessionReuseSSLContext: method __init__ (line 40) | def __init__(self, ctx: ssl.SSLContext, session: ssl.SSLSession) -> None: method __getattr__ (line 44) | def __getattr__(self, name: str) -> object: method wrap_bio (line 47) | def wrap_bio( function detect_port_redirect (line 65) | def detect_port_redirect(port: int) -> int | None: class TLSProxy (line 107) | class TLSProxy: method __init__ (line 114) | def __init__( method _ip_to_le_int_bytes (line 176) | def _ip_to_le_int_bytes(ip: str) -> bytes: method _create_server_ssl_context (line 189) | def _create_server_ssl_context(self) -> ssl.SSLContext: method _create_client_ssl_context (line 199) | def _create_client_ssl_context(self) -> ssl.SSLContext: method start (line 211) | async def start(self) -> None: method stop (line 263) | async def stop(self) -> None: method _handle_client (line 288) | async def _handle_client( method _rewrite_mqtt_ip (line 383) | def _rewrite_mqtt_ip( method _forward (line 527) | async def _forward( class TCPProxy (line 602) | class TCPProxy: method __init__ (line 609) | def __init__( method start (line 631) | async def start(self) -> None: method stop (line 671) | async def stop(self) -> None: method _handle_client (line 695) | async def _handle_client( method _forward (line 772) | async def _forward( class FTPTLSProxy (line 801) | class FTPTLSProxy(TLSProxy): method stop (line 815) | async def stop(self) -> None: method start (line 827) | async def start(self) -> None: method _handle_client (line 832) | async def _handle_client( method _forward_ftp_commands (line 949) | async def _forward_ftp_commands( method _forward_ftp_control (line 1020) | async def _forward_ftp_control( method _maybe_rewrite_pasv (line 1081) | async def _maybe_rewrite_pasv( method _create_data_proxy (line 1132) | async def _create_data_proxy( method _start_data_proxy_server (line 1188) | async def _start_data_proxy_server( class SlicerProxyManager (line 1416) | class SlicerProxyManager: method __init__ (line 1434) | def __init__( method start (line 1479) | async def start(self) -> None: method stop (line 1711) | async def stop(self) -> None: method _probe_handler (line 1768) | async def _probe_handler(self, reader: asyncio.StreamReader, writer: a... method _log_activity (line 1783) | def _log_activity(self, name: str, message: str) -> None: method is_running (line 1792) | def is_running(self) -> bool: method get_status (line 1796) | def get_status(self) -> dict: FILE: backend/app/utils/color_utils.py function colors_similar (line 4) | def colors_similar(hex_a: str, hex_b: str, threshold: int = 50) -> bool: FILE: backend/app/utils/filament_ids.py function filament_id_to_setting_id (line 14) | def filament_id_to_setting_id(filament_id: str) -> str: function setting_id_to_filament_id (line 38) | def setting_id_to_filament_id(setting_id: str) -> str: function normalize_slicer_filament (line 59) | def normalize_slicer_filament(slicer_filament: str | None) -> tuple[str,... FILE: backend/app/utils/printer_models.py function has_ethernet (line 140) | def has_ethernet(model: str | None) -> bool: function get_rod_type (line 148) | def get_rod_type(model: str | None) -> str | None: function normalize_printer_model_id (line 169) | def normalize_printer_model_id(model_id: str | None) -> str | None: function normalize_printer_model (line 189) | def normalize_printer_model(raw_model: str | None) -> str | None: FILE: backend/app/utils/tag_normalization.py function normalize_hex (line 4) | def normalize_hex(value: str | None) -> str: function normalize_tag_uid (line 11) | def normalize_tag_uid(value: str | None) -> str: function normalize_tray_uuid (line 19) | def normalize_tray_uuid(value: str | None) -> str: FILE: backend/app/utils/threemf_tools.py function parse_gcode_layer_filament_usage (line 21) | def parse_gcode_layer_filament_usage(gcode_content: str) -> dict[int, di... function mm_to_grams (line 133) | def mm_to_grams( function extract_layer_filament_usage_from_3mf (line 157) | def extract_layer_filament_usage_from_3mf(file_path: Path) -> dict[int, ... function get_cumulative_usage_at_layer (line 183) | def get_cumulative_usage_at_layer( function extract_filament_properties_from_3mf (line 210) | def extract_filament_properties_from_3mf(file_path: Path) -> dict[int, d... function extract_nozzle_mapping_from_3mf (line 267) | def extract_nozzle_mapping_from_3mf(zf: zipfile.ZipFile) -> dict[int, in... function extract_filament_usage_from_3mf (line 367) | def extract_filament_usage_from_3mf(file_path: Path, plate_id: int | Non... function inject_gcode_into_3mf (line 445) | def inject_gcode_into_3mf( FILE: backend/tests/conftest.py function _cleanup_test_plate_cal_dir (line 35) | def _cleanup_test_plate_cal_dir(): function event_loop (line 49) | def event_loop(): function test_engine (line 63) | async def test_engine(): function db_session (line 119) | async def db_session(test_engine) -> AsyncGenerator[AsyncSession, None]: function async_client (line 127) | async def async_client(test_engine, db_session) -> AsyncGenerator[AsyncC... function mock_tasmota_service (line 176) | def mock_tasmota_service(): function mock_homeassistant_service (line 209) | def mock_homeassistant_service(): function mock_mqtt_client (line 247) | def mock_mqtt_client(): function mock_mqtt_smart_plug_service (line 259) | def mock_mqtt_smart_plug_service(): function mock_ftp_client (line 277) | def mock_ftp_client(): function mock_httpx_client (line 289) | def mock_httpx_client(): function mock_printer_manager (line 308) | def mock_printer_manager(): function smart_plug_factory (line 330) | def smart_plug_factory(db_session): function printer_factory (line 394) | def printer_factory(db_session): function notification_provider_factory (line 425) | def notification_provider_factory(db_session): function archive_factory (line 468) | def archive_factory(db_session): function sample_mqtt_print_start (line 502) | def sample_mqtt_print_start(): function sample_mqtt_print_complete (line 516) | def sample_mqtt_print_complete(): function sample_printer_status (line 528) | def sample_printer_status(): class LogCapture (line 551) | class LogCapture(logging.Handler): method __init__ (line 554) | def __init__(self): method emit (line 558) | def emit(self, record: logging.LogRecord): method clear (line 561) | def clear(self): method get_errors (line 564) | def get_errors(self) -> list[logging.LogRecord]: method get_warnings (line 568) | def get_warnings(self) -> list[logging.LogRecord]: method has_errors (line 572) | def has_errors(self) -> bool: method format_errors (line 576) | def format_errors(self) -> str: function capture_logs (line 586) | def capture_logs(): function assert_no_log_errors (line 610) | def assert_no_log_errors(capture_logs): FILE: backend/tests/integration/test_advanced_auth_api.py function _setup_admin (line 25) | async def _setup_admin(async_client: AsyncClient, username: str = "admin... function _setup_smtp_and_advanced_auth (line 42) | async def _setup_smtp_and_advanced_auth(async_client: AsyncClient, token... function _create_regular_user (line 49) | async def _create_regular_user( class TestSMTPConfigAPI (line 66) | class TestSMTPConfigAPI: method admin_token (line 70) | async def admin_token(self, async_client: AsyncClient): method test_save_smtp_settings (line 75) | async def test_save_smtp_settings(self, async_client: AsyncClient, adm... method test_get_smtp_settings_masks_password (line 87) | async def test_get_smtp_settings_masks_password(self, async_client: As... method test_smtp_settings_requires_admin (line 101) | async def test_smtp_settings_requires_admin(self, async_client: AsyncC... method test_save_smtp_settings_no_auth (line 114) | async def test_save_smtp_settings_no_auth(self, async_client: AsyncCli... method test_test_smtp_connection (line 121) | async def test_test_smtp_connection(self, async_client: AsyncClient, a... class TestAdvancedAuthToggleAPI (line 141) | class TestAdvancedAuthToggleAPI: method admin_token (line 145) | async def admin_token(self, async_client: AsyncClient): method test_enable_advanced_auth (line 150) | async def test_enable_advanced_auth(self, async_client: AsyncClient, a... method test_enable_advanced_auth_without_smtp (line 162) | async def test_enable_advanced_auth_without_smtp(self, async_client: A... method test_disable_advanced_auth (line 171) | async def test_disable_advanced_auth(self, async_client: AsyncClient, ... method test_advanced_auth_status_public (line 184) | async def test_advanced_auth_status_public(self, async_client: AsyncCl... method test_enable_requires_admin (line 194) | async def test_enable_requires_admin(self, async_client: AsyncClient, ... class TestEmailLoginAPI (line 206) | class TestEmailLoginAPI: method admin_token (line 210) | async def admin_token(self, async_client: AsyncClient): method test_login_with_email (line 215) | async def test_login_with_email(self, async_client: AsyncClient, admin... method test_login_with_email_case_insensitive (line 249) | async def test_login_with_email_case_insensitive(self, async_client: A... method test_login_with_email_advanced_auth_disabled (line 277) | async def test_login_with_email_advanced_auth_disabled(self, async_cli... method test_login_with_username_still_works (line 297) | async def test_login_with_username_still_works(self, async_client: Asy... class TestForgotPasswordAPI (line 325) | class TestForgotPasswordAPI: method admin_token (line 329) | async def admin_token(self, async_client: AsyncClient): method test_forgot_password_sends_email (line 334) | async def test_forgot_password_sends_email(self, async_client: AsyncCl... method test_forgot_password_unknown_email (line 362) | async def test_forgot_password_unknown_email(self, async_client: Async... method test_forgot_password_requires_advanced_auth (line 379) | async def test_forgot_password_requires_advanced_auth(self, async_clie... method test_forgot_password_changes_password (line 390) | async def test_forgot_password_changes_password(self, async_client: As... class TestAdminResetPasswordAPI (line 466) | class TestAdminResetPasswordAPI: method admin_token (line 470) | async def admin_token(self, async_client: AsyncClient): method test_reset_password_sends_email (line 475) | async def test_reset_password_sends_email(self, async_client: AsyncCli... method test_reset_password_requires_admin (line 502) | async def test_reset_password_requires_admin(self, async_client: Async... method test_reset_password_requires_advanced_auth (line 519) | async def test_reset_password_requires_advanced_auth(self, async_clien... method test_reset_password_user_not_found (line 533) | async def test_reset_password_user_not_found(self, async_client: Async... method test_reset_password_user_no_email (line 548) | async def test_reset_password_user_no_email(self, async_client: AsyncC... class TestUserCreationAdvancedAuth (line 576) | class TestUserCreationAdvancedAuth: method admin_token (line 580) | async def admin_token(self, async_client: AsyncClient): method test_create_user_advanced_auth_requires_email (line 585) | async def test_create_user_advanced_auth_requires_email(self, async_cl... method test_create_user_advanced_auth_auto_password (line 601) | async def test_create_user_advanced_auth_auto_password(self, async_cli... method test_create_user_duplicate_email (line 624) | async def test_create_user_duplicate_email(self, async_client: AsyncCl... method test_create_user_response_includes_email (line 649) | async def test_create_user_response_includes_email(self, async_client:... class TestAuthSourcePasswordResetBlocking (line 673) | class TestAuthSourcePasswordResetBlocking: method admin_token (line 677) | async def admin_token(self, async_client: AsyncClient): method test_forgot_password_silently_skips_oidc_user (line 682) | async def test_forgot_password_silently_skips_oidc_user( FILE: backend/tests/integration/test_ams_history_api.py class TestAMSHistoryAPI (line 9) | class TestAMSHistoryAPI: method ams_history_factory (line 13) | async def ams_history_factory(self, db_session, printer_factory): method test_get_ams_history_empty (line 43) | async def test_get_ams_history_empty(self, async_client: AsyncClient, ... method test_get_ams_history_with_data (line 55) | async def test_get_ams_history_with_data(self, async_client: AsyncClie... method test_get_ams_history_with_stats (line 68) | async def test_get_ams_history_with_stats( method test_get_ams_history_with_hours_filter (line 90) | async def test_get_ams_history_with_hours_filter( method test_get_ams_history_custom_hours (line 109) | async def test_get_ams_history_custom_hours(self, async_client: AsyncC... method test_get_ams_history_different_ams_units (line 119) | async def test_get_ams_history_different_ams_units( method test_delete_old_history (line 143) | async def test_delete_old_history( method test_delete_old_history_no_records (line 159) | async def test_delete_old_history_no_records(self, async_client: Async... FILE: backend/tests/integration/test_ams_labels_api.py class TestAmsLabelsAPI (line 11) | class TestAmsLabelsAPI: method _mock_printer_state (line 14) | def _mock_printer_state(self, ams_units=None): method test_get_labels_empty (line 29) | async def test_get_labels_empty(self, async_client: AsyncClient, print... method test_save_label_with_serial (line 40) | async def test_save_label_with_serial(self, async_client: AsyncClient,... method test_save_label_without_serial_uses_synthetic_key (line 52) | async def test_save_label_without_serial_uses_synthetic_key( method test_save_label_whitespace_serial_uses_synthetic_key (line 73) | async def test_save_label_whitespace_serial_uses_synthetic_key( method test_save_label_updates_existing (line 93) | async def test_save_label_updates_existing(self, async_client: AsyncCl... method test_save_label_printer_not_found (line 109) | async def test_save_label_printer_not_found(self, async_client: AsyncC... method test_save_label_validation_empty_label (line 119) | async def test_save_label_validation_empty_label(self, async_client: A... method test_get_labels_resolves_serial_to_ams_id (line 130) | async def test_get_labels_resolves_serial_to_ams_id(self, async_client... method test_get_labels_no_printer_state (line 150) | async def test_get_labels_no_printer_state(self, async_client: AsyncCl... method test_delete_label (line 161) | async def test_delete_label(self, async_client: AsyncClient, printer_f... method test_delete_nonexistent_label_succeeds (line 181) | async def test_delete_nonexistent_label_succeeds(self, async_client: A... method test_delete_label_whitespace_serial_uses_synthetic_key (line 190) | async def test_delete_label_whitespace_serial_uses_synthetic_key( FILE: backend/tests/integration/test_archives_api.py class TestArchivesAPI (line 10) | class TestArchivesAPI: method test_list_archives_empty (line 19) | async def test_list_archives_empty(self, async_client: AsyncClient): method test_list_archives_with_data (line 30) | async def test_list_archives_with_data( method test_list_archives_pagination (line 47) | async def test_list_archives_pagination( method test_list_archives_filter_by_printer (line 66) | async def test_list_archives_filter_by_printer( method test_get_archive (line 87) | async def test_get_archive(self, async_client: AsyncClient, archive_fa... method test_get_archive_not_found (line 101) | async def test_get_archive_not_found(self, async_client: AsyncClient): method test_update_archive_name (line 113) | async def test_update_archive_name(self, async_client: AsyncClient, ar... method test_update_archive_notes (line 125) | async def test_update_archive_notes(self, async_client: AsyncClient, a... method test_update_archive_favorite (line 137) | async def test_update_archive_favorite( method test_update_archive_external_url (line 151) | async def test_update_archive_external_url( method test_delete_archive (line 177) | async def test_delete_archive(self, async_client: AsyncClient, archive... method test_delete_nonexistent_archive (line 193) | async def test_delete_nonexistent_archive(self, async_client: AsyncCli... method test_get_archive_stats (line 205) | async def test_get_archive_stats(self, async_client: AsyncClient, arch... class TestArchivesSlimAPI (line 230) | class TestArchivesSlimAPI: method test_slim_empty (line 235) | async def test_slim_empty(self, async_client: AsyncClient): method test_slim_returns_only_expected_fields (line 244) | async def test_slim_returns_only_expected_fields( method test_slim_computes_actual_time (line 296) | async def test_slim_computes_actual_time( method test_slim_actual_time_null_for_failed (line 320) | async def test_slim_actual_time_null_for_failed( method test_slim_date_filtering (line 342) | async def test_slim_date_filtering(self, async_client: AsyncClient, ar... method test_slim_pagination (line 368) | async def test_slim_pagination(self, async_client: AsyncClient, archiv... class TestArchiveDataIntegrity (line 380) | class TestArchiveDataIntegrity: method test_archive_linked_to_printer (line 385) | async def test_archive_linked_to_printer( method test_archive_stores_print_data (line 400) | async def test_archive_stores_print_data( method test_archive_update_persists (line 428) | async def test_archive_update_persists( class TestArchiveF3DEndpoints (line 445) | class TestArchiveF3DEndpoints: method test_archive_response_includes_f3d_path (line 450) | async def test_archive_response_includes_f3d_path( method test_archive_response_f3d_path_null_when_not_set (line 466) | async def test_archive_response_f3d_path_null_when_not_set( method test_upload_f3d_to_nonexistent_archive (line 482) | async def test_upload_f3d_to_nonexistent_archive(self, async_client: A... method test_download_f3d_not_found_when_no_file (line 492) | async def test_download_f3d_not_found_when_no_file( method test_download_f3d_nonexistent_archive (line 505) | async def test_download_f3d_nonexistent_archive(self, async_client: As... method test_delete_f3d_nonexistent_archive (line 513) | async def test_delete_f3d_nonexistent_archive(self, async_client: Asyn... method test_delete_f3d_when_no_file (line 521) | async def test_delete_f3d_when_no_file( method test_list_archives_includes_f3d_path (line 534) | async def test_list_archives_includes_f3d_path( method test_get_archive_plates_not_found (line 562) | async def test_get_archive_plates_not_found(self, async_client: AsyncC... method test_get_plate_thumbnail_not_found (line 569) | async def test_get_plate_thumbnail_not_found(self, async_client: Async... method test_filament_requirements_not_found (line 576) | async def test_filament_requirements_not_found(self, async_client: Asy... method test_filament_requirements_with_plate_id_not_found (line 583) | async def test_filament_requirements_with_plate_id_not_found(self, asy... method test_get_tags_empty (line 594) | async def test_get_tags_empty(self, async_client: AsyncClient): method test_get_tags_with_data (line 604) | async def test_get_tags_with_data(self, async_client: AsyncClient, arc... method test_get_tags_sorted_by_count (line 624) | async def test_get_tags_sorted_by_count( method test_rename_tag (line 647) | async def test_rename_tag(self, async_client: AsyncClient, archive_fac... method test_rename_tag_no_change (line 669) | async def test_rename_tag_no_change(self, async_client: AsyncClient): method test_rename_tag_empty_name_error (line 677) | async def test_rename_tag_empty_name_error(self, async_client: AsyncCl... method test_delete_tag (line 684) | async def test_delete_tag(self, async_client: AsyncClient, archive_fac... method test_delete_tag_not_found (line 706) | async def test_delete_tag_not_found(self, async_client: AsyncClient): FILE: backend/tests/integration/test_auth_api.py class TestAuthStatusAPI (line 10) | class TestAuthStatusAPI: method test_get_auth_status_disabled (line 15) | async def test_get_auth_status_disabled(self, async_client: AsyncClient): class TestAuthSetupAPI (line 26) | class TestAuthSetupAPI: method test_setup_auth_disabled (line 31) | async def test_setup_auth_disabled(self, async_client: AsyncClient): method test_setup_auth_enabled_requires_credentials (line 45) | async def test_setup_auth_enabled_requires_credentials(self, async_cli... method test_setup_auth_enabled_with_credentials (line 57) | async def test_setup_auth_enabled_with_credentials(self, async_client:... class TestAuthLoginAPI (line 74) | class TestAuthLoginAPI: method test_login_auth_disabled (line 79) | async def test_login_auth_disabled(self, async_client: AsyncClient): method test_login_success (line 91) | async def test_login_success(self, async_client: AsyncClient): method test_login_invalid_credentials (line 118) | async def test_login_invalid_credentials(self, async_client: AsyncClie... class TestAuthMeAPI (line 140) | class TestAuthMeAPI: method test_me_without_token (line 145) | async def test_me_without_token(self, async_client: AsyncClient): method test_me_with_valid_token (line 153) | async def test_me_with_valid_token(self, async_client: AsyncClient): method test_me_with_api_key_bearer (line 185) | async def test_me_with_api_key_bearer(self, async_client: AsyncClient,... method test_me_with_api_key_header (line 213) | async def test_me_with_api_key_header(self, async_client: AsyncClient,... method test_me_with_invalid_api_key (line 236) | async def test_me_with_invalid_api_key(self, async_client: AsyncClient): class TestUsersAPI (line 246) | class TestUsersAPI: method auth_token (line 250) | async def auth_token(self, async_client: AsyncClient): method test_list_users_requires_auth (line 269) | async def test_list_users_requires_auth(self, async_client: AsyncClient): method test_list_users_as_admin (line 288) | async def test_list_users_as_admin(self, async_client: AsyncClient, au... method test_create_user (line 302) | async def test_create_user(self, async_client: AsyncClient, auth_token... method test_create_user_duplicate_username (line 322) | async def test_create_user_duplicate_username(self, async_client: Asyn... method test_update_user (line 351) | async def test_update_user(self, async_client: AsyncClient, auth_token... method test_delete_user (line 377) | async def test_delete_user(self, async_client: AsyncClient, auth_token... class TestAuthDisableAPI (line 400) | class TestAuthDisableAPI: method test_disable_auth (line 405) | async def test_disable_auth(self, async_client: AsyncClient): class TestGroupsAPI (line 438) | class TestGroupsAPI: method auth_token (line 442) | async def auth_token(self, async_client: AsyncClient): method test_list_groups (line 461) | async def test_list_groups(self, async_client: AsyncClient, auth_token... method test_get_permissions (line 479) | async def test_get_permissions(self, async_client: AsyncClient, auth_t... method test_create_group (line 494) | async def test_create_group(self, async_client: AsyncClient, auth_toke... method test_update_group (line 515) | async def test_update_group(self, async_client: AsyncClient, auth_toke... method test_cannot_delete_system_group (line 545) | async def test_cannot_delete_system_group(self, async_client: AsyncCli... method test_delete_custom_group (line 565) | async def test_delete_custom_group(self, async_client: AsyncClient, au... class TestUserGroupsAPI (line 584) | class TestUserGroupsAPI: method auth_token (line 588) | async def auth_token(self, async_client: AsyncClient): method test_create_user_with_groups (line 607) | async def test_create_user_with_groups(self, async_client: AsyncClient... method test_add_user_to_group (line 633) | async def test_add_user_to_group(self, async_client: AsyncClient, auth... class TestChangePasswordAPI (line 666) | class TestChangePasswordAPI: method user_token (line 670) | async def user_token(self, async_client: AsyncClient): method test_change_password_success (line 704) | async def test_change_password_success(self, async_client: AsyncClient... method test_change_password_wrong_current (line 727) | async def test_change_password_wrong_current(self, async_client: Async... method test_change_password_requires_auth (line 743) | async def test_change_password_requires_auth(self, async_client: Async... class TestAuthMiddlewarePublicRoutes (line 756) | class TestAuthMiddlewarePublicRoutes: method enabled_auth (line 764) | async def enabled_auth(self, async_client: AsyncClient): method test_auth_status_is_public (line 777) | async def test_auth_status_is_public(self, async_client: AsyncClient, ... method test_auth_login_is_public (line 785) | async def test_auth_login_is_public(self, async_client: AsyncClient, e... method test_auth_setup_is_public (line 797) | async def test_auth_setup_is_public(self, async_client: AsyncClient): method test_updates_version_is_public (line 809) | async def test_updates_version_is_public(self, async_client: AsyncClie... method test_protected_route_requires_auth (line 817) | async def test_protected_route_requires_auth(self, async_client: Async... method test_protected_route_works_with_token (line 824) | async def test_protected_route_works_with_token(self, async_client: As... method test_advanced_auth_status_is_public (line 842) | async def test_advanced_auth_status_is_public(self, async_client: Asyn... method test_forgot_password_is_public (line 855) | async def test_forgot_password_is_public(self, async_client: AsyncClie... class TestInputLengthValidation (line 873) | class TestInputLengthValidation: method test_login_password_too_long_rejected (line 878) | async def test_login_password_too_long_rejected(self, async_client: As... method test_login_username_too_long_rejected (line 888) | async def test_login_username_too_long_rejected(self, async_client: As... method test_setup_password_too_long_rejected (line 898) | async def test_setup_password_too_long_rejected(self, async_client: As... method test_login_password_at_limit_accepted (line 912) | async def test_login_password_at_limit_accepted(self, async_client: As... FILE: backend/tests/integration/test_available_filaments.py function _make_mock_status (line 13) | def _make_mock_status(ams_data: list, vt_tray: list | None = None, ams_e... class TestAvailableFilaments (line 27) | class TestAvailableFilaments: method test_returns_tray_sub_brands (line 32) | async def test_returns_tray_sub_brands(self, async_client: AsyncClient... method test_dedup_distinguishes_subtypes (line 66) | async def test_dedup_distinguishes_subtypes(self, async_client: AsyncC... method test_dedup_same_subtype_same_color (line 108) | async def test_dedup_same_subtype_same_color(self, async_client: Async... method test_empty_sub_brands_handled (line 157) | async def test_empty_sub_brands_handled(self, async_client: AsyncClien... method test_external_spool_includes_sub_brands (line 184) | async def test_external_spool_includes_sub_brands(self, async_client: ... method test_no_printers_returns_empty (line 214) | async def test_no_printers_returns_empty(self, async_client: AsyncClie... FILE: backend/tests/integration/test_background_dispatch_api.py class TestBackgroundDispatchArchivesAPI (line 11) | class TestBackgroundDispatchArchivesAPI: method test_reprint_returns_dispatched_payload (line 16) | async def test_reprint_returns_dispatched_payload( method test_reprint_returns_409_when_enqueue_rejected (line 58) | async def test_reprint_returns_409_when_enqueue_rejected( class TestBackgroundDispatchLibraryAPI (line 90) | class TestBackgroundDispatchLibraryAPI: method library_file_factory (line 94) | async def library_file_factory(self, db_session): method test_library_print_returns_dispatched_payload (line 117) | async def test_library_print_returns_dispatched_payload( method test_library_print_returns_409_when_enqueue_rejected (line 155) | async def test_library_print_returns_409_when_enqueue_rejected( method test_library_print_cleanup_flag_defaults_false (line 184) | async def test_library_print_cleanup_flag_defaults_false( method test_library_print_forwards_cleanup_flag_true (line 217) | async def test_library_print_forwards_cleanup_flag_true( class TestBackgroundDispatchCancelAPI (line 246) | class TestBackgroundDispatchCancelAPI: method test_cancel_job_returns_cancelled (line 251) | async def test_cancel_job_returns_cancelled(self, async_client: AsyncC... method test_cancel_job_returns_cancelling_for_active_job (line 275) | async def test_cancel_job_returns_cancelling_for_active_job(self, asyn... method test_cancel_job_returns_404_when_not_found (line 297) | async def test_cancel_job_returns_404_when_not_found(self, async_clien... FILE: backend/tests/integration/test_camera_api.py class TestCameraAPI (line 12) | class TestCameraAPI: method test_stop_camera_stream_get (line 21) | async def test_stop_camera_stream_get(self, async_client: AsyncClient,... method test_stop_camera_stream_post (line 34) | async def test_stop_camera_stream_post(self, async_client: AsyncClient... method test_stop_camera_stream_no_active_streams (line 47) | async def test_stop_camera_stream_no_active_streams(self, async_client... method test_stop_camera_stream_with_active_stream (line 58) | async def test_stop_camera_stream_with_active_stream(self, async_clien... method test_stop_camera_stream_only_stops_matching_printer (line 78) | async def test_stop_camera_stream_only_stops_matching_printer(self, as... method test_camera_test_printer_not_found (line 115) | async def test_camera_test_printer_not_found(self, async_client: Async... method test_camera_test_success (line 124) | async def test_camera_test_success(self, async_client: AsyncClient, pr... method test_camera_test_failure (line 139) | async def test_camera_test_failure(self, async_client: AsyncClient, pr... method test_camera_snapshot_printer_not_found (line 158) | async def test_camera_snapshot_printer_not_found(self, async_client: A... method test_camera_snapshot_success (line 166) | async def test_camera_snapshot_success(self, async_client: AsyncClient... method test_camera_snapshot_failure (line 188) | async def test_camera_snapshot_failure(self, async_client: AsyncClient... method test_camera_snapshot_external_camera_success (line 203) | async def test_camera_snapshot_external_camera_success(self, async_cli... method test_camera_snapshot_external_camera_failure (line 226) | async def test_camera_snapshot_external_camera_failure(self, async_cli... method test_camera_stream_printer_not_found (line 250) | async def test_camera_stream_printer_not_found(self, async_client: Asy... method test_camera_stream_fps_validation (line 258) | async def test_camera_stream_fps_validation(self, async_client: AsyncC... method test_plate_detection_status_printer_not_found (line 281) | async def test_plate_detection_status_printer_not_found(self, async_cl... method test_plate_detection_status_opencv_not_available (line 289) | async def test_plate_detection_status_opencv_not_available(self, async... method test_plate_detection_status_success (line 303) | async def test_plate_detection_status_success(self, async_client: Asyn... method test_check_plate_empty_printer_not_found (line 317) | async def test_check_plate_empty_printer_not_found(self, async_client:... method test_check_plate_empty_success_structure (line 325) | async def test_check_plate_empty_success_structure(self, async_client:... method test_calibrate_plate_printer_not_found (line 367) | async def test_calibrate_plate_printer_not_found(self, async_client: A... method test_calibrate_plate_success_structure (line 375) | async def test_calibrate_plate_success_structure(self, async_client: A... method test_delete_calibration_printer_not_found (line 394) | async def test_delete_calibration_printer_not_found(self, async_client... method test_delete_calibration_success (line 402) | async def test_delete_calibration_success(self, async_client: AsyncCli... method test_get_references_printer_not_found (line 416) | async def test_get_references_printer_not_found(self, async_client: As... method test_get_references_opencv_not_available (line 424) | async def test_get_references_opencv_not_available(self, async_client:... method test_get_references_success (line 435) | async def test_get_references_success(self, async_client: AsyncClient,... method test_update_reference_label_printer_not_found (line 458) | async def test_update_reference_label_printer_not_found(self, async_cl... method test_delete_reference_printer_not_found (line 468) | async def test_delete_reference_printer_not_found(self, async_client: ... method test_get_reference_thumbnail_printer_not_found (line 476) | async def test_get_reference_thumbnail_printer_not_found(self, async_c... method test_list_usb_cameras_returns_list (line 488) | async def test_list_usb_cameras_returns_list(self, async_client: Async... method test_list_usb_cameras_structure (line 499) | async def test_list_usb_cameras_structure(self, async_client: AsyncCli... method test_list_usb_cameras_empty_on_non_linux (line 518) | async def test_list_usb_cameras_empty_on_non_linux(self, async_client:... FILE: backend/tests/integration/test_client_ip.py function _make_request (line 18) | def _make_request(client_host: str | None, xff: str = "") -> MagicMock: function _call (line 31) | def _call(request, trusted: frozenset[str]) -> str: function test_no_proxy_returns_client_host (line 43) | def test_no_proxy_returns_client_host(): function test_no_proxy_xff_ignored (line 48) | def test_no_proxy_xff_ignored(): function test_trusted_proxy_returns_rightmost_non_proxy (line 59) | def test_trusted_proxy_returns_rightmost_non_proxy(): function test_trusted_proxy_chain_skips_proxy_ips (line 67) | def test_trusted_proxy_chain_skips_proxy_ips(): function test_all_xff_entries_are_proxies_falls_back_to_leftmost (line 77) | def test_all_xff_entries_are_proxies_falls_back_to_leftmost(): function test_empty_xff_with_trusted_proxy_returns_direct_ip (line 85) | def test_empty_xff_with_trusted_proxy_returns_direct_ip(): function test_spoofed_xff_from_untrusted_client_ignored (line 97) | def test_spoofed_xff_from_untrusted_client_ignored(): function test_no_client_returns_unique_token (line 109) | def test_no_client_returns_unique_token(): function test_xff_with_extra_whitespace_trimmed (line 125) | def test_xff_with_extra_whitespace_trimmed(): FILE: backend/tests/integration/test_cloud_auth.py class TestPerUserCloudCredentials (line 15) | class TestPerUserCloudCredentials: method user_with_cloud_auth (line 19) | async def user_with_cloud_auth(self, db_session): method second_user_with_cloud_auth (line 45) | async def second_user_with_cloud_auth(self, db_session): method cloud_auth_token (line 76) | async def cloud_auth_token(self, user_with_cloud_auth, async_client: A... method second_auth_token (line 87) | async def second_auth_token(self, second_user_with_cloud_auth, async_c... method test_cloud_status_returns_not_authenticated_by_default (line 99) | async def test_cloud_status_returns_not_authenticated_by_default(self,... method test_cloud_status_accessible_when_auth_disabled (line 109) | async def test_cloud_status_accessible_when_auth_disabled(self, async_... method test_cloud_status_requires_auth_when_enabled (line 117) | async def test_cloud_status_requires_auth_when_enabled(self, async_cli... class TestCloudEndpointPermissions (line 124) | class TestCloudEndpointPermissions: method settings_only_setup (line 132) | async def settings_only_setup(self, async_client: AsyncClient): method cloud_only_setup (line 163) | async def cloud_only_setup(self, async_client: AsyncClient): method test_cloud_settings_requires_cloud_auth_not_settings_read (line 195) | async def test_cloud_settings_requires_cloud_auth_not_settings_read( method test_cloud_status_requires_cloud_auth (line 221) | async def test_cloud_status_requires_cloud_auth( method test_cloud_fields_requires_cloud_auth (line 242) | async def test_cloud_fields_requires_cloud_auth( class TestCloudTokenStorage (line 262) | class TestCloudTokenStorage: method test_get_stored_token_returns_none_when_no_user_no_global (line 266) | async def test_get_stored_token_returns_none_when_no_user_no_global(se... method test_store_and_get_global_token (line 276) | async def test_store_and_get_global_token(self, db_session): method test_store_and_get_per_user_token (line 287) | async def test_store_and_get_per_user_token(self, db_session): method test_per_user_token_does_not_affect_global (line 310) | async def test_per_user_token_does_not_affect_global(self, db_session): method test_clear_per_user_token (line 330) | async def test_clear_per_user_token(self, db_session): method test_clear_global_token (line 353) | async def test_clear_global_token(self, db_session): method test_two_users_independent_tokens (line 366) | async def test_two_users_independent_tokens(self, db_session): class TestCloudRegionPersistence (line 403) | class TestCloudRegionPersistence: method test_region_survives_roundtrip_per_user (line 407) | async def test_region_survives_roundtrip_per_user(self, db_session): method test_region_survives_roundtrip_global_fallback (line 430) | async def test_region_survives_roundtrip_global_fallback(self, db_sess... method test_invalid_region_is_normalised_to_global (line 439) | async def test_invalid_region_is_normalised_to_global(self, db_session): method test_build_authenticated_cloud_uses_stored_region (line 448) | async def test_build_authenticated_cloud_uses_stored_region(self, db_s... class TestCloudRouteRegionPlumbing (line 475) | class TestCloudRouteRegionPlumbing: method _capturing_client (line 487) | def _capturing_client(response_json: dict, status: int = 200): method test_set_token_route_with_china_region_hits_cn_endpoint (line 511) | async def test_set_token_route_with_china_region_hits_cn_endpoint(self... method test_login_route_with_china_region_hits_cn_endpoint (line 533) | async def test_login_route_with_china_region_hits_cn_endpoint(self, as... method test_verify_route_with_china_region_hits_cn_tfa_endpoint (line 555) | async def test_verify_route_with_china_region_hits_cn_tfa_endpoint(sel... method test_cloud_status_exposes_stored_region (line 584) | async def test_cloud_status_exposes_stored_region(self, async_client: ... method test_cloud_status_region_is_null_when_unauthenticated (line 602) | async def test_cloud_status_region_is_null_when_unauthenticated(self, ... FILE: backend/tests/integration/test_color_map_api.py function _seed (line 21) | async def _seed(db_session, entries): function test_color_map_empty_catalog (line 29) | async def test_color_map_empty_catalog(async_client: AsyncClient): function test_color_map_returns_lowercase_hex_without_hash (line 39) | async def test_color_map_returns_lowercase_hex_without_hash(async_client... function test_color_map_bambu_wins_over_generic_on_same_hex (line 76) | async def test_color_map_bambu_wins_over_generic_on_same_hex(async_clien... function test_color_map_default_wins_over_user_added (line 105) | async def test_color_map_default_wins_over_user_added(async_client: Asyn... function test_color_map_skips_invalid_entries (line 135) | async def test_color_map_skips_invalid_entries(async_client: AsyncClient... FILE: backend/tests/integration/test_cost_statistics.py function cleanup_test_archive_files (line 12) | def cleanup_test_archive_files(): class TestArchiveCostTracking (line 34) | class TestArchiveCostTracking: method test_archive_has_cost_field (line 39) | async def test_archive_has_cost_field( method test_archive_cost_null_when_not_set (line 61) | async def test_archive_cost_null_when_not_set( class TestStatisticsCostAggregation (line 81) | class TestStatisticsCostAggregation: method test_statistics_includes_total_cost (line 86) | async def test_statistics_includes_total_cost( method test_statistics_aggregates_costs_correctly (line 116) | async def test_statistics_aggregates_costs_correctly( method test_statistics_handles_null_costs (line 142) | async def test_statistics_handles_null_costs( method test_statistics_includes_failed_print_costs (line 164) | async def test_statistics_includes_failed_print_costs( method test_statistics_zero_cost_when_no_archives (line 184) | async def test_statistics_zero_cost_when_no_archives(self, async_clien... class TestSpoolCostPersistence (line 193) | class TestSpoolCostPersistence: method test_spool_cost_fields_persist (line 198) | async def test_spool_cost_fields_persist(self, async_client: AsyncClie... method test_spool_update_cost_fields (line 223) | async def test_spool_update_cost_fields(self, async_client: AsyncClien... method test_spool_cost_null_by_default (line 251) | async def test_spool_cost_null_by_default(self, async_client: AsyncCli... class TestCostCalculationScenarios (line 267) | class TestCostCalculationScenarios: method test_cost_with_multiple_colors (line 272) | async def test_cost_with_multiple_colors(self, async_client: AsyncClie... method test_cost_precision (line 303) | async def test_cost_precision(self, async_client: AsyncClient, db_sess... method test_archive_cost_with_archive_id_and_print_name (line 324) | async def test_archive_cost_with_archive_id_and_print_name( FILE: backend/tests/integration/test_discovery_api.py class TestDiscoveryAPI (line 10) | class TestDiscoveryAPI: method test_get_discovery_info (line 19) | async def test_get_discovery_info(self, async_client: AsyncClient): method test_discovery_info_subnets_are_cidr (line 36) | async def test_discovery_info_subnets_are_cidr(self, async_client: Asy... method test_get_discovery_status (line 53) | async def test_get_discovery_status(self, async_client: AsyncClient): method test_start_discovery (line 64) | async def test_start_discovery(self, async_client: AsyncClient): method test_stop_discovery (line 74) | async def test_stop_discovery(self, async_client: AsyncClient): method test_get_discovered_printers_empty (line 85) | async def test_get_discovered_printers_empty(self, async_client: Async... method test_start_subnet_scan (line 99) | async def test_start_subnet_scan(self, async_client: AsyncClient): method test_get_scan_status (line 114) | async def test_get_scan_status(self, async_client: AsyncClient): method test_stop_subnet_scan (line 126) | async def test_stop_subnet_scan(self, async_client: AsyncClient): method test_subnet_scan_invalid_subnet (line 136) | async def test_subnet_scan_invalid_subnet(self, async_client: AsyncCli... class TestDiscoveryService (line 144) | class TestDiscoveryService: method test_docker_detection_fields (line 149) | async def test_docker_detection_fields(self, async_client: AsyncClient): method test_subnets_consistent_across_calls (line 161) | async def test_subnets_consistent_across_calls(self, async_client: Asy... FILE: backend/tests/integration/test_endpoint_auth.py class TestEndpointAuthenticationEnforcement (line 13) | class TestEndpointAuthenticationEnforcement: method user_factory (line 17) | async def user_factory(self, db_session): method admin_user (line 41) | async def admin_user(self, user_factory, db_session): method auth_token (line 58) | async def auth_token(self, admin_user, async_client: AsyncClient): method test_filaments_list_accessible_without_auth_when_disabled (line 70) | async def test_filaments_list_accessible_without_auth_when_disabled(se... method test_external_links_list_accessible_without_auth_when_disabled (line 78) | async def test_external_links_list_accessible_without_auth_when_disabl... method test_notifications_list_accessible_without_auth_when_disabled (line 86) | async def test_notifications_list_accessible_without_auth_when_disable... method test_maintenance_types_accessible_without_auth_when_disabled (line 94) | async def test_maintenance_types_accessible_without_auth_when_disabled... method test_system_info_accessible_without_auth_when_disabled (line 102) | async def test_system_info_accessible_without_auth_when_disabled(self,... class TestImageEndpointsPublicAccess (line 109) | class TestImageEndpointsPublicAccess: method link_with_icon (line 116) | async def link_with_icon(self, db_session): method test_external_link_icon_returns_404_when_no_icon (line 134) | async def test_external_link_icon_returns_404_when_no_icon(self, async... class TestAuthenticationPatterns (line 147) | class TestAuthenticationPatterns: method test_require_permission_if_auth_enabled_allows_access_when_disabled (line 152) | async def test_require_permission_if_auth_enabled_allows_access_when_d... method test_multiple_endpoints_accessible_when_auth_disabled (line 161) | async def test_multiple_endpoints_accessible_when_auth_disabled(self, ... FILE: backend/tests/integration/test_external_folders_api.py class TestExternalFolderCreation (line 11) | class TestExternalFolderCreation: method external_dir (line 15) | def external_dir(self, tmp_path): method nested_external_dir (line 28) | def nested_external_dir(self, external_dir): method test_create_external_folder (line 37) | async def test_create_external_folder(self, async_client: AsyncClient,... method test_create_external_folder_nonexistent_path (line 56) | async def test_create_external_folder_nonexistent_path(self, async_cli... method test_create_external_folder_system_dir_blocked (line 68) | async def test_create_external_folder_system_dir_blocked(self, async_c... method test_create_external_folder_file_not_dir (line 80) | async def test_create_external_folder_file_not_dir(self, async_client:... method test_create_external_folder_duplicate_path (line 94) | async def test_create_external_folder_duplicate_path(self, async_clien... method test_external_folder_appears_in_tree (line 110) | async def test_external_folder_appears_in_tree(self, async_client: Asy... function find_folder_in_tree (line 128) | def find_folder_in_tree(folders: list, name: str) -> dict | None: function collect_folder_names (line 139) | def collect_folder_names(folders: list) -> list[str]: class TestExternalFolderScan (line 148) | class TestExternalFolderScan: method external_dir (line 152) | def external_dir(self, tmp_path): method external_folder (line 167) | async def external_folder(self, async_client, db_session, external_dir): method test_scan_discovers_files (line 180) | async def test_scan_discovers_files(self, async_client: AsyncClient, d... method test_scan_skips_hidden_files (line 212) | async def test_scan_skips_hidden_files(self, async_client: AsyncClient... method test_scan_shows_hidden_when_enabled (line 225) | async def test_scan_shows_hidden_when_enabled(self, async_client: Asyn... method test_scan_idempotent (line 242) | async def test_scan_idempotent(self, async_client: AsyncClient, db_ses... method test_scan_removes_deleted_files (line 253) | async def test_scan_removes_deleted_files( method test_scan_non_external_folder_fails (line 269) | async def test_scan_non_external_folder_fails(self, async_client: Asyn... method test_scan_files_marked_external (line 282) | async def test_scan_files_marked_external(self, async_client: AsyncCli... method test_scan_creates_nested_subfolders (line 305) | async def test_scan_creates_nested_subfolders(self, async_client: Asyn... method test_scan_skips_hidden_directories (line 349) | async def test_scan_skips_hidden_directories(self, async_client: Async... method test_scan_removes_deleted_subfolder (line 376) | async def test_scan_removes_deleted_subfolder( method test_scan_subfolder_inherits_readonly (line 404) | async def test_scan_subfolder_inherits_readonly( class TestExternalFolderProtections (line 416) | class TestExternalFolderProtections: method external_dir (line 420) | def external_dir(self, tmp_path): method readonly_folder (line 427) | async def readonly_folder(self, async_client, db_session, external_dir): method test_upload_to_readonly_folder_blocked (line 441) | async def test_upload_to_readonly_folder_blocked(self, async_client: A... method test_move_to_readonly_folder_blocked (line 455) | async def test_move_to_readonly_folder_blocked(self, async_client: Asy... method test_external_files_cannot_be_moved_out (line 477) | async def test_external_files_cannot_be_moved_out(self, async_client: ... method test_delete_external_file_removes_db_only (line 495) | async def test_delete_external_file_removes_db_only( method test_delete_external_folder_preserves_files (line 513) | async def test_delete_external_folder_preserves_files( method test_zip_to_readonly_folder_blocked (line 525) | async def test_zip_to_readonly_folder_blocked(self, async_client: Asyn... FILE: backend/tests/integration/test_external_links_api.py class TestExternalLinksAPI (line 7) | class TestExternalLinksAPI: method link_factory (line 11) | async def link_factory(self, db_session): method test_list_external_links_empty (line 39) | async def test_list_external_links_empty(self, async_client: AsyncClie... method test_list_external_links_with_data (line 47) | async def test_list_external_links_with_data(self, async_client: Async... method test_create_external_link (line 57) | async def test_create_external_link(self, async_client: AsyncClient): method test_get_external_link (line 72) | async def test_get_external_link(self, async_client: AsyncClient, link... method test_get_external_link_not_found (line 81) | async def test_get_external_link_not_found(self, async_client: AsyncCl... method test_update_external_link (line 88) | async def test_update_external_link(self, async_client: AsyncClient, l... method test_delete_external_link (line 101) | async def test_delete_external_link(self, async_client: AsyncClient, l... method test_reorder_external_links (line 112) | async def test_reorder_external_links(self, async_client: AsyncClient,... class TestExternalLinksIconAPI (line 129) | class TestExternalLinksIconAPI: method link_factory (line 133) | async def link_factory(self, db_session): method test_get_icon_not_set (line 157) | async def test_get_icon_not_set(self, async_client: AsyncClient, link_... method test_delete_icon_when_none (line 165) | async def test_delete_icon_when_none(self, async_client: AsyncClient, ... FILE: backend/tests/integration/test_filaments_api.py class TestFilamentsAPI (line 7) | class TestFilamentsAPI: method filament_factory (line 11) | async def filament_factory(self, db_session): method test_list_filaments_empty (line 37) | async def test_list_filaments_empty(self, async_client: AsyncClient): method test_list_filaments_with_data (line 45) | async def test_list_filaments_with_data(self, async_client: AsyncClien... method test_create_filament (line 55) | async def test_create_filament(self, async_client: AsyncClient): method test_get_filament (line 73) | async def test_get_filament(self, async_client: AsyncClient, filament_... method test_get_filament_not_found (line 82) | async def test_get_filament_not_found(self, async_client: AsyncClient): method test_update_filament (line 89) | async def test_update_filament(self, async_client: AsyncClient, filame... method test_delete_filament (line 102) | async def test_delete_filament(self, async_client: AsyncClient, filame... FILE: backend/tests/integration/test_github_backup_api.py class TestGitHubBackupConfigAPI (line 7) | class TestGitHubBackupConfigAPI: method test_get_config_no_config (line 12) | async def test_get_config_no_config(self, async_client: AsyncClient): method test_create_config (line 20) | async def test_create_config(self, async_client: AsyncClient): method test_get_config_after_create (line 49) | async def test_get_config_after_create(self, async_client: AsyncClient): method test_create_config_with_spools_and_archives (line 76) | async def test_create_config_with_spools_and_archives(self, async_clie... method test_update_config_partial (line 100) | async def test_update_config_partial(self, async_client: AsyncClient): method test_update_config_enable_spools_and_archives (line 133) | async def test_update_config_enable_spools_and_archives(self, async_cl... method test_delete_config (line 167) | async def test_delete_config(self, async_client: AsyncClient): method test_delete_config_not_found (line 194) | async def test_delete_config_not_found(self, async_client: AsyncClient): class TestGitHubBackupStatusAPI (line 204) | class TestGitHubBackupStatusAPI: method test_status_no_config (line 209) | async def test_status_no_config(self, async_client: AsyncClient): method test_status_with_config (line 223) | async def test_status_with_config(self, async_client: AsyncClient): class TestGitHubBackupLogsAPI (line 248) | class TestGitHubBackupLogsAPI: method test_logs_no_config (line 253) | async def test_logs_no_config(self, async_client: AsyncClient): method test_logs_with_config (line 264) | async def test_logs_with_config(self, async_client: AsyncClient): class TestGitHubBackupTriggerAPI (line 286) | class TestGitHubBackupTriggerAPI: method test_trigger_no_config (line 291) | async def test_trigger_no_config(self, async_client: AsyncClient): method test_trigger_disabled_config (line 301) | async def test_trigger_disabled_config(self, async_client: AsyncClient): FILE: backend/tests/integration/test_inventory_assign.py function spool_factory (line 18) | async def spool_factory(db_session: AsyncSession): function _make_mock_status (line 44) | def _make_mock_status(ams_data=None, vt_tray=None, nozzles=None, ams_ext... class TestAssignSpoolTrayInfoIdx (line 58) | class TestAssignSpoolTrayInfoIdx: method test_pfus_slicer_filament_used_directly (line 63) | async def test_pfus_slicer_filament_used_directly(self, async_client: ... method test_spool_preset_takes_priority_over_slot (line 89) | async def test_spool_preset_takes_priority_over_slot( method test_spool_preset_used_even_if_different_material_on_slot (line 121) | async def test_spool_preset_used_even_if_different_material_on_slot( method test_gf_slicer_filament_kept (line 152) | async def test_gf_slicer_filament_kept(self, async_client: AsyncClient... method test_empty_slicer_filament_uses_generic (line 178) | async def test_empty_slicer_filament_uses_generic(self, async_client: ... method test_spool_pfus_used_over_slot_pfus (line 204) | async def test_spool_pfus_used_over_slot_pfus(self, async_client: Asyn... method test_generic_on_slot_not_reused_over_spool_preset (line 234) | async def test_generic_on_slot_not_reused_over_spool_preset( method test_no_preset_with_generic_on_slot_still_uses_generic (line 266) | async def test_no_preset_with_generic_on_slot_still_uses_generic( method test_no_preset_reuses_specific_slot_preset (line 298) | async def test_no_preset_reuses_specific_slot_preset( class TestAssignSpoolPresetMapping (line 329) | class TestAssignSpoolPresetMapping: method test_preset_mapping_saved_with_slicer_filament_name (line 334) | async def test_preset_mapping_saved_with_slicer_filament_name( method test_preset_mapping_overwrites_old_mapping (line 376) | async def test_preset_mapping_overwrites_old_mapping( method test_preset_mapping_fallback_to_tray_sub_brands (line 432) | async def test_preset_mapping_fallback_to_tray_sub_brands( FILE: backend/tests/integration/test_library_api.py class TestLibraryFoldersAPI (line 12) | class TestLibraryFoldersAPI: method folder_factory (line 16) | async def folder_factory(self, db_session): method test_list_folders_empty (line 41) | async def test_list_folders_empty(self, async_client: AsyncClient, db_... method test_create_folder (line 49) | async def test_create_folder(self, async_client: AsyncClient, db_sessi... method test_create_nested_folder (line 60) | async def test_create_nested_folder(self, async_client: AsyncClient, f... method test_get_folder (line 72) | async def test_get_folder(self, async_client: AsyncClient, folder_fact... method test_get_folder_not_found (line 83) | async def test_get_folder_not_found(self, async_client: AsyncClient, d... method test_update_folder (line 90) | async def test_update_folder(self, async_client: AsyncClient, folder_f... method test_delete_folder (line 101) | async def test_delete_folder(self, async_client: AsyncClient, folder_f... class TestLibraryFilesAPI (line 110) | class TestLibraryFilesAPI: method folder_factory (line 114) | async def folder_factory(self, db_session): method file_factory (line 136) | async def file_factory(self, db_session): method test_list_files_empty (line 164) | async def test_list_files_empty(self, async_client: AsyncClient, db_se... method test_list_files_in_folder (line 172) | async def test_list_files_in_folder(self, async_client: AsyncClient, f... method test_list_files_by_project_id (line 186) | async def test_list_files_by_project_id(self, async_client: AsyncClien... method test_list_files_folder_id_takes_precedence_over_project_id (line 217) | async def test_list_files_folder_id_takes_precedence_over_project_id( method test_get_file (line 248) | async def test_get_file(self, async_client: AsyncClient, file_factory,... method test_get_file_not_found (line 259) | async def test_get_file_not_found(self, async_client: AsyncClient, db_... method test_delete_file (line 266) | async def test_delete_file(self, async_client: AsyncClient, file_facto... method test_rename_file (line 276) | async def test_rename_file(self, async_client: AsyncClient, file_facto... method test_rename_file_invalid_path_separator (line 287) | async def test_rename_file_invalid_path_separator(self, async_client: ... method test_rename_file_invalid_backslash (line 297) | async def test_rename_file_invalid_backslash(self, async_client: Async... method test_library_stats (line 307) | async def test_library_stats(self, async_client: AsyncClient, folder_f... method test_file_list_includes_user_tracking_fields (line 321) | async def test_file_list_includes_user_tracking_fields(self, async_cli... method test_file_detail_includes_user_tracking_fields (line 337) | async def test_file_detail_includes_user_tracking_fields(self, async_c... method test_file_with_user_tracking (line 349) | async def test_file_with_user_tracking(self, async_client: AsyncClient... class TestLibraryAddToQueueAPI (line 388) | class TestLibraryAddToQueueAPI: method printer_factory (line 392) | async def printer_factory(self, db_session): method library_file_factory (line 420) | async def library_file_factory(self, db_session): method test_add_to_queue_file_not_found (line 448) | async def test_add_to_queue_file_not_found(self, async_client: AsyncCl... method test_add_non_sliced_file_to_queue_fails (line 462) | async def test_add_non_sliced_file_to_queue_fails( class TestLibraryZipExtractAPI (line 482) | class TestLibraryZipExtractAPI: method test_extract_zip_invalid_file_type (line 487) | async def test_extract_zip_invalid_file_type(self, async_client: Async... method test_extract_zip_basic (line 497) | async def test_extract_zip_basic(self, async_client: AsyncClient, db_s... method test_extract_zip_with_folders (line 518) | async def test_extract_zip_with_folders(self, async_client: AsyncClien... method test_extract_zip_flat (line 540) | async def test_extract_zip_flat(self, async_client: AsyncClient, db_se... method test_extract_zip_skips_macos_files (line 561) | async def test_extract_zip_skips_macos_files(self, async_client: Async... method test_extract_zip_create_folder_from_zip (line 582) | async def test_extract_zip_create_folder_from_zip(self, async_client: ... class TestLibraryStlThumbnailAPI (line 614) | class TestLibraryStlThumbnailAPI: method file_factory (line 618) | async def file_factory(self, db_session): method test_batch_generate_thumbnails_empty (line 646) | async def test_batch_generate_thumbnails_empty(self, async_client: Asy... method test_batch_generate_thumbnails_no_criteria (line 659) | async def test_batch_generate_thumbnails_no_criteria(self, async_clien... method test_batch_generate_thumbnails_file_not_on_disk (line 669) | async def test_batch_generate_thumbnails_file_not_on_disk( method test_batch_generate_thumbnails_with_real_stl (line 692) | async def test_batch_generate_thumbnails_with_real_stl(self, async_cli... method test_upload_file_with_stl_thumbnail_param (line 747) | async def test_upload_file_with_stl_thumbnail_param(self, async_client... method test_extract_zip_with_stl_thumbnail_param (line 764) | async def test_extract_zip_with_stl_thumbnail_param(self, async_client... method test_batch_generate_thumbnails_by_folder (line 783) | async def test_batch_generate_thumbnails_by_folder(self, async_client:... method test_batch_generate_thumbnails_all_missing (line 818) | async def test_batch_generate_thumbnails_all_missing(self, async_clien... class TestLibraryPathHelpers (line 845) | class TestLibraryPathHelpers: method test_to_relative_path_converts_absolute (line 848) | def test_to_relative_path_converts_absolute(self): method test_to_relative_path_handles_path_object (line 860) | def test_to_relative_path_handles_path_object(self): method test_to_relative_path_returns_empty_for_empty_input (line 873) | def test_to_relative_path_returns_empty_for_empty_input(self): method test_to_absolute_path_converts_relative (line 880) | def test_to_absolute_path_converts_relative(self): method test_to_absolute_path_handles_already_absolute (line 892) | def test_to_absolute_path_handles_already_absolute(self): method test_to_absolute_path_returns_none_for_empty (line 902) | def test_to_absolute_path_returns_none_for_empty(self): class TestLibraryPermissions (line 910) | class TestLibraryPermissions: method auth_setup (line 914) | async def auth_setup(self, db_session): method test_file (line 966) | async def test_file(self, db_session, auth_setup): method test_list_files_requires_library_read (line 985) | async def test_list_files_requires_library_read(self, async_client: As... method test_list_files_denied_without_permission (line 995) | async def test_list_files_denied_without_permission(self, async_client... method test_delete_file_own_by_owner (line 1010) | async def test_delete_file_own_by_owner(self, async_client: AsyncClien... method test_delete_file_own_denied_for_others_file (line 1030) | async def test_delete_file_own_denied_for_others_file(self, async_clie... method test_delete_file_admin_can_delete_any (line 1072) | async def test_delete_file_admin_can_delete_any(self, async_client: As... method test_viewer_cannot_delete_files (line 1106) | async def test_viewer_cannot_delete_files(self, async_client: AsyncCli... FILE: backend/tests/integration/test_maintenance_api.py class TestMaintenanceTypesAPI (line 7) | class TestMaintenanceTypesAPI: method test_list_maintenance_types (line 12) | async def test_list_maintenance_types(self, async_client: AsyncClient): method test_list_includes_system_types (line 23) | async def test_list_includes_system_types(self, async_client: AsyncCli... method test_create_custom_maintenance_type (line 34) | async def test_create_custom_maintenance_type(self, async_client: Asyn... method test_update_maintenance_type (line 51) | async def test_update_maintenance_type(self, async_client: AsyncClient): method test_delete_custom_maintenance_type (line 71) | async def test_delete_custom_maintenance_type(self, async_client: Asyn... class TestPrinterMaintenanceAPI (line 87) | class TestPrinterMaintenanceAPI: method test_get_printer_maintenance_not_found (line 92) | async def test_get_printer_maintenance_not_found(self, async_client: A... method test_get_printer_maintenance (line 99) | async def test_get_printer_maintenance(self, async_client: AsyncClient... method test_get_all_maintenance_overview (line 112) | async def test_get_all_maintenance_overview(self, async_client: AsyncC... method test_get_maintenance_summary (line 123) | async def test_get_maintenance_summary(self, async_client: AsyncClient): class TestMaintenanceItemsAPI (line 133) | class TestMaintenanceItemsAPI: method maintenance_item (line 137) | async def maintenance_item(self, async_client: AsyncClient, printer_fa... method test_update_maintenance_item (line 151) | async def test_update_maintenance_item(self, async_client: AsyncClient... method test_disable_maintenance_item (line 164) | async def test_disable_maintenance_item(self, async_client: AsyncClien... method test_perform_maintenance (line 176) | async def test_perform_maintenance(self, async_client: AsyncClient, ma... method test_get_maintenance_history (line 191) | async def test_get_maintenance_history(self, async_client: AsyncClient... method test_update_maintenance_item_not_found (line 207) | async def test_update_maintenance_item_not_found(self, async_client: A... class TestPrinterHoursAPI (line 213) | class TestPrinterHoursAPI: method test_set_printer_hours (line 218) | async def test_set_printer_hours(self, async_client: AsyncClient, prin... method test_set_printer_hours_not_found (line 230) | async def test_set_printer_hours_not_found(self, async_client: AsyncCl... FILE: backend/tests/integration/test_metrics_api.py class TestMetricsAPI (line 10) | class TestMetricsAPI: method test_metrics_disabled_returns_404 (line 19) | async def test_metrics_disabled_returns_404(self, async_client: AsyncC... method test_metrics_enabled_without_token (line 31) | async def test_metrics_enabled_without_token(self, async_client: Async... method test_metrics_with_token_requires_auth (line 43) | async def test_metrics_with_token_requires_auth(self, async_client: As... method test_metrics_format (line 66) | async def test_metrics_format(self, async_client: AsyncClient): method test_metrics_contains_expected_metrics (line 82) | async def test_metrics_contains_expected_metrics(self, async_client: A... method test_metrics_printer_metrics_when_no_printers (line 102) | async def test_metrics_printer_metrics_when_no_printers(self, async_cl... method test_prometheus_settings_persist (line 122) | async def test_prometheus_settings_persist(self, async_client: AsyncCl... FILE: backend/tests/integration/test_mfa_api.py function _norm_pw (line 42) | def _norm_pw(password: str) -> str: function _setup_and_login (line 51) | async def _setup_and_login(client: AsyncClient, username: str, password:... function _login_get_pre_auth_token (line 67) | async def _login_get_pre_auth_token(client: AsyncClient, username: str, ... function _auth_header (line 78) | def _auth_header(token: str) -> dict[str, str]: class TestTwoFAStatus (line 87) | class TestTwoFAStatus: method test_status_requires_auth (line 92) | async def test_status_requires_auth(self, async_client: AsyncClient): method test_status_default_disabled (line 98) | async def test_status_default_disabled(self, async_client: AsyncClient): class TestTOTPSetup (line 113) | class TestTOTPSetup: method test_setup_requires_auth (line 118) | async def test_setup_requires_auth(self, async_client: AsyncClient): method test_setup_returns_secret_and_qr (line 124) | async def test_setup_returns_secret_and_qr(self, async_client: AsyncCl... method test_setup_secret_is_valid_base32 (line 136) | async def test_setup_secret_is_valid_base32(self, async_client: AsyncC... class TestTOTPEnable (line 151) | class TestTOTPEnable: method test_enable_without_setup_returns_400 (line 156) | async def test_enable_without_setup_returns_400(self, async_client: As... method test_enable_with_invalid_code_returns_400 (line 167) | async def test_enable_with_invalid_code_returns_400(self, async_client... method test_enable_with_valid_code_returns_backup_codes (line 179) | async def test_enable_with_valid_code_returns_backup_codes(self, async... method test_status_reflects_enabled_totp (line 199) | async def test_status_reflects_enabled_totp(self, async_client: AsyncC... class TestTOTPDisable (line 221) | class TestTOTPDisable: method test_disable_when_not_enabled_returns_400 (line 226) | async def test_disable_when_not_enabled_returns_400(self, async_client... method test_disable_with_valid_code (line 237) | async def test_disable_with_valid_code(self, async_client: AsyncClient): class TestEmailOTP (line 268) | class TestEmailOTP: method test_enable_email_otp_without_email_returns_400 (line 273) | async def test_enable_email_otp_without_email_returns_400(self, async_... method test_confirm_enable_email_otp_happy_path (line 282) | async def test_confirm_enable_email_otp_happy_path(self, async_client:... method test_confirm_enable_email_otp_wrong_code (line 321) | async def test_confirm_enable_email_otp_wrong_code(self, async_client:... method test_confirm_enable_email_otp_setup_token_is_single_use (line 347) | async def test_confirm_enable_email_otp_setup_token_is_single_use( method test_disable_email_otp_requires_password (line 383) | async def test_disable_email_otp_requires_password(self, async_client:... method test_disable_email_otp_when_enabled (line 396) | async def test_disable_email_otp_when_enabled(self, async_client: Asyn... class TestTwoFAVerifyTOTP (line 436) | class TestTwoFAVerifyTOTP: method test_verify_with_invalid_pre_auth_token (line 441) | async def test_verify_with_invalid_pre_auth_token(self, async_client: ... method test_verify_totp_issues_jwt (line 450) | async def test_verify_totp_issues_jwt(self, async_client: AsyncClient): method test_verify_totp_invalid_code (line 481) | async def test_verify_totp_invalid_code(self, async_client: AsyncClient): method test_verify_invalid_method (line 501) | async def test_verify_invalid_method(self, async_client: AsyncClient): class TestTwoFAVerifyBackup (line 525) | class TestTwoFAVerifyBackup: method test_verify_with_backup_code (line 530) | async def test_verify_with_backup_code(self, async_client: AsyncClient): method test_backup_code_is_single_use (line 552) | async def test_backup_code_is_single_use(self, async_client: AsyncClie... method test_backup_code_count_decrements (line 582) | async def test_backup_code_count_decrements(self, async_client: AsyncC... class TestRateLimiting (line 610) | class TestRateLimiting: method test_rate_limit_lockout (line 615) | async def test_rate_limit_lockout(self, async_client: AsyncClient): class TestAdminDisable2FA (line 649) | class TestAdminDisable2FA: method test_admin_disable_requires_admin (line 654) | async def test_admin_disable_requires_admin(self, async_client: AsyncC... method test_admin_disable_clears_totp (line 670) | async def test_admin_disable_clears_totp(self, async_client: AsyncClie... class TestOIDCProviders (line 718) | class TestOIDCProviders: method test_list_public_providers_empty (line 723) | async def test_list_public_providers_empty(self, async_client: AsyncCl... method test_create_provider_requires_admin (line 730) | async def test_create_provider_requires_admin(self, async_client: Asyn... method test_created_provider_appears_in_all_list (line 753) | async def test_created_provider_appears_in_all_list(self, async_client... method test_disabled_provider_not_in_public_list (line 775) | async def test_disabled_provider_not_in_public_list(self, async_client... method test_update_provider (line 796) | async def test_update_provider(self, async_client: AsyncClient): method test_delete_provider (line 823) | async def test_delete_provider(self, async_client: AsyncClient): method test_update_nonexistent_provider_returns_404 (line 853) | async def test_update_nonexistent_provider_returns_404(self, async_cli... class TestPreAuthTokenSingleUse (line 868) | class TestPreAuthTokenSingleUse: method test_pre_auth_token_is_single_use (line 873) | async def test_pre_auth_token_is_single_use(self, async_client: AsyncC... method test_pre_auth_token_survives_wrong_code (line 903) | async def test_pre_auth_token_survives_wrong_code(self, async_client: ... class TestCrossUserTokenIsolation (line 937) | class TestCrossUserTokenIsolation: method test_token_cannot_be_used_for_different_user (line 942) | async def test_token_cannot_be_used_for_different_user(self, async_cli... class TestAdminDisableNonAdminRejection (line 971) | class TestAdminDisableNonAdminRejection: method test_non_admin_cannot_disable_2fa (line 976) | async def test_non_admin_cannot_disable_2fa(self, async_client: AsyncC... class TestRegenerateBackupCodes (line 1009) | class TestRegenerateBackupCodes: method test_regenerate_requires_totp_enabled (line 1014) | async def test_regenerate_requires_totp_enabled(self, async_client: As... method test_regenerate_invalidates_old_codes (line 1025) | async def test_regenerate_invalidates_old_codes(self, async_client: As... method test_regenerate_with_invalid_code_fails (line 1058) | async def test_regenerate_with_invalid_code_fails(self, async_client: ... class TestVerifyMethodValidation (line 1081) | class TestVerifyMethodValidation: method test_invalid_method_rejected_by_schema (line 1086) | async def test_invalid_method_rejected_by_schema(self, async_client: A... method test_oversized_pre_auth_token_rejected (line 1096) | async def test_oversized_pre_auth_token_rejected(self, async_client: A... class TestLoginResponseShape (line 1110) | class TestLoginResponseShape: method test_login_2fa_user_omits_access_token (line 1116) | async def test_login_2fa_user_omits_access_token(self, async_client: A... function _setup_totp_user (line 1141) | async def _setup_totp_user(client: AsyncClient, username: str, password:... class TestTOTPReplay (line 1154) | class TestTOTPReplay: method test_totp_replay_rejected_on_verify (line 1159) | async def test_totp_replay_rejected_on_verify(self, async_client: Asyn... method test_totp_replay_rejected_on_disable (line 1181) | async def test_totp_replay_rejected_on_disable(self, async_client: Asy... class TestRateLimitingDisableRegenerate (line 1209) | class TestRateLimitingDisableRegenerate: method test_disable_totp_rate_limited_after_failures (line 1214) | async def test_disable_totp_rate_limited_after_failures(self, async_cl... method test_regenerate_backup_codes_rate_limited_after_failures (line 1232) | async def test_regenerate_backup_codes_rate_limited_after_failures(sel... class TestEmailOTPSendVerify (line 1254) | class TestEmailOTPSendVerify: method test_email_otp_send_and_verify (line 1259) | async def test_email_otp_send_and_verify(self, async_client: AsyncClie... method test_email_otp_wrong_code_rejected (line 1330) | async def test_email_otp_wrong_code_rejected(self, async_client: Async... function _make_test_rsa_key (line 1404) | def _make_test_rsa_key(): class TestOIDCEndToEnd (line 1437) | class TestOIDCEndToEnd: method test_oidc_callback_creates_user_and_issues_jwt (line 1442) | async def test_oidc_callback_creates_user_and_issues_jwt(self, async_c... method test_oidc_callback_invalid_state_redirects_error (line 1572) | async def test_oidc_callback_invalid_state_redirects_error(self, async... method test_oidc_state_is_single_use (line 1583) | async def test_oidc_state_is_single_use(self, async_client: AsyncClien... class TestEmailOTPSetupTokenPreservedOnWrongCode (line 1699) | class TestEmailOTPSetupTokenPreservedOnWrongCode: method test_wrong_code_does_not_consume_setup_token (line 1704) | async def test_wrong_code_does_not_consume_setup_token(self, async_cli... class TestOIDCProviderAutoLinkDefault (line 1744) | class TestOIDCProviderAutoLinkDefault: method test_new_provider_auto_link_defaults_to_false (line 1749) | async def test_new_provider_auto_link_defaults_to_false(self, async_cl... class TestTwoFAVerifyCodeFormat (line 1774) | class TestTwoFAVerifyCodeFormat: method test_code_too_long_rejected (line 1779) | async def test_code_too_long_rejected(self, async_client: AsyncClient): method test_code_non_alphanumeric_rejected (line 1789) | async def test_code_non_alphanumeric_rejected(self, async_client: Asyn... method test_code_too_short_rejected (line 1799) | async def test_code_too_short_rejected(self, async_client: AsyncClient): method test_code_exactly_6_passes_schema (line 1809) | async def test_code_exactly_6_passes_schema(self, async_client: AsyncC... method test_code_exactly_8_passes_schema (line 1819) | async def test_code_exactly_8_passes_schema(self, async_client: AsyncC... class TestSlicerTokenResourceBinding (line 1833) | class TestSlicerTokenResourceBinding: method test_wrong_resource_does_not_consume_token (line 1838) | async def test_wrong_resource_does_not_consume_token(self, async_clien... method test_correct_resource_consumes_token (line 1867) | async def test_correct_resource_consumes_token(self, async_client: Asy... class TestSchemaLengthValidationR2 (line 1898) | class TestSchemaLengthValidationR2: method test_change_password_current_too_long_rejected (line 1903) | async def test_change_password_current_too_long_rejected(self, async_c... method test_forgot_password_email_too_long_rejected (line 1913) | async def test_forgot_password_email_too_long_rejected(self, async_cli... method test_forgot_password_email_at_limit_passes_schema (line 1923) | async def test_forgot_password_email_at_limit_passes_schema(self, asyn... class TestTOTPSetupCodeMaxLength (line 1937) | class TestTOTPSetupCodeMaxLength: method test_setup_code_too_long_rejected (line 1942) | async def test_setup_code_too_long_rejected(self, async_client: AsyncC... class TestEmailOTPConfirmCodeFormat (line 1969) | class TestEmailOTPConfirmCodeFormat: method test_non_digit_code_rejected (line 1974) | async def test_non_digit_code_rejected(self, async_client: AsyncClient): method test_seven_digit_code_rejected (line 1987) | async def test_seven_digit_code_rejected(self, async_client: AsyncClie... method test_valid_six_digit_code_passes_schema (line 2000) | async def test_valid_six_digit_code_passes_schema(self, async_client: ... class TestOIDCProviderFieldLengths (line 2017) | class TestOIDCProviderFieldLengths: method test_name_too_long_rejected (line 2022) | async def test_name_too_long_rejected(self, async_client: AsyncClient): method test_client_secret_too_long_rejected (line 2039) | async def test_client_secret_too_long_rejected(self, async_client: Asy... class TestUserCreateUpdateFieldLengths (line 2060) | class TestUserCreateUpdateFieldLengths: method admin_token (line 2064) | async def admin_token(self, async_client: AsyncClient) -> str: method test_create_username_too_long_rejected (line 2069) | async def test_create_username_too_long_rejected(self, async_client: A... method test_create_password_too_long_rejected (line 2083) | async def test_create_password_too_long_rejected(self, async_client: A... method test_create_email_too_long_rejected (line 2097) | async def test_create_email_too_long_rejected(self, async_client: Asyn... method test_create_email_exceeds_limit_rejected (line 2114) | async def test_create_email_exceeds_limit_rejected(self, async_client:... method test_update_username_too_long_rejected (line 2129) | async def test_update_username_too_long_rejected(self, async_client: A... method test_update_password_too_long_rejected (line 2148) | async def test_update_password_too_long_rejected(self, async_client: A... method test_update_email_too_long_rejected (line 2166) | async def test_update_email_too_long_rejected(self, async_client: Asyn... class TestForgotPasswordPerIpRateLimit (line 2198) | class TestForgotPasswordPerIpRateLimit: method advanced_auth_token (line 2207) | async def advanced_auth_token(self, async_client: AsyncClient) -> str: method test_per_ip_limit_triggers_429 (line 2217) | async def test_per_ip_limit_triggers_429(self, async_client: AsyncClie... class TestOIDCAutoLinkExistingLinkRejection (line 2242) | class TestOIDCAutoLinkExistingLinkRejection: method test_auto_link_rejected_when_user_already_linked (line 2248) | async def test_auto_link_rejected_when_user_already_linked( class TestOIDCStateReplay (line 2399) | class TestOIDCStateReplay: method test_state_replay_rejected (line 2405) | async def test_state_replay_rejected(self, async_client: AsyncClient, ... class TestOIDCIssMismatch (line 2466) | class TestOIDCIssMismatch: method test_iss_mismatch_redirects_token_validation_failed (line 2471) | async def test_iss_mismatch_redirects_token_validation_failed( class TestForgotPasswordTokenSingleUse (line 2586) | class TestForgotPasswordTokenSingleUse: method test_token_reuse_rejected (line 2591) | async def test_token_reuse_rejected(self, async_client: AsyncClient, d... class TestSetupTOTPReplayRejected (line 2636) | class TestSetupTOTPReplayRejected: method test_replayed_setup_code_rejected (line 2641) | async def test_replayed_setup_code_rejected(self, async_client: AsyncC... class TestOIDCAudAndNonceMismatch (line 2696) | class TestOIDCAudAndNonceMismatch: method _make_oidc_provider_setup (line 2699) | def _make_oidc_provider_setup(self): method test_aud_mismatch_redirects_token_validation_failed (line 2706) | async def test_aud_mismatch_redirects_token_validation_failed( method test_nonce_mismatch_redirects_token_validation_failed (line 2817) | async def test_nonce_mismatch_redirects_token_validation_failed( class TestOIDCExpiredTokenRejection (line 2931) | class TestOIDCExpiredTokenRejection: method test_expired_state_token_rejected_as_invalid_state (line 2941) | async def test_expired_state_token_rejected_as_invalid_state( method test_expired_exchange_token_rejected (line 2986) | async def test_expired_exchange_token_rejected(self, async_client: Asy... class TestOIDCIssuerUrlTrailingSlash (line 3024) | class TestOIDCIssuerUrlTrailingSlash: method test_trailing_slash_issuer_url_fetches_correct_discovery_url (line 3033) | async def test_trailing_slash_issuer_url_fetches_correct_discovery_url... method test_iss_claim_trailing_slash_accepted (line 3083) | async def test_iss_claim_trailing_slash_accepted(self, async_client: A... class TestOIDCCallbackCodeLength (line 3198) | class TestOIDCCallbackCodeLength: method test_code_512_chars_accepted (line 3203) | async def test_code_512_chars_accepted(self, async_client: AsyncClient): method test_code_2048_chars_accepted (line 3214) | async def test_code_2048_chars_accepted(self, async_client: AsyncClient): method test_code_2049_chars_rejected (line 3225) | async def test_code_2049_chars_rejected(self, async_client: AsyncClient): method test_state_512_chars_accepted (line 3236) | async def test_state_512_chars_accepted(self, async_client: AsyncClient): method test_state_2048_chars_accepted (line 3247) | async def test_state_2048_chars_accepted(self, async_client: AsyncClie... method test_state_2049_chars_rejected (line 3258) | async def test_state_2049_chars_rejected(self, async_client: AsyncClie... FILE: backend/tests/integration/test_notifications_api.py class TestNotificationsAPI (line 10) | class TestNotificationsAPI: method test_list_notification_providers_empty (line 19) | async def test_list_notification_providers_empty(self, async_client: A... method test_list_notification_providers_with_data (line 28) | async def test_list_notification_providers_with_data( method test_create_callmebot_provider (line 47) | async def test_create_callmebot_provider(self, async_client: AsyncClie... method test_create_ntfy_provider (line 71) | async def test_create_ntfy_provider(self, async_client: AsyncClient): method test_create_provider_with_printer (line 92) | async def test_create_provider_with_printer(self, async_client: AsyncC... method test_get_notification_provider (line 115) | async def test_get_notification_provider( method test_get_provider_not_found (line 130) | async def test_get_provider_not_found(self, async_client: AsyncClient): method test_update_event_toggles (line 142) | async def test_update_event_toggles(self, async_client: AsyncClient, n... method test_update_ams_alarm_toggles (line 162) | async def test_update_ams_alarm_toggles(self, async_client: AsyncClien... method test_enable_disable_provider (line 191) | async def test_enable_disable_provider(self, async_client: AsyncClient... method test_update_quiet_hours (line 209) | async def test_update_quiet_hours(self, async_client: AsyncClient, not... method test_update_daily_digest (line 230) | async def test_update_daily_digest(self, async_client: AsyncClient, no... method test_update_multiple_event_toggles (line 249) | async def test_update_multiple_event_toggles( method test_test_notification (line 285) | async def test_test_notification( method test_test_notification_disabled_provider (line 299) | async def test_test_notification_disabled_provider( method test_delete_notification_provider (line 316) | async def test_delete_notification_provider( method test_delete_nonexistent_provider (line 333) | async def test_delete_nonexistent_provider(self, async_client: AsyncCl... method test_create_provider_with_first_layer_complete (line 341) | async def test_create_provider_with_first_layer_complete(self, async_c... method test_update_first_layer_complete_toggle (line 358) | async def test_update_first_layer_complete_toggle( method test_first_layer_complete_independent_from_other_toggles (line 378) | async def test_first_layer_complete_independent_from_other_toggles( method test_create_provider_with_missing_spool_assignment_toggle (line 396) | async def test_create_provider_with_missing_spool_assignment_toggle(se... method test_update_missing_spool_assignment_toggle (line 413) | async def test_update_missing_spool_assignment_toggle( class TestNotificationTemplatesAPI (line 431) | class TestNotificationTemplatesAPI: method seeded_templates (line 435) | async def seeded_templates(self, db_session): method test_list_templates (line 451) | async def test_list_templates(self, async_client: AsyncClient, seeded_... method test_get_template_by_id (line 462) | async def test_get_template_by_id(self, async_client: AsyncClient, see... method test_update_template (line 475) | async def test_update_template(self, async_client: AsyncClient, seeded... method test_reset_template_to_default (line 496) | async def test_reset_template_to_default(self, async_client: AsyncClie... class TestHomeAssistantNotificationProvider (line 507) | class TestHomeAssistantNotificationProvider: method test_create_homeassistant_provider (line 512) | async def test_create_homeassistant_provider(self, async_client: Async... method test_update_homeassistant_provider (line 534) | async def test_update_homeassistant_provider( method test_test_homeassistant_config_without_ha_settings (line 556) | async def test_test_homeassistant_config_without_ha_settings(self, asy... FILE: backend/tests/integration/test_obico_api.py function clear_cache (line 17) | def clear_cache(): class TestObicoCachedFrame (line 23) | class TestObicoCachedFrame: method test_valid_nonce_returns_jpeg (line 26) | async def test_valid_nonce_returns_jpeg(self, async_client: AsyncClient): method test_unknown_nonce_is_404 (line 36) | async def test_unknown_nonce_is_404(self, async_client: AsyncClient): method test_nonce_is_single_use (line 43) | async def test_nonce_is_single_use(self, async_client: AsyncClient): method test_endpoint_is_public (line 53) | async def test_endpoint_is_public(self, async_client: AsyncClient): method test_response_is_not_cached (line 66) | async def test_response_is_not_cached(self, async_client: AsyncClient): FILE: backend/tests/integration/test_ownership_permissions.py class TestOwnershipPermissionsSetup (line 13) | class TestOwnershipPermissionsSetup: method auth_setup (line 17) | async def auth_setup(self, async_client: AsyncClient): class TestArchiveOwnershipPermissions (line 111) | class TestArchiveOwnershipPermissions(TestOwnershipPermissionsSetup): method test_admin_can_delete_any_archive (line 120) | async def test_admin_can_delete_any_archive( method test_operator_can_delete_own_archive (line 142) | async def test_operator_can_delete_own_archive( method test_operator_cannot_delete_others_archive (line 162) | async def test_operator_cannot_delete_others_archive( method test_operator_cannot_delete_ownerless_archive (line 185) | async def test_operator_cannot_delete_ownerless_archive( method test_viewer_cannot_delete_archive (line 206) | async def test_viewer_cannot_delete_archive( method test_admin_can_update_any_archive (line 226) | async def test_admin_can_update_any_archive( method test_operator_can_update_own_archive (line 248) | async def test_operator_can_update_own_archive( method test_operator_cannot_update_others_archive (line 270) | async def test_operator_cannot_update_others_archive( method test_operator_cannot_reprint_others_archive (line 295) | async def test_operator_cannot_reprint_others_archive( class TestQueueOwnershipPermissions (line 313) | class TestQueueOwnershipPermissions(TestOwnershipPermissionsSetup): method queue_item_factory (line 317) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_admin_can_delete_any_queue_item (line 345) | async def test_admin_can_delete_any_queue_item(self, async_client: Asy... method test_operator_can_delete_own_queue_item (line 358) | async def test_operator_can_delete_own_queue_item(self, async_client: ... method test_operator_cannot_delete_others_queue_item (line 371) | async def test_operator_cannot_delete_others_queue_item( method test_operator_can_update_own_queue_item (line 386) | async def test_operator_can_update_own_queue_item(self, async_client: ... method test_operator_cannot_update_others_queue_item (line 400) | async def test_operator_cannot_update_others_queue_item( method test_operator_cannot_cancel_others_queue_item (line 416) | async def test_operator_cannot_cancel_others_queue_item( method test_bulk_update_skips_non_owned_items (line 431) | async def test_bulk_update_skips_non_owned_items(self, async_client: A... class TestLibraryOwnershipPermissions (line 457) | class TestLibraryOwnershipPermissions(TestOwnershipPermissionsSetup): method library_file_factory (line 461) | async def library_file_factory(self, db_session): method library_folder_factory (line 486) | async def library_folder_factory(self, db_session): method test_admin_can_delete_any_library_file (line 509) | async def test_admin_can_delete_any_library_file(self, async_client: A... method test_operator_can_delete_own_library_file (line 522) | async def test_operator_can_delete_own_library_file( method test_operator_cannot_delete_others_library_file (line 537) | async def test_operator_cannot_delete_others_library_file( method test_operator_can_update_own_library_file (line 552) | async def test_operator_can_update_own_library_file( method test_operator_cannot_update_others_library_file (line 568) | async def test_operator_cannot_update_others_library_file( method test_folders_require_all_permission (line 584) | async def test_folders_require_all_permission(self, async_client: Asyn... method test_bulk_delete_skips_non_owned_files (line 598) | async def test_bulk_delete_skips_non_owned_files(self, async_client: A... class TestAuthDisabledPermissions (line 621) | class TestAuthDisabledPermissions: method test_delete_archive_without_auth (line 626) | async def test_delete_archive_without_auth( method test_update_archive_without_auth (line 639) | async def test_update_archive_without_auth( class TestUserItemsCountAndDeletion (line 654) | class TestUserItemsCountAndDeletion(TestOwnershipPermissionsSetup): method test_get_user_items_count (line 659) | async def test_get_user_items_count( method test_delete_user_keeps_items (line 683) | async def test_delete_user_keeps_items( method test_delete_user_with_items (line 712) | async def test_delete_user_with_items( FILE: backend/tests/integration/test_print_lifecycle.py class TestPrintStartLogic (line 21) | class TestPrintStartLogic: method test_print_start_calls_notification_service (line 25) | async def test_print_start_calls_notification_service(self, capture_lo... class TestPrintCompleteLogic (line 62) | class TestPrintCompleteLogic: method test_print_complete_no_import_errors (line 66) | async def test_print_complete_no_import_errors(self, capture_logs): class TestTimelapseTracking (line 123) | class TestTimelapseTracking: method test_timelapse_detected_in_same_message_as_print_start (line 127) | async def test_timelapse_detected_in_same_message_as_print_start(self): method test_timelapse_flag_included_in_completion_callback (line 160) | async def test_timelapse_flag_included_in_completion_callback(self): method test_hms_errors_included_in_failed_completion_callback (line 205) | async def test_hms_errors_included_in_failed_completion_callback(self): method test_aborted_status_when_cancelled (line 261) | async def test_aborted_status_when_cancelled(self): method test_timelapse_detected_from_ipcam_data (line 305) | async def test_timelapse_detected_from_ipcam_data(self): class TestCallbackErrorHandling (line 357) | class TestCallbackErrorHandling: method test_callback_errors_are_logged (line 361) | async def test_callback_errors_are_logged(self, capture_logs): class TestNoImportShadowing (line 386) | class TestNoImportShadowing: method test_on_print_complete_no_import_errors (line 390) | async def test_on_print_complete_no_import_errors(self, capture_logs): FILE: backend/tests/integration/test_print_queue_api.py class TestPrintQueueAPI (line 7) | class TestPrintQueueAPI: method printer_factory (line 11) | async def printer_factory(self, db_session): method archive_factory (line 39) | async def archive_factory(self, db_session): method queue_item_factory (line 68) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_list_queue_empty (line 103) | async def test_list_queue_empty(self, async_client: AsyncClient): method test_add_to_queue (line 111) | async def test_add_to_queue(self, async_client: AsyncClient, printer_f... method test_add_to_queue_with_manual_start (line 130) | async def test_add_to_queue_with_manual_start( method test_add_to_queue_with_project_id (line 152) | async def test_add_to_queue_with_project_id( method test_add_to_queue_invalid_project_id_returns_404 (line 184) | async def test_add_to_queue_invalid_project_id_returns_404( method test_add_to_queue_with_ams_mapping (line 208) | async def test_add_to_queue_with_ams_mapping( method test_add_to_queue_with_plate_id (line 229) | async def test_add_to_queue_with_plate_id( method test_add_to_queue_with_print_options (line 248) | async def test_add_to_queue_with_print_options( method test_update_queue_item_plate_id (line 277) | async def test_update_queue_item_plate_id(self, async_client: AsyncCli... method test_update_queue_item_print_options (line 287) | async def test_update_queue_item_print_options(self, async_client: Asy... method test_get_queue_item (line 304) | async def test_get_queue_item(self, async_client: AsyncClient, queue_i... method test_get_queue_item_not_found (line 313) | async def test_get_queue_item_not_found(self, async_client: AsyncClient): method test_update_queue_item (line 320) | async def test_update_queue_item(self, async_client: AsyncClient, queu... method test_update_queue_item_manual_start (line 330) | async def test_update_queue_item_manual_start(self, async_client: Asyn... method test_delete_queue_item (line 340) | async def test_delete_queue_item(self, async_client: AsyncClient, queu... method test_delete_queue_item_not_found (line 349) | async def test_delete_queue_item_not_found(self, async_client: AsyncCl... class TestQueueStartEndpoint (line 355) | class TestQueueStartEndpoint: method printer_factory (line 359) | async def printer_factory(self, db_session): method archive_factory (line 387) | async def archive_factory(self, db_session): method queue_item_factory (line 416) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_start_staged_queue_item (line 450) | async def test_start_staged_queue_item(self, async_client: AsyncClient... method test_start_non_staged_queue_item (line 463) | async def test_start_non_staged_queue_item(self, async_client: AsyncCl... method test_start_queue_item_not_found (line 475) | async def test_start_queue_item_not_found(self, async_client: AsyncCli... method test_start_non_pending_queue_item (line 482) | async def test_start_non_pending_queue_item(self, async_client: AsyncC... method test_start_completed_queue_item (line 492) | async def test_start_completed_queue_item(self, async_client: AsyncCli... class TestQueueCancelEndpoint (line 500) | class TestQueueCancelEndpoint: method printer_factory (line 504) | async def printer_factory(self, db_session): method archive_factory (line 528) | async def archive_factory(self, db_session): method queue_item_factory (line 553) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_cancel_pending_queue_item (line 583) | async def test_cancel_pending_queue_item(self, async_client: AsyncClie... method test_cancel_non_pending_queue_item (line 593) | async def test_cancel_non_pending_queue_item(self, async_client: Async... class TestQueueLibraryFileSupport (line 601) | class TestQueueLibraryFileSupport: method printer_factory (line 605) | async def printer_factory(self, db_session): method library_file_factory (line 633) | async def library_file_factory(self, db_session): method test_add_to_queue_with_library_file (line 662) | async def test_add_to_queue_with_library_file( method test_add_to_queue_library_file_with_options (line 685) | async def test_add_to_queue_library_file_with_options( method test_add_to_queue_requires_archive_or_library_file (line 713) | async def test_add_to_queue_requires_archive_or_library_file( method test_update_queue_item_with_library_file (line 730) | async def test_update_queue_item_with_library_file( method test_list_queue_includes_library_file_info (line 763) | async def test_list_queue_includes_library_file_info( class TestBulkUpdateEndpoint (line 795) | class TestBulkUpdateEndpoint: method printer_factory (line 799) | async def printer_factory(self, db_session): method archive_factory (line 827) | async def archive_factory(self, db_session): method queue_item_factory (line 856) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_bulk_update_single_field (line 889) | async def test_bulk_update_single_field(self, async_client: AsyncClien... method test_bulk_update_multiple_fields (line 911) | async def test_bulk_update_multiple_fields(self, async_client: AsyncCl... method test_bulk_update_skips_non_pending (line 936) | async def test_bulk_update_skips_non_pending(self, async_client: Async... method test_bulk_update_change_printer (line 964) | async def test_bulk_update_change_printer( method test_bulk_update_empty_item_ids (line 988) | async def test_bulk_update_empty_item_ids(self, async_client: AsyncCli... method test_bulk_update_no_fields (line 999) | async def test_bulk_update_no_fields(self, async_client: AsyncClient, ... method test_bulk_update_invalid_printer (line 1012) | async def test_bulk_update_invalid_printer(self, async_client: AsyncCl... class TestTargetLocationFeature (line 1024) | class TestTargetLocationFeature: method printer_factory (line 1028) | async def printer_factory(self, db_session): method archive_factory (line 1056) | async def archive_factory(self, db_session): method queue_item_factory (line 1085) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_add_to_queue_with_target_location (line 1119) | async def test_add_to_queue_with_target_location( method test_add_to_queue_location_without_model_ignored (line 1141) | async def test_add_to_queue_location_without_model_ignored( method test_queue_item_target_location_in_response (line 1163) | async def test_queue_item_target_location_in_response( method test_queue_list_includes_target_location (line 1181) | async def test_queue_list_includes_target_location(self, async_client:... method test_update_queue_item_target_location (line 1201) | async def test_update_queue_item_target_location(self, async_client: A... method test_clear_target_location (line 1219) | async def test_clear_target_location(self, async_client: AsyncClient, ... class TestAbortedStatusNormalisation (line 1237) | class TestAbortedStatusNormalisation: method printer_factory (line 1241) | async def printer_factory(self, db_session): method archive_factory (line 1269) | async def archive_factory(self, db_session): method queue_item_factory (line 1298) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_on_print_complete_normalises_aborted_to_cancelled (line 1331) | async def test_on_print_complete_normalises_aborted_to_cancelled(self,... method test_startup_fixup_converts_aborted_to_cancelled (line 1392) | async def test_startup_fixup_converts_aborted_to_cancelled(self, queue... method test_completed_status_passes_through_unchanged (line 1428) | async def test_completed_status_passes_through_unchanged(self, queue_i... method test_bump_library_file_usage_on_completed (line 1496) | async def test_bump_library_file_usage_on_completed(self, printer_fact... method test_bump_library_file_usage_repeated_prints_increment_count (line 1535) | async def test_bump_library_file_usage_repeated_prints_increment_count... method test_bump_library_file_usage_skips_non_completed (line 1570) | async def test_bump_library_file_usage_skips_non_completed(self, print... method test_bump_library_file_usage_skips_when_no_library_file_id (line 1605) | async def test_bump_library_file_usage_skips_when_no_library_file_id( method test_add_to_queue_quantity_default (line 1631) | async def test_add_to_queue_quantity_default( method test_add_to_queue_quantity_one_explicit (line 1650) | async def test_add_to_queue_quantity_one_explicit( method test_add_to_queue_quantity_creates_batch (line 1670) | async def test_add_to_queue_quantity_creates_batch( method test_add_to_queue_quantity_sequential_positions (line 1703) | async def test_add_to_queue_quantity_sequential_positions( method test_add_to_queue_quantity_with_print_options (line 1730) | async def test_add_to_queue_quantity_with_print_options( method test_get_batch (line 1757) | async def test_get_batch(self, async_client: AsyncClient, printer_fact... method test_list_batches (line 1784) | async def test_list_batches(self, async_client: AsyncClient, printer_f... method test_cancel_batch (line 1803) | async def test_cancel_batch(self, async_client: AsyncClient, printer_f... method test_get_batch_not_found (line 1832) | async def test_get_batch_not_found(self, async_client: AsyncClient): FILE: backend/tests/integration/test_printers_api.py class TestPrintersAPI (line 12) | class TestPrintersAPI: method test_list_printers_empty (line 21) | async def test_list_printers_empty(self, async_client: AsyncClient): method test_list_printers_with_data (line 30) | async def test_list_printers_with_data(self, async_client: AsyncClient... method test_create_printer (line 47) | async def test_create_printer(self, async_client: AsyncClient): method test_create_printer_with_hostname (line 68) | async def test_create_printer_with_hostname(self, async_client: AsyncC... method test_create_printer_with_fqdn (line 87) | async def test_create_printer_with_fqdn(self, async_client: AsyncClient): method test_create_printer_invalid_hostname (line 105) | async def test_create_printer_invalid_hostname(self, async_client: Asy... method test_create_printer_duplicate_serial (line 120) | async def test_create_printer_duplicate_serial(self, async_client: Asy... method test_get_printer (line 142) | async def test_get_printer(self, async_client: AsyncClient, printer_fa... method test_get_printer_not_found (line 155) | async def test_get_printer_not_found(self, async_client: AsyncClient): method test_update_printer_name (line 167) | async def test_update_printer_name(self, async_client: AsyncClient, pr... method test_update_printer_active_status (line 178) | async def test_update_printer_active_status(self, async_client: AsyncC... method test_update_printer_auto_archive (line 189) | async def test_update_printer_auto_archive(self, async_client: AsyncCl... method test_update_nonexistent_printer (line 200) | async def test_update_nonexistent_printer(self, async_client: AsyncCli... method test_delete_printer (line 212) | async def test_delete_printer(self, async_client: AsyncClient, printer... method test_delete_nonexistent_printer (line 227) | async def test_delete_nonexistent_printer(self, async_client: AsyncCli... method test_get_printer_status (line 239) | async def test_get_printer_status( method test_get_printer_status_not_found (line 254) | async def test_get_printer_status_not_found(self, async_client: AsyncC... class TestPrinterDataIntegrity (line 265) | class TestPrinterDataIntegrity: method test_printer_stores_all_fields (line 270) | async def test_printer_stores_all_fields(self, async_client: AsyncClie... method test_printer_update_persists (line 294) | async def test_printer_update_persists(self, async_client: AsyncClient... method test_refresh_status_not_found (line 313) | async def test_refresh_status_not_found(self, async_client: AsyncClient): method test_refresh_status_not_connected (line 320) | async def test_refresh_status_not_connected(self, async_client: AsyncC... method test_refresh_status_success (line 334) | async def test_refresh_status_success(self, async_client: AsyncClient,... method test_get_current_print_user_not_found (line 353) | async def test_get_current_print_user_not_found(self, async_client: As... method test_get_current_print_user_returns_empty_when_no_user (line 360) | async def test_get_current_print_user_returns_empty_when_no_user(self,... method test_get_current_print_user_returns_user_info (line 374) | async def test_get_current_print_user_returns_user_info(self, async_cl... class TestPrintControlAPI (line 389) | class TestPrintControlAPI: method test_stop_print_not_found (line 398) | async def test_stop_print_not_found(self, async_client: AsyncClient): method test_stop_print_not_connected (line 405) | async def test_stop_print_not_connected(self, async_client: AsyncClien... method test_stop_print_success (line 419) | async def test_stop_print_success(self, async_client: AsyncClient, pri... method test_pause_print_not_found (line 441) | async def test_pause_print_not_found(self, async_client: AsyncClient): method test_pause_print_not_connected (line 448) | async def test_pause_print_not_connected(self, async_client: AsyncClie... method test_pause_print_success (line 462) | async def test_pause_print_success(self, async_client: AsyncClient, pr... method test_resume_print_not_found (line 484) | async def test_resume_print_not_found(self, async_client: AsyncClient): method test_resume_print_not_connected (line 491) | async def test_resume_print_not_connected(self, async_client: AsyncCli... method test_resume_print_success (line 505) | async def test_resume_print_success(self, async_client: AsyncClient, p... class TestAMSRefreshAPI (line 522) | class TestAMSRefreshAPI: method test_ams_refresh_not_found (line 527) | async def test_ams_refresh_not_found(self, async_client: AsyncClient): method test_ams_refresh_not_connected (line 534) | async def test_ams_refresh_not_connected(self, async_client: AsyncClie... method test_ams_refresh_success (line 548) | async def test_ams_refresh_success(self, async_client: AsyncClient, pr... method test_ams_refresh_filament_loaded (line 567) | async def test_ams_refresh_filament_loaded(self, async_client: AsyncCl... class TestConfigureAMSSlotAPI (line 583) | class TestConfigureAMSSlotAPI: method test_configure_not_connected (line 588) | async def test_configure_not_connected(self, async_client: AsyncClient... method test_configure_with_gf_id_keeps_it (line 612) | async def test_configure_with_gf_id_keeps_it(self, async_client: Async... method test_configure_pfus_sent_directly (line 643) | async def test_configure_pfus_sent_directly(self, async_client: AsyncC... method test_configure_pfus_takes_priority_over_slot (line 677) | async def test_configure_pfus_takes_priority_over_slot(self, async_cli... method test_configure_pfus_used_regardless_of_slot_material (line 729) | async def test_configure_pfus_used_regardless_of_slot_material(self, a... method test_configure_empty_id_uses_generic (line 774) | async def test_configure_empty_id_uses_generic(self, async_client: Asy... method test_configure_pfus_preserves_setting_id_pair (line 808) | async def test_configure_pfus_preserves_setting_id_pair(self, async_cl... class TestSkipObjectsAPI (line 851) | class TestSkipObjectsAPI: method test_get_objects_not_found (line 860) | async def test_get_objects_not_found(self, async_client: AsyncClient): method test_get_objects_not_connected (line 867) | async def test_get_objects_not_connected(self, async_client: AsyncClie... method test_get_objects_empty (line 881) | async def test_get_objects_empty(self, async_client: AsyncClient, prin... method test_get_objects_with_data (line 905) | async def test_get_objects_with_data(self, async_client: AsyncClient, ... method test_get_objects_with_positions (line 940) | async def test_get_objects_with_positions(self, async_client: AsyncCli... method test_skip_objects_not_found (line 977) | async def test_skip_objects_not_found(self, async_client: AsyncClient): method test_skip_objects_not_connected (line 984) | async def test_skip_objects_not_connected(self, async_client: AsyncCli... method test_skip_objects_empty_list (line 998) | async def test_skip_objects_empty_list(self, async_client: AsyncClient... method test_skip_objects_invalid_id (line 1016) | async def test_skip_objects_invalid_id(self, async_client: AsyncClient... method test_skip_objects_success (line 1034) | async def test_skip_objects_success(self, async_client: AsyncClient, p... method test_skip_objects_multiple (line 1056) | async def test_skip_objects_multiple(self, async_client: AsyncClient, ... class TestChamberLightAPI (line 1078) | class TestChamberLightAPI: method test_chamber_light_not_found (line 1083) | async def test_chamber_light_not_found(self, async_client: AsyncClient): method test_chamber_light_not_connected (line 1090) | async def test_chamber_light_not_connected(self, async_client: AsyncCl... method test_chamber_light_on_success (line 1104) | async def test_chamber_light_on_success(self, async_client: AsyncClien... method test_chamber_light_off_success (line 1124) | async def test_chamber_light_off_success(self, async_client: AsyncClie... method test_chamber_light_failure (line 1144) | async def test_chamber_light_failure(self, async_client: AsyncClient, ... class TestAirductModeAPI (line 1160) | class TestAirductModeAPI: method test_invalid_mode_rejected (line 1165) | async def test_invalid_mode_rejected(self, async_client: AsyncClient, ... method test_not_connected (line 1172) | async def test_not_connected(self, async_client: AsyncClient, printer_... method test_cooling_success (line 1181) | async def test_cooling_success(self, async_client: AsyncClient, printe... method test_heating_failure_returns_500 (line 1194) | async def test_heating_failure_returns_500(self, async_client: AsyncCl... class TestClearHMSErrorsAPI (line 1204) | class TestClearHMSErrorsAPI: method test_clear_hms_errors_not_found (line 1209) | async def test_clear_hms_errors_not_found(self, async_client: AsyncCli... method test_clear_hms_errors_not_connected (line 1216) | async def test_clear_hms_errors_not_connected(self, async_client: Asyn... method test_clear_hms_errors_success (line 1230) | async def test_clear_hms_errors_success(self, async_client: AsyncClien... method test_clear_hms_errors_failure (line 1250) | async def test_clear_hms_errors_failure(self, async_client: AsyncClien... FILE: backend/tests/integration/test_projects_api.py class TestProjectsAPI (line 7) | class TestProjectsAPI: method project_factory (line 11) | async def project_factory(self, db_session): method test_list_projects_empty (line 38) | async def test_list_projects_empty(self, async_client: AsyncClient): method test_list_projects_with_data (line 46) | async def test_list_projects_with_data(self, async_client: AsyncClient... method test_create_project (line 56) | async def test_create_project(self, async_client: AsyncClient): method test_get_project (line 71) | async def test_get_project(self, async_client: AsyncClient, project_fa... method test_get_project_not_found (line 80) | async def test_get_project_not_found(self, async_client: AsyncClient): method test_update_project (line 87) | async def test_update_project(self, async_client: AsyncClient, project... method test_delete_project (line 100) | async def test_delete_project(self, async_client: AsyncClient, project... method test_delete_project_not_found (line 110) | async def test_delete_project_not_found(self, async_client: AsyncClient): class TestProjectPartsTracking (line 116) | class TestProjectPartsTracking: method project_factory (line 120) | async def project_factory(self, db_session): method archive_factory (line 142) | async def archive_factory(self, db_session): method test_create_project_with_target_parts_count (line 168) | async def test_create_project_with_target_parts_count(self, async_clie... method test_update_project_target_parts_count (line 183) | async def test_update_project_target_parts_count(self, async_client: A... method test_project_parts_progress_calculation (line 195) | async def test_project_parts_progress_calculation( method test_project_list_shows_parts_count (line 219) | async def test_project_list_shows_parts_count( method test_plates_vs_parts_progress (line 243) | async def test_plates_vs_parts_progress( class TestProjectArchivedStatusNotCounted (line 265) | class TestProjectArchivedStatusNotCounted: method project_factory (line 269) | async def project_factory(self, db_session): method archive_factory (line 291) | async def archive_factory(self, db_session): method test_archived_files_not_counted_as_completed (line 317) | async def test_archived_files_not_counted_as_completed( method test_archived_files_not_counted_in_project_list (line 339) | async def test_archived_files_not_counted_in_project_list( method test_only_completed_status_counts (line 359) | async def test_only_completed_status_counts( class TestProjectArchivesAPI (line 380) | class TestProjectArchivesAPI: method project_factory (line 384) | async def project_factory(self, db_session): method test_get_project_with_archives (line 407) | async def test_get_project_with_archives(self, async_client: AsyncClie... class TestProjectExportImport (line 417) | class TestProjectExportImport: method project_factory (line 421) | async def project_factory(self, db_session): method bom_item_factory (line 447) | async def bom_item_factory(self, db_session): method test_export_project (line 472) | async def test_export_project(self, async_client: AsyncClient, project... method test_import_project (line 510) | async def test_import_project(self, async_client: AsyncClient): method test_export_project_with_linked_folder (line 547) | async def test_export_project_with_linked_folder(self, async_client: A... method test_import_project_with_linked_folder (line 568) | async def test_import_project_with_linked_folder(self, async_client: A... method test_import_project_from_json_file (line 587) | async def test_import_project_from_json_file(self, async_client: Async... method test_import_project_from_zip_file (line 610) | async def test_import_project_from_zip_file(self, async_client: AsyncC... method test_export_zip_contains_files (line 639) | async def test_export_zip_contains_files(self, async_client: AsyncClie... method test_import_invalid_file_type (line 706) | async def test_import_invalid_file_type(self, async_client: AsyncClient): method test_import_zip_missing_project_json (line 717) | async def test_import_zip_missing_project_json(self, async_client: Asy... method test_import_invalid_json (line 734) | async def test_import_invalid_json(self, async_client: AsyncClient): FILE: backend/tests/integration/test_security.py function _auth_header (line 37) | def _auth_header(token: str) -> dict[str, str]: function _norm_pw (line 41) | def _norm_pw(password: str) -> str: function _setup_and_login (line 50) | async def _setup_and_login(client: AsyncClient, username: str, password:... function _make_test_rsa_key (line 61) | def _make_test_rsa_key(): class TestEncryption (line 92) | class TestEncryption: method test_encrypt_decrypt_roundtrip_with_key (line 95) | def test_encrypt_decrypt_roundtrip_with_key(self): method test_plaintext_passthrough_without_key (line 115) | def test_plaintext_passthrough_without_key(self): method test_decrypt_raises_runtime_error_without_key_for_encrypted_value (line 133) | def test_decrypt_raises_runtime_error_without_key_for_encrypted_value(... class TestJWTRevocation (line 158) | class TestJWTRevocation: method test_revoke_jti_and_is_jti_revoked (line 163) | async def test_revoke_jti_and_is_jti_revoked(self, async_client: Async... method test_revoke_jti_idempotent (line 176) | async def test_revoke_jti_idempotent(self, async_client: AsyncClient): method test_is_token_fresh_rejects_none_iat (line 186) | def test_is_token_fresh_rejects_none_iat(self): method test_is_token_fresh_rejects_token_before_password_change (line 194) | def test_is_token_fresh_rejects_token_before_password_change(self): method test_is_token_fresh_accepts_token_after_password_change (line 204) | def test_is_token_fresh_accepts_token_after_password_change(self): method test_is_token_fresh_returns_true_when_no_password_change (line 214) | def test_is_token_fresh_returns_true_when_no_password_change(self): method test_me_endpoint_rejects_token_after_logout (line 224) | async def test_me_endpoint_rejects_token_after_logout(self, async_clie... class TestOIDCExchangeReplay (line 246) | class TestOIDCExchangeReplay: method test_exchange_token_is_single_use (line 251) | async def test_exchange_token_is_single_use(self, async_client: AsyncC... class TestOIDCEmailVerified (line 292) | class TestOIDCEmailVerified: method test_unverified_email_does_not_link_to_existing_user (line 297) | async def test_unverified_email_does_not_link_to_existing_user( class TestEmailOTPMaxAttempts (line 430) | class TestEmailOTPMaxAttempts: method test_email_otp_invalidated_after_max_attempts (line 435) | async def test_email_otp_invalidated_after_max_attempts(self, async_cl... class TestOIDCSSRFProtection (line 514) | class TestOIDCSSRFProtection: method test_invalid_authorization_endpoint_scheme_rejected (line 519) | async def test_invalid_authorization_endpoint_scheme_rejected( class TestLoginRateLimiting (line 597) | class TestLoginRateLimiting: method test_excessive_failed_logins_return_429 (line 602) | async def test_excessive_failed_logins_return_429(self, async_client: ... class TestChallengeIdCookieBinding (line 628) | class TestChallengeIdCookieBinding: method test_pre_auth_token_rejected_without_matching_cookie (line 633) | async def test_pre_auth_token_rejected_without_matching_cookie( class TestSecurityHeaders (line 691) | class TestSecurityHeaders: method test_security_headers_present (line 696) | async def test_security_headers_present(self, async_client: AsyncClient): method test_hsts_absent_for_http (line 713) | async def test_hsts_absent_for_http(self, async_client: AsyncClient): class TestRateLimitBuckets (line 724) | class TestRateLimitBuckets: method test_ip_spray_trips_ip_bucket (line 729) | async def test_ip_spray_trips_ip_bucket(self, async_client: AsyncClient): method test_username_spray_trips_username_bucket (line 762) | async def test_username_spray_trips_username_bucket(self, async_client... FILE: backend/tests/integration/test_settings_api.py class TestSettingsAPI (line 12) | class TestSettingsAPI: method test_get_settings (line 21) | async def test_get_settings(self, async_client: AsyncClient): method test_get_settings_has_defaults (line 34) | async def test_get_settings_has_defaults(self, async_client: AsyncClie... method test_update_auto_archive (line 50) | async def test_update_auto_archive(self, async_client: AsyncClient): method test_update_currency (line 65) | async def test_update_currency(self, async_client: AsyncClient): method test_update_date_format (line 74) | async def test_update_date_format(self, async_client: AsyncClient): method test_update_time_format (line 83) | async def test_update_time_format(self, async_client: AsyncClient): method test_update_filament_cost (line 92) | async def test_update_filament_cost(self, async_client: AsyncClient): method test_update_energy_cost (line 101) | async def test_update_energy_cost(self, async_client: AsyncClient): method test_update_multiple_settings (line 110) | async def test_update_multiple_settings(self, async_client: AsyncClient): method test_update_spoolman_settings (line 131) | async def test_update_spoolman_settings(self, async_client: AsyncClient): method test_update_ams_thresholds (line 150) | async def test_update_ams_thresholds(self, async_client: AsyncClient): method test_update_low_stock_threshold (line 171) | async def test_update_low_stock_threshold(self, async_client: AsyncCli... method test_update_notification_language (line 192) | async def test_update_notification_language(self, async_client: AsyncC... method test_update_theme_settings (line 205) | async def test_update_theme_settings(self, async_client: AsyncClient): method test_settings_persist_after_update (line 230) | async def test_settings_persist_after_update(self, async_client: Async... method test_update_check_printer_firmware (line 243) | async def test_update_check_printer_firmware(self, async_client: Async... method test_update_mqtt_settings (line 269) | async def test_update_mqtt_settings(self, async_client: AsyncClient): method test_mqtt_status_endpoint (line 296) | async def test_mqtt_status_endpoint(self, async_client: AsyncClient): method test_mqtt_defaults (line 310) | async def test_mqtt_defaults(self, async_client: AsyncClient): method test_update_camera_view_mode (line 340) | async def test_update_camera_view_mode(self, async_client: AsyncClient): method test_camera_view_mode_persists (line 349) | async def test_camera_view_mode_persists(self, async_client: AsyncClie... method test_camera_view_mode_default (line 367) | async def test_camera_view_mode_default(self, async_client: AsyncClient): method test_update_per_printer_mapping_expanded (line 383) | async def test_update_per_printer_mapping_expanded(self, async_client:... method test_per_printer_mapping_expanded_persists (line 392) | async def test_per_printer_mapping_expanded_persists(self, async_clien... method test_per_printer_mapping_expanded_default (line 410) | async def test_per_printer_mapping_expanded_default(self, async_client... method test_stagger_settings_defaults (line 425) | async def test_stagger_settings_defaults(self, async_client: AsyncClie... method test_update_stagger_settings (line 435) | async def test_update_stagger_settings(self, async_client: AsyncClient): method test_stagger_settings_persist (line 449) | async def test_stagger_settings_persist(self, async_client: AsyncClient): method test_stagger_settings_validation (line 463) | async def test_stagger_settings_validation(self, async_client: AsyncCl... method test_default_print_options_defaults (line 483) | async def test_default_print_options_defaults(self, async_client: Asyn... method test_update_default_print_options (line 496) | async def test_update_default_print_options(self, async_client: AsyncC... method test_default_print_options_persist (line 519) | async def test_default_print_options_persist(self, async_client: Async... method test_default_print_options_partial_update (line 536) | async def test_default_print_options_partial_update(self, async_client... method test_ha_settings_default_no_env_vars (line 564) | async def test_ha_settings_default_no_env_vars(self, async_client: Asy... method test_ha_settings_with_both_env_vars (line 588) | async def test_ha_settings_with_both_env_vars(self, async_client: Asyn... method test_ha_settings_with_only_url_env_var (line 619) | async def test_ha_settings_with_only_url_env_var(self, async_client: A... method test_ha_settings_with_only_token_env_var (line 645) | async def test_ha_settings_with_only_token_env_var(self, async_client:... method test_ha_settings_env_vars_override_database (line 671) | async def test_ha_settings_env_vars_override_database(self, async_clie... method test_ha_settings_database_updates_accepted_but_ignored (line 719) | async def test_ha_settings_database_updates_accepted_but_ignored(self,... method test_ha_settings_empty_env_vars_treated_as_not_set (line 751) | async def test_ha_settings_empty_env_vars_treated_as_not_set(self, asy... method test_ha_settings_can_be_updated_normally_without_env_vars (line 772) | async def test_ha_settings_can_be_updated_normally_without_env_vars(se... class TestSimplifiedBackupRestore (line 805) | class TestSimplifiedBackupRestore: method test_restore_requires_zip_file (line 815) | async def test_restore_requires_zip_file(self, async_client: AsyncClie... method test_restore_requires_database_in_zip (line 825) | async def test_restore_requires_database_in_zip(self, async_client: As... method test_restore_invalid_zip (line 844) | async def test_restore_invalid_zip(self, async_client: AsyncClient): FILE: backend/tests/integration/test_sjf_scheduling.py class TestSJFScheduling (line 10) | class TestSJFScheduling: method printer_factory (line 14) | async def printer_factory(self, db_session): method archive_factory (line 42) | async def archive_factory(self, db_session): method queue_item_factory (line 71) | async def queue_item_factory(self, db_session, printer_factory, archiv... method test_queue_item_has_print_time_seconds (line 99) | async def test_queue_item_has_print_time_seconds(self, queue_item_fact... method test_queue_item_has_been_jumped (line 106) | async def test_queue_item_has_been_jumped(self, queue_item_factory): method test_sjf_ordering_shorter_jobs_first (line 116) | async def test_sjf_ordering_shorter_jobs_first(self, db_session, queue... method test_sjf_null_print_time_goes_last (line 157) | async def test_sjf_null_print_time_goes_last(self, db_session, queue_i... method test_starvation_guard_jumped_items_first (line 181) | async def test_starvation_guard_jumped_items_first(self, db_session, q... method test_fifo_ordering_ignores_print_time (line 209) | async def test_fifo_ordering_ignores_print_time(self, db_session, queu... method test_sjf_position_as_tiebreaker (line 230) | async def test_sjf_position_as_tiebreaker(self, db_session, queue_item... method test_starvation_flag_set_on_jumped_items (line 254) | async def test_starvation_flag_set_on_jumped_items(self, db_session, q... method test_starvation_guard_prevents_double_jump (line 286) | async def test_starvation_guard_prevents_double_jump(self, db_session,... method test_queue_shortest_first_setting (line 316) | async def test_queue_shortest_first_setting(self, db_session): FILE: backend/tests/integration/test_smart_plugs_api.py class TestSmartPlugsAPI (line 10) | class TestSmartPlugsAPI: method test_list_smart_plugs_empty (line 19) | async def test_list_smart_plugs_empty(self, async_client: AsyncClient): method test_list_smart_plugs_with_data (line 28) | async def test_list_smart_plugs_with_data(self, async_client: AsyncCli... method test_create_smart_plug (line 45) | async def test_create_smart_plug(self, async_client: AsyncClient): method test_create_smart_plug_with_printer (line 65) | async def test_create_smart_plug_with_printer(self, async_client: Asyn... method test_create_plug_with_invalid_printer_id (line 83) | async def test_create_plug_with_invalid_printer_id(self, async_client:... method test_get_smart_plug (line 102) | async def test_get_smart_plug(self, async_client: AsyncClient, smart_p... method test_get_smart_plug_not_found (line 115) | async def test_get_smart_plug_not_found(self, async_client: AsyncClient): method test_update_auto_off_toggle (line 127) | async def test_update_auto_off_toggle(self, async_client: AsyncClient,... method test_update_auto_on_toggle (line 153) | async def test_update_auto_on_toggle(self, async_client: AsyncClient, ... method test_update_enabled_toggle (line 168) | async def test_update_enabled_toggle(self, async_client: AsyncClient, ... method test_update_off_delay_mode (line 179) | async def test_update_off_delay_mode(self, async_client: AsyncClient, ... method test_update_schedule_settings (line 194) | async def test_update_schedule_settings(self, async_client: AsyncClien... method test_update_multiple_fields (line 215) | async def test_update_multiple_fields(self, async_client: AsyncClient,... method test_control_smart_plug_on (line 244) | async def test_control_smart_plug_on( method test_control_smart_plug_off (line 259) | async def test_control_smart_plug_off( method test_control_smart_plug_toggle (line 274) | async def test_control_smart_plug_toggle( method test_control_invalid_action (line 289) | async def test_control_invalid_action(self, async_client: AsyncClient,... method test_get_smart_plug_status (line 304) | async def test_get_smart_plug_status( method test_delete_smart_plug (line 323) | async def test_delete_smart_plug(self, async_client: AsyncClient, smar... method test_delete_nonexistent_plug (line 338) | async def test_delete_nonexistent_plug(self, async_client: AsyncClient): method test_update_show_in_switchbar (line 350) | async def test_update_show_in_switchbar(self, async_client: AsyncClien... method test_tasmota_discovery_scan (line 369) | async def test_tasmota_discovery_scan(self, async_client: AsyncClient): method test_tasmota_discovery_status (line 381) | async def test_tasmota_discovery_status(self, async_client: AsyncClient): method test_tasmota_discovery_devices (line 393) | async def test_tasmota_discovery_devices(self, async_client: AsyncClie... method test_tasmota_discovery_stop (line 403) | async def test_tasmota_discovery_stop(self, async_client: AsyncClient): method test_create_homeassistant_plug (line 417) | async def test_create_homeassistant_plug(self, async_client: AsyncClie... method test_create_homeassistant_plug_missing_entity_id (line 439) | async def test_create_homeassistant_plug_missing_entity_id(self, async... method test_create_tasmota_plug_missing_ip (line 454) | async def test_create_tasmota_plug_missing_ip(self, async_client: Asyn... method test_ha_entities_endpoint_not_configured (line 469) | async def test_ha_entities_endpoint_not_configured(self, async_client:... method test_update_plug_type (line 478) | async def test_update_plug_type(self, async_client: AsyncClient, smart... method test_control_homeassistant_plug (line 497) | async def test_control_homeassistant_plug( method test_get_homeassistant_plug_status (line 512) | async def test_get_homeassistant_plug_status( method test_create_homeassistant_plug_with_energy_sensors (line 527) | async def test_create_homeassistant_plug_with_energy_sensors(self, asy... method test_update_ha_energy_sensor_entities (line 549) | async def test_update_ha_energy_sensor_entities(self, async_client: As... method test_ha_sensors_endpoint_not_configured (line 570) | async def test_ha_sensors_endpoint_not_configured(self, async_client: ... method test_create_mqtt_plug (line 583) | async def test_create_mqtt_plug(self, async_client: AsyncClient, mock_... method test_create_mqtt_plug_missing_topic (line 611) | async def test_create_mqtt_plug_missing_topic(self, async_client: Asyn... method test_create_mqtt_plug_missing_topic (line 627) | async def test_create_mqtt_plug_missing_topic(self, async_client: Asyn... method test_create_mqtt_plug_with_multiplier (line 642) | async def test_create_mqtt_plug_with_multiplier(self, async_client: As... method test_control_mqtt_plug_returns_error (line 661) | async def test_control_mqtt_plug_returns_error(self, async_client: Asy... method test_update_mqtt_plug_topic (line 676) | async def test_update_mqtt_plug_topic(self, async_client: AsyncClient,... method test_create_mqtt_plug_with_separate_topics (line 703) | async def test_create_mqtt_plug_with_separate_topics(self, async_clien... method test_create_mqtt_plug_energy_only (line 741) | async def test_create_mqtt_plug_energy_only(self, async_client: AsyncC... method test_create_mqtt_plug_state_only (line 762) | async def test_create_mqtt_plug_state_only(self, async_client: AsyncCl... method test_create_mqtt_plug_topic_only_succeeds (line 783) | async def test_create_mqtt_plug_topic_only_succeeds(self, async_client... method test_update_mqtt_plug_separate_multipliers (line 802) | async def test_update_mqtt_plug_separate_multipliers( method test_create_rest_plug (line 835) | async def test_create_rest_plug(self, async_client: AsyncClient): method test_create_rest_plug_on_url_only (line 864) | async def test_create_rest_plug_on_url_only(self, async_client: AsyncC... method test_create_rest_plug_missing_urls_fails (line 884) | async def test_create_rest_plug_missing_urls_fails(self, async_client:... method test_create_rest_plug_with_status_and_energy (line 898) | async def test_create_rest_plug_with_status_and_energy(self, async_cli... method test_update_rest_plug (line 928) | async def test_update_rest_plug(self, async_client: AsyncClient, smart... method test_rest_plug_is_controllable (line 947) | async def test_rest_plug_is_controllable(self, async_client: AsyncClie... FILE: backend/tests/integration/test_spoolbuddy.py function device_factory (line 18) | def device_factory(db_session: AsyncSession): function spool_factory (line 47) | def spool_factory(db_session: AsyncSession): class TestDeviceEndpoints (line 78) | class TestDeviceEndpoints: method test_register_new_device (line 81) | async def test_register_new_device(self, async_client: AsyncClient): method test_re_register_existing_device (line 105) | async def test_re_register_existing_device(self, async_client: AsyncCl... method test_list_devices_empty (line 136) | async def test_list_devices_empty(self, async_client: AsyncClient): method test_list_devices (line 143) | async def test_list_devices(self, async_client: AsyncClient, device_fa... method test_unregister_device (line 156) | async def test_unregister_device(self, async_client: AsyncClient, devi... method test_unregister_device_not_found (line 180) | async def test_unregister_device_not_found(self, async_client: AsyncCl... method test_heartbeat_updates_status (line 186) | async def test_heartbeat_updates_status(self, async_client: AsyncClien... method test_heartbeat_returns_pending_command (line 208) | async def test_heartbeat_returns_pending_command(self, async_client: A... method test_heartbeat_unknown_device_404 (line 233) | async def test_heartbeat_unknown_device_404(self, async_client: AsyncC... method test_heartbeat_broadcasts_online_when_was_offline (line 245) | async def test_heartbeat_broadcasts_online_when_was_offline(self, asyn... method test_heartbeat_broadcasts_online_when_already_online (line 269) | async def test_heartbeat_broadcasts_online_when_already_online(self, a... method test_heartbeat_online_broadcast_is_throttled (line 291) | async def test_heartbeat_online_broadcast_is_throttled(self, async_cli... class TestNfcEndpoints (line 322) | class TestNfcEndpoints: method test_tag_scanned_matched (line 325) | async def test_tag_scanned_matched(self, async_client: AsyncClient, sp... method test_tag_scanned_unmatched (line 360) | async def test_tag_scanned_unmatched(self, async_client: AsyncClient): method test_tag_removed (line 382) | async def test_tag_removed(self, async_client: AsyncClient): class TestWriteTagEndpoints (line 402) | class TestWriteTagEndpoints: method test_write_tag_queues_command (line 405) | async def test_write_tag_queues_command(self, async_client: AsyncClien... method test_write_tag_heartbeat_not_cleared (line 433) | async def test_write_tag_heartbeat_not_cleared(self, async_client: Asy... method test_write_tag_missing_spool_404 (line 463) | async def test_write_tag_missing_spool_404(self, async_client: AsyncCl... method test_write_tag_missing_device_404 (line 474) | async def test_write_tag_missing_device_404(self, async_client: AsyncC... method test_write_result_success_links_tag (line 485) | async def test_write_result_success_links_tag(self, async_client: Asyn... method test_write_result_failure_broadcasts_error (line 517) | async def test_write_result_failure_broadcasts_error( method test_write_result_clears_pending_command (line 547) | async def test_write_result_clears_pending_command(self, async_client:... method test_cancel_write (line 579) | async def test_cancel_write(self, async_client: AsyncClient, device_fa... method test_cancel_write_unknown_device_404 (line 604) | async def test_cancel_write_unknown_device_404(self, async_client: Asy... method test_write_tag_ndef_data_is_valid (line 610) | async def test_write_tag_ndef_data_is_valid(self, async_client: AsyncC... class TestScaleEndpoints (line 654) | class TestScaleEndpoints: method test_scale_reading_broadcast (line 657) | async def test_scale_reading_broadcast(self, async_client: AsyncClient): method test_update_spool_weight_calculates_correctly (line 680) | async def test_update_spool_weight_calculates_correctly(self, async_cl... method test_update_spool_weight_full_spool (line 697) | async def test_update_spool_weight_full_spool(self, async_client: Asyn... method test_update_spool_weight_stores_scale_reading (line 714) | async def test_update_spool_weight_stores_scale_reading(self, async_cl... method test_update_spool_weight_missing_spool_404 (line 733) | async def test_update_spool_weight_missing_spool_404(self, async_clien... class TestCalibrationEndpoints (line 746) | class TestCalibrationEndpoints: method test_tare_queues_command (line 749) | async def test_tare_queues_command(self, async_client: AsyncClient, de... method test_tare_unknown_device_404 (line 767) | async def test_tare_unknown_device_404(self, async_client: AsyncClient): method test_set_tare_offset (line 773) | async def test_set_tare_offset(self, async_client: AsyncClient, device... method test_set_calibration_factor (line 788) | async def test_set_calibration_factor(self, async_client: AsyncClient,... method test_set_calibration_factor_zero_delta_400 (line 804) | async def test_set_calibration_factor_zero_delta_400(self, async_clien... method test_get_calibration (line 817) | async def test_get_calibration(self, async_client: AsyncClient, device... class TestDisplayEndpoints (line 837) | class TestDisplayEndpoints: method test_update_display_settings (line 840) | async def test_update_display_settings(self, async_client: AsyncClient... method test_update_display_persists_via_heartbeat (line 855) | async def test_update_display_persists_via_heartbeat(self, async_clien... method test_update_display_unknown_device_404 (line 875) | async def test_update_display_unknown_device_404(self, async_client: A... method test_update_display_validates_brightness (line 884) | async def test_update_display_validates_brightness(self, async_client:... method test_get_display_settings (line 895) | async def test_get_display_settings(self, async_client: AsyncClient, d... method test_get_display_unknown_device_404 (line 910) | async def test_get_display_unknown_device_404(self, async_client: Asyn... class TestUpdateEndpoints (line 920) | class TestUpdateEndpoints: method test_trigger_update_starts_ssh_update (line 923) | async def test_trigger_update_starts_ssh_update(self, async_client: As... method test_trigger_update_offline_device_409 (line 938) | async def test_trigger_update_offline_device_409(self, async_client: A... method test_trigger_update_unknown_device_404 (line 949) | async def test_trigger_update_unknown_device_404(self, async_client: A... method test_trigger_update_already_updating (line 955) | async def test_trigger_update_already_updating(self, async_client: Asy... method test_report_update_status_updating (line 967) | async def test_report_update_status_updating(self, async_client: Async... method test_report_update_status_complete_clears_command (line 985) | async def test_report_update_status_complete_clears_command(self, asyn... method test_report_update_status_error (line 1007) | async def test_report_update_status_error(self, async_client: AsyncCli... method test_report_update_status_unknown_device_404 (line 1024) | async def test_report_update_status_unknown_device_404(self, async_cli... method test_device_response_includes_update_fields (line 1033) | async def test_device_response_includes_update_fields(self, async_clie... method test_update_check_returns_version_info (line 1044) | async def test_update_check_returns_version_info(self, async_client: A... method test_update_check_up_to_date (line 1058) | async def test_update_check_up_to_date(self, async_client: AsyncClient... method test_update_check_unknown_device_404 (line 1070) | async def test_update_check_unknown_device_404(self, async_client: Asy... method test_trigger_update_broadcasts_websocket (line 1076) | async def test_trigger_update_broadcasts_websocket(self, async_client:... class TestSystemCommandEndpoints (line 1098) | class TestSystemCommandEndpoints: method test_queue_reboot (line 1101) | async def test_queue_reboot(self, async_client: AsyncClient, device_fa... method test_queue_shutdown (line 1115) | async def test_queue_shutdown(self, async_client: AsyncClient, device_... method test_queue_restart_daemon (line 1127) | async def test_queue_restart_daemon(self, async_client: AsyncClient, d... method test_queue_restart_browser (line 1139) | async def test_queue_restart_browser(self, async_client: AsyncClient, ... method test_invalid_command_rejected (line 1151) | async def test_invalid_command_rejected(self, async_client: AsyncClien... method test_command_unknown_device_404 (line 1163) | async def test_command_unknown_device_404(self, async_client: AsyncCli... method test_command_offline_device_409 (line 1172) | async def test_command_offline_device_409(self, async_client: AsyncCli... method test_command_sets_pending_command (line 1187) | async def test_command_sets_pending_command(self, async_client: AsyncC... method test_heartbeat_clears_system_command (line 1200) | async def test_heartbeat_clears_system_command(self, async_client: Asy... FILE: backend/tests/integration/test_spoolman_api.py class TestSpoolmanAPI (line 9) | class TestSpoolmanAPI: method spoolman_settings (line 13) | async def spoolman_settings(self, db_session): method spoolman_url_only (line 26) | async def spoolman_url_only(self, db_session): method mock_spoolman_client (line 36) | def mock_spoolman_client(self): method mock_spoolman_disconnected (line 66) | def mock_spoolman_disconnected(self): method test_get_status_not_configured (line 86) | async def test_get_status_not_configured(self, async_client: AsyncClie... method test_get_status_url_only_not_enabled (line 96) | async def test_get_status_url_only_not_enabled(self, async_client: Asy... method test_get_status_enabled_and_connected (line 106) | async def test_get_status_enabled_and_connected( method test_connect_not_enabled (line 123) | async def test_connect_not_enabled(self, async_client: AsyncClient): method test_connect_success (line 131) | async def test_connect_success(self, async_client: AsyncClient, spoolm... method test_disconnect (line 141) | async def test_disconnect(self, async_client: AsyncClient, spoolman_se... method test_get_spools_not_enabled (line 153) | async def test_get_spools_not_enabled(self, async_client: AsyncClient): method test_get_spools_success (line 161) | async def test_get_spools_success(self, async_client: AsyncClient, spo... method test_get_unlinked_spools_not_enabled (line 196) | async def test_get_unlinked_spools_not_enabled(self, async_client: Asy... method test_get_unlinked_spools_success (line 203) | async def test_get_unlinked_spools_success( method test_get_unlinked_spools_excludes_linked (line 233) | async def test_get_unlinked_spools_excludes_linked( method test_get_linked_spools_not_enabled (line 269) | async def test_get_linked_spools_not_enabled(self, async_client: Async... method test_get_linked_spools_success (line 276) | async def test_get_linked_spools_success(self, async_client: AsyncClie... method test_get_linked_spools_excludes_unlinked (line 301) | async def test_get_linked_spools_excludes_unlinked( method test_get_linked_spools_empty_tag_excluded (line 326) | async def test_get_linked_spools_empty_tag_excluded( method test_get_linked_spools_includes_weight_data (line 345) | async def test_get_linked_spools_includes_weight_data( method test_get_linked_spools_missing_weight_fields (line 367) | async def test_get_linked_spools_missing_weight_fields( method test_get_linked_spools_null_filament (line 388) | async def test_get_linked_spools_null_filament( method test_link_spool_not_enabled (line 414) | async def test_link_spool_not_enabled(self, async_client: AsyncClient): method test_link_spool_invalid_uuid_length (line 424) | async def test_link_spool_invalid_uuid_length( method test_link_spool_invalid_uuid_format (line 437) | async def test_link_spool_invalid_uuid_format( method test_link_spool_success (line 450) | async def test_link_spool_success(self, async_client: AsyncClient, spo... method test_unlink_spool_success (line 470) | async def test_unlink_spool_success(self, async_client: AsyncClient, s... method test_sync_printer_not_enabled (line 492) | async def test_sync_printer_not_enabled(self, async_client: AsyncClien... method test_sync_printer_not_found (line 501) | async def test_sync_printer_not_found(self, async_client: AsyncClient,... method test_sync_returns_result_structure (line 508) | async def test_sync_returns_result_structure( method test_sync_printer_not_connected (line 538) | async def test_sync_printer_not_connected( method test_get_filaments_not_enabled (line 561) | async def test_get_filaments_not_enabled(self, async_client: AsyncClie... method test_get_filaments_success (line 569) | async def test_get_filaments_success(self, async_client: AsyncClient, ... method spoolman_settings_weight_sync_disabled (line 594) | async def spoolman_settings_weight_sync_disabled(self, db_session): method test_settings_returns_disable_weight_sync (line 616) | async def test_settings_returns_disable_weight_sync( method test_settings_update_disable_weight_sync (line 628) | async def test_settings_update_disable_weight_sync(self, async_client:... method test_sync_with_weight_sync_disabled_updates_location_only (line 653) | async def test_sync_with_weight_sync_disabled_updates_location_only( method spoolman_settings_partial_usage_disabled (line 731) | async def spoolman_settings_partial_usage_disabled(self, db_session): method test_settings_returns_report_partial_usage (line 750) | async def test_settings_returns_report_partial_usage( method test_settings_update_report_partial_usage (line 762) | async def test_settings_update_report_partial_usage(self, async_client... method test_settings_report_partial_usage_defaults_to_true (line 787) | async def test_settings_report_partial_usage_defaults_to_true(self, as... FILE: backend/tests/integration/test_support_api.py class TestSupportLogsAPI (line 14) | class TestSupportLogsAPI: method test_get_logs_empty_file (line 23) | async def test_get_logs_empty_file(self, async_client: AsyncClient): method test_get_logs_with_entries (line 38) | async def test_get_logs_with_entries(self, async_client: AsyncClient): method test_get_logs_with_level_filter (line 68) | async def test_get_logs_with_level_filter(self, async_client: AsyncCli... method test_get_logs_with_search_filter (line 92) | async def test_get_logs_with_search_filter(self, async_client: AsyncCl... method test_get_logs_with_limit (line 115) | async def test_get_logs_with_limit(self, async_client: AsyncClient): method test_get_logs_multiline_entry (line 142) | async def test_get_logs_multiline_entry(self, async_client: AsyncClient): method test_clear_logs_success (line 177) | async def test_clear_logs_success(self, async_client: AsyncClient): method test_clear_logs_no_file (line 200) | async def test_clear_logs_no_file(self, async_client: AsyncClient): class TestLogParsingHelpers (line 212) | class TestLogParsingHelpers: method test_parse_log_line_valid (line 215) | def test_parse_log_line_valid(self): method test_parse_log_line_invalid (line 228) | def test_parse_log_line_invalid(self): method test_parse_log_line_with_brackets_in_message (line 237) | def test_parse_log_line_with_brackets_in_message(self): method test_parse_log_line_all_levels (line 247) | def test_parse_log_line_all_levels(self): FILE: backend/tests/integration/test_system_api.py class TestSystemAPI (line 12) | class TestSystemAPI: method test_get_system_info (line 21) | async def test_get_system_info(self, async_client: AsyncClient): method test_system_info_app_section (line 51) | async def test_system_info_app_section(self, async_client: AsyncClient): method test_system_info_database_section (line 75) | async def test_system_info_database_section(self, async_client: AsyncC... method test_system_info_storage_section (line 107) | async def test_system_info_storage_section(self, async_client: AsyncCl... method test_system_info_memory_section (line 137) | async def test_system_info_memory_section(self, async_client: AsyncCli... method test_system_info_cpu_section (line 163) | async def test_system_info_cpu_section(self, async_client: AsyncClient): method test_system_info_printers_section (line 187) | async def test_system_info_printers_section(self, async_client: AsyncC... method test_system_info_with_archives (line 221) | async def test_system_info_with_archives(self, async_client: AsyncClie... class TestSystemHelperFunctions (line 253) | class TestSystemHelperFunctions: method test_format_bytes_bytes (line 256) | def test_format_bytes_bytes(self): method test_format_bytes_kilobytes (line 262) | def test_format_bytes_kilobytes(self): method test_format_bytes_megabytes (line 269) | def test_format_bytes_megabytes(self): method test_format_bytes_gigabytes (line 276) | def test_format_bytes_gigabytes(self): method test_format_uptime_minutes (line 283) | def test_format_uptime_minutes(self): method test_format_uptime_hours (line 290) | def test_format_uptime_hours(self): method test_format_uptime_days (line 297) | def test_format_uptime_days(self): method test_format_uptime_less_than_minute (line 305) | def test_format_uptime_less_than_minute(self): FILE: backend/tests/integration/test_updates_api.py class TestUpdatesAPI (line 9) | class TestUpdatesAPI: method test_get_version (line 11) | async def test_get_version(self, async_client: AsyncClient): method test_apply_update_docker_rejection (line 16) | async def test_apply_update_docker_rejection(self, async_client: Async... method test_apply_update_non_docker (line 24) | async def test_apply_update_non_docker(self, async_client: AsyncClient): method test_is_docker_with_dockerenv (line 33) | def test_is_docker_with_dockerenv(self): method test_parse_version (line 39) | def test_parse_version(self): method test_is_newer_version (line 44) | def test_is_newer_version(self): FILE: backend/tests/integration/test_user_notifications_api.py class TestUserNotificationsAPI (line 10) | class TestUserNotificationsAPI: method test_get_preferences_returns_defaults_when_no_auth (line 19) | async def test_get_preferences_returns_defaults_when_no_auth(self, asy... method test_update_preferences_fails_without_auth (line 36) | async def test_update_preferences_fails_without_auth(self, async_clien... method test_update_preferences_rejects_missing_fields (line 56) | async def test_update_preferences_rejects_missing_fields(self, async_c... method test_update_preferences_rejects_invalid_type (line 69) | async def test_update_preferences_rejects_invalid_type(self, async_cli... FILE: backend/tests/integration/test_virtual_printer_api.py class TestVirtualPrinterSettingsAPI (line 12) | class TestVirtualPrinterSettingsAPI: method test_get_virtual_printer_settings (line 21) | async def test_get_virtual_printer_settings(self, async_client: AsyncC... method test_get_settings_has_status (line 34) | async def test_get_settings_has_status(self, async_client: AsyncClient): method test_update_mode (line 54) | async def test_update_mode(self, async_client: AsyncClient): method test_update_mode_to_print_queue (line 64) | async def test_update_mode_to_print_queue(self, async_client: AsyncCli... method test_update_mode_legacy_queue_maps_to_review (line 74) | async def test_update_mode_legacy_queue_maps_to_review(self, async_cli... method test_update_mode_to_immediate (line 84) | async def test_update_mode_to_immediate(self, async_client: AsyncClient): method test_update_access_code (line 94) | async def test_update_access_code(self, async_client: AsyncClient): method test_update_access_code_wrong_length (line 104) | async def test_update_access_code_wrong_length(self, async_client: Asy... method test_enable_without_access_code (line 113) | async def test_enable_without_access_code(self, async_client: AsyncCli... method test_enable_with_access_code (line 126) | async def test_enable_with_access_code(self, async_client: AsyncClient): method test_disable_virtual_printer (line 152) | async def test_disable_virtual_printer(self, async_client: AsyncClient): class TestPendingUploadsAPI (line 174) | class TestPendingUploadsAPI: method mock_pending_uploads (line 178) | def mock_pending_uploads(self, db_session): method test_list_pending_uploads_empty (line 206) | async def test_list_pending_uploads_empty(self, async_client: AsyncCli... method test_get_pending_uploads_count (line 216) | async def test_get_pending_uploads_count(self, async_client: AsyncClie... method test_archive_nonexistent_upload (line 231) | async def test_archive_nonexistent_upload(self, async_client: AsyncCli... method test_discard_nonexistent_upload (line 243) | async def test_discard_nonexistent_upload(self, async_client: AsyncCli... method test_archive_all_empty (line 255) | async def test_archive_all_empty(self, async_client: AsyncClient): method test_discard_all_empty (line 266) | async def test_discard_all_empty(self, async_client: AsyncClient): class TestVirtualPrinterAutoDispatchAPI (line 275) | class TestVirtualPrinterAutoDispatchAPI: method test_create_virtual_printer_auto_dispatch_default (line 280) | async def test_create_virtual_printer_auto_dispatch_default(self, asyn... method test_create_virtual_printer_auto_dispatch_false (line 297) | async def test_create_virtual_printer_auto_dispatch_false(self, async_... method test_update_virtual_printer_auto_dispatch (line 315) | async def test_update_virtual_printer_auto_dispatch(self, async_client... FILE: backend/tests/unit/services/conftest.py function ftp_certs (line 25) | def ftp_certs(tmp_path_factory): function _find_free_port (line 33) | def _find_free_port() -> int: function ftp_root (line 41) | def ftp_root(tmp_path_factory): function ftp_server (line 50) | def ftp_server(ftp_certs, ftp_root): function _ftp_test_cleanup (line 68) | def _ftp_test_cleanup(request): function ftp_client_factory (line 97) | def ftp_client_factory(ftp_server): function clear_ftp_mode_cache (line 121) | def clear_ftp_mode_cache(): function patch_ftp_port (line 129) | def patch_ftp_port(ftp_server): FILE: backend/tests/unit/services/mock_ftp_server.py class ImplicitTLS_FTPHandler (line 17) | class ImplicitTLS_FTPHandler(TLS_FTPHandler): method handle (line 43) | def handle(self): method ftp_PROT (line 48) | def ftp_PROT(self, line): method _check_failure (line 59) | def _check_failure(self, command: str, line: str): method ftp_AVBL (line 75) | def ftp_AVBL(self, line): method ftp_RETR (line 79) | def ftp_RETR(self, file): method ftp_STOR (line 84) | def ftp_STOR(self, file): method ftp_DELE (line 89) | def ftp_DELE(self, line): method ftp_CWD (line 94) | def ftp_CWD(self, path): method ftp_LIST (line 99) | def ftp_LIST(self, path=""): method ftp_SIZE (line 104) | def ftp_SIZE(self, path): method ftp_PASS (line 119) | def ftp_PASS(self, line): class MockBambuFTPServer (line 125) | class MockBambuFTPServer: method __init__ (line 135) | def __init__( method start (line 162) | def start(self): method stop (line 191) | def stop(self): method inject_failure (line 200) | def inject_failure(self, command: str, code: int, message: str, count:... method clear_failures (line 211) | def clear_failures(self): method set_avbl_bytes (line 215) | def set_avbl_bytes(self, n: int): method add_file (line 219) | def add_file(self, relative_path: str, content: bytes = b""): method add_directory (line 226) | def add_directory(self, relative_path: str): method file_exists (line 231) | def file_exists(self, relative_path: str) -> bool: method read_file (line 236) | def read_file(self, relative_path: str) -> bytes: FILE: backend/tests/unit/services/test_archive_copy.py function _make_3mf (line 20) | def _make_3mf(path: Path, payload_size: int = 0) -> None: class TestCopyAndFsync (line 29) | class TestCopyAndFsync: method test_copies_small_file_byte_for_byte (line 30) | def test_copies_small_file_byte_for_byte(self, tmp_path: Path) -> None: method test_copies_large_file_byte_for_byte (line 39) | def test_copies_large_file_byte_for_byte(self, tmp_path: Path) -> None: method test_preserves_mtime_via_copystat (line 51) | def test_preserves_mtime_via_copystat(self, tmp_path: Path) -> None: method test_overwrites_existing_destination (line 61) | def test_overwrites_existing_destination(self, tmp_path: Path) -> None: method test_produces_valid_zip_on_3mf (line 71) | def test_produces_valid_zip_on_3mf(self, tmp_path: Path) -> None: class TestThreeMFParserErrorVisibility (line 83) | class TestThreeMFParserErrorVisibility: method test_parse_logs_warning_on_corrupted_zip (line 84) | def test_parse_logs_warning_on_corrupted_zip( method test_parse_returns_partial_metadata_without_raising (line 102) | def test_parse_returns_partial_metadata_without_raising( class TestZipFileSentinel (line 117) | class TestZipFileSentinel: method test_is_zipfile_on_truncated_zip_returns_false (line 120) | def test_is_zipfile_on_truncated_zip_returns_false(self, tmp_path: Pat... FILE: backend/tests/unit/services/test_archive_service.py class TestArchiveServiceHelpers (line 6) | class TestArchiveServiceHelpers: method test_parse_print_time_seconds (line 9) | def test_parse_print_time_seconds(self): method test_parse_filament_grams (line 21) | def test_parse_filament_grams(self): method test_format_duration (line 28) | def test_format_duration(self): class TestArchiveDataParsing (line 40) | class TestArchiveDataParsing: method test_parse_gcode_state (line 43) | def test_parse_gcode_state(self): method test_parse_progress (line 67) | def test_parse_progress(self): method test_parse_layer_info (line 75) | def test_parse_layer_info(self): class TestArchiveFilePaths (line 90) | class TestArchiveFilePaths: method test_generate_archive_path (line 93) | def test_generate_archive_path(self): method test_sanitize_filename (line 108) | def test_sanitize_filename(self): method test_thumbnail_path (line 122) | def test_thumbnail_path(self): class TestArchiveStatus (line 132) | class TestArchiveStatus: method test_valid_status_values (line 135) | def test_valid_status_values(self): method test_status_from_gcode_state (line 141) | def test_status_from_gcode_state(self): class TestArchiveFilamentData (line 152) | class TestArchiveFilamentData: method test_parse_ams_filament (line 155) | def test_parse_ams_filament(self): method test_parse_filament_color_hex (line 173) | def test_parse_filament_color_hex(self): method test_calculate_filament_cost (line 185) | def test_calculate_filament_cost(self): class TestArchiveThumbnails (line 193) | class TestArchiveThumbnails: method test_thumbnail_file_types (line 196) | def test_thumbnail_file_types(self): method test_extract_thumbnail_from_3mf (line 203) | def test_extract_thumbnail_from_3mf(self): class TestPrintableObjectsExtraction (line 216) | class TestPrintableObjectsExtraction: method test_extract_printable_objects_from_slice_info (line 219) | def test_extract_printable_objects_from_slice_info(self): method test_extract_printable_objects_empty_plate (line 248) | def test_extract_printable_objects_empty_plate(self): method test_extract_printable_objects_all_skipped (line 270) | def test_extract_printable_objects_all_skipped(self): class TestThreeMFPlateIndexExtraction (line 294) | class TestThreeMFPlateIndexExtraction: method test_extract_plate_index_from_slice_info (line 297) | def test_extract_plate_index_from_slice_info(self): method test_extract_plate_index_plate_1 (line 323) | def test_extract_plate_index_plate_1(self): method test_thumbnail_path_uses_plate_number (line 346) | def test_thumbnail_path_uses_plate_number(self): method _enhance_print_name (line 365) | def _enhance_print_name(print_name: str, plate_index: int) -> str: method test_print_name_enhanced_for_plate_greater_than_1 (line 372) | def test_print_name_enhanced_for_plate_greater_than_1(self): method test_print_name_not_enhanced_for_plate_1 (line 376) | def test_print_name_not_enhanced_for_plate_1(self): method test_print_name_not_duplicated (line 380) | def test_print_name_not_duplicated(self): method test_high_plate_number_extraction (line 384) | def test_high_plate_number_extraction(self): class TestMultiPlate3MFParsing (line 412) | class TestMultiPlate3MFParsing: method test_parse_multiple_plates_from_slice_info (line 415) | def test_parse_multiple_plates_from_slice_info(self): method test_filter_filaments_by_plate_id (line 492) | def test_filter_filaments_by_plate_id(self): method test_detect_multi_plate_from_gcode_files (line 538) | def test_detect_multi_plate_from_gcode_files(self): method test_single_plate_export_not_multi_plate (line 568) | def test_single_plate_export_not_multi_plate(self): class TestReprintCostCalculation (line 597) | class TestReprintCostCalculation: method test_cost_addition_logic (line 600) | def test_cost_addition_logic(self): method test_cost_addition_with_none_existing (line 615) | def test_cost_addition_with_none_existing(self): method test_cost_with_custom_filament_price (line 628) | def test_cost_with_custom_filament_price(self): method test_multiple_reprints_accumulate (line 636) | def test_multiple_reprints_accumulate(self): FILE: backend/tests/unit/services/test_background_dispatch.py function test_dispatch_rejects_when_printer_busy_printing (line 17) | async def test_dispatch_rejects_when_printer_busy_printing(): function test_dispatch_enqueues_job_and_broadcasts_state (line 40) | async def test_dispatch_enqueues_job_and_broadcasts_state(): function test_dispatch_library_file_defaults_cleanup_flag_false (line 72) | async def test_dispatch_library_file_defaults_cleanup_flag_false(): function test_dispatch_library_file_propagates_cleanup_flag_true (line 96) | async def test_dispatch_library_file_propagates_cleanup_flag_true(): function test_cancel_queued_job_removes_it_and_broadcasts (line 126) | async def test_cancel_queued_job_removes_it_and_broadcasts(): function test_cancel_active_job_marks_pending_and_sets_cancel_flag (line 160) | async def test_cancel_active_job_marks_pending_and_sets_cancel_flag(): function test_resolve_plate_id_uses_request_value_when_provided (line 187) | def test_resolve_plate_id_uses_request_value_when_provided(tmp_path): function test_resolve_plate_id_auto_detects_from_3mf (line 196) | def test_resolve_plate_id_auto_detects_from_3mf(tmp_path): function test_is_sliced_file_recognizes_supported_extensions (line 208) | def test_is_sliced_file_recognizes_supported_extensions(): function test_cancel_job_not_found_returns_false (line 216) | async def test_cancel_job_not_found_returns_false(): function test_cancel_job_single_lock_covers_both_active_and_queued (line 228) | async def test_cancel_job_single_lock_covers_both_active_and_queued(): function test_mark_job_finished_resets_batch_when_all_done (line 277) | async def test_mark_job_finished_resets_batch_when_all_done(): function test_mark_job_finished_no_reset_when_jobs_remain (line 300) | async def test_mark_job_finished_no_reset_when_jobs_remain(): function test_mark_job_finished_batch_reset_rechecks_under_lock (line 332) | async def test_mark_job_finished_batch_reset_rechecks_under_lock(): FILE: backend/tests/unit/services/test_bambu_cloud.py class TestBambuCloudLogin (line 10) | class TestBambuCloudLogin: method cloud_service (line 14) | def cloud_service(self): method test_login_detects_email_verification (line 19) | async def test_login_detects_email_verification(self, cloud_service): method test_login_detects_totp (line 39) | async def test_login_detects_totp(self, cloud_service): method test_login_direct_success (line 60) | async def test_login_direct_success(self, cloud_service): method test_login_failure (line 79) | async def test_login_failure(self, cloud_service): class TestBambuCloudEmailVerification (line 97) | class TestBambuCloudEmailVerification: method cloud_service (line 101) | def cloud_service(self): method test_verify_code_success (line 106) | async def test_verify_code_success(self, cloud_service): method test_verify_code_failure (line 124) | async def test_verify_code_failure(self, cloud_service): class TestBambuCloudTOTPVerification (line 141) | class TestBambuCloudTOTPVerification: method cloud_service (line 145) | def cloud_service(self): method test_verify_totp_success (line 150) | async def test_verify_totp_success(self, cloud_service): method test_verify_totp_uses_correct_endpoint (line 169) | async def test_verify_totp_uses_correct_endpoint(self, cloud_service): method test_verify_totp_empty_response (line 189) | async def test_verify_totp_empty_response(self, cloud_service): method test_verify_totp_cloudflare_blocked (line 204) | async def test_verify_totp_cloudflare_blocked(self, cloud_service): method test_verify_totp_includes_browser_headers (line 221) | async def test_verify_totp_includes_browser_headers(self, cloud_service): class TestBambuCloudRegion (line 241) | class TestBambuCloudRegion: method test_global_region_uses_com_base (line 244) | def test_global_region_uses_com_base(self): method test_china_region_uses_cn_base (line 252) | def test_china_region_uses_cn_base(self): method test_china_region_login_hits_cn_endpoint (line 258) | async def test_china_region_login_hits_cn_endpoint(self): method test_china_region_totp_hits_cn_tfa_endpoint (line 276) | async def test_china_region_totp_hits_cn_tfa_endpoint(self): FILE: backend/tests/unit/services/test_bambu_ftp.py class TestConnection (line 45) | class TestConnection: method test_connect_success (line 48) | def test_connect_success(self, ftp_client_factory): method test_connect_wrong_access_code (line 54) | def test_connect_wrong_access_code(self, ftp_client_factory): method test_connect_unreachable_host (line 59) | def test_connect_unreachable_host(self, ftp_server): method test_connect_timeout (line 70) | def test_connect_timeout(self, ftp_server): method test_disconnect_clean (line 81) | def test_disconnect_clean(self, ftp_client_factory): method test_disconnect_without_connect (line 88) | def test_disconnect_without_connect(self, ftp_client_factory): method test_x1c_uses_prot_p (line 94) | def test_x1c_uses_prot_p(self, ftp_client_factory): method test_a1_defaults_prot_p (line 101) | def test_a1_defaults_prot_p(self, ftp_client_factory): method test_a1_force_prot_c (line 108) | def test_a1_force_prot_c(self, ftp_client_factory): method test_cached_mode_respected (line 115) | def test_cached_mode_respected(self, ftp_client_factory): class TestDisconnectServerGone (line 128) | class TestDisconnectServerGone: method test_disconnect_after_server_gone (line 131) | def test_disconnect_after_server_gone(self, ftp_certs, tmp_path): class TestListFiles (line 161) | class TestListFiles: method test_list_empty_directory (line 164) | def test_list_empty_directory(self, ftp_client_factory): method test_list_directory_with_files (line 172) | def test_list_directory_with_files(self, ftp_client_factory, ftp_server): method test_directories_marked (line 184) | def test_directories_marked(self, ftp_client_factory, ftp_server): method test_nonexistent_path_returns_empty (line 195) | def test_nonexistent_path_returns_empty(self, ftp_client_factory): method test_file_sizes_and_paths (line 203) | def test_file_sizes_and_paths(self, ftp_client_factory, ftp_server): class TestDownload (line 219) | class TestDownload: method test_download_file_returns_bytes (line 222) | def test_download_file_returns_bytes(self, ftp_client_factory, ftp_ser... method test_download_file_missing (line 232) | def test_download_file_missing(self, ftp_client_factory): method test_download_to_file_writes_to_disk (line 240) | def test_download_to_file_writes_to_disk(self, ftp_client_factory, ftp... method test_download_to_file_creates_parent_dirs (line 252) | def test_download_to_file_creates_parent_dirs(self, ftp_client_factory... method test_zero_byte_download_returns_false (line 263) | def test_zero_byte_download_returns_false(self, ftp_client_factory, ft... method test_download_to_file_missing_raises_not_on_printer (line 274) | def test_download_to_file_missing_raises_not_on_printer(self, ftp_clie... method test_download_large_file (line 288) | def test_download_large_file(self, ftp_client_factory, ftp_server): method test_download_not_connected (line 298) | def test_download_not_connected(self): class TestUpload (line 307) | class TestUpload: method test_upload_success (line 310) | def test_upload_success(self, ftp_client_factory, ftp_server, tmp_path): method test_upload_progress_callback (line 329) | def test_upload_progress_callback(self, ftp_client_factory, ftp_server... method test_upload_not_connected (line 349) | def test_upload_not_connected(self, tmp_path): method test_upload_553_no_sd_card (line 356) | def test_upload_553_no_sd_card(self, ftp_client_factory, ftp_server, t... method test_upload_550_permission_denied (line 367) | def test_upload_550_permission_denied(self, ftp_client_factory, ftp_se... method test_upload_552_storage_full (line 378) | def test_upload_552_storage_full(self, ftp_client_factory, ftp_server,... method test_upload_bytes_success (line 389) | def test_upload_bytes_success(self, ftp_client_factory, ftp_server): method test_upload_bytes_failure (line 405) | def test_upload_bytes_failure(self, ftp_client_factory, ftp_server): method test_upload_large_chunked (line 414) | def test_upload_large_chunked(self, ftp_client_factory, ftp_server, tm... class TestDelete (line 445) | class TestDelete: method test_delete_success (line 448) | def test_delete_success(self, ftp_client_factory, ftp_server): method test_delete_not_found (line 458) | def test_delete_not_found(self, ftp_client_factory): method test_delete_not_connected (line 466) | def test_delete_not_connected(self): class TestFileSize (line 475) | class TestFileSize: method test_file_size_correct (line 478) | def test_file_size_correct(self, ftp_client_factory, ftp_server): method test_file_size_missing (line 487) | def test_file_size_missing(self, ftp_client_factory): method test_file_size_not_connected (line 495) | def test_file_size_not_connected(self): class TestStorageInfo (line 504) | class TestStorageInfo: method test_avbl_parsed (line 507) | def test_avbl_parsed(self, ftp_client_factory, ftp_server): method test_used_bytes_from_scan (line 517) | def test_used_bytes_from_scan(self, ftp_client_factory, ftp_server): method test_storage_info_not_connected (line 528) | def test_storage_info_not_connected(self): method test_diagnose_storage_success (line 533) | def test_diagnose_storage_success(self, ftp_client_factory, ftp_server): method test_diagnose_storage_not_connected (line 545) | def test_diagnose_storage_not_connected(self): class TestModelSpecificBehavior (line 556) | class TestModelSpecificBehavior: method test_x1c_upload (line 559) | def test_x1c_upload(self, ftp_client_factory, ftp_server, tmp_path): method test_a1_upload_prot_c (line 577) | def test_a1_upload_prot_c(self, ftp_client_factory, ftp_server, tmp_pa... method test_a1_mini_upload (line 595) | def test_a1_mini_upload(self, ftp_client_factory, ftp_server, tmp_path): method test_p1s_upload (line 606) | def test_p1s_upload(self, ftp_client_factory, ftp_server, tmp_path): method test_unknown_model_defaults_prot_p (line 617) | def test_unknown_model_defaults_prot_p(self, ftp_client_factory): method test_mode_cache_persists_and_clears (line 625) | def test_mode_cache_persists_and_clears(self, ftp_client_factory): class TestAsyncWrappers (line 644) | class TestAsyncWrappers: method test_upload_file_async_success (line 648) | async def test_upload_file_async_success(self, patch_ftp_port, tmp_path): method test_upload_file_async_a1_fallback (line 664) | async def test_upload_file_async_a1_fallback(self, patch_ftp_port, tmp... method test_download_file_async_success (line 683) | async def test_download_file_async_success(self, patch_ftp_port, tmp_p... method test_download_file_async_a1_fallback (line 701) | async def test_download_file_async_a1_fallback(self, patch_ftp_port, t... method test_download_file_async_timeout_salvages_completed_zombie (line 717) | async def test_download_file_async_timeout_salvages_completed_zombie(s... method test_download_file_async_timeout_no_salvage_when_incomplete (line 777) | async def test_download_file_async_timeout_no_salvage_when_incomplete(... method test_download_file_async_timeout_waits_for_slow_zombie (line 823) | async def test_download_file_async_timeout_waits_for_slow_zombie(self,... method test_download_file_try_paths_first_succeeds (line 879) | async def test_download_file_try_paths_first_succeeds(self, patch_ftp_... method test_download_file_try_paths_fallback (line 895) | async def test_download_file_try_paths_fallback(self, patch_ftp_port, ... method test_list_files_async_success (line 911) | async def test_list_files_async_success(self, patch_ftp_port): method test_delete_file_async_success (line 926) | async def test_delete_file_async_success(self, patch_ftp_port): class TestFailureScenarios (line 943) | class TestFailureScenarios: method test_550_caught_by_broad_except (line 946) | def test_550_caught_by_broad_except(self, ftp_client_factory, ftp_serv... method test_zero_byte_download_detected (line 961) | def test_zero_byte_download_detected(self, ftp_client_factory, ftp_ser... method test_connection_refused_handled (line 975) | def test_connection_refused_handled(self): method test_auth_failure_530 (line 981) | def test_auth_failure_530(self, ftp_client_factory, ftp_server): method test_retr_550_handled (line 988) | def test_retr_550_handled(self, ftp_client_factory, ftp_server): method test_cwd_550_handled (line 998) | def test_cwd_550_handled(self, ftp_client_factory, ftp_server): method test_stor_553_handled (line 1007) | def test_stor_553_handled(self, ftp_client_factory, ftp_server, tmp_pa... method test_diagnose_storage_cwd_failure_doesnt_propagate (line 1018) | def test_diagnose_storage_cwd_failure_doesnt_propagate(self, ftp_clien... method test_failure_injection_count_decrements (line 1033) | def test_failure_injection_count_decrements(self, ftp_client_factory, ... method test_upload_skips_voidresp (line 1047) | def test_upload_skips_voidresp(self, ftp_client_factory, ftp_server, t... class TestFileNotOnPrinterShortCircuit (line 1076) | class TestFileNotOnPrinterShortCircuit: method test_with_ftp_retry_propagates_file_not_on_printer_without_retrying (line 1086) | async def test_with_ftp_retry_propagates_file_not_on_printer_without_r... method test_with_ftp_retry_still_retries_transient_errors (line 1109) | async def test_with_ftp_retry_still_retries_transient_errors(self): method test_download_to_file_raises_on_missing_path (line 1128) | def test_download_to_file_raises_on_missing_path(self, ftp_client_fact... class TestThreeMFCache (line 1145) | class TestThreeMFCache: method setup_method (line 1150) | def setup_method(self): method teardown_method (line 1153) | def teardown_method(self): method test_normalize_collapses_filename_variants (line 1156) | def test_normalize_collapses_filename_variants(self): method test_cache_hit_returns_stored_path (line 1167) | def test_cache_hit_returns_stored_path(self, tmp_path): method test_cache_lookup_uses_normalized_name (line 1174) | def test_cache_lookup_uses_normalized_name(self, tmp_path): method test_cache_miss_on_different_printer (line 1182) | def test_cache_miss_on_different_printer(self, tmp_path): method test_cache_evicts_when_file_deleted (line 1189) | def test_cache_evicts_when_file_deleted(self, tmp_path): method test_clear_by_printer_scoped (line 1201) | def test_clear_by_printer_scoped(self, tmp_path): method test_clear_without_deleting_files (line 1216) | def test_clear_without_deleting_files(self, tmp_path): FILE: backend/tests/unit/services/test_bambu_mqtt.py class TestTimelapseTracking (line 13) | class TestTimelapseTracking: method mqtt_client (line 17) | def mqtt_client(self): method test_timelapse_flag_initializes_to_false (line 28) | def test_timelapse_flag_initializes_to_false(self, mqtt_client): method test_timelapse_flag_set_when_timelapse_active_during_running (line 32) | def test_timelapse_flag_set_when_timelapse_active_during_running(self,... method test_timelapse_flag_not_set_when_not_running (line 45) | def test_timelapse_flag_not_set_when_not_running(self, mqtt_client): method test_timelapse_flag_persists_after_timelapse_stops (line 59) | def test_timelapse_flag_persists_after_timelapse_stops(self, mqtt_clie... method test_timelapse_flag_from_print_data (line 77) | def test_timelapse_flag_from_print_data(self, mqtt_client): class TestPrintCompletionWithTimelapse (line 94) | class TestPrintCompletionWithTimelapse: method mqtt_client (line 98) | def mqtt_client(self): method test_print_complete_includes_timelapse_flag (line 109) | def test_print_complete_includes_timelapse_flag(self, mqtt_client): method test_print_complete_timelapse_flag_false_when_no_timelapse (line 157) | def test_print_complete_timelapse_flag_false_when_no_timelapse(self, m... method test_timelapse_flag_reset_after_completion (line 188) | def test_timelapse_flag_reset_after_completion(self, mqtt_client): class TestRealisticMessageFlow (line 202) | class TestRealisticMessageFlow: method mqtt_client (line 210) | def mqtt_client(self): method test_timelapse_detected_at_print_start_in_same_message (line 221) | def test_timelapse_detected_at_print_start_in_same_message(self, mqtt_... method test_timelapse_not_detected_when_disabled (line 267) | def test_timelapse_not_detected_when_disabled(self, mqtt_client): method test_timelapse_detected_when_enabled_after_print_start (line 295) | def test_timelapse_detected_when_enabled_after_print_start(self, mqtt_... method test_print_complete_includes_timelapse_flag_full_flow (line 328) | def test_print_complete_includes_timelapse_flag_full_flow(self, mqtt_c... method test_print_failed_includes_timelapse_flag (line 393) | def test_print_failed_includes_timelapse_flag(self, mqtt_client): class TestAMSDataMerging (line 430) | class TestAMSDataMerging: method mqtt_client (line 434) | def mqtt_client(self): method test_empty_slot_clears_tray_type (line 445) | def test_empty_slot_clears_tray_type(self, mqtt_client): method test_partial_update_preserves_other_fields (line 506) | def test_partial_update_preserves_other_fields(self, mqtt_client): method test_tray_exist_bits_clears_empty_slots (line 553) | def test_tray_exist_bits_clears_empty_slots(self, mqtt_client): method test_shutdown_message_preserves_ams_data (line 610) | def test_shutdown_message_preserves_ams_data(self, mqtt_client): method test_genuine_removal_still_clears_with_power_on (line 665) | def test_genuine_removal_still_clears_with_power_on(self, mqtt_client): method test_power_on_flag_defaults_true_when_absent (line 705) | def test_power_on_flag_defaults_true_when_absent(self, mqtt_client): class TestAMSTrayStateClearning (line 738) | class TestAMSTrayStateClearning: method mqtt_client (line 748) | def mqtt_client(self): method _seed_loaded_tray (line 758) | def _seed_loaded_tray(self, mqtt_client): method test_state_10_clears_stale_tray_data (line 796) | def test_state_10_clears_stale_tray_data(self, mqtt_client): method test_state_9_clears_stale_tray_data (line 836) | def test_state_9_clears_stale_tray_data(self, mqtt_client): method test_state_11_preserves_tray_data (line 858) | def test_state_11_preserves_tray_data(self, mqtt_client): method test_no_clearing_when_tray_type_already_empty (line 881) | def test_no_clearing_when_tray_type_already_empty(self, mqtt_client): method test_reload_after_unload_restores_data (line 898) | def test_reload_after_unload_restores_data(self, mqtt_client): class TestNozzleRackData (line 939) | class TestNozzleRackData: method mqtt_client (line 943) | def mqtt_client(self): method test_h2c_nozzle_rack_populated_with_8_entries (line 954) | def test_h2c_nozzle_rack_populated_with_8_entries(self, mqtt_client): method test_h2d_nozzle_rack_populated_with_2_entries (line 1044) | def test_h2d_nozzle_rack_populated_with_2_entries(self, mqtt_client): method test_single_nozzle_h2s_populated (line 1080) | def test_single_nozzle_h2s_populated(self, mqtt_client): method test_empty_nozzle_info_does_not_populate_rack (line 1106) | def test_empty_nozzle_info_does_not_populate_rack(self, mqtt_client): method test_nozzle_rack_sorted_by_id (line 1113) | def test_nozzle_rack_sorted_by_id(self, mqtt_client): method test_nozzle_rack_field_mapping (line 1134) | def test_nozzle_rack_field_mapping(self, mqtt_client): method test_nozzle_info_updates_nozzle_state (line 1172) | def test_nozzle_info_updates_nozzle_state(self, mqtt_client): class TestRequestTopicFailSafe (line 1194) | class TestRequestTopicFailSafe: method clear_request_topic_cache (line 1198) | def clear_request_topic_cache(self): method mqtt_client (line 1205) | def mqtt_client(self): method test_request_topic_supported_by_default (line 1215) | def test_request_topic_supported_by_default(self, mqtt_client): method test_on_subscribe_confirms_success (line 1220) | def test_on_subscribe_confirms_success(self, mqtt_client): method test_on_subscribe_detects_rejection (line 1233) | def test_on_subscribe_detects_rejection(self, mqtt_client): method test_on_subscribe_ignores_other_mids (line 1244) | def test_on_subscribe_ignores_other_mids(self, mqtt_client): method test_disconnect_after_subscription_disables_topic (line 1255) | def test_disconnect_after_subscription_disables_topic(self, mqtt_client): method test_disconnect_after_confirmation_does_not_disable (line 1268) | def test_disconnect_after_confirmation_does_not_disable(self, mqtt_cli... method test_late_disconnect_does_not_disable (line 1280) | def test_late_disconnect_does_not_disable(self, mqtt_client): method test_on_connect_skips_request_topic_when_unsupported (line 1292) | def test_on_connect_skips_request_topic_when_unsupported(self, mqtt_cl... method test_cache_persists_across_instances (line 1311) | def test_cache_persists_across_instances(self): method test_cache_does_not_affect_different_serial (line 1337) | def test_cache_does_not_affect_different_serial(self): method test_cache_updated_on_suback_success (line 1350) | def test_cache_updated_on_suback_success(self): method test_cache_updated_on_suback_rejection (line 1367) | def test_cache_updated_on_suback_rejection(self): class TestRequestTopicAmsMapping (line 1385) | class TestRequestTopicAmsMapping: method mqtt_client (line 1389) | def mqtt_client(self): method test_captured_ams_mapping_initializes_to_none (line 1400) | def test_captured_ams_mapping_initializes_to_none(self, mqtt_client): method test_handle_request_message_captures_ams_mapping (line 1404) | def test_handle_request_message_captures_ams_mapping(self, mqtt_client): method test_handle_request_message_ignores_non_print_commands (line 1416) | def test_handle_request_message_ignores_non_print_commands(self, mqtt_... method test_handle_request_message_ignores_missing_ams_mapping (line 1426) | def test_handle_request_message_ignores_missing_ams_mapping(self, mqtt... method test_handle_request_message_ignores_non_dict_print (line 1437) | def test_handle_request_message_ignores_non_dict_print(self, mqtt_clie... method test_handle_request_message_ignores_missing_print (line 1443) | def test_handle_request_message_ignores_missing_print(self, mqtt_client): method test_captured_mapping_overwrites_previous (line 1449) | def test_captured_mapping_overwrites_previous(self, mqtt_client): method test_print_start_callback_includes_ams_mapping (line 1461) | def test_print_start_callback_includes_ams_mapping(self, mqtt_client): method test_print_start_callback_ams_mapping_none_when_not_captured (line 1484) | def test_print_start_callback_ams_mapping_none_when_not_captured(self,... method test_print_complete_callback_includes_ams_mapping (line 1506) | def test_print_complete_callback_includes_ams_mapping(self, mqtt_client): method test_captured_mapping_cleared_after_print_complete (line 1541) | def test_captured_mapping_cleared_after_print_complete(self, mqtt_clie... method test_full_flow_capture_and_deliver (line 1571) | def test_full_flow_capture_and_deliver(self, mqtt_client): function _ams_payload (line 1626) | def _ams_payload(tray_now, ams_units=None, tray_exist_bits=None, ams_exi... function _extruder_info_payload (line 1638) | def _extruder_info_payload(extruders): function _extruder_state_payload (line 1654) | def _extruder_state_payload(state_val): class TestTrayNowSingleNozzleX1E (line 1672) | class TestTrayNowSingleNozzleX1E: method mqtt_client (line 1676) | def mqtt_client(self): method test_tray_now_direct_passthrough_slot_0_to_3 (line 1685) | def test_tray_now_direct_passthrough_slot_0_to_3(self, mqtt_client): method test_tray_now_255_means_unloaded (line 1691) | def test_tray_now_255_means_unloaded(self, mqtt_client): method test_single_extruder_does_not_trigger_dual_nozzle (line 1696) | def test_single_extruder_does_not_trigger_dual_nozzle(self, mqtt_client): method test_last_loaded_tray_survives_unload (line 1701) | def test_last_loaded_tray_survives_unload(self, mqtt_client): class TestTrayNowSingleNozzleP2S (line 1716) | class TestTrayNowSingleNozzleP2S: method mqtt_client (line 1720) | def mqtt_client(self): method test_tray_now_ams1_global_ids_4_to_7 (line 1729) | def test_tray_now_ams1_global_ids_4_to_7(self, mqtt_client): method test_tray_change_across_ams_units (line 1735) | def test_tray_change_across_ams_units(self, mqtt_client): class TestTrayNowP2SMultiAmsDisambiguation (line 1749) | class TestTrayNowP2SMultiAmsDisambiguation: method mqtt_client (line 1758) | def mqtt_client(self): method test_resolves_ams1_slot1_from_mapping (line 1768) | def test_resolves_ams1_slot1_from_mapping(self, mqtt_client): method test_resolves_ams1_slot0_from_mapping (line 1780) | def test_resolves_ams1_slot0_from_mapping(self, mqtt_client): method test_resolves_ams1_slot3_from_mapping (line 1789) | def test_resolves_ams1_slot3_from_mapping(self, mqtt_client): method test_ams0_slot_unchanged_when_mapping_confirms_ams0 (line 1798) | def test_ams0_slot_unchanged_when_mapping_confirms_ams0(self, mqtt_cli... method test_multicolor_resolves_ams1_from_multi_entry_mapping (line 1807) | def test_multicolor_resolves_ams1_from_multi_entry_mapping(self, mqtt_... method test_multicolor_four_slot_mapping (line 1817) | def test_multicolor_four_slot_mapping(self, mqtt_client): method test_ambiguous_mapping_falls_back_to_local_slot (line 1827) | def test_ambiguous_mapping_falls_back_to_local_slot(self, mqtt_client): method test_no_mapping_falls_back_to_local_slot (line 1837) | def test_no_mapping_falls_back_to_local_slot(self, mqtt_client): method test_empty_mapping_falls_back_to_local_slot (line 1843) | def test_empty_mapping_falls_back_to_local_slot(self, mqtt_client): method test_single_ams_passthrough (line 1849) | def test_single_ams_passthrough(self, mqtt_client): method test_no_ams_exist_bits_passthrough (line 1854) | def test_no_ams_exist_bits_passthrough(self, mqtt_client): method test_tray_now_255_unaffected_by_multi_ams (line 1859) | def test_tray_now_255_unaffected_by_multi_ams(self, mqtt_client): method test_tray_now_above_3_unaffected (line 1865) | def test_tray_now_above_3_unaffected(self, mqtt_client): method test_last_loaded_tray_uses_resolved_global_id (line 1870) | def test_last_loaded_tray_uses_resolved_global_id(self, mqtt_client): class TestResolveLocalSlotFromMapping (line 1879) | class TestResolveLocalSlotFromMapping: method test_single_match_ams0 (line 1882) | def test_single_match_ams0(self): method test_single_match_ams1 (line 1887) | def test_single_match_ams1(self): method test_single_match_ams2 (line 1893) | def test_single_match_ams2(self): method test_unmapped_entries_skipped (line 1899) | def test_unmapped_entries_skipped(self): method test_no_match_returns_none (line 1904) | def test_no_match_returns_none(self): method test_ambiguous_returns_none (line 1910) | def test_ambiguous_returns_none(self): method test_none_mapping_returns_none (line 1916) | def test_none_mapping_returns_none(self): method test_empty_mapping_returns_none (line 1921) | def test_empty_mapping_returns_none(self): method test_ams_ht_slot0_match (line 1926) | def test_ams_ht_slot0_match(self): class TestTrayNowDualNozzleH2DSetup (line 1938) | class TestTrayNowDualNozzleH2DSetup: method mqtt_client (line 1942) | def mqtt_client(self): method test_dual_nozzle_detected_from_extruder_info (line 1951) | def test_dual_nozzle_detected_from_extruder_info(self, mqtt_client): method test_ams_extruder_map_parsed_from_info_field (line 1963) | def test_ams_extruder_map_parsed_from_info_field(self, mqtt_client): method test_ams_extruder_map_real_h2d_values (line 1985) | def test_ams_extruder_map_real_h2d_values(self, mqtt_client): method test_ams_extruder_map_skips_uninitialized (line 2006) | def test_ams_extruder_map_skips_uninitialized(self, mqtt_client): method test_ams_extruder_map_partial_update_preserves_entries (line 2023) | def test_ams_extruder_map_partial_update_preserves_entries(self, mqtt_... method test_dual_nozzle_detection_before_ams_in_same_message (line 2057) | def test_dual_nozzle_detection_before_ams_in_same_message(self, mqtt_c... class _H2DFixtureMixin (line 2096) | class _H2DFixtureMixin: method mqtt_client (line 2100) | def mqtt_client(self): method h2d_client (line 2110) | def h2d_client(self, mqtt_client): class TestTrayNowDualNozzleH2DSnow (line 2145) | class TestTrayNowDualNozzleH2DSnow(_H2DFixtureMixin): method test_snow_disambiguates_ams0_slot (line 2148) | def test_snow_disambiguates_ams0_slot(self, h2d_client): method test_snow_disambiguates_ams_ht_to_128 (line 2167) | def test_snow_disambiguates_ams_ht_to_128(self, h2d_client): method test_snow_updates_h2d_extruder_snow_state (line 2190) | def test_snow_updates_h2d_extruder_snow_state(self, h2d_client): method test_snow_unloaded_value (line 2205) | def test_snow_unloaded_value(self, h2d_client): method test_snow_initial_sentinel_not_stored (line 2218) | def test_snow_initial_sentinel_not_stored(self, h2d_client): class TestTrayNowDualNozzleH2DPendingTarget (line 2238) | class TestTrayNowDualNozzleH2DPendingTarget(_H2DFixtureMixin): method test_pending_target_matches_slot (line 2241) | def test_pending_target_matches_slot(self, h2d_client): method test_pending_target_slot_mismatch (line 2248) | def test_pending_target_slot_mismatch(self, h2d_client): method test_pending_target_takes_priority_over_snow (line 2256) | def test_pending_target_takes_priority_over_snow(self, h2d_client): class TestTrayNowDualNozzleH2DFallback (line 2282) | class TestTrayNowDualNozzleH2DFallback(_H2DFixtureMixin): method test_single_ams_on_extruder_computes_global_id (line 2285) | def test_single_ams_on_extruder_computes_global_id(self, h2d_client): method test_multiple_ams_keeps_current_if_valid (line 2293) | def test_multiple_ams_keeps_current_if_valid(self, h2d_client): method test_no_ams_on_extruder_uses_raw_slot (line 2303) | def test_no_ams_on_extruder_uses_raw_slot(self, h2d_client): method test_single_ams_ht_on_extruder_returns_unit_id (line 2310) | def test_single_ams_ht_on_extruder_returns_unit_id(self, h2d_client): method test_single_ams_ht_ignores_nonzero_slot (line 2318) | def test_single_ams_ht_ignores_nonzero_slot(self, h2d_client): method test_multiple_ams_keeps_current_ams_ht (line 2325) | def test_multiple_ams_keeps_current_ams_ht(self, h2d_client): method test_multiple_ams_slot_nonzero_excludes_ams_ht (line 2332) | def test_multiple_ams_slot_nonzero_excludes_ams_ht(self, h2d_client): method test_multiple_ams_slot_nonzero_narrows_to_single_ht_excluded (line 2341) | def test_multiple_ams_slot_nonzero_narrows_to_single_ht_excluded(self,... class TestLastLoadedTrayValidation (line 2355) | class TestLastLoadedTrayValidation(_H2DFixtureMixin): method test_regular_ams_tray_stored (line 2358) | def test_regular_ams_tray_stored(self, h2d_client): method test_ams_ht_tray_stored (line 2374) | def test_ams_ht_tray_stored(self, h2d_client): method test_unloaded_not_stored (line 2389) | def test_unloaded_not_stored(self, h2d_client): class TestTrayNowDualNozzleH2DActiveExtruder (line 2402) | class TestTrayNowDualNozzleH2DActiveExtruder(_H2DFixtureMixin): method test_active_extruder_right_by_default (line 2405) | def test_active_extruder_right_by_default(self, h2d_client): method test_extruder_state_bit8_switches_to_left (line 2409) | def test_extruder_state_bit8_switches_to_left(self, h2d_client): method test_extruder_state_bit8_switches_back_to_right (line 2414) | def test_extruder_state_bit8_switches_back_to_right(self, h2d_client): method test_extruder_switch_changes_tray_disambiguation (line 2422) | def test_extruder_switch_changes_tray_disambiguation(self, h2d_client): class TestTrayNowDualNozzleH2DFullSequence (line 2451) | class TestTrayNowDualNozzleH2DFullSequence(_H2DFixtureMixin): method test_h2d_right_nozzle_ams0_lifecycle (line 2454) | def test_h2d_right_nozzle_ams0_lifecycle(self, h2d_client): method test_h2d_left_nozzle_ams_ht_lifecycle (line 2470) | def test_h2d_left_nozzle_ams_ht_lifecycle(self, h2d_client): method test_h2d_multi_color_alternating_nozzles (line 2490) | def test_h2d_multi_color_alternating_nozzles(self, h2d_client): class TestTrayChangeLog (line 2543) | class TestTrayChangeLog: method mqtt_client (line 2547) | def mqtt_client(self): method test_tray_change_log_defaults_empty (line 2558) | def test_tray_change_log_defaults_empty(self, mqtt_client): method test_tray_change_log_seeded_on_print_start (line 2562) | def test_tray_change_log_seeded_on_print_start(self, mqtt_client): method test_tray_change_log_cleared_on_new_print (line 2580) | def test_tray_change_log_cleared_on_new_print(self, mqtt_client): method test_tray_change_recorded_during_running (line 2598) | def test_tray_change_recorded_during_running(self, mqtt_client): method test_tray_change_not_recorded_when_idle (line 2615) | def test_tray_change_not_recorded_when_idle(self, mqtt_client): method test_tray_change_recorded_during_pause (line 2630) | def test_tray_change_recorded_during_pause(self, mqtt_client): method test_same_tray_not_logged_twice (line 2645) | def test_same_tray_not_logged_twice(self, mqtt_client): method test_multiple_tray_changes (line 2661) | def test_multiple_tray_changes(self, mqtt_client): class TestDeveloperModeDetection (line 2679) | class TestDeveloperModeDetection: method mqtt_client (line 2683) | def mqtt_client(self): method test_developer_mode_initially_none (line 2694) | def test_developer_mode_initially_none(self, mqtt_client): method test_developer_mode_on_when_bit_clear (line 2698) | def test_developer_mode_on_when_bit_clear(self, mqtt_client): method test_developer_mode_off_when_bit_set (line 2710) | def test_developer_mode_off_when_bit_set(self, mqtt_client): method test_developer_mode_exact_bit_check (line 2722) | def test_developer_mode_exact_bit_check(self, mqtt_client): method test_developer_mode_invalid_fun_ignored (line 2739) | def test_developer_mode_invalid_fun_ignored(self, mqtt_client): method test_developer_mode_missing_fun_preserves_state (line 2753) | def test_developer_mode_missing_fun_preserves_state(self, mqtt_client): method test_developer_mode_persists_across_messages (line 2766) | def test_developer_mode_persists_across_messages(self, mqtt_client): class TestDeveloperModeProbeTimeout (line 2792) | class TestDeveloperModeProbeTimeout: method mqtt_client (line 2801) | def mqtt_client(self): method _make_pushall_data (line 2821) | def _make_pushall_data(self): method test_first_timeout_allows_retry (line 2825) | def test_first_timeout_allows_retry(self, mqtt_client): method test_second_timeout_forces_reconnect (line 2849) | def test_second_timeout_forces_reconnect(self, mqtt_client): method test_successful_probe_resets_failure_counter (line 2877) | def test_successful_probe_resets_failure_counter(self, mqtt_client): method test_no_timeout_when_probe_not_sent (line 2908) | def test_no_timeout_when_probe_not_sent(self, mqtt_client): method test_on_connect_resets_probe_state_but_preserves_developer_mode (line 2915) | def test_on_connect_resets_probe_state_but_preserves_developer_mode(se... method test_probe_deferred_when_connect_too_recent (line 2937) | def test_probe_deferred_when_connect_too_recent(self, mqtt_client): method test_probe_fires_after_delay (line 2952) | def test_probe_fires_after_delay(self, mqtt_client): method test_probe_fires_on_incremental_after_delay (line 2967) | def test_probe_fires_on_incremental_after_delay(self, mqtt_client): method test_no_reprobe_when_developer_mode_cached (line 2986) | def test_no_reprobe_when_developer_mode_cached(self, mqtt_client): method test_on_connect_resets_needs_probe (line 3003) | def test_on_connect_resets_needs_probe(self, mqtt_client): class TestVtTrayNormalization (line 3013) | class TestVtTrayNormalization: method mqtt_client (line 3023) | def mqtt_client(self): method test_vt_tray_dict_normalized_in_update_state (line 3033) | def test_vt_tray_dict_normalized_in_update_state(self, mqtt_client): method test_vt_tray_list_unchanged_in_update_state (line 3050) | def test_vt_tray_list_unchanged_in_update_state(self, mqtt_client): method test_preserved_vt_tray_restored_before_probe (line 3063) | def test_preserved_vt_tray_restored_before_probe(self, mqtt_client): method test_first_message_vt_tray_dict_becomes_list (line 3089) | def test_first_message_vt_tray_dict_becomes_list(self, mqtt_client): class TestSendDryingCommand (line 3109) | class TestSendDryingCommand: method mqtt_client (line 3113) | def mqtt_client(self): method test_rotate_tray_false_by_default (line 3127) | def test_rotate_tray_false_by_default(self, mqtt_client): method test_rotate_tray_true_when_enabled (line 3135) | def test_rotate_tray_true_when_enabled(self, mqtt_client): method test_rotate_tray_false_on_stop (line 3143) | def test_rotate_tray_false_on_stop(self, mqtt_client): method test_all_required_fields_present (line 3151) | def test_all_required_fields_present(self, mqtt_client): method test_publishes_with_qos_1 (line 3170) | def test_publishes_with_qos_1(self, mqtt_client): class TestStartPrintAmsMapping (line 3180) | class TestStartPrintAmsMapping: method mqtt_client (line 3190) | def mqtt_client(self): method _get_published_command (line 3204) | def _get_published_command(self, mqtt_client): method test_regular_ams_trays_preserved_in_flat_mapping (line 3209) | def test_regular_ams_trays_preserved_in_flat_mapping(self, mqtt_client): method test_unmapped_slots (line 3221) | def test_unmapped_slots(self, mqtt_client): method test_external_main_nozzle_becomes_minus_one_in_flat (line 3232) | def test_external_main_nozzle_becomes_minus_one_in_flat(self, mqtt_cli... method test_single_nozzle_external_spool_uses_main_id (line 3240) | def test_single_nozzle_external_spool_uses_main_id(self, mqtt_client): method test_h2d_external_spool_mixed_with_ams (line 3253) | def test_h2d_external_spool_mixed_with_ams(self, mqtt_client): method test_ams_ht_trays_preserved_in_flat_mapping (line 3271) | def test_ams_ht_trays_preserved_in_flat_mapping(self, mqtt_client): method test_non_h2d_both_external_maps_to_main_id (line 3282) | def test_non_h2d_both_external_maps_to_main_id(self, mqtt_client): method test_h2d_external_preserves_deputy_id (line 3293) | def test_h2d_external_preserves_deputy_id(self, mqtt_client): method test_h2d_single_external_deputy (line 3305) | def test_h2d_single_external_deputy(self, mqtt_client): method test_external_spool_only_sets_use_ams_false (line 3314) | def test_external_spool_only_sets_use_ams_false(self, mqtt_client): method test_all_unmapped_sets_use_ams_false (line 3321) | def test_all_unmapped_sets_use_ams_false(self, mqtt_client): method test_mixed_ams_and_external_keeps_use_ams_true (line 3328) | def test_mixed_ams_and_external_keeps_use_ams_true(self, mqtt_client): method test_h2d_both_external_keeps_use_ams_true (line 3335) | def test_h2d_both_external_keeps_use_ams_true(self, mqtt_client): method test_empty_ams_mapping_keeps_use_ams_true (line 3343) | def test_empty_ams_mapping_keeps_use_ams_true(self, mqtt_client): method test_no_ams_mapping_omits_fields (line 3350) | def test_no_ams_mapping_omits_fields(self, mqtt_client): method test_x2d_external_preserves_deputy_id (line 3358) | def test_x2d_external_preserves_deputy_id(self, mqtt_client): method test_x2d_uses_integer_format_for_calibration_fields (line 3375) | def test_x2d_uses_integer_format_for_calibration_fields(self, mqtt_cli... method test_p2s_still_uses_boolean_format (line 3400) | def test_p2s_still_uses_boolean_format(self, mqtt_client): class TestStartPrintUniqueIdentityFields (line 3414) | class TestStartPrintUniqueIdentityFields: method mqtt_client (line 3426) | def mqtt_client(self): method _get_published_command (line 3440) | def _get_published_command(self, mqtt_client): method test_identity_fields_are_non_zero (line 3444) | def test_identity_fields_are_non_zero(self, mqtt_client): method test_identity_fields_are_all_equal_per_submission (line 3451) | def test_identity_fields_are_all_equal_per_submission(self, mqtt_client): method test_md5_stays_empty (line 3458) | def test_md5_stays_empty(self, mqtt_client): method test_identity_fields_change_between_submissions (line 3464) | def test_identity_fields_change_between_submissions(self, mqtt_client): method test_submission_id_is_numeric_string (line 3482) | def test_submission_id_is_numeric_string(self, mqtt_client): method test_submission_id_fits_signed_int32 (line 3493) | def test_submission_id_fits_signed_int32(self, mqtt_client): method test_unrelated_payload_fields_untouched (line 3506) | def test_unrelated_payload_fields_untouched(self, mqtt_client): class TestDeleteKProfileDualNozzleDetection (line 3522) | class TestDeleteKProfileDualNozzleDetection: method _make_client (line 3531) | def _make_client(self, serial: str): method _published (line 3545) | def _published(self, client): method test_h2d_serial_uses_dual_nozzle_format (line 3548) | def test_h2d_serial_uses_dual_nozzle_format(self): method test_x2d_serial_uses_dual_nozzle_format (line 3556) | def test_x2d_serial_uses_dual_nozzle_format(self): method test_p2s_serial_uses_single_nozzle_format (line 3563) | def test_p2s_serial_uses_single_nozzle_format(self): method test_x1c_serial_uses_single_nozzle_format (line 3576) | def test_x1c_serial_uses_single_nozzle_format(self): class TestStaleReconnect (line 3588) | class TestStaleReconnect: method mqtt_client (line 3592) | def mqtt_client(self): method test_check_staleness_sets_flag_and_broadcasts_once (line 3602) | def test_check_staleness_sets_flag_and_broadcasts_once(self, mqtt_clie... method test_check_staleness_noop_when_not_connected (line 3618) | def test_check_staleness_noop_when_not_connected(self, mqtt_client): method test_check_staleness_noop_when_not_stale (line 3629) | def test_check_staleness_noop_when_not_stale(self, mqtt_client): method test_on_disconnect_skipped_during_stale_reconnect (line 3642) | def test_on_disconnect_skipped_during_stale_reconnect(self, mqtt_client): method test_on_disconnect_fires_event_during_stale_reconnect (line 3655) | def test_on_disconnect_fires_event_during_stale_reconnect(self, mqtt_c... method test_on_connect_clears_stale_reconnecting_flag (line 3670) | def test_on_connect_clears_stale_reconnecting_flag(self, mqtt_client): method test_full_stale_reconnect_cycle_no_bounce (line 3689) | def test_full_stale_reconnect_cycle_no_bounce(self, mqtt_client): method test_spurious_disconnect_suppressed_when_recent_messages (line 3720) | def test_spurious_disconnect_suppressed_when_recent_messages(self, mqt... method test_error_disconnect_not_suppressed_despite_recent_messages (line 3735) | def test_error_disconnect_not_suppressed_despite_recent_messages(self,... class TestDoorOpenParsing (line 3755) | class TestDoorOpenParsing: method _make_client (line 3758) | def _make_client(self, model: str): method test_x1c_door_open_from_home_flag (line 3768) | def test_x1c_door_open_from_home_flag(self): method test_x1c_door_closed_from_home_flag (line 3774) | def test_x1c_door_closed_from_home_flag(self): method test_x1c_ignores_stat_field (line 3780) | def test_x1c_ignores_stat_field(self): method test_h2d_door_open_from_stat (line 3786) | def test_h2d_door_open_from_stat(self): method test_h2d_door_closed_from_stat (line 3791) | def test_h2d_door_closed_from_stat(self): method test_h2d_ignores_home_flag (line 3797) | def test_h2d_ignores_home_flag(self): method test_invalid_stat_does_not_raise (line 3803) | def test_invalid_stat_does_not_raise(self): class TestSdCardParsing (line 3809) | class TestSdCardParsing: method _make_client (line 3815) | def _make_client(self, model: str = "H2D"): method test_home_flag_alone_does_not_touch_sdcard (line 3825) | def test_home_flag_alone_does_not_touch_sdcard(self): method test_sdcard_string_fallback_when_no_home_flag (line 3832) | def test_sdcard_string_fallback_when_no_home_flag(self): method test_sdcard_int_fallback_when_no_home_flag (line 3837) | def test_sdcard_int_fallback_when_no_home_flag(self): method test_sdcard_bool_fallback_when_no_home_flag (line 3843) | def test_sdcard_bool_fallback_when_no_home_flag(self): class TestZombieSessionDetection (line 3851) | class TestZombieSessionDetection: method mqtt_client (line 3861) | def mqtt_client(self): method test_initial_state_is_clean (line 3881) | def test_initial_state_is_clean(self, mqtt_client): method test_publish_sets_pending_time (line 3886) | def test_publish_sets_pending_time(self, mqtt_client): method test_reset_slot_sets_pending_time (line 3903) | def test_reset_slot_sets_pending_time(self, mqtt_client): method test_response_clears_pending (line 3911) | def test_response_clears_pending(self, mqtt_client): method test_single_timeout_increments_counter (line 3933) | def test_single_timeout_increments_counter(self, mqtt_client): method test_two_timeouts_force_reconnect (line 3946) | def test_two_timeouts_force_reconnect(self, mqtt_client): method test_response_between_timeouts_resets_counter (line 3969) | def test_response_between_timeouts_resets_counter(self, mqtt_client): method test_on_connect_resets_tracking (line 3989) | def test_on_connect_resets_tracking(self, mqtt_client): method test_no_check_when_no_command_pending (line 4003) | def test_no_check_when_no_command_pending(self, mqtt_client): method test_no_timeout_within_window (line 4009) | def test_no_timeout_within_window(self, mqtt_client): FILE: backend/tests/unit/services/test_camera_tls_proxy.py class TestRewriteRtspRequestUrl (line 10) | class TestRewriteRtspRequestUrl: method test_rewrites_describe_request_line (line 13) | def test_rewrites_describe_request_line(self): method test_rewrites_setup_request_line (line 22) | def test_rewrites_setup_request_line(self): method test_rewrites_play_request_line (line 31) | def test_rewrites_play_request_line(self): method test_preserves_authorization_header (line 40) | def test_preserves_authorization_header(self): method test_no_rewrite_on_non_rtsp_data (line 61) | def test_no_rewrite_on_non_rtsp_data(self): method test_no_rewrite_on_empty_data (line 71) | def test_no_rewrite_on_empty_data(self): method test_only_first_rtsp_line_rewritten (line 77) | def test_only_first_rtsp_line_rewritten(self): method test_preserves_crlf_structure (line 96) | def test_preserves_crlf_structure(self): class TestCreateTlsProxy (line 109) | class TestCreateTlsProxy: method test_proxy_returns_port_and_server (line 113) | async def test_proxy_returns_port_and_server(self): method test_proxy_accepts_connection (line 126) | async def test_proxy_accepts_connection(self): method test_proxy_cleanup (line 147) | async def test_proxy_cleanup(self): FILE: backend/tests/unit/services/test_email_service.py class TestEmailTemplateFormatting (line 22) | class TestEmailTemplateFormatting: method test_welcome_email_newlines_converted_to_br (line 26) | async def test_welcome_email_newlines_converted_to_br(self): method test_password_reset_email_newlines_converted_to_br (line 72) | async def test_password_reset_email_newlines_converted_to_br(self): method test_email_header_padding (line 112) | async def test_email_header_padding(self): method test_email_xss_protection (line 140) | async def test_email_xss_protection(self): class TestGenerateSecurePassword (line 170) | class TestGenerateSecurePassword: method test_password_default_length (line 173) | def test_password_default_length(self): method test_password_custom_length (line 178) | def test_password_custom_length(self): method test_password_has_required_char_types (line 183) | def test_password_has_required_char_types(self): class TestRenderTemplate (line 194) | class TestRenderTemplate: method test_render_template_basic (line 197) | def test_render_template_basic(self): method test_render_template_removes_unreplaced (line 202) | def test_render_template_removes_unreplaced(self): class TestSMTPSettingsPersistence (line 208) | class TestSMTPSettingsPersistence: method test_save_and_retrieve_smtp_settings (line 212) | async def test_save_and_retrieve_smtp_settings(self, db_session): method test_get_smtp_settings_returns_none_when_unconfigured (line 240) | async def test_get_smtp_settings_returns_none_when_unconfigured(self, ... FILE: backend/tests/unit/services/test_external_camera.py class TestFormatMjpegFrame (line 12) | class TestFormatMjpegFrame: method test_format_mjpeg_frame_basic (line 15) | def test_format_mjpeg_frame_basic(self): method test_format_mjpeg_frame_larger_data (line 35) | def test_format_mjpeg_frame_larger_data(self): class TestGetFfmpegPath (line 47) | class TestGetFfmpegPath: method test_get_ffmpeg_path_from_shutil_which (line 50) | def test_get_ffmpeg_path_from_shutil_which(self): method test_get_ffmpeg_path_fallback_to_common_paths (line 58) | def test_get_ffmpeg_path_fallback_to_common_paths(self): method test_get_ffmpeg_path_returns_none_when_not_found (line 68) | def test_get_ffmpeg_path_returns_none_when_not_found(self): class TestJpegFrameExtraction (line 77) | class TestJpegFrameExtraction: method test_extract_single_frame_from_buffer (line 80) | def test_extract_single_frame_from_buffer(self): method test_extract_frame_with_leading_garbage (line 102) | def test_extract_frame_with_leading_garbage(self): method test_incomplete_frame_detection (line 122) | def test_incomplete_frame_detection(self): method test_multiple_frames_in_buffer (line 135) | def test_multiple_frames_in_buffer(self): class TestCameraTypeValidation (line 158) | class TestCameraTypeValidation: method test_capture_frame_unknown_type_returns_none (line 162) | async def test_capture_frame_unknown_type_returns_none(self): method test_capture_frame_valid_types (line 170) | async def test_capture_frame_valid_types(self): class TestRtspUrlHandling (line 182) | class TestRtspUrlHandling: method test_rtsps_url_detection (line 185) | def test_rtsps_url_detection(self): method test_ffmpeg_handles_both_rtsp_and_rtsps (line 194) | def test_ffmpeg_handles_both_rtsp_and_rtsps(self): class TestUsbCameraHandling (line 220) | class TestUsbCameraHandling: method test_list_usb_cameras_returns_list (line 223) | def test_list_usb_cameras_returns_list(self): method test_list_usb_cameras_dict_structure (line 230) | def test_list_usb_cameras_dict_structure(self): method test_capture_frame_usb_type_accepted (line 241) | async def test_capture_frame_usb_type_accepted(self): method test_capture_frame_usb_invalid_device_path (line 250) | async def test_capture_frame_usb_invalid_device_path(self): FILE: backend/tests/unit/services/test_hms_errors.py class TestHMSErrorDescriptions (line 6) | class TestHMSErrorDescriptions: method test_dictionary_is_not_empty (line 9) | def test_dictionary_is_not_empty(self): method test_dictionary_has_expected_count (line 13) | def test_dictionary_has_expected_count(self): method test_all_keys_are_valid_format (line 18) | def test_all_keys_are_valid_format(self): method test_all_values_are_non_empty_strings (line 26) | def test_all_values_are_non_empty_strings(self): class TestGetErrorDescription (line 33) | class TestGetErrorDescription: method test_returns_description_for_known_code (line 36) | def test_returns_description_for_known_code(self): method test_returns_description_for_ams_error (line 42) | def test_returns_description_for_ams_error(self): method test_returns_none_for_unknown_code (line 48) | def test_returns_none_for_unknown_code(self): method test_handles_lowercase_input (line 53) | def test_handles_lowercase_input(self): method test_handles_mixed_case_input (line 58) | def test_handles_mixed_case_input(self): method test_common_error_codes_have_descriptions (line 63) | def test_common_error_codes_have_descriptions(self): FILE: backend/tests/unit/services/test_layer_timelapse.py class TestTimelapseSessionManagement (line 14) | class TestTimelapseSessionManagement: method test_start_session_creates_new_session (line 17) | def test_start_session_creates_new_session(self): method test_start_session_cancels_existing (line 54) | def test_start_session_cancels_existing(self): method test_get_session_returns_none_for_unknown (line 89) | def test_get_session_returns_none_for_unknown(self): method test_cancel_session_removes_and_cleans_up (line 98) | def test_cancel_session_removes_and_cleans_up(self): method test_cancel_nonexistent_session_is_safe (line 124) | def test_cancel_nonexistent_session_is_safe(self): class TestTimelapseSession (line 134) | class TestTimelapseSession: method test_session_id_format (line 137) | def test_session_id_format(self): method test_frames_dir_path_structure (line 163) | def test_frames_dir_path_structure(self): class TestLayerChangeLogic (line 182) | class TestLayerChangeLogic: method test_capture_layer_only_on_increase (line 186) | async def test_capture_layer_only_on_increase(self): method test_capture_layer_handles_failed_capture (line 226) | async def test_capture_layer_handles_failed_capture(self): class TestOnLayerChange (line 249) | class TestOnLayerChange: method test_on_layer_change_captures_when_session_exists (line 253) | async def test_on_layer_change_captures_when_session_exists(self): method test_on_layer_change_does_nothing_without_session (line 280) | async def test_on_layer_change_does_nothing_without_session(self): class TestGetActiveSessions (line 290) | class TestGetActiveSessions: method test_get_active_sessions_returns_copy (line 293) | def test_get_active_sessions_returns_copy(self): FILE: backend/tests/unit/services/test_ldap_service.py class TestParseConfig (line 25) | class TestParseConfig: method test_returns_none_when_disabled (line 28) | def test_returns_none_when_disabled(self): method test_returns_none_when_missing_enabled (line 32) | def test_returns_none_when_missing_enabled(self): method test_returns_none_when_no_server_url (line 36) | def test_returns_none_when_no_server_url(self): method test_returns_none_when_server_url_whitespace (line 40) | def test_returns_none_when_server_url_whitespace(self): method test_parses_minimal_config (line 44) | def test_parses_minimal_config(self): method test_parses_full_config (line 61) | def test_parses_full_config(self): method test_handles_invalid_group_mapping_json (line 87) | def test_handles_invalid_group_mapping_json(self): method test_handles_non_dict_group_mapping (line 97) | def test_handles_non_dict_group_mapping(self): method test_enabled_case_insensitive (line 107) | def test_enabled_case_insensitive(self): method test_strips_whitespace (line 114) | def test_strips_whitespace(self): class TestLDAPEscape (line 129) | class TestLDAPEscape: method test_plain_string (line 132) | def test_plain_string(self): method test_escapes_backslash (line 135) | def test_escapes_backslash(self): method test_escapes_asterisk (line 138) | def test_escapes_asterisk(self): method test_escapes_open_paren (line 141) | def test_escapes_open_paren(self): method test_escapes_close_paren (line 144) | def test_escapes_close_paren(self): method test_escapes_null (line 147) | def test_escapes_null(self): method test_escapes_multiple_chars (line 150) | def test_escapes_multiple_chars(self): method test_empty_string (line 153) | def test_empty_string(self): class TestResolveGroupMapping (line 157) | class TestResolveGroupMapping: method test_empty_mapping (line 160) | def test_empty_mapping(self): method test_empty_groups (line 163) | def test_empty_groups(self): method test_single_match (line 167) | def test_single_match(self): method test_multiple_matches (line 172) | def test_multiple_matches(self): method test_no_match (line 181) | def test_no_match(self): method test_case_insensitive_dn (line 186) | def test_case_insensitive_dn(self): method test_partial_match_not_matched (line 191) | def test_partial_match_not_matched(self): method test_extra_groups_ignored (line 196) | def test_extra_groups_ignored(self): class TestDataclasses (line 202) | class TestDataclasses: method test_ldap_user_info (line 205) | def test_ldap_user_info(self): method test_ldap_user_info_none_fields (line 217) | def test_ldap_user_info_none_fields(self): method test_ldap_config (line 223) | def test_ldap_config(self): class _MockAttr (line 249) | class _MockAttr: method __init__ (line 256) | def __init__(self, value): method value (line 260) | def value(self): method values (line 264) | def values(self): method __str__ (line 267) | def __str__(self): method __bool__ (line 270) | def __bool__(self): method __iter__ (line 273) | def __iter__(self): class _MockEntry (line 279) | class _MockEntry: method __init__ (line 282) | def __init__(self, dn, **attrs): class _MockConnection (line 288) | class _MockConnection: method __init__ (line 298) | def __init__(self, *args, **kwargs): method open (line 303) | def open(self): method start_tls (line 306) | def start_tls(self): method bind (line 309) | def bind(self): method unbind (line 312) | def unbind(self): method search (line 315) | def search(self, search_base=None, search_filter=None, search_scope=No... function mock_ldap (line 326) | def mock_ldap(monkeypatch): function _base_config (line 335) | def _base_config(**overrides): class TestAuthenticateLdapUserGroups (line 353) | class TestAuthenticateLdapUserGroups: method test_primary_gidnumber_group_found (line 361) | def test_primary_gidnumber_group_found(self, mock_ldap): method test_dedupes_group_found_via_both_memberuid_and_primary_gid (line 377) | def test_dedupes_group_found_via_both_memberuid_and_primary_gid(self, ... method test_case_insensitive_dedupe (line 392) | def test_case_insensitive_dedupe(self, mock_ldap): method test_no_gidnumber_skips_primary_search (line 410) | def test_no_gidnumber_skips_primary_search(self, mock_ldap): FILE: backend/tests/unit/services/test_mqtt_smart_plug_subscribe.py function _plug (line 19) | def _plug(**overrides): function test_per_type_topics_restored_without_legacy_mqtt_topic (line 39) | def test_per_type_topics_restored_without_legacy_mqtt_topic(): function test_legacy_single_topic_falls_back_for_all_data_types (line 64) | def test_legacy_single_topic_falls_back_for_all_data_types(): function test_per_type_multipliers_override_legacy (line 89) | def test_per_type_multipliers_override_legacy(): function test_per_type_topics_beat_legacy_topic_when_both_set (line 106) | def test_per_type_topics_beat_legacy_topic_when_both_set(): function test_no_topics_configured_skips_subscribe (line 124) | def test_no_topics_configured_skips_subscribe(): function test_returns_unique_topic_list_when_same_topic_used_for_multiple_types (line 135) | def test_returns_unique_topic_list_when_same_topic_used_for_multiple_typ... FILE: backend/tests/unit/services/test_notification_service.py class TestNotificationService (line 14) | class TestNotificationService: method service (line 18) | def service(self): method mock_provider (line 23) | def mock_provider(self): method mock_db (line 51) | def mock_db(self): method test_on_print_start_sends_notification (line 62) | async def test_on_print_start_sends_notification(self, service, mock_p... method test_on_print_start_skipped_when_no_providers (line 83) | async def test_on_print_start_skipped_when_no_providers(self, service,... method test_on_print_complete_routes_completed_status (line 105) | async def test_on_print_complete_routes_completed_status(self, service... method test_on_print_complete_routes_failed_status (line 128) | async def test_on_print_complete_routes_failed_status(self, service, m... method test_on_print_complete_routes_stopped_status (line 150) | async def test_on_print_complete_routes_stopped_status(self, service, ... method test_on_print_complete_routes_aborted_status (line 172) | async def test_on_print_complete_routes_aborted_status(self, service, ... method test_disabled_provider_not_returned (line 198) | async def test_disabled_provider_not_returned(self, service, mock_prov... method test_provider_filtered_by_printer_id (line 213) | async def test_provider_filtered_by_printer_id(self, service, mock_pro... method test_is_in_quiet_hours_during_quiet_period (line 229) | def test_is_in_quiet_hours_during_quiet_period(self, service, mock_pro... method test_is_in_quiet_hours_outside_quiet_period (line 246) | def test_is_in_quiet_hours_outside_quiet_period(self, service, mock_pr... method test_is_in_quiet_hours_disabled (line 263) | def test_is_in_quiet_hours_disabled(self, service, mock_provider): method test_is_in_quiet_hours_early_morning (line 271) | def test_is_in_quiet_hours_early_morning(self, service, mock_provider): method test_on_ams_humidity_high_sends_notification (line 293) | async def test_on_ams_humidity_high_sends_notification(self, service, ... method test_on_ams_temperature_high_sends_notification (line 320) | async def test_on_ams_temperature_high_sends_notification(self, servic... method test_ams_alarm_skipped_when_toggle_disabled (line 347) | async def test_ams_alarm_skipped_when_toggle_disabled(self, service, m... method test_daily_digest_queues_notification (line 374) | async def test_daily_digest_queues_notification(self, service, mock_pr... method test_force_immediate_bypasses_digest (line 400) | async def test_force_immediate_bypasses_digest(self, service, mock_pro... class TestDigestModeAlwaysSendsImmediately (line 427) | class TestDigestModeAlwaysSendsImmediately: method service (line 431) | def service(self): method test_notification_sends_immediately_even_with_digest_enabled (line 435) | async def test_notification_sends_immediately_even_with_digest_enabled... method test_notification_sends_without_digest_queue_when_disabled (line 473) | async def test_notification_sends_without_digest_queue_when_disabled(s... class TestNotificationProviderTypes (line 509) | class TestNotificationProviderTypes: method service (line 513) | def service(self): method test_webhook_provider_sends_request (line 517) | async def test_webhook_provider_sends_request(self, service): method test_webhook_handles_failure (line 542) | async def test_webhook_handles_failure(self, service): method test_webhook_slack_format_sends_text_only (line 560) | async def test_webhook_slack_format_sends_text_only(self, service): method test_webhook_generic_format_includes_image (line 592) | async def test_webhook_generic_format_includes_image(self, service): method test_webhook_generic_format_no_image_when_none (line 622) | async def test_webhook_generic_format_no_image_when_none(self, service): method test_webhook_slack_format_excludes_image (line 647) | async def test_webhook_slack_format_excludes_image(self, service): class TestHomeAssistantProvider (line 673) | class TestHomeAssistantProvider: method service (line 677) | def service(self): method test_send_homeassistant_success (line 681) | async def test_send_homeassistant_success(self, service): method test_send_homeassistant_no_db_no_env (line 716) | async def test_send_homeassistant_no_db_no_env(self, service): method test_send_homeassistant_auth_failure (line 725) | async def test_send_homeassistant_auth_failure(self, service): method test_send_homeassistant_env_fallback (line 755) | async def test_send_homeassistant_env_fallback(self, service): method test_send_homeassistant_empty_config_accepted (line 776) | async def test_send_homeassistant_empty_config_accepted(self, service): method test_send_to_provider_dispatches_homeassistant (line 805) | async def test_send_to_provider_dispatches_homeassistant(self, service): class TestNotificationVariableFallbacks (line 821) | class TestNotificationVariableFallbacks: method service (line 825) | def service(self): method test_format_duration_with_valid_seconds (line 828) | def test_format_duration_with_valid_seconds(self, service): method test_format_duration_with_none_returns_unknown (line 833) | def test_format_duration_with_none_returns_unknown(self, service): method test_format_duration_with_zero (line 838) | def test_format_duration_with_zero(self, service): method test_format_duration_hours_and_minutes (line 845) | def test_format_duration_hours_and_minutes(self, service): method test_format_duration_minutes_only (line 851) | def test_format_duration_minutes_only(self, service): method test_print_complete_fallback_values (line 857) | async def test_print_complete_fallback_values(self, service): method test_print_complete_with_archive_data (line 881) | async def test_print_complete_with_archive_data(self, service): method test_print_complete_with_finish_photo_url (line 915) | async def test_print_complete_with_finish_photo_url(self, service): method test_print_start_estimated_time_fallback (line 954) | async def test_print_start_estimated_time_fallback(self, service): method test_print_progress_remaining_time_fallback (line 989) | async def test_print_progress_remaining_time_fallback(self, service): method test_filename_fallback_to_unknown (line 1023) | async def test_filename_fallback_to_unknown(self, service): method test_print_start_uses_archive_print_time_seconds (line 1055) | async def test_print_start_uses_archive_print_time_seconds(self, servi... method test_print_start_archive_data_overrides_mqtt (line 1088) | async def test_print_start_archive_data_overrides_mqtt(self, service): method test_print_start_falls_back_to_mqtt_when_no_archive (line 1125) | async def test_print_start_falls_back_to_mqtt_when_no_archive(self, se... method test_print_start_eta_calculated_from_estimated_time (line 1161) | async def test_print_start_eta_calculated_from_estimated_time(self, se... method test_print_start_eta_unknown_when_no_time (line 1196) | async def test_print_start_eta_unknown_when_no_time(self, service): method test_print_start_eta_respects_12h_format (line 1226) | async def test_print_start_eta_respects_12h_format(self, service): class TestNotificationTemplates (line 1260) | class TestNotificationTemplates: method service (line 1264) | def service(self): method test_template_renders_variables (line 1268) | async def test_template_renders_variables(self, service): method test_template_handles_missing_variables (line 1289) | async def test_template_handles_missing_variables(self, service): class TestPrinterErrorNotifications (line 1302) | class TestPrinterErrorNotifications: method service (line 1306) | def service(self): method mock_provider (line 1310) | def mock_provider(self): method mock_db (line 1325) | def mock_db(self): method test_on_printer_error_sends_notification (line 1332) | async def test_on_printer_error_sends_notification(self, service, mock... method test_on_printer_error_skipped_when_disabled (line 1354) | async def test_on_printer_error_skipped_when_disabled(self, service, m... method test_on_printer_error_includes_error_detail (line 1376) | async def test_on_printer_error_includes_error_detail(self, service, m... method test_on_printer_error_fallback_when_no_detail (line 1404) | async def test_on_printer_error_fallback_when_no_detail(self, service,... class TestPlateNotEmptyNotifications (line 1430) | class TestPlateNotEmptyNotifications: method service (line 1434) | def service(self): method mock_provider (line 1438) | def mock_provider(self): method mock_db (line 1453) | def mock_db(self): method test_on_plate_not_empty_sends_notification (line 1460) | async def test_on_plate_not_empty_sends_notification(self, service, mo... method test_on_plate_not_empty_skipped_when_disabled (line 1484) | async def test_on_plate_not_empty_skipped_when_disabled(self, service,... method test_on_plate_not_empty_includes_difference_percent (line 1503) | async def test_on_plate_not_empty_includes_difference_percent(self, se... class TestBedCooledNotifications (line 1529) | class TestBedCooledNotifications: method service (line 1533) | def service(self): method mock_provider (line 1537) | def mock_provider(self): method mock_db (line 1552) | def mock_db(self): method test_on_bed_cooled_sends_notification (line 1559) | async def test_on_bed_cooled_sends_notification(self, service, mock_pr... method test_on_bed_cooled_skipped_when_no_providers (line 1582) | async def test_on_bed_cooled_skipped_when_no_providers(self, service, ... method test_on_bed_cooled_includes_correct_variables (line 1602) | async def test_on_bed_cooled_includes_correct_variables(self, service,... method test_on_bed_cooled_handles_none_filename (line 1632) | async def test_on_bed_cooled_handles_none_filename(self, service, mock... class TestFirstLayerCompleteNotifications (line 1659) | class TestFirstLayerCompleteNotifications: method service (line 1663) | def service(self): method mock_provider (line 1667) | def mock_provider(self): method mock_db (line 1682) | def mock_db(self): method test_on_first_layer_complete_sends_notification (line 1689) | async def test_on_first_layer_complete_sends_notification(self, servic... method test_on_first_layer_complete_skipped_when_no_providers (line 1711) | async def test_on_first_layer_complete_skipped_when_no_providers(self,... method test_on_first_layer_complete_includes_correct_variables (line 1730) | async def test_on_first_layer_complete_includes_correct_variables(self... method test_on_first_layer_complete_passes_image_data (line 1758) | async def test_on_first_layer_complete_passes_image_data(self, service... FILE: backend/tests/unit/services/test_plate_detection.py class TestPlateDetectionResult (line 12) | class TestPlateDetectionResult: method test_result_to_dict (line 15) | def test_result_to_dict(self): method test_result_with_debug_image (line 43) | def test_result_with_debug_image(self): method test_result_needs_calibration (line 65) | def test_result_needs_calibration(self): class TestPlateDetector (line 87) | class TestPlateDetector: method test_detector_initialization (line 90) | def test_detector_initialization(self): method test_detector_custom_roi (line 107) | def test_detector_custom_roi(self): method test_detector_raises_without_opencv (line 122) | def test_detector_raises_without_opencv(self): class TestCalibrationStatus (line 137) | class TestCalibrationStatus: method test_get_calibration_status_no_opencv (line 140) | def test_get_calibration_status_no_opencv(self): method test_is_plate_detection_available_true (line 158) | def test_is_plate_detection_available_true(self): method test_is_plate_detection_available_false (line 170) | def test_is_plate_detection_available_false(self): class TestDeleteCalibration (line 183) | class TestDeleteCalibration: method test_delete_calibration_no_opencv (line 186) | def test_delete_calibration_no_opencv(self): FILE: backend/tests/unit/services/test_printer_manager.py class TestPrinterManager (line 23) | class TestPrinterManager: method manager (line 27) | def manager(self): method mock_printer (line 32) | def mock_printer(self): method mock_client (line 43) | def mock_client(self): method test_init_creates_empty_clients_dict (line 59) | def test_init_creates_empty_clients_dict(self, manager): method test_init_callbacks_are_none (line 63) | def test_init_callbacks_are_none(self, manager): method test_init_loop_is_none (line 70) | def test_init_loop_is_none(self, manager): method test_set_event_loop (line 78) | def test_set_event_loop(self, manager): method test_set_print_start_callback (line 84) | def test_set_print_start_callback(self, manager): method test_set_print_complete_callback (line 90) | def test_set_print_complete_callback(self, manager): method test_set_status_change_callback (line 96) | def test_set_status_change_callback(self, manager): method test_set_ams_change_callback (line 102) | def test_set_ams_change_callback(self, manager): method test_schedule_async_with_running_loop (line 112) | def test_schedule_async_with_running_loop(self, manager): method test_schedule_async_without_loop (line 128) | def test_schedule_async_without_loop(self, manager): method test_schedule_async_with_stopped_loop (line 139) | def test_schedule_async_with_stopped_loop(self, manager): method test_connect_printer_creates_client (line 157) | async def test_connect_printer_creates_client(self, manager, mock_prin... method test_connect_printer_disconnects_existing (line 173) | async def test_connect_printer_disconnects_existing(self, manager, moc... method test_connect_printer_returns_false_on_failure (line 188) | async def test_connect_printer_returns_false_on_failure(self, manager,... method test_disconnect_printer_removes_client (line 204) | def test_disconnect_printer_removes_client(self, manager, mock_client): method test_disconnect_printer_handles_missing (line 213) | def test_disconnect_printer_handles_missing(self, manager): method test_disconnect_all_disconnects_all_clients (line 221) | def test_disconnect_all_disconnects_all_clients(self, manager): method test_get_status_returns_state (line 238) | def test_get_status_returns_state(self, manager, mock_client): method test_get_status_returns_none_for_unknown (line 247) | def test_get_status_returns_none_for_unknown(self, manager): method test_get_all_statuses_returns_all (line 256) | def test_get_all_statuses_returns_all(self, manager): method test_is_connected_returns_true (line 277) | def test_is_connected_returns_true(self, manager, mock_client): method test_is_connected_returns_false_for_unknown (line 286) | def test_is_connected_returns_false_for_unknown(self, manager): method test_get_client_returns_client (line 295) | def test_get_client_returns_client(self, manager, mock_client): method test_get_client_returns_none_for_unknown (line 303) | def test_get_client_returns_none_for_unknown(self, manager): method test_mark_printer_offline_updates_state (line 312) | def test_mark_printer_offline_updates_state(self, manager, mock_client): method test_mark_printer_offline_triggers_callback (line 322) | def test_mark_printer_offline_triggers_callback(self, manager, mock_cl... method test_mark_printer_offline_handles_unknown (line 345) | def test_mark_printer_offline_handles_unknown(self, manager): method test_mark_printer_offline_skips_already_offline (line 349) | def test_mark_printer_offline_skips_already_offline(self, manager, moc... method test_start_print_calls_client (line 363) | def test_start_print_calls_client(self, manager, mock_client): method test_start_print_returns_false_for_unknown (line 383) | def test_start_print_returns_false_for_unknown(self, manager): method test_start_print_logs_print_command_with_caller (line 388) | def test_start_print_logs_print_command_with_caller(self, manager, moc... method test_start_print_logs_even_when_printer_unknown (line 403) | def test_start_print_logs_even_when_printer_unknown(self, manager, cap... method test_stop_print_calls_client (line 416) | def test_stop_print_calls_client(self, manager, mock_client): method test_stop_print_returns_false_for_unknown (line 426) | def test_stop_print_returns_false_for_unknown(self, manager): method test_wait_for_cooldown_returns_true_when_cool (line 436) | async def test_wait_for_cooldown_returns_true_when_cool(self, manager,... method test_wait_for_cooldown_returns_false_on_disconnect (line 448) | async def test_wait_for_cooldown_returns_false_on_disconnect(self, man... method test_wait_for_cooldown_returns_false_for_unknown (line 459) | async def test_wait_for_cooldown_returns_false_for_unknown(self, manag... method test_wait_for_cooldown_checks_both_nozzles (line 465) | async def test_wait_for_cooldown_checks_both_nozzles(self, manager, mo... method test_enable_logging_calls_client (line 480) | def test_enable_logging_calls_client(self, manager, mock_client): method test_enable_logging_returns_false_for_unknown (line 489) | def test_enable_logging_returns_false_for_unknown(self, manager): method test_get_logs_returns_logs (line 494) | def test_get_logs_returns_logs(self, manager, mock_client): method test_get_logs_returns_empty_for_unknown (line 504) | def test_get_logs_returns_empty_for_unknown(self, manager): method test_clear_logs_calls_client (line 509) | def test_clear_logs_calls_client(self, manager, mock_client): method test_clear_logs_returns_false_for_unknown (line 518) | def test_clear_logs_returns_false_for_unknown(self, manager): method test_is_logging_enabled_returns_status (line 523) | def test_is_logging_enabled_returns_status(self, manager, mock_client): method test_is_logging_enabled_returns_false_for_unknown (line 532) | def test_is_logging_enabled_returns_false_for_unknown(self, manager): method test_request_status_update_calls_client (line 541) | def test_request_status_update_calls_client(self, manager, mock_client): method test_request_status_update_returns_false_for_unknown (line 551) | def test_request_status_update_returns_false_for_unknown(self, manager): method test_test_connection_success (line 561) | async def test_test_connection_success(self, manager): method test_test_connection_failure (line 579) | async def test_test_connection_failure(self, manager): method test_set_current_print_user (line 597) | def test_set_current_print_user(self, manager): method test_get_current_print_user_returns_user (line 605) | def test_get_current_print_user_returns_user(self, manager): method test_get_current_print_user_returns_none_for_unknown (line 615) | def test_get_current_print_user_returns_none_for_unknown(self, manager): method test_clear_current_print_user (line 620) | def test_clear_current_print_user(self, manager): method test_clear_current_print_user_no_error_for_unknown (line 628) | def test_clear_current_print_user_no_error_for_unknown(self, manager): method test_set_current_print_user_overwrites_existing (line 633) | def test_set_current_print_user_overwrites_existing(self, manager): method test_multiple_printers_have_separate_users (line 642) | def test_multiple_printers_have_separate_users(self, manager): class TestPrinterStateToDict (line 654) | class TestPrinterStateToDict: method mock_state (line 658) | def mock_state(self): method test_basic_conversion (line 681) | def test_basic_conversion(self, mock_state): method test_ams_data_parsing (line 690) | def test_ams_data_parsing(self, mock_state): method test_empty_tag_uid_becomes_none (line 722) | def test_empty_tag_uid_becomes_none(self, mock_state): method test_zero_tag_uid_becomes_none (line 744) | def test_zero_tag_uid_becomes_none(self, mock_state): method test_vt_tray_parsing (line 764) | def test_vt_tray_parsing(self, mock_state): method test_vt_tray_dict_normalized_to_list (line 786) | def test_vt_tray_dict_normalized_to_list(self, mock_state): method test_vt_tray_non_list_non_dict_ignored (line 809) | def test_vt_tray_non_list_non_dict_ignored(self, mock_state): method test_hms_errors_conversion (line 817) | def test_hms_errors_conversion(self, mock_state): method test_cover_url_added_for_running_print (line 832) | def test_cover_url_added_for_running_print(self, mock_state): method test_current_plate_id_extracted_from_gcode_file (line 838) | def test_current_plate_id_extracted_from_gcode_file(self, mock_state): method test_current_plate_id_none_when_no_plate_segment (line 846) | def test_current_plate_id_none_when_no_plate_segment(self, mock_state): method test_cover_url_none_when_not_running (line 854) | def test_cover_url_none_when_not_running(self, mock_state): method test_ams_ht_detection (line 862) | def test_ams_ht_detection(self, mock_state): method test_regular_ams_detection (line 877) | def test_regular_ams_detection(self, mock_state): method test_chamber_temp_filtered_for_p1s (line 885) | def test_chamber_temp_filtered_for_p1s(self, mock_state): method test_chamber_temp_kept_for_x1c (line 903) | def test_chamber_temp_kept_for_x1c(self, mock_state): method test_chamber_temp_filtered_for_a1 (line 919) | def test_chamber_temp_filtered_for_a1(self, mock_state): method test_chamber_temp_kept_when_no_model (line 927) | def test_chamber_temp_kept_when_no_model(self, mock_state): method test_ams_drying_fields_included (line 938) | def test_ams_drying_fields_included(self, mock_state): method test_awaiting_plate_clear_defaults_false (line 969) | def test_awaiting_plate_clear_defaults_false(self, mock_state): method test_awaiting_plate_clear_surfaced_when_set (line 974) | def test_awaiting_plate_clear_surfaced_when_set(self, mock_state): class TestStatusKeyDryingDedup (line 990) | class TestStatusKeyDryingDedup: method test_dry_time_change_changes_status_key (line 998) | def test_dry_time_change_changes_status_key(self): class TestSupportsChamberTemp (line 1032) | class TestSupportsChamberTemp: method test_x1_series_supported (line 1035) | def test_x1_series_supported(self): method test_p2_series_supported (line 1041) | def test_p2_series_supported(self): method test_h2_series_supported (line 1045) | def test_h2_series_supported(self): method test_p1_series_not_supported (line 1052) | def test_p1_series_not_supported(self): method test_a1_series_not_supported (line 1057) | def test_a1_series_not_supported(self): method test_none_model_not_supported (line 1062) | def test_none_model_not_supported(self): method test_case_insensitive (line 1066) | def test_case_insensitive(self): method test_internal_model_codes_supported (line 1072) | def test_internal_model_codes_supported(self): method test_internal_model_codes_not_supported (line 1089) | def test_internal_model_codes_not_supported(self): class TestSupportsDrying (line 1101) | class TestSupportsDrying: method test_known_supported_with_firmware (line 1104) | def test_known_supported_with_firmware(self): method test_known_supported_old_firmware (line 1113) | def test_known_supported_old_firmware(self): method test_known_supported_no_firmware (line 1121) | def test_known_supported_no_firmware(self): method test_unsupported_models (line 1126) | def test_unsupported_models(self): method test_unknown_models_allowed (line 1131) | def test_unknown_models_allowed(self): method test_none_model (line 1145) | def test_none_model(self): method test_case_insensitive (line 1149) | def test_case_insensitive(self): class TestGetDerivedStatusName (line 1156) | class TestGetDerivedStatusName: method test_stg_cur_255_returns_none (line 1159) | def test_stg_cur_255_returns_none(self): method test_stg_cur_negative_one_returns_none_when_idle (line 1169) | def test_stg_cur_negative_one_returns_none_when_idle(self): method test_valid_stage_returns_name (line 1179) | def test_valid_stage_returns_name(self): method test_stg_cur_zero_returns_printing (line 1188) | def test_stg_cur_zero_returns_printing(self): method test_a1_idle_with_stg_cur_zero_returns_none (line 1197) | def test_a1_idle_with_stg_cur_zero_returns_none(self): method test_a1_running_with_stg_cur_zero_returns_printing (line 1208) | def test_a1_running_with_stg_cur_zero_returns_printing(self): method test_non_a1_idle_with_stg_cur_zero_returns_printing (line 1218) | def test_non_a1_idle_with_stg_cur_zero_returns_printing(self): class TestHasStgCurIdleBug (line 1230) | class TestHasStgCurIdleBug: method test_a1_models_return_true (line 1233) | def test_a1_models_return_true(self): method test_p1_models_return_true (line 1242) | def test_p1_models_return_true(self): method test_internal_codes_return_true (line 1248) | def test_internal_codes_return_true(self): method test_non_affected_models_return_false (line 1255) | def test_non_affected_models_return_false(self): method test_none_model_returns_false (line 1261) | def test_none_model_returns_false(self): method test_empty_model_returns_false (line 1265) | def test_empty_model_returns_false(self): class TestInitPrinterConnections (line 1270) | class TestInitPrinterConnections: method test_connects_all_active_printers (line 1274) | async def test_connects_all_active_printers(self): method test_handles_empty_printer_list (line 1291) | async def test_handles_empty_printer_list(self): class TestAmsChangeCallback (line 1306) | class TestAmsChangeCallback: method manager (line 1310) | def manager(self): method test_ams_change_callback_is_triggered (line 1314) | def test_ams_change_callback_is_triggered(self, manager): method test_ams_change_callback_receives_correct_data (line 1322) | def test_ams_change_callback_receives_correct_data(self, manager): class TestParsePlateId (line 1337) | class TestParsePlateId: method test_bambu_metadata_path (line 1345) | def test_bambu_metadata_path(self): method test_plate_one (line 1349) | def test_plate_one(self): method test_double_digit_plate (line 1352) | def test_double_digit_plate(self): method test_none_input (line 1355) | def test_none_input(self): method test_empty_string (line 1358) | def test_empty_string(self): method test_path_without_plate_segment (line 1361) | def test_path_without_plate_segment(self): method test_similar_but_non_matching_names (line 1365) | def test_similar_but_non_matching_names(self): method test_substring_match_still_extracts (line 1371) | def test_substring_match_still_extracts(self): FILE: backend/tests/unit/services/test_rest_smart_plug.py function service (line 13) | def service(): function mock_plug (line 18) | def mock_plug(): class TestURLValidation (line 40) | class TestURLValidation: method test_valid_ip_url (line 41) | def test_valid_ip_url(self, service): method test_hostname_url (line 44) | def test_hostname_url(self, service): method test_loopback_blocked (line 47) | def test_loopback_blocked(self, service): method test_link_local_blocked (line 50) | def test_link_local_blocked(self, service): method test_empty_hostname (line 53) | def test_empty_hostname(self, service): class TestParseHeaders (line 57) | class TestParseHeaders: method test_valid_json (line 58) | def test_valid_json(self, service): method test_none_headers (line 62) | def test_none_headers(self, service): method test_empty_string (line 65) | def test_empty_string(self, service): method test_invalid_json (line 68) | def test_invalid_json(self, service): class TestExtractJsonPath (line 72) | class TestExtractJsonPath: method test_simple_path (line 73) | def test_simple_path(self, service): method test_nested_path (line 77) | def test_nested_path(self, service): method test_missing_path (line 81) | def test_missing_path(self, service): method test_empty_path (line 85) | def test_empty_path(self, service): method test_none_path (line 88) | def test_none_path(self, service): class TestTurnOn (line 92) | class TestTurnOn: method test_turn_on_success (line 94) | async def test_turn_on_success(self, service, mock_plug): method test_turn_on_failure (line 104) | async def test_turn_on_failure(self, service, mock_plug): method test_turn_on_no_url (line 111) | async def test_turn_on_no_url(self, service, mock_plug): class TestTurnOff (line 117) | class TestTurnOff: method test_turn_off_success (line 119) | async def test_turn_off_success(self, service, mock_plug): method test_turn_off_no_url (line 129) | async def test_turn_off_no_url(self, service, mock_plug): class TestGetStatus (line 135) | class TestGetStatus: method test_status_on (line 137) | async def test_status_on(self, service, mock_plug): method test_status_off (line 148) | async def test_status_off(self, service, mock_plug): method test_status_unreachable (line 159) | async def test_status_unreachable(self, service, mock_plug): method test_status_no_url (line 167) | async def test_status_no_url(self, service, mock_plug): class TestGetEnergy (line 175) | class TestGetEnergy: method test_energy_with_paths (line 177) | async def test_energy_with_paths(self, service, mock_plug): method test_energy_no_status_url_no_separate_urls (line 188) | async def test_energy_no_status_url_no_separate_urls(self, service, mo... method test_energy_no_paths (line 197) | async def test_energy_no_paths(self, service, mock_plug): method test_energy_with_separate_urls (line 204) | async def test_energy_with_separate_urls(self, service, mock_plug): method test_energy_with_multipliers (line 231) | async def test_energy_with_multipliers(self, service, mock_plug): method test_energy_separate_url_falls_back_to_status (line 245) | async def test_energy_separate_url_falls_back_to_status(self, service,... method test_energy_no_urls_at_all (line 260) | async def test_energy_no_urls_at_all(self, service, mock_plug): method test_energy_deduplicates_same_url (line 270) | async def test_energy_deduplicates_same_url(self, service, mock_plug): class TestTestConnection (line 286) | class TestTestConnection: method test_connection_success (line 288) | async def test_connection_success(self, service): method test_connection_timeout (line 303) | async def test_connection_timeout(self, service): method test_connection_invalid_url (line 317) | async def test_connection_invalid_url(self, service): FILE: backend/tests/unit/services/test_smart_plug_manager.py class TestSmartPlugManager (line 15) | class TestSmartPlugManager: method manager (line 19) | def manager(self): method mock_plug (line 24) | def mock_plug(self): method mock_db (line 46) | def mock_db(self): method test_on_print_start_turns_on_plug (line 58) | async def test_on_print_start_turns_on_plug(self, manager, mock_plug, ... method test_on_print_start_skipped_when_auto_on_disabled (line 72) | async def test_on_print_start_skipped_when_auto_on_disabled(self, mana... method test_on_print_start_skipped_when_plug_disabled (line 88) | async def test_on_print_start_skipped_when_plug_disabled(self, manager... method test_on_print_start_skipped_when_no_plug_found (line 104) | async def test_on_print_start_skipped_when_no_plug_found(self, manager... method test_on_print_start_cancels_pending_off (line 119) | async def test_on_print_start_cancels_pending_off(self, manager, mock_... method test_on_print_start_resets_auto_off_executed_flag (line 139) | async def test_on_print_start_resets_auto_off_executed_flag(self, mana... method test_on_print_complete_schedules_time_based_off (line 159) | async def test_on_print_complete_schedules_time_based_off(self, manage... method test_on_print_complete_schedules_temp_based_off (line 175) | async def test_on_print_complete_schedules_temp_based_off(self, manage... method test_on_print_complete_skipped_when_auto_off_disabled (line 191) | async def test_on_print_complete_skipped_when_auto_off_disabled(self, ... method test_on_print_complete_skipped_when_plug_disabled (line 211) | async def test_on_print_complete_skipped_when_plug_disabled(self, mana... method test_on_print_complete_skipped_on_failed_print (line 226) | async def test_on_print_complete_skipped_on_failed_print(self, manager... method test_on_print_complete_skipped_on_aborted_print (line 239) | async def test_on_print_complete_skipped_on_aborted_print(self, manage... method test_cancel_pending_off_removes_task (line 256) | async def test_cancel_pending_off_removes_task(self, manager, mock_plug): method test_cancel_pending_off_handles_missing_task (line 268) | async def test_cancel_pending_off_handles_missing_task(self, manager): method test_cancel_all_pending (line 275) | async def test_cancel_all_pending(self, manager, mock_plug): method test_start_scheduler (line 293) | def test_start_scheduler(self, manager): method test_stop_scheduler (line 305) | def test_stop_scheduler(self, manager): method test_start_scheduler_idempotent (line 315) | def test_start_scheduler_idempotent(self, manager): method test_stop_scheduler_cancels_snapshot_task (line 334) | def test_stop_scheduler_cancels_snapshot_task(self, manager): class TestGetPlugsForPrinter (line 349) | class TestGetPlugsForPrinter: method manager (line 353) | def manager(self): method test_returns_empty_list_when_no_plugs (line 357) | async def test_returns_empty_list_when_no_plugs(self, manager): method test_returns_single_plug_as_list (line 368) | async def test_returns_single_plug_as_list(self, manager): method test_returns_all_plugs (line 382) | async def test_returns_all_plugs(self, manager): class TestAutoOffPersistent (line 401) | class TestAutoOffPersistent: method manager (line 409) | def manager(self): method test_mark_auto_off_executed_one_shot_disables_auto_off (line 413) | async def test_mark_auto_off_executed_one_shot_disables_auto_off(self,... method test_mark_auto_off_executed_persistent_keeps_auto_off_enabled (line 441) | async def test_mark_auto_off_executed_persistent_keeps_auto_off_enable... method test_persistent_auto_off_full_cycle (line 469) | async def test_persistent_auto_off_full_cycle(self, manager): class TestScheduleLoop (line 544) | class TestScheduleLoop: method manager (line 548) | def manager(self): method test_check_schedules_turns_on_at_scheduled_time (line 552) | async def test_check_schedules_turns_on_at_scheduled_time(self, manager): method test_check_schedules_turns_off_at_scheduled_time (line 592) | async def test_check_schedules_turns_off_at_scheduled_time(self, manag... method test_check_schedules_skipped_when_disabled (line 634) | async def test_check_schedules_skipped_when_disabled(self, manager): class TestPendingAutoOffPersistence (line 667) | class TestPendingAutoOffPersistence: method manager (line 671) | def manager(self): method test_resume_pending_auto_offs_temperature_mode (line 675) | async def test_resume_pending_auto_offs_temperature_mode(self, manager): method test_resume_pending_auto_offs_time_mode_immediate_off (line 706) | async def test_resume_pending_auto_offs_time_mode_immediate_off(self, ... FILE: backend/tests/unit/services/test_spool_assignment_notifications.py class _FakeAssignmentsResult (line 12) | class _FakeAssignmentsResult: method __init__ (line 13) | def __init__(self, rows): method fetchall (line 16) | def fetchall(self): class _FakeSession (line 20) | class _FakeSession: method __init__ (line 21) | def __init__(self, printer_name: str, assignments: list[SimpleNamespac... method __aenter__ (line 25) | async def __aenter__(self): method __aexit__ (line 28) | async def __aexit__(self, exc_type, exc, tb): method get (line 31) | async def get(self, model, key): method execute (line 34) | async def execute(self, statement): function test_missing_assignment_broadcasts_websocket_event_and_push_notification (line 39) | async def test_missing_assignment_broadcasts_websocket_event_and_push_no... FILE: backend/tests/unit/services/test_spool_tag_matcher.py function _relationship_is_loaded (line 36) | def _relationship_is_loaded(obj, attr_name: str) -> bool: function test_is_valid_tag_with_real_uid (line 44) | def test_is_valid_tag_with_real_uid(): function test_is_valid_tag_with_real_uuid (line 48) | def test_is_valid_tag_with_real_uuid(): function test_is_valid_tag_all_zeros (line 52) | def test_is_valid_tag_all_zeros(): function test_is_valid_tag_empty (line 56) | def test_is_valid_tag_empty(): function test_is_bambu_tag_with_uuid (line 60) | def test_is_bambu_tag_with_uuid(): function test_is_bambu_tag_with_uid_and_preset (line 64) | def test_is_bambu_tag_with_uid_and_preset(): function test_is_bambu_tag_uid_only_no_preset (line 68) | def test_is_bambu_tag_uid_only_no_preset(): function test_create_spool_from_tray_basic (line 77) | async def test_create_spool_from_tray_basic(db_session): function test_create_spool_from_tray_weight_from_remain (line 91) | async def test_create_spool_from_tray_weight_from_remain(db_session): function test_create_spool_from_tray_relationships_loaded (line 99) | async def test_create_spool_from_tray_relationships_loaded(db_session): function test_get_spool_by_tag_by_uuid (line 118) | async def test_get_spool_by_tag_by_uuid(db_session): function test_get_spool_by_tag_by_uid (line 135) | async def test_get_spool_by_tag_by_uid(db_session): function test_get_spool_by_tag_skips_archived (line 152) | async def test_get_spool_by_tag_skips_archived(db_session): function test_get_spool_by_tag_relationships_loaded (line 171) | async def test_get_spool_by_tag_relationships_loaded(db_session): function test_get_spool_by_tag_returns_none_for_zeros (line 196) | async def test_get_spool_by_tag_returns_none_for_zeros(db_session): function test_get_spool_by_tag_first_char_variance_same_length (line 203) | async def test_get_spool_by_tag_first_char_variance_same_length(db_sessi... function test_get_spool_by_tag_first_char_variance_short_uid (line 228) | async def test_get_spool_by_tag_first_char_variance_short_uid(db_session): function test_get_spool_by_tag_short_uid_exact_match_preferred (line 255) | async def test_get_spool_by_tag_short_uid_exact_match_preferred(db_sessi... function test_get_spool_by_tag_no_false_positive_different_suffix (line 287) | async def test_get_spool_by_tag_no_false_positive_different_suffix(db_se... function test_auto_assign_creates_assignment (line 309) | async def test_auto_assign_creates_assignment(db_session, printer_factory): function test_auto_assign_replaces_existing (line 338) | async def test_auto_assign_replaces_existing(db_session, printer_factory): function test_auto_assign_no_greenlet_error_new_spool (line 384) | async def test_auto_assign_no_greenlet_error_new_spool(db_session, print... function test_auto_assign_no_greenlet_error_existing_spool (line 418) | async def test_auto_assign_no_greenlet_error_existing_spool(db_session, ... function test_find_matching_untagged_spool_exact_match (line 467) | async def test_find_matching_untagged_spool_exact_match(db_session): function test_find_matching_untagged_spool_skips_tagged (line 486) | async def test_find_matching_untagged_spool_skips_tagged(db_session): function test_find_matching_untagged_spool_skips_uuid_tagged (line 505) | async def test_find_matching_untagged_spool_skips_uuid_tagged(db_session): function test_find_matching_untagged_spool_skips_archived (line 524) | async def test_find_matching_untagged_spool_skips_archived(db_session): function test_find_matching_untagged_spool_wrong_material (line 545) | async def test_find_matching_untagged_spool_wrong_material(db_session): function test_find_matching_untagged_spool_wrong_color (line 563) | async def test_find_matching_untagged_spool_wrong_color(db_session): function test_find_matching_untagged_spool_wrong_subtype (line 581) | async def test_find_matching_untagged_spool_wrong_subtype(db_session): function test_find_matching_untagged_spool_fifo (line 599) | async def test_find_matching_untagged_spool_fifo(db_session): function test_find_matching_untagged_spool_case_insensitive (line 634) | async def test_find_matching_untagged_spool_case_insensitive(db_session): function test_find_matching_untagged_spool_no_subtype (line 653) | async def test_find_matching_untagged_spool_no_subtype(db_session): function test_find_matching_untagged_spool_relationships_loaded (line 673) | async def test_find_matching_untagged_spool_relationships_loaded(db_sess... function test_link_tag_to_inventory_spool (line 697) | async def test_link_tag_to_inventory_spool(db_session): function test_link_tag_preserves_existing_slicer_filament (line 721) | async def test_link_tag_preserves_existing_slicer_filament(db_session): function test_create_spool_gradient_from_tray_id_name (line 747) | async def test_create_spool_gradient_from_tray_id_name(db_session): function test_create_spool_dual_color_from_tray_id_name (line 760) | async def test_create_spool_dual_color_from_tray_id_name(db_session): function test_create_spool_tri_color_from_tray_id_name (line 773) | async def test_create_spool_tri_color_from_tray_id_name(db_session): function test_create_spool_silk_plus_subtype (line 786) | async def test_create_spool_silk_plus_subtype(db_session): function test_create_spool_standard_not_affected (line 799) | async def test_create_spool_standard_not_affected(db_session): function test_color_resolves_from_catalog_not_suffix_fallback (line 815) | async def test_color_resolves_from_catalog_not_suffix_fallback(db_session): function test_color_name_is_none_when_catalog_miss_and_code_unreadable (line 847) | async def test_color_name_is_none_when_catalog_miss_and_code_unreadable(... function test_color_name_falls_back_to_readable_tray_id_name (line 864) | async def test_color_name_falls_back_to_readable_tray_id_name(db_session): function test_find_matching_untagged_gradient_spool (line 879) | async def test_find_matching_untagged_gradient_spool(db_session): function test_find_matching_untagged_gradient_no_match_basic (line 903) | async def test_find_matching_untagged_gradient_no_match_basic(db_session): FILE: backend/tests/unit/services/test_spoolbuddy_ssh.py function test_get_ssh_key_dir_creates_directory (line 21) | def test_get_ssh_key_dir_creates_directory(tmp_path): function test_get_ssh_key_dir_returns_existing (line 29) | def test_get_ssh_key_dir_returns_existing(tmp_path): function test_get_or_create_keypair_returns_existing (line 41) | async def test_get_or_create_keypair_returns_existing(tmp_path): function test_get_or_create_keypair_generates_new (line 56) | async def test_get_or_create_keypair_generates_new(tmp_path): function test_get_or_create_keypair_does_not_shell_out (line 87) | async def test_get_or_create_keypair_does_not_shell_out(tmp_path): function test_get_public_key (line 102) | async def test_get_public_key(tmp_path): function test_detect_branch_from_git_head (line 117) | def test_detect_branch_from_git_head(tmp_path): function test_detect_branch_uses_app_dir_not_data_dir (line 135) | def test_detect_branch_uses_app_dir_not_data_dir(tmp_path): function test_detect_branch_worktree_gitdir_file (line 165) | def test_detect_branch_worktree_gitdir_file(tmp_path): function test_detect_branch_detached_head_falls_back (line 176) | def test_detect_branch_detached_head_falls_back(tmp_path): function test_detect_branch_env_fallback (line 189) | def test_detect_branch_env_fallback(tmp_path): function test_detect_branch_default_main (line 197) | def test_detect_branch_default_main(tmp_path): function test_run_ssh_command_success (line 217) | async def test_run_ssh_command_success(tmp_path): function test_run_ssh_command_no_subprocess (line 254) | async def test_run_ssh_command_no_subprocess(tmp_path): function test_run_ssh_command_connection_failure (line 283) | async def test_run_ssh_command_connection_failure(tmp_path): function test_run_ssh_command_os_error (line 302) | async def test_run_ssh_command_os_error(tmp_path): function test_run_ssh_command_timeout (line 318) | async def test_run_ssh_command_timeout(tmp_path): function _make_update_mocks (line 344) | def _make_update_mocks(tmp_path): function test_perform_ssh_update_success (line 369) | async def test_perform_ssh_update_success(tmp_path): function test_perform_ssh_update_ssh_failure (line 409) | async def test_perform_ssh_update_ssh_failure(tmp_path): function test_perform_ssh_update_git_fetch_failure (line 440) | async def test_perform_ssh_update_git_fetch_failure(tmp_path): FILE: backend/tests/unit/services/test_spoolman_service.py class TestIsBambuLabSpool (line 15) | class TestIsBambuLabSpool: method client (line 19) | def client(self): method test_valid_tray_uuid_returns_true (line 22) | def test_valid_tray_uuid_returns_true(self, client): method test_valid_tag_uid_returns_true (line 26) | def test_valid_tag_uid_returns_true(self, client): method test_zero_tray_uuid_returns_false (line 30) | def test_zero_tray_uuid_returns_false(self, client): method test_zero_tag_uid_returns_false (line 34) | def test_zero_tag_uid_returns_false(self, client): method test_empty_identifiers_returns_false (line 38) | def test_empty_identifiers_returns_false(self, client): method test_tray_info_idx_ignored (line 43) | def test_tray_info_idx_ignored(self, client): method test_tray_info_idx_with_valid_uuid_returns_true (line 51) | def test_tray_info_idx_with_valid_uuid_returns_true(self, client): method test_tray_uuid_preferred_over_tag_uid (line 61) | def test_tray_uuid_preferred_over_tag_uid(self, client): method test_short_tray_uuid_returns_false (line 71) | def test_short_tray_uuid_returns_false(self, client): method test_non_hex_tray_uuid_returns_false (line 75) | def test_non_hex_tray_uuid_returns_false(self, client): class TestSpoolmanClient (line 80) | class TestSpoolmanClient: method client (line 84) | def client(self): method sample_tray (line 89) | def sample_tray(self): method existing_spool (line 105) | def existing_spool(self): method mock_filament (line 115) | def mock_filament(self): method test_sync_ams_tray_updates_weight_by_default (line 124) | async def test_sync_ams_tray_updates_weight_by_default(self, client, s... method test_sync_ams_tray_skips_weight_when_disabled (line 139) | async def test_sync_ams_tray_skips_weight_when_disabled(self, client, ... method test_sync_ams_tray_new_spool_always_includes_weight (line 156) | async def test_sync_ams_tray_new_spool_always_includes_weight(self, cl... method test_sync_ams_tray_location_format (line 172) | async def test_sync_ams_tray_location_format(self, client, sample_tray... method test_sync_ams_tray_skips_non_bambu_spool (line 187) | async def test_sync_ams_tray_skips_non_bambu_spool(self, client): method test_sync_ams_tray_weight_calculation (line 207) | async def test_sync_ams_tray_weight_calculation(self, client, existing... method test_find_spool_by_tag_with_cached_spools (line 247) | async def test_find_spool_by_tag_with_cached_spools(self, client): method test_find_spool_by_tag_without_cached_spools (line 260) | async def test_find_spool_by_tag_without_cached_spools(self, client): method test_find_spools_by_location_prefix_with_cached_spools (line 270) | async def test_find_spools_by_location_prefix_with_cached_spools(self,... method test_sync_ams_tray_with_cached_spools (line 286) | async def test_sync_ams_tray_with_cached_spools(self, client, sample_t... method test_clear_location_for_removed_spools_with_cached_spools (line 298) | async def test_clear_location_for_removed_spools_with_cached_spools(se... method test_get_spools_succeeds_on_first_attempt (line 329) | async def test_get_spools_succeeds_on_first_attempt(self, client): method test_get_spools_retries_on_connection_error (line 348) | async def test_get_spools_retries_on_connection_error(self, client): method test_get_spools_raises_after_3_failed_attempts (line 387) | async def test_get_spools_raises_after_3_failed_attempts(self, client): method test_get_spools_handles_non_connection_errors (line 413) | async def test_get_spools_handles_non_connection_errors(self, client): FILE: backend/tests/unit/services/test_spoolman_tracking.py class TestResolveSpoolTag (line 19) | class TestResolveSpoolTag: method test_prefers_tray_uuid (line 22) | def test_prefers_tray_uuid(self): method test_falls_back_to_tag_uid (line 26) | def test_falls_back_to_tag_uid(self): method test_skips_zero_uuid (line 30) | def test_skips_zero_uuid(self): method test_rejects_zero_tag_uid (line 34) | def test_rejects_zero_tag_uid(self): method test_uses_fallback_tag_when_ids_missing (line 38) | def test_uses_fallback_tag_when_ids_missing(self): method test_uses_fallback_tag_when_ids_zero (line 43) | def test_uses_fallback_tag_when_ids_zero(self): method test_empty_both (line 48) | def test_empty_both(self): method test_missing_keys (line 52) | def test_missing_keys(self): method test_zero_uuid_no_tag (line 55) | def test_zero_uuid_no_tag(self): class TestResolveGlobalTrayId (line 60) | class TestResolveGlobalTrayId: method test_default_mapping (line 63) | def test_default_mapping(self): method test_custom_mapping (line 69) | def test_custom_mapping(self): method test_unmapped_slot (line 76) | def test_unmapped_slot(self): method test_slot_beyond_mapping (line 81) | def test_slot_beyond_mapping(self): method test_empty_mapping (line 86) | def test_empty_mapping(self): class TestFallbackTagHelpers (line 91) | class TestFallbackTagHelpers: method test_hash_serial_matches_frontend_algorithm (line 94) | def test_hash_serial_matches_frontend_algorithm(self): method test_global_tray_to_ams_slot_standard_ams (line 99) | def test_global_tray_to_ams_slot_standard_ams(self): method test_global_tray_to_ams_slot_ams_ht (line 103) | def test_global_tray_to_ams_slot_ams_ht(self): method test_global_tray_to_ams_slot_external (line 107) | def test_global_tray_to_ams_slot_external(self): method test_get_fallback_spool_tag_standard (line 111) | def test_get_fallback_spool_tag_standard(self): method test_get_fallback_spool_tag_ams_ht (line 114) | def test_get_fallback_spool_tag_ams_ht(self): method test_get_fallback_spool_tag_external (line 117) | def test_get_fallback_spool_tag_external(self): class TestBuildAmsTrayLookup (line 121) | class TestBuildAmsTrayLookup: method test_single_ams_unit (line 124) | def test_single_ams_unit(self): method test_multiple_ams_units (line 140) | def test_multiple_ams_units(self): method test_external_spool (line 152) | def test_external_spool(self): method test_empty_external_spool_skipped (line 161) | def test_empty_external_spool_skipped(self): method test_no_ams_data (line 166) | def test_no_ams_data(self): method test_missing_fields_default (line 170) | def test_missing_fields_default(self): class TestStorePrintData (line 176) | class TestStorePrintData: method test_prefers_explicit_ams_mapping_over_queue_mapping (line 180) | async def test_prefers_explicit_ams_mapping_over_queue_mapping(self): FILE: backend/tests/unit/services/test_stl_thumbnail.py function _check_trimesh_available (line 9) | def _check_trimesh_available(): class TestStlThumbnailService (line 19) | class TestStlThumbnailService: method test_generate_stl_thumbnail_imports_available (line 22) | def test_generate_stl_thumbnail_imports_available(self): method test_generate_stl_thumbnail_returns_none_on_missing_deps (line 33) | def test_generate_stl_thumbnail_returns_none_on_missing_deps(self): method test_generate_stl_thumbnail_with_simple_cube (line 52) | def test_generate_stl_thumbnail_with_simple_cube(self): method test_generate_stl_thumbnail_nonexistent_file (line 158) | def test_generate_stl_thumbnail_nonexistent_file(self): method test_generate_stl_thumbnail_empty_file (line 169) | def test_generate_stl_thumbnail_empty_file(self): class TestStlThumbnailConstants (line 184) | class TestStlThumbnailConstants: method test_bambu_green_color (line 187) | def test_bambu_green_color(self): method test_background_color (line 193) | def test_background_color(self): method test_max_vertices_threshold (line 199) | def test_max_vertices_threshold(self): FILE: backend/tests/unit/services/test_tasmota.py class TestTasmotaService (line 14) | class TestTasmotaService: method service (line 18) | def service(self): method mock_plug (line 23) | def mock_plug(self): method test_build_url_without_auth (line 36) | def test_build_url_without_auth(self, service): method test_build_url_never_includes_credentials (line 41) | def test_build_url_never_includes_credentials(self, service): method test_build_url_encodes_special_characters (line 47) | def test_build_url_encodes_special_characters(self, service): method test_turn_on_success (line 57) | async def test_turn_on_success(self, service, mock_plug): method test_turn_on_failure (line 68) | async def test_turn_on_failure(self, service, mock_plug): method test_turn_on_with_auth (line 78) | async def test_turn_on_with_auth(self, service, mock_plug): method test_turn_off_success (line 95) | async def test_turn_off_success(self, service, mock_plug): method test_turn_off_failure (line 105) | async def test_turn_off_failure(self, service, mock_plug): method test_toggle_success (line 119) | async def test_toggle_success(self, service, mock_plug): method test_get_status_returns_on (line 134) | async def test_get_status_returns_on(self, service, mock_plug): method test_get_status_returns_off (line 147) | async def test_get_status_returns_off(self, service, mock_plug): method test_get_status_unreachable (line 159) | async def test_get_status_unreachable(self, service, mock_plug): method test_get_energy_returns_data (line 174) | async def test_get_energy_returns_data(self, service, mock_plug): method test_get_energy_handles_missing_data (line 201) | async def test_get_energy_handles_missing_data(self, service, mock_plug): method test_get_energy_handles_unreachable (line 211) | async def test_get_energy_handles_unreachable(self, service, mock_plug): method test_get_energy_handles_partial_data (line 221) | async def test_get_energy_handles_partial_data(self, service, mock_plug): method test_test_connection_success (line 245) | async def test_test_connection_success(self, service): method test_test_connection_failure (line 261) | async def test_test_connection_failure(self, service): method test_send_command_handles_timeout (line 275) | async def test_send_command_handles_timeout(self, service): method test_send_command_handles_connection_error (line 288) | async def test_send_command_handles_connection_error(self, service): method test_send_command_handles_invalid_json (line 301) | async def test_send_command_handles_invalid_json(self, service): method test_send_command_success (line 316) | async def test_send_command_success(self, service): class TestTasmotaServiceSingleton (line 331) | class TestTasmotaServiceSingleton: method test_singleton_exists (line 334) | def test_singleton_exists(self): FILE: backend/tests/unit/services/test_usage_tracker.py function _make_spool (line 21) | def _make_spool(*, id=1, label_weight=1000, weight_used=0, tag_uid=None,... function _make_assignment (line 35) | def _make_assignment(*, spool_id=1, printer_id=1, ams_id=0, tray_id=0, c... function _make_printer_state (line 46) | def _make_printer_state(ams_data, progress=0, layer_num=0, tray_now=255): function _make_printer_manager (line 56) | def _make_printer_manager(state=None): class TestOnPrintStart (line 63) | class TestOnPrintStart: method _clear_sessions (line 67) | def _clear_sessions(self): method test_creates_session_with_valid_remain (line 73) | async def test_creates_session_with_valid_remain(self): method test_creates_session_even_without_valid_remain (line 86) | async def test_creates_session_even_without_valid_remain(self): method test_skips_without_ams_data (line 98) | async def test_skips_without_ams_data(self): class TestOnPrintCompleteAMSDelta (line 109) | class TestOnPrintCompleteAMSDelta: method _clear_sessions (line 113) | def _clear_sessions(self): method _mock_get_setting (line 119) | def _mock_get_setting(self): method test_computes_delta_and_updates_spool (line 128) | async def test_computes_delta_and_updates_spool(self): method test_skips_negative_delta (line 167) | async def test_skips_negative_delta(self): method test_no_session_falls_through_to_3mf (line 187) | async def test_no_session_falls_through_to_3mf(self): class TestTrackFrom3MF (line 197) | class TestTrackFrom3MF: method test_updates_non_bl_spool_from_3mf (line 201) | async def test_updates_non_bl_spool_from_3mf(self): method test_scales_by_progress_for_failed_print (line 247) | async def test_scales_by_progress_for_failed_print(self): method test_tracks_bl_spools_via_3mf (line 292) | async def test_tracks_bl_spools_via_3mf(self): method test_skips_already_handled_trays (line 336) | async def test_skips_already_handled_trays(self): method test_slot_to_tray_mapping (line 374) | async def test_slot_to_tray_mapping(self): class TestSpoolAssignmentSnapshot (line 419) | class TestSpoolAssignmentSnapshot: method _clear_sessions (line 427) | def _clear_sessions(self): method _mock_get_setting (line 433) | def _mock_get_setting(self): method test_on_print_start_snapshots_assignments_with_db (line 442) | async def test_on_print_start_snapshots_assignments_with_db(self): method test_on_print_start_empty_snapshot_without_db (line 463) | async def test_on_print_start_empty_snapshot_without_db(self): method test_3mf_uses_snapshot_instead_of_live_query (line 474) | async def test_3mf_uses_snapshot_instead_of_live_query(self): method test_3mf_falls_back_to_live_query_without_snapshot (line 517) | async def test_3mf_falls_back_to_live_query_without_snapshot(self): method test_ams_delta_uses_snapshot_over_live_query (line 561) | async def test_ams_delta_uses_snapshot_over_live_query(self): method test_ams_delta_falls_back_to_live_query_without_snapshot (line 602) | async def test_ams_delta_falls_back_to_live_query_without_snapshot(self): method test_snapshot_survives_mid_print_unlink (line 642) | async def test_snapshot_survives_mid_print_unlink(self): FILE: backend/tests/unit/services/test_virtual_printer.py class TestVirtualPrinterInstance (line 13) | class TestVirtualPrinterInstance: method instance (line 17) | def instance(self, tmp_path): method test_instance_stores_parameters (line 35) | def test_instance_stores_parameters(self, instance): method test_instance_serial_property (line 44) | def test_instance_serial_property(self, instance): method test_instance_serial_x1c (line 49) | def test_instance_serial_x1c(self, tmp_path): method test_instance_is_proxy_false (line 64) | def test_instance_is_proxy_false(self, instance): method test_instance_is_proxy_true (line 68) | def test_instance_is_proxy_true(self, tmp_path): method test_instance_is_running_with_active_tasks (line 84) | def test_instance_is_running_with_active_tasks(self, instance): method test_instance_is_running_with_no_tasks (line 91) | def test_instance_is_running_with_no_tasks(self, instance): method test_instance_creates_directories (line 95) | def test_instance_creates_directories(self, instance, tmp_path): method test_get_status_returns_correct_format (line 105) | def test_get_status_returns_correct_format(self, instance): method test_get_status_not_running (line 115) | def test_get_status_not_running(self, instance): method test_on_file_received_adds_to_pending (line 126) | async def test_on_file_received_adds_to_pending(self, instance): method test_on_file_received_archives_immediately (line 139) | async def test_on_file_received_archives_immediately(self, instance): method test_archive_file_skips_non_3mf (line 149) | async def test_archive_file_skips_non_3mf(self, instance): method test_auto_dispatch_defaults_to_true (line 163) | def test_auto_dispatch_defaults_to_true(self, tmp_path): method test_add_to_print_queue_with_auto_dispatch_on (line 179) | async def test_add_to_print_queue_with_auto_dispatch_on(self, tmp_path): method test_add_to_print_queue_with_auto_dispatch_off (line 230) | async def test_add_to_print_queue_with_auto_dispatch_off(self, tmp_path): class TestVirtualPrinterManager (line 281) | class TestVirtualPrinterManager: method manager (line 285) | def manager(self): method test_manager_starts_empty (line 291) | def test_manager_starts_empty(self, manager): method test_manager_get_status_empty (line 296) | def test_manager_get_status_empty(self, manager): method test_manager_is_enabled_with_instance (line 303) | def test_manager_is_enabled_with_instance(self, manager, tmp_path): method test_manager_remove_instance_server (line 320) | async def test_manager_remove_instance_server(self, manager, tmp_path): method test_manager_remove_instance_proxy (line 342) | async def test_manager_remove_instance_proxy(self, manager, tmp_path): method test_manager_get_status_with_instance (line 364) | def test_manager_get_status_with_instance(self, manager, tmp_path): method test_manager_get_all_status (line 392) | def test_manager_get_all_status(self, manager, tmp_path): method test_manager_stop_all (line 414) | async def test_manager_stop_all(self, manager, tmp_path): method _make_db_vp (line 438) | def _make_db_vp(self, **overrides): method _setup_sync_mocks (line 460) | def _setup_sync_mocks(self, manager, enabled_vps, tmp_path): method test_sync_from_db_restarts_on_mode_change (line 474) | async def test_sync_from_db_restarts_on_mode_change(self, manager, tmp... method test_sync_from_db_restarts_on_access_code_change (line 506) | async def test_sync_from_db_restarts_on_access_code_change(self, manag... method test_sync_from_db_skips_unchanged_instance (line 536) | async def test_sync_from_db_skips_unchanged_instance(self, manager, tm... method test_sync_from_db_restarts_on_bind_ip_change (line 561) | async def test_sync_from_db_restarts_on_bind_ip_change(self, manager, ... method test_sync_from_db_restarts_on_model_change (line 592) | async def test_sync_from_db_restarts_on_model_change(self, manager, tm... class TestFTPSession (line 622) | class TestFTPSession: method mock_reader (line 626) | def mock_reader(self): method mock_writer (line 632) | def mock_writer(self): method ssl_context (line 644) | def ssl_context(self): method session (line 649) | def session(self, mock_reader, mock_writer, ssl_context, tmp_path): method test_user_command_accepts_bblp (line 667) | async def test_user_command_accepts_bblp(self, session): method test_pass_command_authenticates (line 674) | async def test_pass_command_authenticates(self, session): method test_pass_command_rejects_wrong_code (line 683) | async def test_pass_command_rejects_wrong_code(self, session): method test_syst_command (line 696) | async def test_syst_command(self, session): method test_pwd_command_requires_auth (line 706) | async def test_pwd_command_requires_auth(self, session): method test_pwd_command_when_authenticated (line 716) | async def test_pwd_command_when_authenticated(self, session): method test_type_command_sets_binary (line 726) | async def test_type_command_sets_binary(self, session): method test_pbsz_command (line 735) | async def test_pbsz_command(self, session): method test_prot_command_accepts_p (line 743) | async def test_prot_command_accepts_p(self, session): method test_quit_command (line 751) | async def test_quit_command(self, session): class TestSSDPServer (line 757) | class TestSSDPServer: method ssdp_server (line 761) | def ssdp_server(self): method test_build_notify_message (line 775) | def test_build_notify_message(self, ssdp_server): method test_build_response_message (line 786) | def test_build_response_message(self, ssdp_server): method test_ssdp_server_uses_correct_model (line 797) | def test_ssdp_server_uses_correct_model(self, ssdp_server): method test_advertise_ip_sets_local_ip (line 809) | def test_advertise_ip_sets_local_ip(self): method test_advertise_ip_empty_string_uses_auto_detect (line 822) | def test_advertise_ip_empty_string_uses_auto_detect(self): method test_advertise_ip_in_notify_message (line 835) | def test_advertise_ip_in_notify_message(self): method test_advertise_ip_in_response_message (line 850) | def test_advertise_ip_in_response_message(self): method test_default_no_advertise_ip (line 865) | def test_default_no_advertise_ip(self): class TestCertificateService (line 874) | class TestCertificateService: method cert_service (line 878) | def cert_service(self, tmp_path): method test_generate_certificates (line 884) | def test_generate_certificates(self, cert_service, tmp_path): method test_certificates_reused_if_exist (line 898) | def test_certificates_reused_if_exist(self, cert_service): method test_delete_certificates (line 910) | def test_delete_certificates(self, cert_service): method test_ensure_creates_if_not_exist (line 922) | def test_ensure_creates_if_not_exist(self, cert_service): class TestBindServer (line 932) | class TestBindServer: method bind_server (line 936) | def bind_server(self): method test_build_frame (line 946) | def test_build_frame(self, bind_server): method test_parse_frame_valid (line 967) | def test_parse_frame_valid(self, bind_server): method test_parse_frame_invalid_header (line 983) | def test_parse_frame_invalid_header(self, bind_server): method test_parse_frame_invalid_trailer (line 988) | def test_parse_frame_invalid_trailer(self, bind_server): method test_parse_frame_too_short (line 993) | def test_parse_frame_too_short(self, bind_server): method test_parse_frame_invalid_json (line 998) | def test_parse_frame_invalid_json(self, bind_server): method test_build_frame_roundtrip (line 1008) | def test_build_frame_roundtrip(self, bind_server): method test_bind_server_stores_config (line 1032) | def test_bind_server_stores_config(self, bind_server): method test_bind_server_custom_version (line 1039) | def test_bind_server_custom_version(self): method test_bind_ports_constant (line 1051) | def test_bind_ports_constant(self): method test_bind_server_initializes_empty_servers_list (line 1058) | def test_bind_server_initializes_empty_servers_list(self, bind_server): method bind_server (line 1491) | def bind_server(self): method test_build_frame (line 1501) | def test_build_frame(self, bind_server): method test_parse_frame_valid (line 1522) | def test_parse_frame_valid(self, bind_server): method test_parse_frame_invalid_header (line 1531) | def test_parse_frame_invalid_header(self, bind_server): method test_parse_frame_invalid_trailer (line 1536) | def test_parse_frame_invalid_trailer(self, bind_server): method test_parse_frame_too_short (line 1541) | def test_parse_frame_too_short(self, bind_server): method test_parse_frame_invalid_json (line 1546) | def test_parse_frame_invalid_json(self, bind_server): method test_build_frame_roundtrip (line 1555) | def test_build_frame_roundtrip(self, bind_server): method test_bind_server_stores_config (line 1562) | def test_bind_server_stores_config(self, bind_server): method test_bind_server_custom_version (line 1569) | def test_bind_server_custom_version(self): method test_bind_ports_includes_both (line 1581) | def test_bind_ports_includes_both(self): method test_bind_server_initializes_empty_servers_list (line 1588) | def test_bind_server_initializes_empty_servers_list(self, bind_server): method test_start_server_creates_bind_server (line 1594) | async def test_start_server_creates_bind_server(self, tmp_path): class TestSlicerProxyManager (line 1064) | class TestSlicerProxyManager: method proxy_manager (line 1068) | def proxy_manager(self, tmp_path): method test_proxy_manager_initializes_ports (line 1085) | def test_proxy_manager_initializes_ports(self, proxy_manager): method test_proxy_manager_stores_target_host (line 1102) | def test_proxy_manager_stores_target_host(self, proxy_manager): method test_get_status_before_start (line 1106) | def test_get_status_before_start(self, proxy_manager): method test_proxy_start_creates_transparent_proxies (line 1115) | async def test_proxy_start_creates_transparent_proxies(self, tmp_path): method test_proxy_manager_mqtt_has_ip_rewriting (line 1185) | def test_proxy_manager_mqtt_has_ip_rewriting(self, tmp_path): class TestSSDPProxy (line 1206) | class TestSSDPProxy: method ssdp_proxy (line 1210) | def ssdp_proxy(self): method test_ssdp_proxy_stores_interface_ips (line 1220) | def test_ssdp_proxy_stores_interface_ips(self, ssdp_proxy): method test_rewrite_ssdp_location (line 1226) | def test_rewrite_ssdp_location(self, ssdp_proxy): method test_rewrite_ssdp_location_case_insensitive (line 1238) | def test_rewrite_ssdp_location_case_insensitive(self, ssdp_proxy): method test_rewrite_ssdp_location_no_match (line 1246) | def test_rewrite_ssdp_location_no_match(self, ssdp_proxy): method test_parse_ssdp_message (line 1255) | def test_parse_ssdp_message(self, ssdp_proxy): class TestVirtualPrinterManagerDirectories (line 1272) | class TestVirtualPrinterManagerDirectories: method test_ensure_base_directories_creates_subdirs (line 1275) | def test_ensure_base_directories_creates_subdirs(self, tmp_path): method test_ensure_base_directories_handles_permission_error (line 1287) | def test_ensure_base_directories_handles_permission_error(self, tmp_pa... method test_instance_creates_per_vp_directories (line 1308) | def test_instance_creates_per_vp_directories(self, tmp_path): class TestVirtualPrinterInstanceProxyMode (line 1327) | class TestVirtualPrinterInstanceProxyMode: method proxy_instance (line 1331) | def proxy_instance(self, tmp_path): method test_proxy_instance_properties (line 1347) | def test_proxy_instance_properties(self, proxy_instance): method test_proxy_instance_does_not_require_access_code (line 1354) | def test_proxy_instance_does_not_require_access_code(self, proxy_insta... method test_get_status_proxy_includes_proxy_fields (line 1358) | def test_get_status_proxy_includes_proxy_fields(self, proxy_instance): method test_proxy_instance_stores_remote_interface (line 1376) | def test_proxy_instance_stores_remote_interface(self, tmp_path): class TestVirtualPrinterInstanceIPOverride (line 1394) | class TestVirtualPrinterInstanceIPOverride: method instance_with_remote_ip (line 1398) | def instance_with_remote_ip(self, tmp_path): method test_instance_stores_bind_ip (line 1414) | def test_instance_stores_bind_ip(self, instance_with_remote_ip): method test_instance_stores_remote_interface_ip (line 1418) | def test_instance_stores_remote_interface_ip(self, instance_with_remot... method test_generate_certificates_includes_remote_and_bind_ip (line 1422) | def test_generate_certificates_includes_remote_and_bind_ip(self, insta... method test_generate_certificates_no_remote_ip (line 1435) | def test_generate_certificates_no_remote_ip(self, tmp_path): method test_generate_certificates_no_ips (line 1461) | def test_generate_certificates_no_ips(self, tmp_path): class TestBindServer (line 1487) | class TestBindServer: method bind_server (line 936) | def bind_server(self): method test_build_frame (line 946) | def test_build_frame(self, bind_server): method test_parse_frame_valid (line 967) | def test_parse_frame_valid(self, bind_server): method test_parse_frame_invalid_header (line 983) | def test_parse_frame_invalid_header(self, bind_server): method test_parse_frame_invalid_trailer (line 988) | def test_parse_frame_invalid_trailer(self, bind_server): method test_parse_frame_too_short (line 993) | def test_parse_frame_too_short(self, bind_server): method test_parse_frame_invalid_json (line 998) | def test_parse_frame_invalid_json(self, bind_server): method test_build_frame_roundtrip (line 1008) | def test_build_frame_roundtrip(self, bind_server): method test_bind_server_stores_config (line 1032) | def test_bind_server_stores_config(self, bind_server): method test_bind_server_custom_version (line 1039) | def test_bind_server_custom_version(self): method test_bind_ports_constant (line 1051) | def test_bind_ports_constant(self): method test_bind_server_initializes_empty_servers_list (line 1058) | def test_bind_server_initializes_empty_servers_list(self, bind_server): method bind_server (line 1491) | def bind_server(self): method test_build_frame (line 1501) | def test_build_frame(self, bind_server): method test_parse_frame_valid (line 1522) | def test_parse_frame_valid(self, bind_server): method test_parse_frame_invalid_header (line 1531) | def test_parse_frame_invalid_header(self, bind_server): method test_parse_frame_invalid_trailer (line 1536) | def test_parse_frame_invalid_trailer(self, bind_server): method test_parse_frame_too_short (line 1541) | def test_parse_frame_too_short(self, bind_server): method test_parse_frame_invalid_json (line 1546) | def test_parse_frame_invalid_json(self, bind_server): method test_build_frame_roundtrip (line 1555) | def test_build_frame_roundtrip(self, bind_server): method test_bind_server_stores_config (line 1562) | def test_bind_server_stores_config(self, bind_server): method test_bind_server_custom_version (line 1569) | def test_bind_server_custom_version(self): method test_bind_ports_includes_both (line 1581) | def test_bind_ports_includes_both(self): method test_bind_server_initializes_empty_servers_list (line 1588) | def test_bind_server_initializes_empty_servers_list(self, bind_server): method test_start_server_creates_bind_server (line 1594) | async def test_start_server_creates_bind_server(self, tmp_path): class TestResolveModelCodes (line 1633) | class TestResolveModelCodes: method test_display_name_to_model_code_maps_all_models (line 1636) | def test_display_name_to_model_code_maps_all_models(self): method test_resolve_printer_model_with_ssdp_code (line 1645) | def test_resolve_printer_model_with_ssdp_code(self): method test_resolve_printer_model_with_display_name (line 1653) | def test_resolve_printer_model_with_display_name(self): method test_resolve_printer_model_with_none_or_unknown (line 1662) | def test_resolve_printer_model_with_none_or_unknown(self): class TestMqttIpRewrite (line 1670) | class TestMqttIpRewrite: method _build_mqtt_publish (line 1674) | def _build_mqtt_publish(topic: str, payload: bytes) -> bytes: method _build_mqtt_pingreq (line 1697) | def _build_mqtt_pingreq() -> bytes: method test_rewrite_ip_in_publish (line 1701) | def test_rewrite_ip_in_publish(self): method test_no_rewrite_when_ip_absent (line 1713) | def test_no_rewrite_when_ip_absent(self): method test_non_publish_packets_unchanged (line 1724) | def test_non_publish_packets_unchanged(self): method test_rewrite_preserves_packet_framing (line 1733) | def test_rewrite_preserves_packet_framing(self): method test_incomplete_packet_buffered (line 1764) | def test_incomplete_packet_buffered(self): method test_multiple_packets_in_one_chunk (line 1786) | def test_multiple_packets_in_one_chunk(self): method test_extra_replacements (line 1803) | def test_extra_replacements(self): class TestIpToLeIntBytes (line 1822) | class TestIpToLeIntBytes: method test_converts_ip_to_le_int (line 1825) | def test_converts_ip_to_le_int(self): method test_roundtrip (line 1832) | def test_roundtrip(self): class TestSSDPProxyName (line 1845) | class TestSSDPProxyName: method ssdp_proxy_with_name (line 1849) | def ssdp_proxy_with_name(self): method ssdp_proxy_without_name (line 1860) | def ssdp_proxy_without_name(self): method test_rewrite_uses_configured_name (line 1869) | def test_rewrite_uses_configured_name(self, ssdp_proxy_with_name): method test_rewrite_appends_proxy_without_name (line 1877) | def test_rewrite_appends_proxy_without_name(self, ssdp_proxy_without_n... FILE: backend/tests/unit/test_archive_file_path_guard.py class TestIsFileGuard (line 17) | class TestIsFileGuard: method test_empty_path_resolves_to_parent (line 20) | def test_empty_path_resolves_to_parent(self, tmp_path: Path): method test_real_file_passes_is_file (line 31) | def test_real_file_passes_is_file(self, tmp_path: Path): method test_nonexistent_file_fails_is_file (line 39) | def test_nonexistent_file_fails_is_file(self, tmp_path: Path): method test_directory_fails_is_file (line 44) | def test_directory_fails_is_file(self, tmp_path: Path): class TestFallbackArchiveFilePath (line 51) | class TestFallbackArchiveFilePath: method test_base_dir_slash_empty_string_is_base_dir (line 54) | def test_base_dir_slash_empty_string_is_base_dir(self, tmp_path: Path): method test_archive_file_path_empty_string_is_falsy (line 70) | def test_archive_file_path_empty_string_is_falsy(self): method test_archive_file_path_real_is_truthy (line 75) | def test_archive_file_path_real_is_truthy(self): class TestPhotoPathDerivation (line 81) | class TestPhotoPathDerivation: method test_empty_file_path_parent_is_dot (line 84) | def test_empty_file_path_parent_is_dot(self): method test_real_file_path_parent_is_archive_dir (line 89) | def test_real_file_path_parent_is_archive_dir(self): FILE: backend/tests/unit/test_archive_filtering.py class TestCalibrationPrintFiltering (line 17) | class TestCalibrationPrintFiltering: method test_usr_prefix_skips_archive (line 21) | async def test_usr_prefix_skips_archive(self, capture_logs): method test_usr_prefix_various_paths (line 71) | async def test_usr_prefix_various_paths(self, capture_logs): method test_normal_gcode_not_skipped (line 116) | async def test_normal_gcode_not_skipped(self, capture_logs): class TestListTimelapseVideos (line 159) | class TestListTimelapseVideos: method test_finds_video_files_in_timelapse_dir (line 163) | async def test_finds_video_files_in_timelapse_dir(self): method test_tries_multiple_directories (line 189) | async def test_tries_multiple_directories(self): method test_returns_empty_when_no_files (line 211) | async def test_returns_empty_when_no_files(self): method test_skips_directories (line 229) | async def test_skips_directories(self): class TestScanForTimelapseWithRetries (line 252) | class TestScanForTimelapseWithRetries: method _make_mocks (line 255) | def _make_mocks(self, archive_filename="benchy.gcode.3mf", timelapse_p... method _make_session_mock (line 271) | def _make_session_mock(self, mock_printer): method test_detects_new_file_after_baseline (line 282) | async def test_detects_new_file_after_baseline(self): method test_ignores_old_files_with_wrong_mtime (line 328) | async def test_ignores_old_files_with_wrong_mtime(self): method test_name_match_fallback (line 366) | async def test_name_match_fallback(self): method test_stops_when_archive_already_has_timelapse (line 409) | async def test_stops_when_archive_already_has_timelapse(self): method test_stops_when_archive_not_found (line 435) | async def test_stops_when_archive_not_found(self): method test_retries_four_times (line 458) | async def test_retries_four_times(self): class TestListTimelapseVideosAvi (line 489) | class TestListTimelapseVideosAvi: method test_finds_avi_files (line 493) | async def test_finds_avi_files(self): method test_finds_avi_case_insensitive (line 521) | async def test_finds_avi_case_insensitive(self): method test_scan_detects_new_avi_file (line 542) | async def test_scan_detects_new_avi_file(self): class TestConvertTimelapseToMp4 (line 606) | class TestConvertTimelapseToMp4: method test_converts_avi_to_mp4 (line 610) | async def test_converts_avi_to_mp4(self, tmp_path): method test_skips_when_no_ffmpeg (line 659) | async def test_skips_when_no_ffmpeg(self, tmp_path): method test_cleans_up_on_ffmpeg_failure (line 673) | async def test_cleans_up_on_ffmpeg_failure(self, tmp_path): class TestAttachTimelapseBackgroundConversion (line 701) | class TestAttachTimelapseBackgroundConversion: method test_mp4_does_not_spawn_conversion (line 705) | async def test_mp4_does_not_spawn_conversion(self, tmp_path): method test_avi_spawns_background_conversion (line 731) | async def test_avi_spawns_background_conversion(self, tmp_path): class TestDeleteTimelapse (line 761) | class TestDeleteTimelapse: method test_delete_timelapse_removes_file_and_clears_db (line 765) | async def test_delete_timelapse_removes_file_and_clears_db(self, tmp_p... method test_delete_timelapse_404_when_no_timelapse (line 793) | async def test_delete_timelapse_404_when_no_timelapse(self): method test_delete_timelapse_404_when_archive_not_found (line 813) | async def test_delete_timelapse_404_when_archive_not_found(self): FILE: backend/tests/unit/test_bed_jog.py class TestBedJogAPI (line 14) | class TestBedJogAPI: method test_bed_jog_not_found (line 16) | async def test_bed_jog_not_found(self, async_client: AsyncClient): method test_bed_jog_zero_distance_rejected (line 21) | async def test_bed_jog_zero_distance_rejected(self, async_client: Asyn... method test_bed_jog_too_large_rejected (line 28) | async def test_bed_jog_too_large_rejected(self, async_client: AsyncCli... method test_bed_jog_not_connected (line 34) | async def test_bed_jog_not_connected(self, async_client: AsyncClient, ... method test_bed_jog_send_failure (line 43) | async def test_bed_jog_send_failure(self, async_client: AsyncClient, p... method test_bed_jog_success_without_force (line 53) | async def test_bed_jog_success_without_force(self, async_client: Async... method test_bed_jog_success_with_force (line 69) | async def test_bed_jog_success_with_force(self, async_client: AsyncCli... class TestHomeAxesAPI (line 85) | class TestHomeAxesAPI: method test_home_axes_not_found (line 87) | async def test_home_axes_not_found(self, async_client: AsyncClient): method test_home_axes_invalid (line 92) | async def test_home_axes_invalid(self, async_client: AsyncClient, prin... method test_home_axes_always_runs_full_home (line 99) | async def test_home_axes_always_runs_full_home(self, async_client: Asy... method test_home_axes_not_connected (line 113) | async def test_home_axes_not_connected(self, async_client: AsyncClient... FILE: backend/tests/unit/test_bug_report.py class TestBugReportService (line 8) | class TestBugReportService: method test_submit_success (line 13) | async def test_submit_success(self): method test_submit_rate_limited (line 59) | async def test_submit_rate_limited(self): method test_submit_no_relay_url (line 80) | async def test_submit_no_relay_url(self): method test_submit_relay_http_error (line 100) | async def test_submit_relay_http_error(self): method test_submit_relay_connection_error (line 139) | async def test_submit_relay_connection_error(self): method test_submit_relay_failure_response (line 174) | async def test_submit_relay_failure_response(self): class TestStartLogging (line 215) | class TestStartLogging: method test_enables_debug_when_not_already_enabled (line 220) | async def test_enables_debug_when_not_already_enabled(self): method test_skips_enable_when_already_debug (line 251) | async def test_skips_enable_when_already_debug(self): method test_pushes_all_connected_printers (line 277) | async def test_pushes_all_connected_printers(self): class TestStopLogging (line 299) | class TestStopLogging: method test_collects_logs_and_restores_level (line 304) | async def test_collects_logs_and_restores_level(self): method test_skips_restore_when_was_debug (line 331) | async def test_skips_restore_when_was_debug(self): class TestSubmitBugReportRoute (line 352) | class TestSubmitBugReportRoute: method test_uses_provided_debug_logs (line 357) | async def test_uses_provided_debug_logs(self): method test_no_logs_when_debug_logs_not_provided (line 385) | async def test_no_logs_when_debug_logs_not_provided(self): class TestRateLimit (line 408) | class TestRateLimit: method test_check_rate_limit_allows_first (line 411) | def test_check_rate_limit_allows_first(self): method test_check_rate_limit_blocks_at_max (line 418) | def test_check_rate_limit_blocks_at_max(self): method test_check_rate_limit_clears_old (line 430) | def test_check_rate_limit_clears_old(self): FILE: backend/tests/unit/test_bulk_spool_create.py class TestSpoolBulkCreateSchema (line 20) | class TestSpoolBulkCreateSchema: method test_default_quantity_is_1 (line 23) | def test_default_quantity_is_1(self): method test_quantity_within_range (line 27) | def test_quantity_within_range(self): method test_quantity_max_100 (line 31) | def test_quantity_max_100(self): method test_quantity_zero_rejected (line 35) | def test_quantity_zero_rejected(self): method test_quantity_negative_rejected (line 39) | def test_quantity_negative_rejected(self): method test_quantity_over_100_rejected (line 43) | def test_quantity_over_100_rejected(self): method test_spool_fields_preserved (line 47) | def test_spool_fields_preserved(self): method test_spool_without_slicer_filament_is_stock (line 66) | def test_spool_without_slicer_filament_is_stock(self): method test_spool_with_slicer_filament_is_configured (line 74) | def test_spool_with_slicer_filament_is_configured(self): method test_material_required (line 81) | def test_material_required(self): function _make_mock_spool (line 89) | def _make_mock_spool(spool_id): class TestBulkCreateEndpoint (line 99) | class TestBulkCreateEndpoint: method test_creates_requested_number_of_spools (line 103) | async def test_creates_requested_number_of_spools(self): method test_single_quantity_creates_one_spool (line 129) | async def test_single_quantity_creates_one_spool(self): method test_all_spools_have_same_fields (line 153) | async def test_all_spools_have_same_fields(self): FILE: backend/tests/unit/test_camera_stderr_summary.py function test_empty_input (line 26) | def test_empty_input(): function test_keeps_error_lines_drops_banner (line 31) | def test_keeps_error_lines_drops_banner(): function test_caps_at_10_lines (line 49) | def test_caps_at_10_lines(): function test_drops_blank_lines (line 60) | def test_drops_blank_lines(): function test_banner_only_returns_empty (line 66) | def test_banner_only_returns_empty(): FILE: backend/tests/unit/test_capture_pid_tracking.py function _clear_capture_pids (line 21) | def _clear_capture_pids(): class TestCapturePidRegistration (line 28) | class TestCapturePidRegistration: method test_pid_registered_during_capture (line 32) | async def test_pid_registered_during_capture(self): method test_pid_removed_after_failure (line 67) | async def test_pid_removed_after_failure(self): method test_pid_removed_after_timeout (line 94) | async def test_pid_removed_after_timeout(self): method test_no_pid_tracked_for_chamber_image_models (line 128) | async def test_no_pid_tracked_for_chamber_image_models(self): method test_no_pid_tracked_when_subprocess_fails (line 140) | async def test_no_pid_tracked_when_subprocess_fails(self): class TestCleanupExcludesCapturePids (line 158) | class TestCleanupExcludesCapturePids: method test_cleanup_skips_capture_pids (line 162) | async def test_cleanup_skips_capture_pids(self): method test_cleanup_kills_non_capture_pids (line 182) | async def test_cleanup_kills_non_capture_pids(self): FILE: backend/tests/unit/test_catalog_bulk_delete.py class TestBulkDeleteIdsRequest (line 9) | class TestBulkDeleteIdsRequest: method test_accepts_list_of_ids (line 12) | def test_accepts_list_of_ids(self): method test_accepts_empty_list (line 16) | def test_accepts_empty_list(self): method test_rejects_missing_ids (line 20) | def test_rejects_missing_ids(self): FILE: backend/tests/unit/test_cli.py function session_maker (line 20) | async def session_maker() -> AsyncGenerator[async_sessionmaker, None]: function test_bootstrap_creates_key_when_none_exists (line 33) | async def test_bootstrap_creates_key_when_none_exists(session_maker): function test_bootstrap_refuses_to_overwrite_without_force (line 61) | async def test_bootstrap_refuses_to_overwrite_without_force(session_maker): function test_bootstrap_force_rotates_existing_key (line 90) | async def test_bootstrap_force_rotates_existing_key(session_maker): function test_bootstrap_marks_setup_completed (line 119) | async def test_bootstrap_marks_setup_completed(session_maker): function test_bootstrap_setup_idempotent_on_rotate (line 135) | async def test_bootstrap_setup_idempotent_on_rotate(session_maker): function test_bootstrap_custom_name (line 158) | async def test_bootstrap_custom_name(session_maker): FILE: backend/tests/unit/test_code_quality.py class DangerousImportVisitor (line 39) | class DangerousImportVisitor(ast.NodeVisitor): method __init__ (line 50) | def __init__(self): method visit_Import (line 57) | def visit_Import(self, node: ast.Import): method visit_ImportFrom (line 64) | def visit_ImportFrom(self, node: ast.ImportFrom): method _check_function (line 71) | def _check_function(self, node): method visit_FunctionDef (line 101) | def visit_FunctionDef(self, node: ast.FunctionDef): method visit_AsyncFunctionDef (line 117) | def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef): function find_import_shadowing (line 134) | def find_import_shadowing(file_path: Path) -> list[tuple[str, int, str]]: function get_python_files (line 151) | def get_python_files(directory: Path) -> list[Path]: class TestImportShadowing (line 156) | class TestImportShadowing: method test_no_import_shadowing_in_main (line 159) | def test_no_import_shadowing_in_main(self): method test_no_import_shadowing_in_services (line 177) | def test_no_import_shadowing_in_services(self): method test_no_import_shadowing_in_routes (line 195) | def test_no_import_shadowing_in_routes(self): class TestModuleImports (line 214) | class TestModuleImports: method test_all_modules_importable (line 217) | def test_all_modules_importable(self): class TestLogErrorPatterns (line 249) | class TestLogErrorPatterns: method test_mqtt_message_processing_no_errors (line 252) | def test_mqtt_message_processing_no_errors(self, capture_logs): FILE: backend/tests/unit/test_color_utils.py class TestColorsSimilar (line 6) | class TestColorsSimilar: method test_exact_match (line 9) | def test_exact_match(self): method test_exact_match_case_insensitive (line 12) | def test_exact_match_case_insensitive(self): method test_similar_colors_within_threshold (line 15) | def test_similar_colors_within_threshold(self): method test_different_colors_beyond_threshold (line 19) | def test_different_colors_beyond_threshold(self): method test_ignores_alpha_channel (line 23) | def test_ignores_alpha_channel(self): method test_six_digit_hex (line 27) | def test_six_digit_hex(self): method test_short_string_returns_false (line 30) | def test_short_string_returns_false(self): method test_empty_strings_match (line 34) | def test_empty_strings_match(self): method test_invalid_hex_returns_false (line 38) | def test_invalid_hex_returns_false(self): method test_whitespace_stripped (line 41) | def test_whitespace_stripped(self): method test_custom_threshold (line 44) | def test_custom_threshold(self): method test_black_and_near_black (line 49) | def test_black_and_near_black(self): method test_white_and_off_white (line 53) | def test_white_and_off_white(self): FILE: backend/tests/unit/test_cost_tracking.py function _make_spool (line 28) | def _make_spool(spool_id=1, label_weight=1000, weight_used=0, cost_per_k... function _make_assignment (line 40) | def _make_assignment(spool_id=1, printer_id=1, ams_id=0, tray_id=0): function _make_archive (line 50) | def _make_archive(archive_id=1, file_path=None): function cleanup_temp_archives (line 82) | def cleanup_temp_archives(): function cleanup_test_print_gcode (line 95) | def cleanup_test_print_gcode(): function archive_factory_temp (line 108) | def archive_factory_temp(): function _mock_db_sequential (line 128) | def _mock_db_sequential(responses): class TestCostCalculation (line 147) | class TestCostCalculation: method _clear_sessions (line 151) | def _clear_sessions(self): method test_cost_with_spool_specific_cost_per_kg (line 157) | async def test_cost_with_spool_specific_cost_per_kg(self): method test_cost_with_default_fallback (line 214) | async def test_cost_with_default_fallback(self): method test_cost_zero_when_default_cost_is_zero (line 271) | async def test_cost_zero_when_default_cost_is_zero(self): method test_cost_for_failed_print_uses_actual_usage (line 324) | async def test_cost_for_failed_print_uses_actual_usage(self): method test_cost_with_ams_fallback_tracking (line 385) | async def test_cost_with_ams_fallback_tracking(self): method test_multi_filament_cost_aggregation (line 425) | async def test_multi_filament_cost_aggregation(self): class TestCostAggregation (line 497) | class TestCostAggregation: method test_costs_summed_in_results (line 501) | async def test_costs_summed_in_results(self): method test_null_costs_handled_in_aggregation (line 512) | async def test_null_costs_handled_in_aggregation(self): method test_archive_cost_not_overwritten_with_zero (line 524) | async def test_archive_cost_not_overwritten_with_zero(self): method test_archive_cost_set_when_spool_has_cost (line 613) | async def test_archive_cost_set_when_spool_has_cost(self): method test_cost_with_archive_id (line 693) | async def test_cost_with_archive_id(self): method test_cost_with_print_name_ams_fallback (line 733) | async def test_cost_with_print_name_ams_fallback(self): FILE: backend/tests/unit/test_db_dialect.py class TestDialectDetection (line 8) | class TestDialectDetection: method test_sqlite_detected (line 11) | def test_sqlite_detected(self): method test_postgres_detected (line 19) | def test_postgres_detected(self): class TestRunPragma (line 28) | class TestRunPragma: method test_pragma_runs_on_sqlite (line 32) | async def test_pragma_runs_on_sqlite(self): method test_pragma_skipped_on_postgres (line 41) | async def test_pragma_skipped_on_postgres(self): class TestTimezoneStripping (line 50) | class TestTimezoneStripping: method test_strip_aware_datetime (line 53) | def test_strip_aware_datetime(self): method test_strip_in_dict_params (line 71) | def test_strip_in_dict_params(self): method test_strip_in_tuple_params (line 88) | def test_strip_in_tuple_params(self): method test_naive_datetime_unchanged (line 104) | def test_naive_datetime_unchanged(self): class TestCrossDatabaseConversion (line 120) | class TestCrossDatabaseConversion: method test_boolean_conversion (line 123) | def test_boolean_conversion(self): method test_datetime_string_conversion (line 128) | def test_datetime_string_conversion(self): method test_datetime_with_timezone_string (line 138) | def test_datetime_with_timezone_string(self): method test_json_serialization_for_backup (line 146) | def test_json_serialization_for_backup(self): class TestSafeExecutePattern (line 159) | class TestSafeExecutePattern: method test_safe_execute_catches_expected_exceptions (line 162) | def test_safe_execute_catches_expected_exceptions(self): method test_safe_execute_would_not_catch_integrity_error (line 174) | def test_safe_execute_would_not_catch_integrity_error(self): FILE: backend/tests/unit/test_energy_snapshots.py function _snap (line 21) | def _snap(plug_id: int, recorded_at: datetime, kwh: float) -> SmartPlugE... class TestSumSnapshotDeltas (line 25) | class TestSumSnapshotDeltas: method test_returns_zero_when_no_plugs (line 27) | async def test_returns_zero_when_no_plugs(self, db_session): method test_simple_delta_with_baseline_and_endpoint (line 33) | async def test_simple_delta_with_baseline_and_endpoint(self, db_sessio... method test_warming_up_when_no_baseline_before_range (line 49) | async def test_warming_up_when_no_baseline_before_range(self, db_sessi... method test_counter_reset_is_clamped_to_zero (line 66) | async def test_counter_reset_is_clamped_to_zero(self, db_session, smar... method test_multiple_plugs_are_summed (line 84) | async def test_multiple_plugs_are_summed(self, db_session, smart_plug_... method test_plug_with_no_snapshots_signals_warming (line 106) | async def test_plug_with_no_snapshots_signals_warming(self, db_session... method test_endpoint_picks_last_snapshot_at_or_before_range_end (line 121) | async def test_endpoint_picks_last_snapshot_at_or_before_range_end(sel... class TestPerPrintRestartResilience (line 140) | class TestPerPrintRestartResilience: method test_energy_start_kwh_persists_to_db (line 148) | async def test_energy_start_kwh_persists_to_db(self, db_session, print... method test_energy_kwh_delta_computes_from_persisted_start (line 172) | async def test_energy_kwh_delta_computes_from_persisted_start(self, db... FILE: backend/tests/unit/test_firmware_versions.py function test_wiki_extraction_ignores_prose_version_mentions (line 29) | async def test_wiki_extraction_ignores_prose_version_mentions(): function test_wiki_extraction_returns_empty_for_unknown_api_key (line 48) | async def test_wiki_extraction_returns_empty_for_unknown_api_key(): function test_wiki_extraction_accepts_nodash_anchors (line 65) | async def test_wiki_extraction_accepts_nodash_anchors(): function test_wiki_extraction_fallback_accepts_fullwidth_parens (line 88) | async def test_wiki_extraction_fallback_accepts_fullwidth_parens(): function test_get_available_versions_merges_sources (line 101) | async def test_get_available_versions_merges_sources(): function test_get_available_versions_sorts_newest_first (line 146) | async def test_get_available_versions_sorts_newest_first(): function test_check_for_update_includes_available_versions (line 163) | async def test_check_for_update_includes_available_versions(): FILE: backend/tests/unit/test_gcode_injection.py function _make_temp_path (line 12) | def _make_temp_path(suffix=".3mf") -> Path: function _make_test_3mf (line 21) | def _make_test_3mf(gcode_content: str = "G28\nG1 X0 Y0\nM400\n", plate_i... class TestInjectGcodeInto3mf (line 33) | class TestInjectGcodeInto3mf: method test_inject_start_gcode (line 36) | def test_inject_start_gcode(self): method test_inject_end_gcode (line 53) | def test_inject_end_gcode(self): method test_inject_both_start_and_end (line 70) | def test_inject_both_start_and_end(self): method test_no_injection_returns_none (line 88) | def test_no_injection_returns_none(self): method test_empty_strings_returns_none (line 97) | def test_empty_strings_returns_none(self): method test_plate_id_selection (line 106) | def test_plate_id_selection(self): method test_preserves_other_files (line 130) | def test_preserves_other_files(self): method test_no_gcode_file_returns_none (line 148) | def test_no_gcode_file_returns_none(self): method test_invalid_file_returns_none (line 161) | def test_invalid_file_returns_none(self): method test_fallback_to_first_gcode (line 172) | def test_fallback_to_first_gcode(self): method test_original_file_unchanged (line 193) | def test_original_file_unchanged(self): FILE: backend/tests/unit/test_homeassistant_settings.py function test_get_homeassistant_settings_no_env_vars (line 15) | async def test_get_homeassistant_settings_no_env_vars(): function test_get_homeassistant_settings_with_env_vars (line 48) | async def test_get_homeassistant_settings_with_env_vars(): function test_get_homeassistant_settings_partial_env_url_only (line 76) | async def test_get_homeassistant_settings_partial_env_url_only(): function test_get_homeassistant_settings_partial_env_token_only (line 106) | async def test_get_homeassistant_settings_partial_env_token_only(): function test_get_homeassistant_settings_empty_env_vars (line 136) | async def test_get_homeassistant_settings_empty_env_vars(): function test_get_homeassistant_settings_auto_enable_logic (line 164) | async def test_get_homeassistant_settings_auto_enable_logic(): function test_get_homeassistant_settings_env_vars_override_enabled_true (line 208) | async def test_get_homeassistant_settings_env_vars_override_enabled_true(): FILE: backend/tests/unit/test_ldap_migration.py function force_sqlite_dialect (line 19) | def force_sqlite_dialect(monkeypatch): function legacy_engine (line 34) | async def legacy_engine(): function test_legacy_schema_rejects_null_password_before_migration (line 97) | async def test_legacy_schema_rejects_null_password_before_migration(lega... function test_migration_allows_null_password_hash_for_ldap_users (line 113) | async def test_migration_allows_null_password_hash_for_ldap_users(legacy... function test_migration_is_idempotent (line 139) | async def test_migration_is_idempotent(legacy_engine): FILE: backend/tests/unit/test_local_backup.py class TestCalculateNextRun (line 14) | class TestCalculateNextRun: method test_hourly_returns_next_full_hour (line 17) | def test_hourly_returns_next_full_hour(self): method test_daily_before_target_time_schedules_today (line 27) | def test_daily_before_target_time_schedules_today(self): method test_daily_after_target_time_schedules_tomorrow (line 37) | def test_daily_after_target_time_schedules_tomorrow(self): method test_weekly_adds_full_week (line 47) | def test_weekly_adds_full_week(self): method test_weekly_after_target_time_adds_full_week_from_tomorrow (line 57) | def test_weekly_after_target_time_adds_full_week_from_tomorrow(self): method test_invalid_time_defaults_to_0300 (line 67) | def test_invalid_time_defaults_to_0300(self): method test_unknown_schedule_type_defaults_to_daily (line 77) | def test_unknown_schedule_type_defaults_to_daily(self): class TestPruneBackups (line 88) | class TestPruneBackups: method test_prune_keeps_retention_count (line 91) | def test_prune_keeps_retention_count(self, tmp_path): method test_prune_noop_when_under_retention (line 101) | def test_prune_noop_when_under_retention(self, tmp_path): method test_prune_only_touches_matching_files (line 110) | def test_prune_only_touches_matching_files(self, tmp_path): class TestResolveBackupFile (line 124) | class TestResolveBackupFile: method test_valid_filename (line 127) | def test_valid_filename(self, tmp_path): method test_path_traversal_blocked (line 134) | def test_path_traversal_blocked(self, tmp_path): method test_backslash_blocked (line 139) | def test_backslash_blocked(self, tmp_path): method test_dotdot_blocked (line 144) | def test_dotdot_blocked(self, tmp_path): method test_wrong_prefix_blocked (line 149) | def test_wrong_prefix_blocked(self, tmp_path): method test_nonexistent_file (line 156) | def test_nonexistent_file(self, tmp_path): class TestDeleteBackup (line 162) | class TestDeleteBackup: method test_delete_valid_backup (line 165) | def test_delete_valid_backup(self, tmp_path): method test_delete_nonexistent_backup (line 173) | def test_delete_nonexistent_backup(self, tmp_path): method test_delete_path_traversal_blocked (line 178) | def test_delete_path_traversal_blocked(self, tmp_path): class TestListBackups (line 184) | class TestListBackups: method test_list_empty_dir (line 187) | def test_list_empty_dir(self, tmp_path): method test_list_nonexistent_dir (line 192) | def test_list_nonexistent_dir(self): method test_list_only_matching_files (line 197) | def test_list_only_matching_files(self, tmp_path): method test_list_sorted_newest_first (line 206) | def test_list_sorted_newest_first(self, tmp_path): method test_list_includes_size (line 218) | def test_list_includes_size(self, tmp_path): class TestGetStatus (line 225) | class TestGetStatus: method test_initial_status (line 228) | def test_initial_status(self): FILE: backend/tests/unit/test_log_error_detection.py class TestMQTTMessageProcessingNoErrors (line 9) | class TestMQTTMessageProcessingNoErrors: method test_process_print_status_message (line 12) | def test_process_print_status_message(self, capture_logs): method test_process_xcam_data (line 41) | def test_process_xcam_data(self, capture_logs): method test_process_ams_data (line 67) | def test_process_ams_data(self, capture_logs): method test_process_hms_errors (line 103) | def test_process_hms_errors(self, capture_logs): class TestPrintLifecycleNoErrors (line 129) | class TestPrintLifecycleNoErrors: method test_print_start_to_complete (line 132) | def test_print_start_to_complete(self, capture_logs): method test_print_failure_handling (line 181) | def test_print_failure_handling(self, capture_logs): class TestServiceImports (line 219) | class TestServiceImports: method test_archive_service_import (line 222) | def test_archive_service_import(self, capture_logs): method test_notification_service_import (line 229) | def test_notification_service_import(self, capture_logs): method test_printer_manager_import (line 236) | def test_printer_manager_import(self, capture_logs): method test_main_module_import (line 243) | def test_main_module_import(self, capture_logs): class TestEdgeCases (line 256) | class TestEdgeCases: method test_empty_message (line 259) | def test_empty_message(self, capture_logs): method test_message_with_unknown_fields (line 273) | def test_message_with_unknown_fields(self, capture_logs): method test_message_with_null_values (line 296) | def test_message_with_null_values(self, capture_logs): FILE: backend/tests/unit/test_maintenance_rod_filtering.py class TestShouldApplyToPrinter (line 8) | class TestShouldApplyToPrinter: method test_carbon_rod_tasks_apply_to_carbon_models (line 13) | def test_carbon_rod_tasks_apply_to_carbon_models(self, model: str): method test_carbon_rod_tasks_do_not_apply_to_p2s (line 16) | def test_carbon_rod_tasks_do_not_apply_to_p2s(self): method test_carbon_rod_tasks_do_not_apply_to_a1 (line 20) | def test_carbon_rod_tasks_do_not_apply_to_a1(self): method test_steel_rod_tasks_apply_to_p2s (line 24) | def test_steel_rod_tasks_apply_to_p2s(self): method test_steel_rod_tasks_do_not_apply_to_x1c (line 28) | def test_steel_rod_tasks_do_not_apply_to_x1c(self): method test_steel_rod_tasks_do_not_apply_to_a1 (line 32) | def test_steel_rod_tasks_do_not_apply_to_a1(self): method test_linear_rail_tasks_apply_to_rail_models (line 37) | def test_linear_rail_tasks_apply_to_rail_models(self, model: str): method test_linear_rail_tasks_do_not_apply_to_p2s (line 41) | def test_linear_rail_tasks_do_not_apply_to_p2s(self): method test_universal_tasks_apply_to_all (line 46) | def test_universal_tasks_apply_to_all(self, model: str): method test_unknown_model_defaults_to_carbon (line 51) | def test_unknown_model_defaults_to_carbon(self): FILE: backend/tests/unit/test_mfa_helpers.py class TestBackupCodeGeneration (line 12) | class TestBackupCodeGeneration: method test_generates_ten_codes (line 15) | def test_generates_ten_codes(self): method test_codes_are_eight_chars (line 20) | def test_codes_are_eight_chars(self): method test_codes_are_alphanumeric (line 25) | def test_codes_are_alphanumeric(self): method test_hashes_verify_against_plain (line 31) | def test_hashes_verify_against_plain(self): method test_codes_are_unique (line 37) | def test_codes_are_unique(self): class TestTOTPQRCode (line 42) | class TestTOTPQRCode: method test_generates_base64_png (line 45) | def test_generates_base64_png(self): FILE: backend/tests/unit/test_obico_detection.py class TestSettingsSchemaValidators (line 20) | class TestSettingsSchemaValidators: method test_sensitivity_accepts_valid_values (line 23) | def test_sensitivity_accepts_valid_values(self): method test_sensitivity_rejects_garbage (line 28) | def test_sensitivity_rejects_garbage(self): method test_action_accepts_valid_values (line 32) | def test_action_accepts_valid_values(self): method test_action_rejects_garbage (line 36) | def test_action_rejects_garbage(self): method test_enabled_printers_accepts_empty (line 40) | def test_enabled_printers_accepts_empty(self): method test_enabled_printers_accepts_int_array (line 44) | def test_enabled_printers_accepts_int_array(self): method test_enabled_printers_rejects_non_json (line 48) | def test_enabled_printers_rejects_non_json(self): method test_enabled_printers_rejects_non_list (line 52) | def test_enabled_printers_rejects_non_list(self): method test_enabled_printers_rejects_non_int_elements (line 56) | def test_enabled_printers_rejects_non_int_elements(self): method test_poll_interval_bounds (line 60) | def test_poll_interval_bounds(self): class TestGetStatus (line 68) | class TestGetStatus: method test_empty_initial_status (line 69) | def test_empty_initial_status(self): class TestTestConnection (line 78) | class TestTestConnection: method test_empty_url_via_route (line 80) | async def test_empty_url_via_route(self): method test_healthy_response_is_ok (line 89) | async def test_healthy_response_is_ok(self): method test_non_ok_body_is_not_ok (line 105) | async def test_non_ok_body_is_not_ok(self): class TestPollOneStateLifecycle (line 119) | class TestPollOneStateLifecycle: method test_new_task_name_resets_state (line 123) | async def test_new_task_name_resets_state(self): method test_ml_api_error_does_not_crash (line 166) | async def test_ml_api_error_does_not_crash(self): method test_ml_api_empty_exception_message_falls_back_to_type (line 194) | async def test_ml_api_empty_exception_message_falls_back_to_type(self): method test_failure_fires_action_only_once (line 229) | async def test_failure_fires_action_only_once(self): class TestFrameCache (line 273) | class TestFrameCache: method setup_method (line 283) | def setup_method(self): method test_stash_and_pop_roundtrip (line 287) | async def test_stash_and_pop_roundtrip(self): method test_nonce_is_single_use (line 294) | async def test_nonce_is_single_use(self): method test_unknown_nonce_returns_none (line 301) | async def test_unknown_nonce_returns_none(self): method test_stash_produces_unique_nonces (line 305) | async def test_stash_produces_unique_nonces(self): method test_expired_entries_are_pruned_on_stash (line 310) | async def test_expired_entries_are_pruned_on_stash(self): method test_pop_rejects_expired_nonce (line 321) | async def test_pop_rejects_expired_nonce(self): class TestCheckPrinterUsesCachedFrameUrl (line 329) | class TestCheckPrinterUsesCachedFrameUrl: method setup_method (line 332) | def setup_method(self): method test_ml_api_called_with_cached_frame_url (line 336) | async def test_ml_api_called_with_cached_frame_url(self): method test_capture_failure_skips_ml_call (line 375) | async def test_capture_failure_skips_ml_call(self): method test_missing_external_url_skips_ml_call (line 405) | async def test_missing_external_url_skips_ml_call(self): method test_successful_cycle_clears_previous_error (line 435) | async def test_successful_cycle_clears_previous_error(self): FILE: backend/tests/unit/test_obico_smoothing.py class TestThresholds (line 16) | class TestThresholds: method test_medium_matches_base (line 17) | def test_medium_matches_base(self): method test_low_sensitivity_is_stricter (line 22) | def test_low_sensitivity_is_stricter(self): method test_high_sensitivity_is_looser (line 27) | def test_high_sensitivity_is_looser(self): method test_unknown_falls_back_to_medium (line 32) | def test_unknown_falls_back_to_medium(self): class TestScoreFromDetections (line 36) | class TestScoreFromDetections: method test_empty (line 37) | def test_empty(self): method test_sums_confidences (line 41) | def test_sums_confidences(self): method test_ignores_malformed (line 45) | def test_ignores_malformed(self): class TestPrintState (line 50) | class TestPrintState: method test_warmup_returns_zero (line 51) | def test_warmup_returns_zero(self): method test_after_warmup_returns_nonzero_for_hits (line 56) | def test_after_warmup_returns_nonzero_for_hits(self): method test_sustained_zero_stays_safe (line 63) | def test_sustained_zero_stays_safe(self): method test_sustained_hits_eventually_cross_high (line 68) | def test_sustained_hits_eventually_cross_high(self): method test_isolated_spike_does_not_trigger_failure (line 77) | def test_isolated_spike_does_not_trigger_failure(self): class TestClassify (line 87) | class TestClassify: method test_safe (line 88) | def test_safe(self): method test_warning (line 92) | def test_warning(self): method test_failure (line 96) | def test_failure(self): FILE: backend/tests/unit/test_opentag3d.py function _make_spool (line 14) | def _make_spool(**kwargs): class TestBuildPayload (line 32) | class TestBuildPayload: method test_payload_is_102_bytes (line 33) | def test_payload_is_102_bytes(self): method test_tag_version (line 38) | def test_tag_version(self): method test_material_field (line 43) | def test_material_field(self): method test_material_truncated (line 48) | def test_material_truncated(self): method test_modifiers_field (line 53) | def test_modifiers_field(self): method test_modifiers_none (line 58) | def test_modifiers_none(self): method test_reserved_is_zero (line 63) | def test_reserved_is_zero(self): method test_brand_field (line 67) | def test_brand_field(self): method test_color_name_field (line 72) | def test_color_name_field(self): method test_rgba_field (line 78) | def test_rgba_field(self): method test_rgba_none (line 82) | def test_rgba_none(self): method test_target_diameter (line 86) | def test_target_diameter(self): method test_target_weight (line 91) | def test_target_weight(self): method test_print_temp (line 96) | def test_print_temp(self): method test_print_temp_none (line 100) | def test_print_temp_none(self): class TestEncodeOpentag3d (line 105) | class TestEncodeOpentag3d: method test_starts_with_cc (line 106) | def test_starts_with_cc(self): method test_tlv_header (line 110) | def test_tlv_header(self): method test_ndef_record_header (line 117) | def test_ndef_record_header(self): method test_mime_type (line 124) | def test_mime_type(self): method test_ends_with_terminator (line 129) | def test_ends_with_terminator(self): method test_total_size (line 133) | def test_total_size(self): method test_fits_ntag213 (line 138) | def test_fits_ntag213(self): FILE: backend/tests/unit/test_orca_profiles.py class TestGuessProfileType (line 12) | class TestGuessProfileType: method test_explicit_filament_type (line 15) | def test_explicit_filament_type(self): method test_explicit_process_type (line 21) | def test_explicit_process_type(self): method test_explicit_machine_type (line 27) | def test_explicit_machine_type(self): method test_explicit_printer_type (line 33) | def test_explicit_printer_type(self): method test_explicit_print_type (line 39) | def test_explicit_print_type(self): method test_path_hint_filament (line 45) | def test_path_hint_filament(self): method test_path_hint_process (line 51) | def test_path_hint_process(self): method test_path_hint_machine (line 57) | def test_path_hint_machine(self): method test_print_settings_id_indicates_process (line 63) | def test_print_settings_id_indicates_process(self): method test_filament_settings_id_indicates_filament (line 69) | def test_filament_settings_id_indicates_filament(self): method test_printer_settings_id_indicates_printer (line 75) | def test_printer_settings_id_indicates_printer(self): method test_prime_tower_keys_indicate_process (line 81) | def test_prime_tower_keys_indicate_process(self): method test_outer_wall_speed_indicates_process (line 91) | def test_outer_wall_speed_indicates_process(self): method test_layer_height_indicates_process (line 97) | def test_layer_height_indicates_process(self): method test_machine_keys_indicate_printer (line 103) | def test_machine_keys_indicate_printer(self): method test_filament_type_indicates_filament (line 109) | def test_filament_type_indicates_filament(self): method test_name_with_layer_height_pattern (line 115) | def test_name_with_layer_height_pattern(self): method test_name_ending_with_process (line 121) | def test_name_ending_with_process(self): method test_default_to_filament (line 127) | def test_default_to_filament(self): method test_override_keys_only_process (line 133) | def test_override_keys_only_process(self): class TestParseMaterialFromName (line 151) | class TestParseMaterialFromName: method test_pla_in_name (line 154) | def test_pla_in_name(self): method test_abs_in_name (line 159) | def test_abs_in_name(self): method test_petg_in_name (line 164) | def test_petg_in_name(self): method test_tpu_in_name (line 169) | def test_tpu_in_name(self): method test_no_material_in_name (line 174) | def test_no_material_in_name(self): method test_material_word_boundary (line 179) | def test_material_word_boundary(self): method test_asa_in_name (line 185) | def test_asa_in_name(self): method test_pa_in_name (line 190) | def test_pa_in_name(self): method test_support_for_pattern (line 197) | def test_support_for_pattern(self): class TestParseVendorFromName (line 206) | class TestParseVendorFromName: method test_overture_vendor (line 209) | def test_overture_vendor(self): method test_esun_vendor (line 214) | def test_esun_vendor(self): method test_bambu_vendor (line 219) | def test_bambu_vendor(self): method test_devil_design_vendor (line 224) | def test_devil_design_vendor(self): method test_no_vendor_process_name (line 229) | def test_no_vendor_process_name(self): method test_strips_at_suffix (line 234) | def test_strips_at_suffix(self): method test_single_char_vendor_rejected (line 241) | def test_single_char_vendor_rejected(self): class TestExtractCoreFields (line 248) | class TestExtractCoreFields: method test_filament_type_array (line 251) | def test_filament_type_array(self): method test_filament_type_string (line 257) | def test_filament_type_string(self): method test_filament_vendor_array (line 263) | def test_filament_vendor_array(self): method test_nozzle_temp_from_array (line 269) | def test_nozzle_temp_from_array(self): method test_nozzle_temp_range_override (line 276) | def test_nozzle_temp_range_override(self): method test_pressure_advance_array (line 289) | def test_pressure_advance_array(self): method test_default_filament_colour (line 295) | def test_default_filament_colour(self): method test_filament_cost_array (line 301) | def test_filament_cost_array(self): method test_filament_density (line 307) | def test_filament_density(self): method test_compatible_printers (line 313) | def test_compatible_printers(self): method test_empty_data (line 321) | def test_empty_data(self): method test_full_resolved_preset (line 327) | def test_full_resolved_preset(self): FILE: backend/tests/unit/test_permissions.py class TestPermissionEnum (line 11) | class TestPermissionEnum: method test_clear_plate_permission_exists (line 14) | def test_clear_plate_permission_exists(self): method test_clear_plate_in_all_permissions (line 19) | def test_clear_plate_in_all_permissions(self): method test_clear_plate_in_printers_category (line 23) | def test_clear_plate_in_printers_category(self): method test_clear_plate_separate_from_control (line 28) | def test_clear_plate_separate_from_control(self): class TestDefaultGroups (line 34) | class TestDefaultGroups: method test_operators_have_clear_plate (line 37) | def test_operators_have_clear_plate(self): method test_operators_have_control_and_clear_plate (line 42) | def test_operators_have_control_and_clear_plate(self): method test_administrators_have_all_permissions (line 48) | def test_administrators_have_all_permissions(self): method test_viewers_do_not_have_clear_plate (line 53) | def test_viewers_do_not_have_clear_plate(self): class TestPermissionCategoriesCompleteness (line 59) | class TestPermissionCategoriesCompleteness: method test_all_permissions_categorized (line 62) | def test_all_permissions_categorized(self): method test_no_duplicate_categorization (line 70) | def test_no_duplicate_categorization(self): class TestInventoryViewAssignmentsPermission (line 79) | class TestInventoryViewAssignmentsPermission: method test_view_assignments_permission_exists (line 82) | def test_view_assignments_permission_exists(self): method test_view_assignments_in_all_permissions (line 87) | def test_view_assignments_in_all_permissions(self): method test_view_assignments_in_inventory_category (line 91) | def test_view_assignments_in_inventory_category(self): method test_view_assignments_separate_from_read (line 96) | def test_view_assignments_separate_from_read(self): method test_operators_have_view_assignments (line 101) | def test_operators_have_view_assignments(self): method test_viewers_have_view_assignments (line 106) | def test_viewers_have_view_assignments(self): method test_administrators_have_view_assignments (line 111) | def test_administrators_have_view_assignments(self): FILE: backend/tests/unit/test_permissions_stats_filter.py class TestStatsFilterByUserPermission (line 11) | class TestStatsFilterByUserPermission: method test_permission_enum_exists (line 14) | def test_permission_enum_exists(self): method test_permission_in_all_permissions (line 19) | def test_permission_in_all_permissions(self): method test_permission_in_administrators_group (line 23) | def test_permission_in_administrators_group(self): method test_permission_not_in_operators_group (line 28) | def test_permission_not_in_operators_group(self): method test_permission_not_in_viewers_group (line 33) | def test_permission_not_in_viewers_group(self): method test_permission_in_stats_category (line 38) | def test_permission_in_stats_category(self): class TestValidateUserFilterPermission (line 44) | class TestValidateUserFilterPermission: method validate (line 48) | def validate(self): method test_no_filter_no_check (line 53) | def test_no_filter_no_check(self, validate): method test_no_user_no_check (line 57) | def test_no_user_no_check(self, validate): method test_admin_always_allowed (line 61) | def test_admin_always_allowed(self, validate): method test_user_with_permission_allowed (line 67) | def test_user_with_permission_allowed(self, validate): method test_user_without_permission_denied (line 75) | def test_user_without_permission_denied(self, validate): method test_sentinel_minus_one_also_checked (line 84) | def test_sentinel_minus_one_also_checked(self, validate): class TestApplyUserFilter (line 93) | class TestApplyUserFilter: method apply_filter (line 97) | def apply_filter(self): method test_none_does_nothing (line 102) | def test_none_does_nothing(self, apply_filter): method test_positive_id_adds_filter (line 108) | def test_positive_id_adds_filter(self, apply_filter): method test_minus_one_adds_is_null (line 116) | def test_minus_one_adds_is_null(self, apply_filter): method test_appends_to_existing_conditions (line 123) | def test_appends_to_existing_conditions(self, apply_filter): FILE: backend/tests/unit/test_phantom_print_hardening.py class TestArchiveMatchQueryShape (line 20) | class TestArchiveMatchQueryShape: method _build_archive_query (line 28) | def _build_archive_query(self, check_name: str, printer_id: int = 1) -... method test_query_does_not_contain_ilike (line 49) | def test_query_does_not_contain_ilike(self): method test_query_uses_exact_equality (line 56) | def test_query_uses_exact_equality(self): method test_query_uses_in_for_filename_variants (line 63) | def test_query_uses_in_for_filename_variants(self): method test_partial_name_not_in_query (line 72) | def test_partial_name_not_in_query(self): method test_check_name_derivation_from_subtask (line 80) | def test_check_name_derivation_from_subtask(self): method test_check_name_derivation_from_filename (line 95) | def test_check_name_derivation_from_filename(self): class TestMultiplePrintingQueueItemsWarning (line 103) | class TestMultiplePrintingQueueItemsWarning: method test_single_item_returns_item_no_warning (line 110) | def test_single_item_returns_item_no_warning(self, caplog): method test_multiple_items_warns_and_returns_first (line 135) | def test_multiple_items_warns_and_returns_first(self, caplog): method test_empty_list_returns_none_no_warning (line 166) | def test_empty_list_returns_none_no_warning(self, caplog): method test_three_items_warns_with_all_details (line 185) | def test_three_items_warns_with_all_details(self, caplog): class TestBusyPrinterSeedingFromPrintingItems (line 214) | class TestBusyPrinterSeedingFromPrintingItems: method test_seed_query_returns_printers_with_printing_items (line 226) | async def test_seed_query_returns_printers_with_printing_items(self): method test_seed_query_empty_when_no_printing_items (line 263) | async def test_seed_query_empty_when_no_printing_items(self): method test_check_queue_skips_printer_with_existing_printing_item (line 299) | async def test_check_queue_skips_printer_with_existing_printing_item(s... FILE: backend/tests/unit/test_plate_object_extraction.py class TestPlateObjectExtraction (line 6) | class TestPlateObjectExtraction: method test_extract_object_names_from_xml (line 9) | def test_extract_object_names_from_xml(self): method test_extract_object_names_missing_name (line 42) | def test_extract_object_names_missing_name(self): method test_extract_plate_object_associations (line 71) | def test_extract_plate_object_associations(self): method test_extract_plate_object_associations_empty_plate (line 115) | def test_extract_plate_object_associations_empty_plate(self): method test_object_count_matches_objects_length (line 145) | def test_object_count_matches_objects_length(self): method test_resolve_object_names_from_ids (line 152) | def test_resolve_object_names_from_ids(self): method test_resolve_object_names_missing_id (line 165) | def test_resolve_object_names_missing_id(self): method test_plate_id_alternatives (line 176) | def test_plate_id_alternatives(self): FILE: backend/tests/unit/test_print_log.py class TestPrintLogEntrySchema (line 10) | class TestPrintLogEntrySchema: method test_minimal_entry (line 13) | def test_minimal_entry(self): method test_full_entry (line 26) | def test_full_entry(self): method test_failed_status (line 51) | def test_failed_status(self): class TestPrintLogResponse (line 58) | class TestPrintLogResponse: method test_empty_response (line 61) | def test_empty_response(self): method test_paginated_response (line 67) | def test_paginated_response(self): class TestWriteLogEntry (line 75) | class TestWriteLogEntry: method test_duration_calculation (line 78) | def test_duration_calculation(self): method test_duration_none_when_missing_times (line 87) | def test_duration_none_when_missing_times(self): FILE: backend/tests/unit/test_print_speed.py class TestPrintSpeedAPI (line 13) | class TestPrintSpeedAPI: method test_print_speed_not_found (line 17) | async def test_print_speed_not_found(self, async_client: AsyncClient): method test_print_speed_not_connected (line 23) | async def test_print_speed_not_connected(self, async_client: AsyncClie... method test_print_speed_failure (line 36) | async def test_print_speed_failure(self, async_client: AsyncClient, pr... method test_print_speed_success (line 61) | async def test_print_speed_success(self, async_client: AsyncClient, pr... FILE: backend/tests/unit/test_print_start_expected_promotion.py function _clear_dicts (line 27) | def _clear_dicts(): class TestRegisterExpectedPrint (line 42) | class TestRegisterExpectedPrint: method test_registers_filename_and_variants (line 45) | def test_registers_filename_and_variants(self): method test_stores_ams_mapping (line 52) | def test_stores_ams_mapping(self): method test_no_ams_mapping_when_none (line 56) | def test_no_ams_mapping_when_none(self): method test_stores_creator (line 60) | def test_stores_creator(self): method test_stores_registered_at (line 64) | def test_stores_registered_at(self): class TestExpectedPrintDetection (line 73) | class TestExpectedPrintDetection: method _build_check_keys (line 82) | def _build_check_keys(printer_id: int, filename: str, subtask_name: str): method test_detects_expected_print_by_subtask (line 101) | def test_detects_expected_print_by_subtask(self): method test_detects_expected_print_by_filename (line 107) | def test_detects_expected_print_by_filename(self): method test_detects_expected_print_by_gcode_filename (line 113) | def test_detects_expected_print_by_gcode_filename(self): method test_no_false_positive_for_different_file (line 120) | def test_no_false_positive_for_different_file(self): method test_no_false_positive_for_different_printer (line 126) | def test_no_false_positive_for_different_printer(self): method test_empty_expected_prints_returns_false (line 132) | def test_empty_expected_prints_returns_false(self): method test_filename_with_spaces_and_parens (line 137) | def test_filename_with_spaces_and_parens(self): class TestExpectedPrintPromotion (line 148) | class TestExpectedPrintPromotion: method _simulate_expected_print_promotion (line 157) | def _simulate_expected_print_promotion(printer_id: int, subtask_name: ... method test_promotion_populates_active_prints (line 188) | def test_promotion_populates_active_prints(self): method test_promotion_cleans_up_expected_prints (line 202) | def test_promotion_cleans_up_expected_prints(self): method test_ams_mapping_survives_promotion (line 218) | def test_ams_mapping_survives_promotion(self): method test_completion_lookup_finds_promoted_archive (line 232) | def test_completion_lookup_finds_promoted_archive(self): method test_no_promotion_for_external_print (line 259) | def test_no_promotion_for_external_print(self): class TestAMSMappingInjection (line 272) | class TestAMSMappingInjection: method test_injection_into_session (line 275) | def test_injection_into_session(self): method test_no_injection_when_session_already_has_mapping (line 311) | def test_no_injection_when_session_already_has_mapping(self): FILE: backend/tests/unit/test_printer_models.py class TestGetRodType (line 16) | class TestGetRodType: method test_carbon_rod_models (line 20) | def test_carbon_rod_models(self, model: str): method test_carbon_rod_internal_codes (line 24) | def test_carbon_rod_internal_codes(self, model: str): method test_p2s_is_steel_rod (line 27) | def test_p2s_is_steel_rod(self): method test_p2s_internal_code_is_steel_rod (line 31) | def test_p2s_internal_code_is_steel_rod(self): method test_linear_rail_models (line 36) | def test_linear_rail_models(self, model: str): method test_linear_rail_internal_codes (line 40) | def test_linear_rail_internal_codes(self, model: str): method test_unknown_model_returns_none (line 43) | def test_unknown_model_returns_none(self): method test_none_returns_none (line 46) | def test_none_returns_none(self): method test_case_insensitive (line 49) | def test_case_insensitive(self): method test_strips_whitespace_and_dashes (line 54) | def test_strips_whitespace_and_dashes(self): class TestX2DModel (line 59) | class TestX2DModel: method test_x2d_is_steel_rod_display_name (line 68) | def test_x2d_is_steel_rod_display_name(self): method test_x2d_is_steel_rod_internal_code (line 71) | def test_x2d_is_steel_rod_internal_code(self): method test_x2d_model_id_map (line 74) | def test_x2d_model_id_map(self): method test_x2d_model_map (line 77) | def test_x2d_model_map(self): method test_x2d_has_ethernet_display_name (line 80) | def test_x2d_has_ethernet_display_name(self): method test_x2d_has_ethernet_internal_code (line 83) | def test_x2d_has_ethernet_internal_code(self): method test_x2d_supports_rtsp_display_name (line 86) | def test_x2d_supports_rtsp_display_name(self): method test_x2d_supports_rtsp_internal_code (line 89) | def test_x2d_supports_rtsp_internal_code(self): method test_x2d_camera_port_is_rtsp (line 92) | def test_x2d_camera_port_is_rtsp(self): method test_x2d_not_in_carbon_rod_set (line 96) | def test_x2d_not_in_carbon_rod_set(self): FILE: backend/tests/unit/test_run_with_retry.py function _force_sqlite (line 12) | def _force_sqlite(): function _make_locked_error (line 18) | def _make_locked_error() -> OperationalError: function _make_other_error (line 27) | def _make_other_error() -> OperationalError: function test_succeeds_on_first_attempt (line 37) | async def test_succeeds_on_first_attempt(): function test_retries_on_sqlite_locked (line 55) | async def test_retries_on_sqlite_locked(): function test_raises_after_max_attempts (line 84) | async def test_raises_after_max_attempts(): function test_non_lock_error_not_retried (line 104) | async def test_non_lock_error_not_retried(): function test_backoff_increases (line 131) | async def test_backoff_increases(): function test_postgres_no_retry (line 161) | async def test_postgres_no_retry(): function test_postgres_error_not_retried (line 182) | async def test_postgres_error_not_retried(): FILE: backend/tests/unit/test_scheduler_ams_mapping.py class TestSchedulerAmsMappingHelpers (line 13) | class TestSchedulerAmsMappingHelpers: method scheduler (line 17) | def scheduler(self): method test_normalize_color_with_hash (line 20) | def test_normalize_color_with_hash(self, scheduler): method test_normalize_color_without_hash (line 25) | def test_normalize_color_without_hash(self, scheduler): method test_normalize_color_with_alpha (line 30) | def test_normalize_color_with_alpha(self, scheduler): method test_normalize_color_none (line 35) | def test_normalize_color_none(self, scheduler): method test_normalize_color_empty (line 40) | def test_normalize_color_empty(self, scheduler): method test_normalize_color_for_compare (line 45) | def test_normalize_color_for_compare(self, scheduler): method test_normalize_color_for_compare_with_alpha (line 50) | def test_normalize_color_for_compare_with_alpha(self, scheduler): method test_colors_are_similar_exact_match (line 55) | def test_colors_are_similar_exact_match(self, scheduler): method test_colors_are_similar_within_threshold (line 59) | def test_colors_are_similar_within_threshold(self, scheduler): method test_colors_are_similar_outside_threshold (line 64) | def test_colors_are_similar_outside_threshold(self, scheduler): method test_colors_are_similar_none_colors (line 69) | def test_colors_are_similar_none_colors(self, scheduler): class TestBuildLoadedFilaments (line 75) | class TestBuildLoadedFilaments: method scheduler (line 79) | def scheduler(self): method test_build_loaded_filaments_empty_status (line 82) | def test_build_loaded_filaments_empty_status(self, scheduler): method test_build_loaded_filaments_with_ams (line 91) | def test_build_loaded_filaments_with_ams(self, scheduler): method test_build_loaded_filaments_with_ht_ams (line 121) | def test_build_loaded_filaments_with_ht_ams(self, scheduler): method test_build_loaded_filaments_with_external (line 139) | def test_build_loaded_filaments_with_external(self, scheduler): method test_build_loaded_filaments_skips_empty_trays (line 151) | def test_build_loaded_filaments_skips_empty_trays(self, scheduler): class TestMatchFilamentsToSlots (line 173) | class TestMatchFilamentsToSlots: method scheduler (line 177) | def scheduler(self): method test_match_empty_required (line 180) | def test_match_empty_required(self, scheduler): method test_match_exact_color (line 185) | def test_match_exact_color(self, scheduler): method test_match_similar_color (line 196) | def test_match_similar_color(self, scheduler): method test_match_type_only (line 206) | def test_match_type_only(self, scheduler): method test_match_no_match_returns_minus_one (line 216) | def test_match_no_match_returns_minus_one(self, scheduler): method test_match_multiple_filaments (line 226) | def test_match_multiple_filaments(self, scheduler): method test_match_avoids_duplicate_assignment (line 240) | def test_match_avoids_duplicate_assignment(self, scheduler): method test_match_h2d_pro_ams_ids (line 254) | def test_match_h2d_pro_ams_ids(self, scheduler): method test_match_external_spool (line 264) | def test_match_external_spool(self, scheduler): method test_match_by_tray_info_idx_priority (line 274) | def test_match_by_tray_info_idx_priority(self, scheduler): method test_match_by_tray_info_idx_with_different_colors (line 301) | def test_match_by_tray_info_idx_with_different_colors(self, scheduler): method test_match_fallback_to_color_when_no_tray_info_idx (line 317) | def test_match_fallback_to_color_when_no_tray_info_idx(self, scheduler): method test_match_fallback_to_color_when_no_matching_tray_info_idx (line 328) | def test_match_fallback_to_color_when_no_matching_tray_info_idx(self, ... method test_match_multiple_same_color_with_tray_info_idx (line 343) | def test_match_multiple_same_color_with_tray_info_idx(self, scheduler): method test_match_tray_info_idx_not_reused (line 364) | def test_match_tray_info_idx_not_reused(self, scheduler): method test_match_non_unique_tray_info_idx_uses_color (line 378) | def test_match_non_unique_tray_info_idx_uses_color(self, scheduler): method test_match_non_unique_tray_info_idx_same_color (line 399) | def test_match_non_unique_tray_info_idx_same_color(self, scheduler): class TestPreferLowestFilament (line 418) | class TestPreferLowestFilament: method scheduler (line 422) | def scheduler(self): method test_prefer_lowest_picks_lower_remain (line 425) | def test_prefer_lowest_picks_lower_remain(self, scheduler): method test_prefer_lowest_disabled_picks_first (line 436) | def test_prefer_lowest_disabled_picks_first(self, scheduler): method test_prefer_lowest_unknown_remain_sorted_last (line 447) | def test_prefer_lowest_unknown_remain_sorted_last(self, scheduler): method test_prefer_lowest_missing_remain_sorted_last (line 458) | def test_prefer_lowest_missing_remain_sorted_last(self, scheduler): method test_prefer_lowest_multiple_slots (line 469) | def test_prefer_lowest_multiple_slots(self, scheduler): method test_prefer_lowest_with_tray_info_idx (line 485) | def test_prefer_lowest_with_tray_info_idx(self, scheduler): method test_prefer_lowest_external_spool (line 496) | def test_prefer_lowest_external_spool(self, scheduler): class TestBuildLoadedFilamentsTrayInfoIdx (line 508) | class TestBuildLoadedFilamentsTrayInfoIdx: method scheduler (line 512) | def scheduler(self): method test_build_loaded_filaments_includes_tray_info_idx (line 515) | def test_build_loaded_filaments_includes_tray_info_idx(self, scheduler): method test_build_loaded_filaments_empty_tray_info_idx (line 536) | def test_build_loaded_filaments_empty_tray_info_idx(self, scheduler): method test_build_loaded_filaments_external_spool_tray_info_idx (line 555) | def test_build_loaded_filaments_external_spool_tray_info_idx(self, sch... function _make_3mf_zip (line 567) | def _make_3mf_zip( class TestExtractNozzleMappingFrom3mf (line 582) | class TestExtractNozzleMappingFrom3mf: method test_group_id_priority_over_filament_nozzle_map (line 585) | def test_group_id_priority_over_filament_nozzle_map(self): method test_fallback_to_filament_nozzle_map_without_group_id (line 613) | def test_fallback_to_filament_nozzle_map_without_group_id(self): method test_fallback_to_filament_nozzle_map_without_slice_info (line 632) | def test_fallback_to_filament_nozzle_map_without_slice_info(self): method test_single_nozzle_returns_none (line 644) | def test_single_nozzle_returns_none(self): method test_missing_project_settings_returns_none (line 656) | def test_missing_project_settings_returns_none(self): method test_missing_fields_returns_none (line 663) | def test_missing_fields_returns_none(self): method test_physical_extruder_map_remapping (line 670) | def test_physical_extruder_map_remapping(self): method test_single_active_extruder_maps_all_slots (line 683) | def test_single_active_extruder_maps_all_slots(self): method test_two_active_extruders_falls_through (line 709) | def test_two_active_extruders_falls_through(self): method test_missing_extruder_nozzle_stats_falls_through (line 733) | def test_missing_extruder_nozzle_stats_falls_through(self): method test_single_active_extruder_no_slice_info_returns_none (line 756) | def test_single_active_extruder_no_slice_info_returns_none(self): class TestNozzleAwareMapping (line 769) | class TestNozzleAwareMapping: method scheduler (line 773) | def scheduler(self): method test_dual_nozzle_matching (line 776) | def test_dual_nozzle_matching(self, scheduler): method test_nozzle_hard_filter_no_fallback (line 792) | def test_nozzle_hard_filter_no_fallback(self, scheduler): method test_no_nozzle_id_skips_filtering (line 805) | def test_no_nozzle_id_skips_filtering(self, scheduler): method test_extruder_id_in_loaded_filaments (line 818) | def test_extruder_id_in_loaded_filaments(self, scheduler): method test_extruder_id_none_without_map (line 835) | def test_extruder_id_none_without_map(self, scheduler): method test_external_spool_extruder_id (line 849) | def test_external_spool_extruder_id(self, scheduler): method test_external_spool_no_extruder_map (line 864) | def test_external_spool_no_extruder_map(self, scheduler): method test_dual_nozzle_with_tray_info_idx (line 874) | def test_dual_nozzle_with_tray_info_idx(self, scheduler): function _h2d_raw_data (line 893) | def _h2d_raw_data(): function _x1c_raw_data (line 945) | def _x1c_raw_data(): class TestH2DModel (line 982) | class TestH2DModel: method scheduler (line 986) | def scheduler(self): method test_build_loaded_filaments_h2d (line 989) | def test_build_loaded_filaments_h2d(self, scheduler): method test_external_spool_extruder_h2d (line 1022) | def test_external_spool_extruder_h2d(self, scheduler): method test_match_left_nozzle_only (line 1035) | def test_match_left_nozzle_only(self, scheduler): method test_match_right_nozzle_only (line 1049) | def test_match_right_nozzle_only(self, scheduler): method test_reject_cross_nozzle (line 1063) | def test_reject_cross_nozzle(self, scheduler): method test_dual_nozzle_multi_filament (line 1077) | def test_dual_nozzle_multi_filament(self, scheduler): method test_external_spool_matches_on_correct_nozzle (line 1093) | def test_external_spool_matches_on_correct_nozzle(self, scheduler): class TestX1CModel (line 1107) | class TestX1CModel: method scheduler (line 1111) | def scheduler(self): method test_build_loaded_filaments_x1c (line 1114) | def test_build_loaded_filaments_x1c(self, scheduler): method test_single_nozzle_no_filtering (line 1129) | def test_single_nozzle_no_filtering(self, scheduler): method test_tray_info_idx_matching_x1c (line 1143) | def test_tray_info_idx_matching_x1c(self, scheduler): method test_non_unique_tray_info_idx_color_match_x1c (line 1157) | def test_non_unique_tray_info_idx_color_match_x1c(self, scheduler): method test_multi_filament_x1c (line 1172) | def test_multi_filament_x1c(self, scheduler): FILE: backend/tests/unit/test_scheduler_auto_drying.py class TestConservativeDryingParams (line 19) | class TestConservativeDryingParams: method scheduler (line 23) | def scheduler(self): method test_single_filament_pla (line 26) | def test_single_filament_pla(self, scheduler): method test_mixed_filaments_lowest_temp (line 33) | def test_mixed_filaments_lowest_temp(self, scheduler): method test_mixed_filaments_longest_duration (line 42) | def test_mixed_filaments_longest_duration(self, scheduler): method test_empty_trays_returns_none (line 51) | def test_empty_trays_returns_none(self, scheduler): method test_unknown_filament_skipped (line 56) | def test_unknown_filament_skipped(self, scheduler): method test_filament_type_normalization (line 62) | def test_filament_type_normalization(self, scheduler): method test_empty_tray_type_skipped (line 70) | def test_empty_tray_type_skipped(self, scheduler): method test_n3s_uses_n3s_keys (line 78) | def test_n3s_uses_n3s_keys(self, scheduler): method test_n3f_uses_n3f_keys (line 85) | def test_n3f_uses_n3f_keys(self, scheduler): method test_custom_presets (line 92) | def test_custom_presets(self, scheduler): class TestDryingPresets (line 100) | class TestDryingPresets: method scheduler (line 104) | def scheduler(self): method test_default_presets_when_no_setting (line 108) | async def test_default_presets_when_no_setting(self, scheduler): method test_user_presets_from_db (line 119) | async def test_user_presets_from_db(self, scheduler): method test_invalid_json_falls_back (line 132) | async def test_invalid_json_falls_back(self, scheduler): method test_empty_string_falls_back (line 145) | async def test_empty_string_falls_back(self, scheduler): class TestSyncDryingState (line 158) | class TestSyncDryingState: method scheduler (line 162) | def scheduler(self): method test_removes_stopped_printers (line 166) | def test_removes_stopped_printers(self, mock_pm, scheduler): method test_keeps_active_printers (line 177) | def test_keeps_active_printers(self, mock_pm, scheduler): method test_removes_disconnected_printers (line 189) | def test_removes_disconnected_printers(self, mock_pm, scheduler): class TestStopDrying (line 198) | class TestStopDrying: method scheduler (line 202) | def scheduler(self): method test_stops_all_ams_units (line 207) | async def test_stops_all_ams_units(self, mock_pm, scheduler): method test_clears_tracking_when_no_state (line 231) | async def test_clears_tracking_when_no_state(self, mock_pm, scheduler): class TestMinimumDryingTime (line 240) | class TestMinimumDryingTime: method scheduler (line 244) | def scheduler(self): method test_no_stop_before_minimum_time (line 252) | async def test_no_stop_before_minimum_time(self, mock_sd, mock_pm, sch... method test_stops_after_minimum_time (line 308) | async def test_stops_after_minimum_time(self, mock_sd, mock_pm, schedu... method _make_setting (line 353) | def _make_setting(value): method _make_db_side_effect (line 359) | def _make_db_side_effect(settings_map, printer_id=1): class TestAutoStopOnFeatureDisabled (line 396) | class TestAutoStopOnFeatureDisabled: method scheduler (line 400) | def scheduler(self): method test_stops_drying_when_disabled (line 405) | async def test_stops_drying_when_disabled(self, mock_pm, scheduler): class TestAutoStopOnNoScheduledItems (line 432) | class TestAutoStopOnNoScheduledItems: method scheduler (line 436) | def scheduler(self): method _make_setting (line 440) | def _make_setting(value): method _make_db_side_effect (line 446) | def _make_db_side_effect(settings_map): method test_stops_when_no_scheduled_items (line 469) | async def test_stops_when_no_scheduled_items(self, mock_pm, scheduler): method test_stops_when_empty_queue (line 498) | async def test_stops_when_empty_queue(self, mock_pm, scheduler): class TestDryingTrackingTimestamps (line 519) | class TestDryingTrackingTimestamps: method test_initial_state_empty (line 522) | def test_initial_state_empty(self): method test_timestamp_is_monotonic (line 527) | def test_timestamp_is_monotonic(self): method test_timestamp_is_truthy (line 535) | def test_timestamp_is_truthy(self): class _DryingTestBase (line 543) | class _DryingTestBase: method _make_setting (line 547) | def _make_setting(value): method _make_db_side_effect (line 553) | def _make_db_side_effect(settings_map, printer_ids=None): class TestAmbientDrying (line 590) | class TestAmbientDrying(_DryingTestBase): method scheduler (line 594) | def scheduler(self): method test_ambient_dries_idle_printer_without_queue (line 600) | async def test_ambient_dries_idle_printer_without_queue(self, mock_sd,... method test_ambient_does_not_dry_below_threshold (line 642) | async def test_ambient_does_not_dry_below_threshold(self, mock_sd, moc... method test_ambient_off_stops_drying_without_queue (line 680) | async def test_ambient_off_stops_drying_without_queue(self, mock_pm, s... method test_ambient_continues_when_queue_empty (line 703) | async def test_ambient_continues_when_queue_empty(self, mock_sd, mock_... method test_queue_only_does_not_dry_without_scheduled_items (line 747) | async def test_queue_only_does_not_dry_without_scheduled_items(self, m... class TestBlockForDryingBugFix (line 785) | class TestBlockForDryingBugFix(_DryingTestBase): method scheduler (line 789) | def scheduler(self): method test_block_mode_allows_humidity_stop_for_active_drying (line 797) | async def test_block_mode_allows_humidity_stop_for_active_drying(self,... method test_block_mode_prevents_new_drying_start (line 846) | async def test_block_mode_prevents_new_drying_start(self, mock_sd, moc... FILE: backend/tests/unit/test_scheduler_busy_only.py class TestIsBusyOnly (line 6) | class TestIsBusyOnly: method test_single_busy (line 9) | def test_single_busy(self): method test_multiple_busy (line 12) | def test_multiple_busy(self): method test_busy_and_offline (line 15) | def test_busy_and_offline(self): method test_busy_and_filament (line 18) | def test_busy_and_filament(self): method test_offline_only (line 21) | def test_offline_only(self): method test_filament_only (line 24) | def test_filament_only(self): method test_no_matching_color (line 27) | def test_no_matching_color(self): method test_no_available_printers (line 30) | def test_no_available_printers(self): FILE: backend/tests/unit/test_scheduler_clear_plate.py class TestPrinterManagerPlateCleared (line 12) | class TestPrinterManagerPlateCleared: method manager (line 16) | def manager(self): method test_plate_cleared_initially_false (line 19) | def test_plate_cleared_initially_false(self, manager): method test_set_plate_cleared (line 24) | def test_set_plate_cleared(self, manager): method test_consume_plate_cleared (line 30) | def test_consume_plate_cleared(self, manager): method test_consume_plate_cleared_idempotent (line 37) | def test_consume_plate_cleared_idempotent(self, manager): method test_set_plate_cleared_multiple_printers (line 42) | def test_set_plate_cleared_multiple_printers(self, manager): method test_consume_only_affects_target_printer (line 50) | def test_consume_only_affects_target_printer(self, manager): class TestAwaitingPlateClearPersistence (line 59) | class TestAwaitingPlateClearPersistence: method test_load_rehydrates_in_memory_set_from_db (line 63) | async def test_load_rehydrates_in_memory_set_from_db(self): method test_persist_writes_flag_to_db (line 111) | async def test_persist_writes_flag_to_db(self): method test_persist_missing_printer_does_not_raise (line 156) | async def test_persist_missing_printer_does_not_raise(self): class TestSchedulerIdleCheckWithPlateCleared (line 176) | class TestSchedulerIdleCheckWithPlateCleared: method scheduler (line 180) | def scheduler(self): method test_idle_state_is_idle (line 184) | def test_idle_state_is_idle(self, mock_pm, scheduler): method test_running_state_not_idle (line 192) | def test_running_state_not_idle(self, mock_pm, scheduler): method test_finish_state_not_idle_when_awaiting (line 200) | def test_finish_state_not_idle_when_awaiting(self, mock_pm, scheduler): method test_finish_state_idle_when_acknowledged (line 208) | def test_finish_state_idle_when_acknowledged(self, mock_pm, scheduler): method test_failed_state_not_idle_when_awaiting (line 216) | def test_failed_state_not_idle_when_awaiting(self, mock_pm, scheduler): method test_failed_state_idle_when_acknowledged (line 224) | def test_failed_state_idle_when_acknowledged(self, mock_pm, scheduler): method test_idle_state_not_idle_when_awaiting_survives_power_cycle (line 232) | def test_idle_state_not_idle_when_awaiting_survives_power_cycle(self, ... method test_disconnected_printer_not_idle (line 243) | def test_disconnected_printer_not_idle(self, mock_pm, scheduler): method test_no_status_not_idle (line 248) | def test_no_status_not_idle(self, mock_pm, scheduler): method test_finish_state_idle_when_require_plate_clear_disabled (line 254) | def test_finish_state_idle_when_require_plate_clear_disabled(self, moc... method test_failed_state_idle_when_require_plate_clear_disabled (line 262) | def test_failed_state_idle_when_require_plate_clear_disabled(self, moc... method test_running_state_not_idle_even_when_require_plate_clear_disabled (line 269) | def test_running_state_not_idle_even_when_require_plate_clear_disabled... method test_idle_state_unaffected_by_require_plate_clear (line 276) | def test_idle_state_unaffected_by_require_plate_clear(self, mock_pm, s... class TestSchedulerQueueCheckLogging (line 283) | class TestSchedulerQueueCheckLogging: method scheduler (line 287) | def scheduler(self): method test_check_queue_logs_pending_items (line 292) | async def test_check_queue_logs_pending_items(self, mock_pm, scheduler... method test_check_queue_no_log_when_empty (line 326) | async def test_check_queue_no_log_when_empty(self, scheduler, caplog): FILE: backend/tests/unit/test_scheduler_filament_override.py class TestCountOverrideColorMatches (line 10) | class TestCountOverrideColorMatches: method scheduler (line 14) | def scheduler(self): method test_no_status_returns_zero (line 18) | def test_no_status_returns_zero(self, mock_pm, scheduler): method test_exact_match (line 26) | def test_exact_match(self, mock_pm, scheduler): method test_no_match (line 38) | def test_no_match(self, mock_pm, scheduler): method test_multiple_overrides_partial_match (line 50) | def test_multiple_overrides_partial_match(self, mock_pm, scheduler): method test_color_normalization (line 66) | def test_color_normalization(self, mock_pm, scheduler): method test_external_spool_match (line 79) | def test_external_spool_match(self, mock_pm, scheduler): class TestFilamentOverrideInMatching (line 92) | class TestFilamentOverrideInMatching: method scheduler (line 96) | def scheduler(self): method _apply_overrides (line 99) | def _apply_overrides(self, filament_reqs, overrides): method test_override_changes_color_match (line 110) | def test_override_changes_color_match(self, scheduler): method test_override_clears_tray_info_idx (line 131) | def test_override_clears_tray_info_idx(self, scheduler): method test_override_type_change (line 152) | def test_override_type_change(self, scheduler): method test_partial_override (line 171) | def test_partial_override(self, scheduler): method test_nozzle_filtering_with_override (line 198) | def test_nozzle_filtering_with_override(self, scheduler): FILE: backend/tests/unit/test_scheduler_watchdog.py function db_session (line 26) | async def db_session(): function _status (line 48) | def _status(state: str, subtask_id: str | None = None): class TestWatchdogExitsEarlyOnPickup (line 53) | class TestWatchdogExitsEarlyOnPickup: method test_exits_on_state_change (line 57) | async def test_exits_on_state_change(self, db_session): method test_exits_on_subtask_id_change_even_if_state_still_finish (line 79) | async def test_exits_on_subtask_id_change_even_if_state_still_finish(s... class TestWatchdogRevertsWhenStuck (line 106) | class TestWatchdogRevertsWhenStuck: method test_reverts_when_neither_state_nor_subtask_id_changes (line 110) | async def test_reverts_when_neither_state_nor_subtask_id_changes(self,... method test_default_timeout_is_90_seconds (line 139) | async def test_default_timeout_is_90_seconds(self): class TestWatchdogFallbackBehaviour (line 150) | class TestWatchdogFallbackBehaviour: method test_pre_subtask_id_none_falls_back_to_state_only (line 154) | async def test_pre_subtask_id_none_falls_back_to_state_only(self, db_s... method test_current_subtask_id_none_does_not_trigger_early_exit (line 181) | async def test_current_subtask_id_none_does_not_trigger_early_exit(sel... method test_printer_disconnected_returns_without_reverting (line 208) | async def test_printer_disconnected_returns_without_reverting(self, db... method test_no_revert_if_item_already_completed (line 231) | async def test_no_revert_if_item_already_completed(self, db_session): FILE: backend/tests/unit/test_slicer_settings.py class TestPreferredSlicerSchema (line 9) | class TestPreferredSlicerSchema: method test_default_value_is_bambu_studio (line 12) | def test_default_value_is_bambu_studio(self): method test_set_to_orcaslicer (line 17) | def test_set_to_orcaslicer(self): method test_set_to_bambu_studio_explicit (line 22) | def test_set_to_bambu_studio_explicit(self): method test_update_schema_default_is_none (line 27) | def test_update_schema_default_is_none(self): method test_update_schema_accepts_value (line 32) | def test_update_schema_accepts_value(self): method test_serialization_roundtrip (line 37) | def test_serialization_roundtrip(self): method test_partial_update_preserves_other_fields (line 44) | def test_partial_update_preserves_other_fields(self): FILE: backend/tests/unit/test_slot_preset_key.py function test_regular_ams_uses_global_tray_id (line 11) | def test_regular_ams_uses_global_tray_id(): function test_ams_ht_keyed_by_ams_id (line 19) | def test_ams_ht_keyed_by_ams_id(): function test_external_spool_uses_multiplied_id (line 27) | def test_external_spool_uses_multiplied_id(): FILE: backend/tests/unit/test_spool_schemas_rgba.py class TestSpoolCreateRgbaValidation (line 17) | class TestSpoolCreateRgbaValidation: method test_accepts_valid_8char_hex (line 20) | def test_accepts_valid_8char_hex(self): method test_accepts_lowercase_hex (line 24) | def test_accepts_lowercase_hex(self): method test_accepts_null_rgba (line 28) | def test_accepts_null_rgba(self): method test_rejects_7char_rgba (line 32) | def test_rejects_7char_rgba(self): method test_rejects_6char_rgba (line 37) | def test_rejects_6char_rgba(self): method test_rejects_non_hex_char (line 42) | def test_rejects_non_hex_char(self): class TestSpoolUpdateRgbaValidation (line 47) | class TestSpoolUpdateRgbaValidation: method test_accepts_valid_8char_hex (line 55) | def test_accepts_valid_8char_hex(self): method test_accepts_null_rgba (line 59) | def test_accepts_null_rgba(self): method test_accepts_missing_rgba (line 63) | def test_accepts_missing_rgba(self): method test_rejects_7char_rgba (line 68) | def test_rejects_7char_rgba(self): method test_rejects_9char_rgba (line 73) | def test_rejects_9char_rgba(self): method test_rejects_non_hex_char (line 77) | def test_rejects_non_hex_char(self): class TestSpoolResponseRgbaLeniency (line 82) | class TestSpoolResponseRgbaLeniency: method _make_response_kwargs (line 95) | def _make_response_kwargs(**overrides): method test_tolerates_7char_rgba_on_serialize (line 107) | def test_tolerates_7char_rgba_on_serialize(self): method test_tolerates_null_rgba (line 114) | def test_tolerates_null_rgba(self): method test_tolerates_non_hex_rgba (line 120) | def test_tolerates_non_hex_rgba(self): method test_passes_valid_rgba_through (line 127) | def test_passes_valid_rgba_through(self): FILE: backend/tests/unit/test_spoolbuddy_system_stats.py class TestCpuTemp (line 21) | class TestCpuTemp: method test_reads_thermal_zone (line 22) | def test_reads_thermal_zone(self): method test_returns_none_on_missing_file (line 26) | def test_returns_none_on_missing_file(self): method test_returns_none_on_bad_value (line 30) | def test_returns_none_on_bad_value(self): class TestMemoryInfo (line 35) | class TestMemoryInfo: method test_parses_meminfo (line 43) | def test_parses_meminfo(self): method test_returns_none_on_missing (line 52) | def test_returns_none_on_missing(self): class TestDiskInfo (line 57) | class TestDiskInfo: method test_returns_disk_stats (line 58) | def test_returns_disk_stats(self): class TestLoadAvg (line 69) | class TestLoadAvg: method test_returns_three_values (line 70) | def test_returns_three_values(self): class TestCpuCount (line 78) | class TestCpuCount: method test_returns_positive_int (line 79) | def test_returns_positive_int(self): class TestOsInfo (line 85) | class TestOsInfo: method test_returns_required_keys (line 86) | def test_returns_required_keys(self): method test_parses_pretty_name (line 93) | def test_parses_pretty_name(self): class TestSystemUptime (line 100) | class TestSystemUptime: method test_parses_uptime (line 101) | def test_parses_uptime(self): method test_returns_none_on_missing (line 105) | def test_returns_none_on_missing(self): class TestCollect (line 110) | class TestCollect: method test_returns_dict_with_expected_keys (line 111) | def test_returns_dict_with_expected_keys(self): method test_all_values_are_json_serializable (line 117) | def test_all_values_are_json_serializable(self): FILE: backend/tests/unit/test_spoolman_clear_location.py function _make_spool (line 21) | def _make_spool(spool_id: int, location: str, tag: str = "", extra: dict... function client (line 31) | def client(): class TestClearLocationForRemovedSpools (line 36) | class TestClearLocationForRemovedSpools: method test_clears_spool_no_longer_in_ams (line 40) | async def test_clears_spool_no_longer_in_ams(self, client): method test_keeps_spool_still_in_ams (line 55) | async def test_keeps_spool_still_in_ams(self, client): method test_skips_non_bambu_spools (line 70) | async def test_skips_non_bambu_spools(self, client): method test_skips_spools_from_other_printers (line 86) | async def test_skips_spools_from_other_printers(self, client): method test_synced_spool_ids_protects_location_matched_spools (line 101) | async def test_synced_spool_ids_protects_location_matched_spools(self,... method test_clears_only_removed_spools_in_mixed_set (line 119) | async def test_clears_only_removed_spools_in_mixed_set(self, client): method test_uuid_comparison_is_case_insensitive (line 138) | async def test_uuid_comparison_is_case_insensitive(self, client): method test_returns_zero_when_no_spools_at_printer (line 155) | async def test_returns_zero_when_no_spools_at_printer(self, client): method test_double_booking_scenario (line 166) | async def test_double_booking_scenario(self, client): FILE: backend/tests/unit/test_subtask_archive_resume.py function _extract_subtask_id (line 24) | def _extract_subtask_id(data: dict) -> str | None: class TestSubtaskIdExtraction (line 41) | class TestSubtaskIdExtraction: method test_valid_id_returns_string (line 44) | def test_valid_id_returns_string(self): method test_zero_collapses_to_none (line 47) | def test_zero_collapses_to_none(self): method test_empty_collapses_to_none (line 51) | def test_empty_collapses_to_none(self): method test_missing_raw_data (line 54) | def test_missing_raw_data(self): method test_missing_subtask_id (line 57) | def test_missing_subtask_id(self): method test_integer_value_stringified (line 60) | def test_integer_value_stringified(self): method test_whitespace_trimmed (line 64) | def test_whitespace_trimmed(self): class TestSubtaskIdResume (line 68) | class TestSubtaskIdResume: method archive_factory (line 73) | async def archive_factory(self, db_session, printer_factory): method test_subtask_id_query_finds_matching_printing_row (line 103) | async def test_subtask_id_query_finds_matching_printing_row(self, arch... method test_subtask_id_revives_stale_cancelled_row (line 120) | async def test_subtask_id_revives_stale_cancelled_row(self, archive_fa... method test_subtask_id_null_does_not_match_other_nulls (line 158) | async def test_subtask_id_null_does_not_match_other_nulls(self, archiv... method test_completed_archive_not_resumed (line 173) | async def test_completed_archive_not_resumed(self, archive_factory, db... FILE: backend/tests/unit/test_support_helpers.py class TestApplyLogLevel (line 15) | class TestApplyLogLevel: method test_debug_mode_suppresses_sqlalchemy_to_warning (line 18) | def test_debug_mode_suppresses_sqlalchemy_to_warning(self): method test_debug_mode_suppresses_aiosqlite (line 28) | def test_debug_mode_suppresses_aiosqlite(self): method test_debug_mode_keeps_httpx_pinned_to_warning (line 38) | def test_debug_mode_keeps_httpx_pinned_to_warning(self): method test_non_debug_mode_suppresses_all_noisy_loggers (line 50) | def test_non_debug_mode_suppresses_all_noisy_loggers(self): class TestAnonymizeMqttBroker (line 64) | class TestAnonymizeMqttBroker: method test_empty_string (line 67) | def test_empty_string(self): method test_ipv4_address (line 72) | def test_ipv4_address(self): method test_ipv6_address (line 77) | def test_ipv6_address(self): method test_hostname_with_domain (line 82) | def test_hostname_with_domain(self): method test_hostname_with_subdomain (line 87) | def test_hostname_with_subdomain(self): method test_single_part_hostname (line 92) | def test_single_part_hostname(self): class TestCheckPort (line 98) | class TestCheckPort: method test_reachable_port (line 103) | async def test_reachable_port(self): method test_unreachable_port (line 118) | async def test_unreachable_port(self): method test_timeout (line 137) | async def test_timeout(self): class TestGetContainerMemoryLimit (line 149) | class TestGetContainerMemoryLimit: method test_cgroup_v2_with_limit (line 152) | def test_cgroup_v2_with_limit(self): method test_cgroup_v2_unlimited (line 174) | def test_cgroup_v2_unlimited(self): method test_no_cgroup_files (line 191) | def test_no_cgroup_files(self): class TestFormatBytes (line 204) | class TestFormatBytes: method test_bytes (line 207) | def test_bytes(self): method test_kilobytes (line 212) | def test_kilobytes(self): method test_megabytes (line 217) | def test_megabytes(self): method test_gigabytes (line 222) | def test_gigabytes(self): method test_zero (line 227) | def test_zero(self): class TestSanitizeLogContent (line 233) | class TestSanitizeLogContent: method test_ipv4_addresses_redacted (line 236) | def test_ipv4_addresses_redacted(self): method test_multiple_ipv4_addresses_redacted (line 246) | def test_multiple_ipv4_addresses_redacted(self): method test_firmware_versions_with_leading_zeros_preserved (line 254) | def test_firmware_versions_with_leading_zeros_preserved(self): method test_firmware_version_mixed_with_ip (line 262) | def test_firmware_version_mixed_with_ip(self): method test_printer_ip_from_sensitive_strings (line 272) | def test_printer_ip_from_sensitive_strings(self): method test_edge_case_zero_ip (line 280) | def test_edge_case_zero_ip(self): method test_edge_case_broadcast_ip (line 288) | def test_edge_case_broadcast_ip(self): method test_invalid_octet_not_redacted (line 296) | def test_invalid_octet_not_redacted(self): method test_existing_serial_redaction_still_works (line 304) | def test_existing_serial_redaction_still_works(self): method test_existing_email_redaction_still_works (line 315) | def test_existing_email_redaction_still_works(self): method test_existing_path_redaction_still_works (line 324) | def test_existing_path_redaction_still_works(self): class TestCollectSupportInfo (line 334) | class TestCollectSupportInfo: method test_environment_has_timezone (line 339) | async def test_environment_has_timezone(self): method test_docker_section_present_when_in_docker (line 371) | async def test_docker_section_present_when_in_docker(self): method test_docker_section_absent_when_not_docker (line 409) | async def test_docker_section_absent_when_not_docker(self): method test_dependencies_section (line 439) | async def test_dependencies_section(self): method test_websockets_section (line 472) | async def test_websockets_section(self): method test_network_section (line 502) | async def test_network_section(self): method test_log_file_section (line 543) | async def test_log_file_section(self): method test_settings_include_all_keys_with_sensitive_redacted (line 584) | async def test_settings_include_all_keys_with_sensitive_redacted(self): FILE: backend/tests/unit/test_sync_ams_weights.py function _calc_weight_used (line 12) | def _calc_weight_used(label_weight: int | None, remain: int) -> float: function _is_valid_remain (line 18) | def _is_valid_remain(remain_raw) -> tuple[bool, int]: class TestWeightCalculation (line 35) | class TestWeightCalculation: method test_remain_100_means_no_usage (line 38) | def test_remain_100_means_no_usage(self): method test_remain_50_with_1000g_spool (line 42) | def test_remain_50_with_1000g_spool(self): method test_remain_0_means_fully_used (line 46) | def test_remain_0_means_fully_used(self): method test_respects_label_weight_500g (line 54) | def test_respects_label_weight_500g(self): method test_respects_label_weight_250g (line 58) | def test_respects_label_weight_250g(self): method test_none_label_weight_defaults_to_1000 (line 62) | def test_none_label_weight_defaults_to_1000(self): method test_result_is_rounded_to_one_decimal (line 66) | def test_result_is_rounded_to_one_decimal(self): method test_odd_fraction_rounds_correctly (line 73) | def test_odd_fraction_rounds_correctly(self): method test_small_spool_small_remain (line 77) | def test_small_spool_small_remain(self): class TestRemainValidation (line 82) | class TestRemainValidation: method test_remain_minus_1_is_invalid (line 85) | def test_remain_minus_1_is_invalid(self): method test_remain_101_is_invalid (line 90) | def test_remain_101_is_invalid(self): method test_remain_negative_large_is_invalid (line 95) | def test_remain_negative_large_is_invalid(self): method test_remain_200_is_invalid (line 100) | def test_remain_200_is_invalid(self): method test_remain_none_is_invalid (line 105) | def test_remain_none_is_invalid(self): method test_remain_non_numeric_string_is_invalid (line 110) | def test_remain_non_numeric_string_is_invalid(self): method test_remain_0_is_valid (line 115) | def test_remain_0_is_valid(self): method test_remain_100_is_valid (line 121) | def test_remain_100_is_valid(self): method test_remain_50_is_valid (line 127) | def test_remain_50_is_valid(self): method test_remain_string_number_is_valid (line 133) | def test_remain_string_number_is_valid(self): class TestFindTrayInAmsData (line 140) | class TestFindTrayInAmsData: method test_finds_matching_tray (line 143) | def test_finds_matching_tray(self): method test_returns_none_for_missing_ams_unit (line 158) | def test_returns_none_for_missing_ams_unit(self): method test_returns_none_for_missing_tray (line 163) | def test_returns_none_for_missing_tray(self): method test_returns_none_for_empty_data (line 168) | def test_returns_none_for_empty_data(self): method test_returns_none_for_none_data (line 172) | def test_returns_none_for_none_data(self): method test_multi_ams_unit_lookup (line 176) | def test_multi_ams_unit_lookup(self): method test_ams_ht_high_id (line 186) | def test_ams_ht_high_id(self): class TestSyncSkipLogic (line 194) | class TestSyncSkipLogic: method test_same_value_is_skipped (line 197) | def test_same_value_is_skipped(self): method test_different_value_is_synced (line 206) | def test_different_value_is_synced(self): method test_none_old_used_treated_as_zero (line 214) | def test_none_old_used_treated_as_zero(self): method test_remain_0_synced_not_skipped (line 222) | def test_remain_0_synced_not_skipped(self): method test_remain_minus_1_never_reaches_calc (line 233) | def test_remain_minus_1_never_reaches_calc(self): method test_remain_101_never_reaches_calc (line 239) | def test_remain_101_never_reaches_calc(self): FILE: backend/tests/unit/test_threemf_tools.py function create_mock_3mf (line 19) | def create_mock_3mf(slice_info_content: str) -> io.BytesIO: class TestParseGcodeLayerFilamentUsage (line 28) | class TestParseGcodeLayerFilamentUsage: method test_single_filament_single_layer (line 31) | def test_single_filament_single_layer(self): method test_multi_layer_single_filament (line 41) | def test_multi_layer_single_filament(self): method test_multi_material (line 56) | def test_multi_material(self): method test_retractions_ignored (line 77) | def test_retractions_ignored(self): method test_m620_s255_unloads (line 88) | def test_m620_s255_unloads(self): method test_m620_with_suffix (line 99) | def test_m620_with_suffix(self): method test_comments_ignored (line 110) | def test_comments_ignored(self): method test_empty_gcode (line 121) | def test_empty_gcode(self): method test_no_extrusion (line 126) | def test_no_extrusion(self): method test_no_active_filament_extrusion_ignored (line 134) | def test_no_active_filament_extrusion_ignored(self): method test_g0_g2_g3_extrusion (line 144) | def test_g0_g2_g3_extrusion(self): method test_cumulative_across_layers (line 156) | def test_cumulative_across_layers(self): class TestMmToGrams (line 172) | class TestMmToGrams: method test_default_pla_175 (line 175) | def test_default_pla_175(self): method test_zero_length (line 184) | def test_zero_length(self): method test_custom_diameter (line 188) | def test_custom_diameter(self): method test_custom_density (line 197) | def test_custom_density(self): method test_known_value (line 204) | def test_known_value(self): class TestGetCumulativeUsageAtLayer (line 216) | class TestGetCumulativeUsageAtLayer: method test_exact_layer_match (line 219) | def test_exact_layer_match(self): method test_between_layers (line 224) | def test_between_layers(self): method test_beyond_last_layer (line 230) | def test_beyond_last_layer(self): method test_before_first_layer (line 235) | def test_before_first_layer(self): method test_empty_data (line 240) | def test_empty_data(self): method test_none_data (line 244) | def test_none_data(self): method test_multi_filament (line 248) | def test_multi_filament(self): method test_layer_zero (line 258) | def test_layer_zero(self): class TestExtractFilamentUsageFrom3mf (line 264) | class TestExtractFilamentUsageFrom3mf: method test_extract_single_filament (line 267) | def test_extract_single_filament(self, tmp_path): method test_extract_multiple_filaments (line 286) | def test_extract_multiple_filaments(self, tmp_path): method test_extract_filament_with_plate_id (line 306) | def test_extract_filament_with_plate_id(self, tmp_path): method test_missing_slice_info_returns_empty (line 330) | def test_missing_slice_info_returns_empty(self, tmp_path): method test_invalid_file_returns_empty (line 344) | def test_invalid_file_returns_empty(self, tmp_path): method test_nonexistent_file_returns_empty (line 353) | def test_nonexistent_file_returns_empty(self, tmp_path): method test_filament_without_id_is_skipped (line 361) | def test_filament_without_id_is_skipped(self, tmp_path): method test_invalid_used_g_is_skipped (line 378) | def test_invalid_used_g_is_skipped(self, tmp_path): method test_missing_optional_fields (line 395) | def test_missing_optional_fields(self, tmp_path): FILE: backend/tests/unit/test_usage_tracker.py function _make_spool (line 26) | def _make_spool(spool_id=1, label_weight=1000, weight_used=0, tag_uid=No... function _make_assignment (line 40) | def _make_assignment(spool_id=1, printer_id=1, ams_id=0, tray_id=0): function _make_archive (line 50) | def _make_archive(archive_id=1, file_path="archives/1/test.3mf", extra_d... function _make_queue_item (line 59) | def _make_queue_item(ams_mapping=None, status="printing"): function _mock_db_execute (line 67) | def _mock_db_execute(*return_values): function _mock_db_sequential (line 79) | def _mock_db_sequential(responses): class TestOnPrintStart (line 100) | class TestOnPrintStart: method _clear_sessions (line 104) | def _clear_sessions(self): method test_captures_remain_data (line 110) | async def test_captures_remain_data(self): method test_captures_tray_now_at_start (line 126) | async def test_captures_tray_now_at_start(self): method test_tray_now_at_start_255_when_unloaded (line 139) | async def test_tray_now_at_start_255_when_unloaded(self): method test_creates_session_without_remain (line 152) | async def test_creates_session_without_remain(self): class TestOnPrintComplete (line 166) | class TestOnPrintComplete: method _clear_sessions (line 170) | def _clear_sessions(self): method _mock_get_setting (line 176) | def _mock_get_setting(self): method test_bl_spool_uses_3mf (line 185) | async def test_bl_spool_uses_3mf(self): method test_ams_delta_fallback_no_archive (line 239) | async def test_ams_delta_fallback_no_archive(self): method test_no_double_tracking (line 277) | async def test_no_double_tracking(self): class TestTrackFrom3mf (line 329) | class TestTrackFrom3mf: method test_prefers_live_assignment_when_reassigned_mid_print (line 333) | async def test_prefers_live_assignment_when_reassigned_mid_print(self): method test_keeps_snapshot_when_live_assignment_predates_print (line 384) | async def test_keeps_snapshot_when_live_assignment_predates_print(self): method test_linear_fallback_for_partial_print (line 434) | async def test_linear_fallback_for_partial_print(self): method test_per_layer_partial_print (line 486) | async def test_per_layer_partial_print(self): method test_completed_print_uses_full_weight (line 551) | async def test_completed_print_uses_full_weight(self): method test_tray_now_override_for_single_filament (line 596) | async def test_tray_now_override_for_single_filament(self): method test_queue_ams_mapping_overrides_default (line 648) | async def test_queue_ams_mapping_overrides_default(self): method test_multi_filament_uses_queue_mapping (line 699) | async def test_multi_filament_uses_queue_mapping(self): method test_no_tray_now_override_for_multi_filament (line 758) | async def test_no_tray_now_override_for_multi_filament(self): method test_stored_ams_mapping_overrides_all (line 809) | async def test_stored_ams_mapping_overrides_all(self): method test_last_loaded_tray_fallback (line 861) | async def test_last_loaded_tray_fallback(self): method test_tray_now_at_start_preferred_over_last_loaded (line 912) | async def test_tray_now_at_start_preferred_over_last_loaded(self): class TestTrayChangeSplit (line 960) | class TestTrayChangeSplit: method test_tray_switch_splits_weight_with_gcode (line 964) | async def test_tray_switch_splits_weight_with_gcode(self): method test_tray_switch_linear_fallback (line 1044) | async def test_tray_switch_linear_fallback(self): method test_no_tray_change_uses_normal_path (line 1105) | async def test_no_tray_change_uses_normal_path(self): method test_empty_tray_change_log_uses_normal_path (line 1157) | async def test_empty_tray_change_log_uses_normal_path(self): method test_tray_switch_segment_no_spool (line 1206) | async def test_tray_switch_segment_no_spool(self): method test_tray_switch_three_segments (line 1262) | async def test_tray_switch_three_segments(self): class TestDecodeMqttMapping (line 1340) | class TestDecodeMqttMapping: method test_none_input (line 1343) | def test_none_input(self): method test_empty_list (line 1346) | def test_empty_list(self): method test_all_unmapped (line 1349) | def test_all_unmapped(self): method test_single_ams_slots (line 1353) | def test_single_ams_slots(self): method test_multi_ams_slots (line 1357) | def test_multi_ams_slots(self): method test_ams_ht_slot (line 1361) | def test_ams_ht_slot(self): method test_external_spool (line 1365) | def test_external_spool(self): method test_mixed_with_unmapped (line 1370) | def test_mixed_with_unmapped(self): method test_h2c_real_mapping (line 1375) | def test_h2c_real_mapping(self): method test_non_int_values_treated_as_unmapped (line 1381) | def test_non_int_values_treated_as_unmapped(self): class TestMatchSlotsByColor (line 1386) | class TestMatchSlotsByColor: method _ams (line 1389) | def _ams(self, trays): method _usage (line 1396) | def _usage(self, slots): method test_none_inputs (line 1400) | def test_none_inputs(self): method test_empty_ams (line 1405) | def test_empty_ams(self): method test_single_slot_single_tray (line 1409) | def test_single_slot_single_tray(self): method test_a1_mini_three_colors (line 1415) | def test_a1_mini_three_colors(self): method test_dual_ams_p2s_like (line 1427) | def test_dual_ams_p2s_like(self): method test_ams_ht_global_id (line 1440) | def test_ams_ht_global_id(self): method test_ambiguous_same_color_returns_none (line 1451) | def test_ambiguous_same_color_returns_none(self): method test_no_matching_color_returns_none (line 1462) | def test_no_matching_color_returns_none(self): method test_color_normalization_strips_alpha (line 1468) | def test_color_normalization_strips_alpha(self): method test_case_insensitive (line 1474) | def test_case_insensitive(self): method test_empty_tray_color_skipped (line 1480) | def test_empty_tray_color_skipped(self): method test_empty_tray_type_skipped (line 1491) | def test_empty_tray_type_skipped(self): method test_short_slot_color_returns_none (line 1502) | def test_short_slot_color_returns_none(self): method test_slot_id_zero_skipped (line 1508) | def test_slot_id_zero_skipped(self): method test_ams_data_as_list (line 1514) | def test_ams_data_as_list(self): method test_same_color_two_trays_disambiguated_by_usage (line 1520) | def test_same_color_two_trays_disambiguated_by_usage(self): method test_dict_wrapper_with_ams_key (line 1534) | def test_dict_wrapper_with_ams_key(self): class TestMqttMappingIntegration (line 1541) | class TestMqttMappingIntegration: method test_h2c_multi_filament_uses_mqtt_mapping (line 1545) | async def test_h2c_multi_filament_uses_mqtt_mapping(self): method test_print_cmd_mapping_takes_priority_over_mqtt (line 1630) | async def test_print_cmd_mapping_takes_priority_over_mqtt(self): class TestNotificationVariables (line 1678) | class TestNotificationVariables: method test_filament_details_single_slot (line 1681) | def test_filament_details_single_slot(self): method test_filament_details_multi_slot (line 1692) | def test_filament_details_multi_slot(self): method test_filament_details_empty_type (line 1706) | def test_filament_details_empty_type(self): method test_filament_grams_scaled_for_partial (line 1717) | def test_filament_grams_scaled_for_partial(self): method test_filament_grams_zero_progress (line 1725) | def test_filament_grams_zero_progress(self): method test_slot_scaling_for_partial (line 1733) | def test_slot_scaling_for_partial(self): class TestOnPrintStartAmsMapping (line 1746) | class TestOnPrintStartAmsMapping: method _clear_sessions (line 1750) | def _clear_sessions(self): method test_captures_ams_mapping_from_data (line 1756) | async def test_captures_ams_mapping_from_data(self): method test_ams_mapping_none_when_not_in_data (line 1769) | async def test_ams_mapping_none_when_not_in_data(self): class TestFindThreemfByFilename (line 1782) | class TestFindThreemfByFilename: method test_finds_library_file (line 1786) | async def test_finds_library_file(self): method test_returns_none_for_empty_filename (line 1811) | async def test_returns_none_for_empty_filename(self): method test_falls_through_to_archive_search (line 1823) | async def test_falls_through_to_archive_search(self): method test_returns_none_when_nothing_found (line 1853) | async def test_returns_none_when_nothing_found(self): method test_strips_path_and_extensions (line 1868) | async def test_strips_path_and_extensions(self): class TestTrackFrom3mfWithPreresolvedPath (line 1885) | class TestTrackFrom3mfWithPreresolvedPath: method test_uses_preresolved_path_without_archive (line 1889) | async def test_uses_preresolved_path_without_archive(self): method test_skips_queue_lookup_without_archive_id (line 1935) | async def test_skips_queue_lookup_without_archive_id(self): FILE: backend/tests/unit/test_user_notifications.py class TestNotificationsUserEmailPermission (line 15) | class TestNotificationsUserEmailPermission: method test_permission_exists (line 18) | def test_permission_exists(self): method test_permission_in_all_permissions (line 23) | def test_permission_in_all_permissions(self): method test_permission_in_notifications_category (line 27) | def test_permission_in_notifications_category(self): method test_administrators_have_permission (line 32) | def test_administrators_have_permission(self): method test_operators_have_permission (line 37) | def test_operators_have_permission(self): method test_viewers_do_not_have_permission (line 42) | def test_viewers_do_not_have_permission(self): method test_permission_separate_from_notifications_read (line 47) | def test_permission_separate_from_notifications_read(self): class TestUserEmailPreferenceSchemas (line 53) | class TestUserEmailPreferenceSchemas: method test_response_schema_defaults (line 56) | def test_response_schema_defaults(self): method test_response_schema_all_disabled (line 69) | def test_response_schema_all_disabled(self): method test_update_schema_accepts_mixed (line 82) | def test_update_schema_accepts_mixed(self): method test_response_schema_from_attributes (line 95) | def test_response_schema_from_attributes(self): class TestNotificationTemplateTypes (line 100) | class TestNotificationTemplateTypes: method test_user_print_template_types_exist (line 103) | def test_user_print_template_types_exist(self): method test_user_print_template_display_names (line 116) | def test_user_print_template_display_names(self): FILE: backend/tests/unit/test_vp_ftp_port.py class TestFTPPort (line 6) | class TestFTPPort: method test_ftp_port_is_990 (line 9) | def test_ftp_port_is_990(self): FILE: backend/tests/unit/test_vp_mqtt_server.py class TestMQTTServerNoGlobalState (line 15) | class TestMQTTServerNoGlobalState: method test_no_global_exception_handler (line 18) | def test_no_global_exception_handler(self): function _make_server (line 37) | def _make_server(serial: str = "01P00A391800001") -> SimpleMQTTServer: class TestExtractSerialFromTopic (line 48) | class TestExtractSerialFromTopic: method test_valid_topics (line 59) | def test_valid_topics(self, topic, expected): method test_invalid_topics (line 72) | def test_invalid_topics(self, topic): function _build_publish_payload (line 76) | def _build_publish_payload(topic: str, message: dict) -> bytes: class TestPublishHandlerAdaptiveSerial (line 83) | class TestPublishHandlerAdaptiveSerial: method test_handle_publish_accepts_mismatched_serial (line 87) | def test_handle_publish_accepts_mismatched_serial(self): method test_handle_publish_ignores_non_request_topics (line 118) | def test_handle_publish_ignores_non_request_topics(self): method test_handle_publish_pushall_uses_client_serial (line 135) | def test_handle_publish_pushall_uses_client_serial(self): method test_handle_publish_tolerates_null_terminated_payload (line 155) | def test_handle_publish_tolerates_null_terminated_payload(self): class TestClientSerialLifecycle (line 179) | class TestClientSerialLifecycle: method test_stop_clears_client_serials (line 182) | def test_stop_clears_client_serials(self): FILE: frontend/docs/create_proxy_diagram.py function load_fonts (line 30) | def load_fonts(): function draw_rounded_rect (line 53) | def draw_rounded_rect(draw, xy, radius, fill=None, outline=None, width=1): function draw_lock_icon (line 77) | def draw_lock_icon(draw, x, y, size, color): function draw_computer_icon (line 94) | def draw_computer_icon(draw, x, y, size, color): function draw_server_icon (line 118) | def draw_server_icon(draw, x, y, size, color): function draw_printer_icon (line 130) | def draw_printer_icon(draw, x, y, size, color): function draw_cloud_icon (line 162) | def draw_cloud_icon(draw, x, y, size, color): function draw_arrow (line 178) | def draw_arrow(draw, x1, y1, x2, y2, color, width=2): function draw_bidirectional_arrow (line 195) | def draw_bidirectional_arrow(draw, x1, y1, x2, y2, color, width=2): function draw_tls_badge (line 228) | def draw_tls_badge(draw, x, y, fonts, color=TLS_BADGE_BG, text_color=BAM... function create_diagram (line 241) | def create_diagram(): function main (line 384) | def main(): FILE: frontend/public/sw.js constant CACHE_NAME (line 2) | const CACHE_NAME = 'bambuddy-v25'; constant STATIC_CACHE (line 3) | const STATIC_CACHE = 'bambuddy-static-v25'; constant STATIC_ASSETS (line 6) | const STATIC_ASSETS = [ FILE: frontend/scripts/check-i18n-parity.mjs function collectLeaves (line 23) | function collectLeaves(node, prefix, leaves) { function extractStringValue (line 53) | function extractStringValue(node, keyPath) { function loadLocale (line 70) | function loadLocale(filePath) { function compareLocales (line 107) | function compareLocales(locales) { constant STRICT (line 167) | const STRICT = ['de', 'zh-CN', 'zh-TW']; FILE: frontend/src/App.tsx class ErrorBoundary (line 37) | class ErrorBoundary extends Component<{ children: ReactNode }, { error: ... method getDerivedStateFromError (line 40) | static getDerivedStateFromError(error: Error) { method componentDidCatch (line 44) | componentDidCatch(error: Error, errorInfo: ErrorInfo) { method render (line 49) | render() { function StreamTokenSync (line 80) | function StreamTokenSync() { function WebSocketProvider (line 85) | function WebSocketProvider({ children }: { children: React.ReactNode }) { function ProtectedRoute (line 90) | function ProtectedRoute({ children }: { children: React.ReactNode }) { function AdminRoute (line 104) | function AdminRoute({ children }: { children: React.ReactNode }) { function SetupRoute (line 129) | function SetupRoute({ children }: { children: React.ReactNode }) { function App (line 146) | function App() { FILE: frontend/src/__tests__/api/githubBackupApi.test.ts constant API_BASE (line 15) | const API_BASE = 'http://localhost:5000/api/v1'; FILE: frontend/src/__tests__/components/BugReportBubble.test.tsx function getDescriptionTextarea (line 12) | function getDescriptionTextarea() { function getSubmitButton (line 16) | function getSubmitButton() { function setupLoggingEndpoints (line 26) | function setupLoggingEndpoints() { FILE: frontend/src/__tests__/components/FilamentHoverCard.test.tsx function renderWithHover (line 20) | function renderWithHover(ui: React.ReactElement) { FILE: frontend/src/__tests__/components/FilamentSlotCircle.test.tsx function expectColor (line 14) | function expectColor(actual: string, hex: string, rgb: string) { FILE: frontend/src/__tests__/components/PrinterSelector.test.ts function makeFilament (line 21) | function makeFilament(overrides: Partial & { globalTrayI... function makeReq (line 38) | function makeReq(overrides: Partial = {}): Filament... constant H2D_FILAMENTS (line 51) | const H2D_FILAMENTS: LoadedFilament[] = [ FILE: frontend/src/__tests__/components/spool-form/ColorSectionHexInput.test.tsx type UpdateField (line 30) | type UpdateField = ( function renderColorSection (line 35) | function renderColorSection(overrides: Partial =... function lastRgba (line 55) | function lastRgba(updateField: ReturnType): string | undef... FILE: frontend/src/__tests__/components/spoolbuddy/AmsUnitCard.test.tsx function makeTray (line 22) | function makeTray(overrides: Partial = {}): AMSTray { function makeUnit (line 43) | function makeUnit(overrides: Partial = {}): AMSUnit { FILE: frontend/src/__tests__/components/spoolbuddy/SpoolBuddyBottomNav.test.tsx function renderNav (line 20) | function renderNav() { FILE: frontend/src/__tests__/components/spoolbuddy/SpoolBuddyLayout.test.tsx function renderLayout (line 43) | function renderLayout() { FILE: frontend/src/__tests__/components/spoolbuddy/SpoolBuddyTopBar.test.tsx function renderTopBar (line 37) | function renderTopBar(deviceOnline = false) { FILE: frontend/src/__tests__/contexts/AuthContext.test.tsx function createWrapper (line 16) | function createWrapper() { FILE: frontend/src/__tests__/contexts/ColorCatalogContext.test.tsx function createWrapper (line 19) | function createWrapper() { FILE: frontend/src/__tests__/contexts/ToastContext.test.tsx function Wrapper (line 20) | function Wrapper({ children }: { children: ReactNode }) { FILE: frontend/src/__tests__/hooks/useFilamentMapping.test.ts function createPrinterStatus (line 16) | function createPrinterStatus(ams: PrinterStatus['ams'], vt_tray: Printer... function createH2DStatus (line 588) | function createH2DStatus(): PrinterStatus { function createX1CStatus (line 651) | function createX1CStatus(): PrinterStatus { FILE: frontend/src/__tests__/hooks/useSpoolBuddyState.test.ts function dispatchCustomEvent (line 12) | function dispatchCustomEvent(name: string, detail: Record; FILE: frontend/src/__tests__/pages/CameraPage.test.tsx function renderCameraPage (line 35) | function renderCameraPage(printerId: number) { FILE: frontend/src/__tests__/pages/InventoryPageGrouping.test.ts function spoolGroupKey (line 15) | function spoolGroupKey(s: InventorySpool): string { type DisplayItem (line 19) | type DisplayItem = function computeDisplayItems (line 24) | function computeDisplayItems( function makeSpool (line 62) | function makeSpool(overrides: Partial & { id: number }):... FILE: frontend/src/__tests__/pages/LoginPage.test.tsx function loginWith2FA (line 165) | async function loginWith2FA(twoFAMethods = ['totp', 'backup']) { FILE: frontend/src/__tests__/pages/PrintersPageDrying.test.ts constant DRYING_PRESETS (line 14) | const DRYING_PRESETS: Record = {}) { function renderPage (line 84) | function renderPage(contextOverrides: Record = {}) { FILE: frontend/src/__tests__/pages/SpoolBuddyDashboard.test.tsx function renderPage (line 63) | function renderPage(overrides: Partial( type Printer (line 116) | interface Printer { type HMSError (line 137) | interface HMSError { type AMSTray (line 144) | interface AMSTray { type AMSUnit (line 163) | interface AMSUnit { type NozzleInfo (line 178) | interface NozzleInfo { type NozzleRackSlot (line 183) | interface NozzleRackSlot { type PrintOptions (line 196) | interface PrintOptions { type PrinterStatus (line 216) | interface PrinterStatus { type PrinterCreate (line 304) | interface PrinterCreate { type PlateDetectionROI (line 321) | interface PlateDetectionROI { type PlateDetectionResult (line 328) | interface PlateDetectionResult { type PlateDetectionStatus (line 342) | interface PlateDetectionStatus { type CalibrationResult (line 350) | interface CalibrationResult { type PlateReference (line 355) | interface PlateReference { type ArchiveDuplicate (line 364) | interface ArchiveDuplicate { type Archive (line 371) | interface Archive { type ArchiveSlim (line 424) | interface ArchiveSlim { type PrintLogEntry (line 440) | interface PrintLogEntry { type PrintLogResponse (line 457) | interface PrintLogResponse { type ArchiveStats (line 462) | interface ArchiveStats { type TagInfo (line 481) | interface TagInfo { type FailureAnalysis (line 486) | interface FailureAnalysis { type BulkUploadResult (line 511) | interface BulkUploadResult { type ComparisonArchiveInfo (line 519) | interface ComparisonArchiveInfo { type ComparisonField (line 528) | interface ComparisonField { type SuccessCorrelationInsight (line 537) | interface SuccessCorrelationInsight { type SuccessCorrelation (line 547) | interface SuccessCorrelation { type ArchiveComparison (line 555) | interface ArchiveComparison { type SimilarArchive (line 562) | interface SimilarArchive { type ProjectStats (line 574) | interface ProjectStats { type ProjectChildPreview (line 595) | interface ProjectChildPreview { type Project (line 603) | interface Project { type ProjectAttachment (line 627) | interface ProjectAttachment { type ArchivePreview (line 634) | interface ArchivePreview { type ProjectListItem (line 643) | interface ProjectListItem { type ProjectCreate (line 662) | interface ProjectCreate { type ProjectUpdate (line 676) | interface ProjectUpdate { type BOMItem (line 692) | interface BOMItem { type BOMItemCreate (line 710) | interface BOMItemCreate { type BOMItemUpdate (line 720) | interface BOMItemUpdate { type BOMItemExport (line 732) | interface BOMItemExport { type LinkedFolderExport (line 742) | interface LinkedFolderExport { type ProjectExport (line 746) | interface ProjectExport { type ProjectImport (line 762) | interface ProjectImport { type TimelineEvent (line 779) | interface TimelineEvent { type APIKey (line 788) | interface APIKey { type APIKeyCreate (line 802) | interface APIKeyCreate { type APIKeyCreateResponse (line 811) | interface APIKeyCreateResponse extends APIKey { type APIKeyUpdate (line 815) | interface APIKeyUpdate { type AppSettings (line 826) | interface AppSettings { type AppSettingsUpdate (line 947) | type AppSettingsUpdate = Partial; type MQTTStatus (line 950) | interface MQTTStatus { type CloudAuthStatus (line 959) | interface CloudAuthStatus { type CloudLoginResponse (line 965) | interface CloudLoginResponse { type SlicerSetting (line 973) | interface SlicerSetting { type SpoolCatalogEntry (line 983) | interface SpoolCatalogEntry { type ColorCatalogEntry (line 990) | interface ColorCatalogEntry { type ColorLookupResult (line 999) | interface ColorLookupResult { type SlicerSettingsResponse (line 1005) | interface SlicerSettingsResponse { type SlicerSettingDetail (line 1011) | interface SlicerSettingDetail { type SlicerSettingCreate (line 1027) | interface SlicerSettingCreate { type SlicerSettingUpdate (line 1034) | interface SlicerSettingUpdate { type SlicerSettingDeleteResponse (line 1039) | interface SlicerSettingDeleteResponse { type BuiltinFilament (line 1045) | interface BuiltinFilament { type LocalPreset (line 1051) | interface LocalPreset { type LocalPresetDetail (line 1071) | interface LocalPresetDetail extends LocalPreset { type LocalPresetsResponse (line 1075) | interface LocalPresetsResponse { type ImportResponse (line 1081) | interface ImportResponse { type FieldOption (line 1088) | interface FieldOption { type FieldDefinition (line 1093) | interface FieldDefinition { type FieldDefinitionsResponse (line 1106) | interface FieldDefinitionsResponse { type CloudDevice (line 1112) | interface CloudDevice { type SmartPlug (line 1121) | interface SmartPlug { type SmartPlugCreate (line 1193) | interface SmartPlugCreate { type SmartPlugUpdate (line 1257) | interface SmartPlugUpdate { type HAEntity (line 1321) | interface HAEntity { type HASensorEntity (line 1329) | interface HASensorEntity { type HATestConnectionResult (line 1336) | interface HATestConnectionResult { type SmartPlugEnergy (line 1342) | interface SmartPlugEnergy { type SmartPlugStatus (line 1354) | interface SmartPlugStatus { type SmartPlugTestResult (line 1361) | interface SmartPlugTestResult { type TasmotaScanStatus (line 1368) | interface TasmotaScanStatus { type DiscoveredTasmotaDevice (line 1374) | interface DiscoveredTasmotaDevice { type PrintQueueItem (line 1383) | interface PrintQueueItem { type PrintBatch (line 1432) | interface PrintBatch { type PrintQueueItemCreate (line 1449) | interface PrintQueueItemCreate { type PrintQueueItemUpdate (line 1477) | interface PrintQueueItemUpdate { type PrintQueueBulkUpdate (line 1500) | interface PrintQueueBulkUpdate { type PrintQueueBulkUpdateResponse (line 1518) | interface PrintQueueBulkUpdateResponse { type MQTTLogEntry (line 1525) | interface MQTTLogEntry { type MQTTLogsResponse (line 1532) | interface MQTTLogsResponse { type KProfile (line 1538) | interface KProfile { type KProfileCreate (line 1552) | interface KProfileCreate { type KProfileDelete (line 1566) | interface KProfileDelete { type KProfilesResponse (line 1575) | interface KProfilesResponse { type KProfileNote (line 1580) | interface KProfileNote { type KProfileNotesResponse (line 1585) | interface KProfileNotesResponse { type SlotPresetMapping (line 1590) | interface SlotPresetMapping { type Filament (line 1598) | interface Filament { type ProviderType (line 1618) | type ProviderType = 'callmebot' | 'ntfy' | 'pushover' | 'telegram' | 'em... type NotificationProvider (line 1620) | interface NotificationProvider { type NotificationProviderCreate (line 1676) | interface NotificationProviderCreate { type NotificationProviderUpdate (line 1724) | interface NotificationProviderUpdate { type ScheduleType (line 1773) | type ScheduleType = 'hourly' | 'daily' | 'weekly'; type GitHubBackupConfig (line 1775) | interface GitHubBackupConfig { type GitHubBackupConfigCreate (line 1797) | interface GitHubBackupConfigCreate { type GitHubBackupLog (line 1811) | interface GitHubBackupLog { type GitHubBackupStatus (line 1823) | interface GitHubBackupStatus { type LocalBackupStatus (line 1833) | interface LocalBackupStatus { type LocalBackupFile (line 1847) | interface LocalBackupFile { type ObicoDetectionEvent (line 1853) | interface ObicoDetectionEvent { type ObicoStatus (line 1863) | interface ObicoStatus { type ObicoTestConnection (line 1877) | interface ObicoTestConnection { type GitHubTestConnectionResponse (line 1884) | interface GitHubTestConnectionResponse { type GitHubBackupTriggerResponse (line 1891) | interface GitHubBackupTriggerResponse { type NotificationTestRequest (line 1899) | interface NotificationTestRequest { type NotificationTestResponse (line 1904) | interface NotificationTestResponse { type BackgroundDispatchResponse (line 1909) | interface BackgroundDispatchResponse { type CallMeBotConfig (line 1919) | interface CallMeBotConfig { type NtfyConfig (line 1924) | interface NtfyConfig { type PushoverConfig (line 1930) | interface PushoverConfig { type TelegramConfig (line 1936) | interface TelegramConfig { type EmailConfig (line 1941) | interface EmailConfig { type NotificationTemplate (line 1952) | interface NotificationTemplate { type NotificationTemplateUpdate (line 1963) | interface NotificationTemplateUpdate { type EventVariablesResponse (line 1968) | interface EventVariablesResponse { type TemplatePreviewRequest (line 1974) | interface TemplatePreviewRequest { type TemplatePreviewResponse (line 1980) | interface TemplatePreviewResponse { type NotificationLogEntry (line 1986) | interface NotificationLogEntry { type NotificationLogStats (line 2001) | interface NotificationLogStats { type SpoolmanStatus (line 2010) | interface SpoolmanStatus { type SkippedSpool (line 2016) | interface SkippedSpool { type SpoolmanSyncResult (line 2023) | interface SpoolmanSyncResult { type UnlinkedSpool (line 2031) | interface UnlinkedSpool { type LinkedSpoolInfo (line 2041) | interface LinkedSpoolInfo { type LinkedSpoolsMap (line 2047) | interface LinkedSpoolsMap { type InventorySpool (line 2052) | interface InventorySpool { type SpoolUsageRecord (line 2084) | interface SpoolUsageRecord { type SpoolKProfile (line 2096) | interface SpoolKProfile { type SpoolKProfileInput (line 2110) | interface SpoolKProfileInput { type SpoolAssignment (line 2121) | interface SpoolAssignment { type VersionInfo (line 2137) | interface VersionInfo { type UpdateCheckResult (line 2142) | interface UpdateCheckResult { type UpdateStatus (line 2156) | interface UpdateStatus { type MaintenanceType (line 2164) | interface MaintenanceType { type MaintenanceTypeCreate (line 2176) | interface MaintenanceTypeCreate { type MaintenanceStatus (line 2185) | interface MaintenanceStatus { type PrinterMaintenanceOverview (line 2207) | interface PrinterMaintenanceOverview { type MaintenanceHistory (line 2217) | interface MaintenanceHistory { type MaintenanceSummary (line 2225) | interface MaintenanceSummary { type ExternalLink (line 2237) | interface ExternalLink { type ExternalLinkCreate (line 2249) | interface ExternalLinkCreate { type ExternalLinkUpdate (line 2256) | interface ExternalLinkUpdate { type Permission (line 2264) | type Permission = type GroupBrief (line 2298) | interface GroupBrief { type Group (line 2303) | interface Group { type GroupDetail (line 2314) | interface GroupDetail extends Group { type GroupCreate (line 2318) | interface GroupCreate { type GroupUpdate (line 2324) | interface GroupUpdate { type PermissionInfo (line 2330) | interface PermissionInfo { type PermissionCategory (line 2335) | interface PermissionCategory { type PermissionsListResponse (line 2340) | interface PermissionsListResponse { type UserEmailPreferences (line 2346) | interface UserEmailPreferences { type LoginRequest (line 2354) | interface LoginRequest { type LoginResponse (line 2359) | interface LoginResponse { type UserResponse (line 2369) | interface UserResponse { type UserCreate (line 2382) | interface UserCreate { type UserUpdate (line 2390) | interface UserUpdate { type SetupRequest (line 2399) | interface SetupRequest { type ForgotPasswordRequest (line 2405) | interface ForgotPasswordRequest { type ForgotPasswordResponse (line 2409) | interface ForgotPasswordResponse { type ResetPasswordRequest (line 2413) | interface ResetPasswordRequest { type ResetPasswordResponse (line 2417) | interface ResetPasswordResponse { type SMTPSettings (line 2421) | interface SMTPSettings { type TwoFAStatus (line 2433) | interface TwoFAStatus { type TOTPSetupResponse (line 2439) | interface TOTPSetupResponse { type TOTPEnableResponse (line 2445) | interface TOTPEnableResponse { type BackupCodesResponse (line 2450) | interface BackupCodesResponse { type TwoFAVerifyRequest (line 2455) | interface TwoFAVerifyRequest { type OIDCProvider (line 2462) | interface OIDCProvider { type OIDCProviderCreate (line 2474) | interface OIDCProviderCreate { type OIDCLink (line 2486) | interface OIDCLink { type TestSMTPRequest (line 2494) | interface TestSMTPRequest { type TestSMTPResponse (line 2498) | interface TestSMTPResponse { type AdvancedAuthStatus (line 2503) | interface AdvancedAuthStatus { type LDAPStatus (line 2508) | interface LDAPStatus { type LDAPTestResponse (line 2513) | interface LDAPTestResponse { type SetupResponse (line 2518) | interface SetupResponse { type AuthStatus (line 2523) | interface AuthStatus { type AMSHistoryPoint (line 4792) | interface AMSHistoryPoint { type AMSHistoryResponse (line 4799) | interface AMSHistoryResponse { type SystemInfo (line 4812) | interface SystemInfo { type StorageUsageCategory (line 4884) | interface StorageUsageCategory { type StorageUsageOtherItem (line 4892) | interface StorageUsageOtherItem { type StorageUsageResponse (line 4902) | interface StorageUsageResponse { type LibraryFolderTree (line 4918) | interface LibraryFolderTree { type LibraryFolder (line 4933) | interface LibraryFolder { type LibraryFolderCreate (line 4950) | interface LibraryFolderCreate { type ExternalFolderCreate (line 4957) | interface ExternalFolderCreate { type LibraryFolderUpdate (line 4965) | interface LibraryFolderUpdate { type LibraryFileDuplicate (line 4972) | interface LibraryFileDuplicate { type LibraryFile (line 4980) | interface LibraryFile { type LibraryFileListItem (line 5011) | interface LibraryFileListItem { type LibraryFileUpdate (line 5031) | interface LibraryFileUpdate { type LibraryFileUploadResponse (line 5038) | interface LibraryFileUploadResponse { type LibraryStats (line 5048) | interface LibraryStats { type ZipExtractResult (line 5059) | interface ZipExtractResult { type ZipExtractError (line 5065) | interface ZipExtractError { type ZipExtractResponse (line 5070) | interface ZipExtractResponse { type BatchThumbnailResult (line 5078) | interface BatchThumbnailResult { type BatchThumbnailResponse (line 5085) | interface BatchThumbnailResponse { type AddToQueueResult (line 5093) | interface AddToQueueResult { type AddToQueueError (line 5100) | interface AddToQueueError { type AddToQueueResponse (line 5106) | interface AddToQueueResponse { type DiscoveredPrinter (line 5112) | interface DiscoveredPrinter { type DiscoveryStatus (line 5120) | interface DiscoveryStatus { type DiscoveryInfo (line 5124) | interface DiscoveryInfo { type SubnetScanStatus (line 5131) | interface SubnetScanStatus { type VirtualPrinterMode (line 5166) | type VirtualPrinterMode = 'immediate' | 'queue' | 'review' | 'print_queu... type VirtualPrinterProxyStatus (line 5168) | interface VirtualPrinterProxyStatus { type VirtualPrinterStatus (line 5177) | interface VirtualPrinterStatus { type VirtualPrinterSettings (line 5190) | interface VirtualPrinterSettings { type NetworkInterface (line 5200) | interface NetworkInterface { type VirtualPrinterModels (line 5209) | interface VirtualPrinterModels { type PendingUpload (line 5214) | interface PendingUpload { type VirtualPrinterConfig (line 5255) | interface VirtualPrinterConfig { type VirtualPrinterListResponse (line 5272) | interface VirtualPrinterListResponse { type AvailableFirmwareVersion (line 5345) | interface AvailableFirmwareVersion { type FirmwareUpdateInfo (line 5353) | interface FirmwareUpdateInfo { type FirmwareUploadPrepare (line 5365) | interface FirmwareUploadPrepare { type FirmwareUploadStatus (line 5379) | interface FirmwareUploadStatus { type DebugLoggingState (line 5412) | interface DebugLoggingState { type LogEntry (line 5418) | interface LogEntry { type LogsResponse (line 5425) | interface LogsResponse { type SpoolBuddyDevice (line 5482) | interface SpoolBuddyDevice { type DaemonUpdateCheck (line 5518) | interface DaemonUpdateCheck { type BugReportRequest (line 5610) | interface BugReportRequest { type BugReportResponse (line 5618) | interface BugReportResponse { FILE: frontend/src/components/AMSHistoryModal.tsx type AMSHistoryModalProps (line 20) | interface AMSHistoryModalProps { type TimeRange (line 36) | type TimeRange = '6h' | '24h' | '48h' | '7d'; constant TIME_RANGES (line 38) | const TIME_RANGES: { value: TimeRange; label: string; hours: number }[] = [ function AMSHistoryModal (line 45) | function AMSHistoryModal({ FILE: frontend/src/components/APIBrowser.tsx type OpenAPISchema (line 6) | interface OpenAPISchema { type EndpointSpec (line 13) | interface EndpointSpec { type ParameterSpec (line 28) | interface ParameterSpec { type SchemaSpec (line 40) | interface SchemaSpec { type ResponseSpec (line 55) | interface ResponseSpec { type APIResponse (line 64) | interface APIResponse { constant METHOD_COLORS (line 72) | const METHOD_COLORS: Record = { function resolveRef (line 80) | function resolveRef(schema: OpenAPISchema, ref: string): SchemaSpec { function getSchemaExample (line 90) | function getSchemaExample(schema: OpenAPISchema, spec: SchemaSpec, depth... type EndpointItemProps (line 136) | interface EndpointItemProps { function EndpointItem (line 144) | function EndpointItem({ path, method, spec, schema, apiKey }: EndpointIt... type APIBrowserProps (line 465) | interface APIBrowserProps { function APIBrowser (line 469) | function APIBrowser({ apiKey = '' }: APIBrowserProps) { FILE: frontend/src/components/AddExternalLinkModal.tsx type AddExternalLinkModalProps (line 9) | interface AddExternalLinkModalProps { function AddExternalLinkModal (line 14) | function AddExternalLinkModal({ link, onClose }: AddExternalLinkModalPro... FILE: frontend/src/components/AddNotificationModal.tsx type AddNotificationModalProps (line 10) | interface AddNotificationModalProps { constant PROVIDER_VALUES (line 15) | const PROVIDER_VALUES: ProviderType[] = ['email', 'telegram', 'discord',... function AddNotificationModal (line 17) | function AddNotificationModal({ provider, onClose }: AddNotificationModa... FILE: frontend/src/components/AddSmartPlugModal.tsx type AddSmartPlugModalProps (line 9) | interface AddSmartPlugModalProps { function AddSmartPlugModal (line 14) | function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) { FILE: frontend/src/components/AssignSpoolModal.tsx type AssignSpoolModalProps (line 11) | interface AssignSpoolModalProps { function AssignSpoolModal (line 26) | function AssignSpoolModal({ isOpen, onClose, printerId, amsId, trayId, t... FILE: frontend/src/components/BackupModal.tsx type BackupCategory (line 8) | interface BackupCategory { constant BACKUP_CATEGORIES (line 18) | const BACKUP_CATEGORIES: BackupCategory[] = [ type BackupModalProps (line 126) | interface BackupModalProps { function BackupModal (line 131) | function BackupModal({ onClose, onExport }: BackupModalProps) { FILE: frontend/src/components/BatchProjectModal.tsx type BatchProjectModalProps (line 9) | interface BatchProjectModalProps { function BatchProjectModal (line 14) | function BatchProjectModal({ selectedIds, onClose }: BatchProjectModalPr... FILE: frontend/src/components/BatchTagModal.tsx type BatchTagModalProps (line 9) | interface BatchTagModalProps { function BatchTagModal (line 15) | function BatchTagModal({ selectedIds, existingTags, onClose }: BatchTagM... FILE: frontend/src/components/BugReportBubble.tsx type ViewState (line 6) | type ViewState = 'form' | 'logging' | 'stopping' | 'submitting' | 'succe... constant MAX_DIMENSION (line 8) | const MAX_DIMENSION = 1920; constant JPEG_QUALITY (line 9) | const JPEG_QUALITY = 0.7; constant MAX_LOG_SECONDS (line 10) | const MAX_LOG_SECONDS = 300; function compressImage (line 12) | function compressImage(file: File): Promise { function formatElapsed (line 36) | function formatElapsed(seconds: number): string { function BugReportBubble (line 42) | function BugReportBubble() { FILE: frontend/src/components/BulkPrinterToolbar.tsx type BulkAction (line 18) | type BulkAction = 'stop' | 'pause' | 'resume' | 'clearPlate' | 'clearHMS'; type PrinterState (line 19) | type PrinterState = 'printing' | 'paused' | 'finished' | 'idle' | 'error... type PrinterStatus (line 21) | interface PrinterStatus { type BulkPrinterToolbarProps (line 28) | interface BulkPrinterToolbarProps { constant STATE_OPTIONS (line 39) | const STATE_OPTIONS: { key: PrinterState; dot: string }[] = [ function BulkPrinterToolbar (line 48) | function BulkPrinterToolbar({ FILE: frontend/src/components/Button.tsx type ButtonProps (line 3) | interface ButtonProps extends ButtonHTMLAttributes { function Button (line 9) | function Button({ FILE: frontend/src/components/CalendarView.tsx type CalendarViewProps (line 7) | interface CalendarViewProps { function getDaysInMonth (line 13) | function getDaysInMonth(year: number, month: number): number { function getFirstDayOfMonth (line 17) | function getFirstDayOfMonth(year: number, month: number): number { constant MONTH_NAMES (line 21) | const MONTH_NAMES = [ constant DAY_NAMES (line 26) | const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; function CalendarView (line 28) | function CalendarView({ archives, onArchiveClick, highlightedArchiveId }... FILE: frontend/src/components/Card.tsx type CardDensity (line 4) | type CardDensity = 'normal' | 'dense'; function CardDensityProvider (line 8) | function CardDensityProvider({ density, children }: { density: CardDensi... type CardProps (line 12) | interface CardProps extends HTMLAttributes { type CardSectionProps (line 19) | interface CardSectionProps { function Card (line 25) | function Card({ children, className = '', onClick, onContextMenu, ...res... function CardHeader (line 38) | function CardHeader({ children, className = '', dense }: CardSectionProp... function CardContent (line 49) | function CardContent({ children, className = '', dense }: CardSectionPro... FILE: frontend/src/components/Collapsible.tsx type CollapsibleProps (line 5) | interface CollapsibleProps { function Collapsible (line 27) | function Collapsible({ FILE: frontend/src/components/ColorCatalogSettings.tsx function ColorCatalogSettings (line 10) | function ColorCatalogSettings() { FILE: frontend/src/components/ColumnConfigModal.tsx type ColumnConfig (line 7) | interface ColumnConfig { type ColumnConfigModalProps (line 13) | interface ColumnConfigModalProps { function ColumnConfigModal (line 21) | function ColumnConfigModal({ isOpen, onClose, columns, defaultColumns, o... FILE: frontend/src/components/CompactHistoryRow.tsx constant STATUS_CONFIG (line 17) | const STATUS_CONFIG = { function CompactHistoryRow (line 24) | function CompactHistoryRow({ FILE: frontend/src/components/CompareArchivesModal.tsx type CompareArchivesModalProps (line 8) | interface CompareArchivesModalProps { function CompareArchivesModal (line 13) | function CompareArchivesModal({ archiveIds, onClose }: CompareArchivesMo... function ComparisonContent (line 74) | function ComparisonContent({ comparison }: { comparison: ArchiveComparis... FILE: frontend/src/components/ConfigureAmsSlotModal.tsx type SlotInfo (line 9) | interface SlotInfo { function getAmsLabel (line 23) | function getAmsLabel(amsId: number, trayCount: number): string { function convertToTrayInfoIdx (line 53) | function convertToTrayInfoIdx(settingId: string): string { type ConfigureAmsSlotModalProps (line 72) | interface ConfigureAmsSlotModalProps { constant MATERIAL_TYPES (line 84) | const MATERIAL_TYPES = ['PLA', 'PETG', 'PCTG', 'ABS', 'ASA', 'TPU', 'PC'... function parsePresetName (line 87) | function parsePresetName(name: string): { material: string; brand: strin... function isUserPreset (line 129) | function isUserPreset(settingId: string): boolean { constant COLOR_NAME_MAP (line 135) | const COLOR_NAME_MAP: Record = { constant QUICK_COLORS_BASIC (line 186) | const QUICK_COLORS_BASIC = [ constant QUICK_COLORS_EXTENDED (line 198) | const QUICK_COLORS_EXTENDED = [ function colorNameToHex (line 226) | function colorNameToHex(name: string): string | null { function extractPresetModel (line 232) | function extractPresetModel(name: string): string | null { function ConfigureAmsSlotModal (line 241) | function ConfigureAmsSlotModal({ FILE: frontend/src/components/ConfirmModal.tsx type ConfirmModalProps (line 7) | interface ConfirmModalProps { function ConfirmModal (line 21) | function ConfirmModal({ FILE: frontend/src/components/ContextMenu.tsx type ContextMenuItem (line 4) | interface ContextMenuItem { type ContextMenuProps (line 15) | interface ContextMenuProps { function ContextMenu (line 22) | function ContextMenu({ x, y, items, onClose }: ContextMenuProps) { FILE: frontend/src/components/CreateUserAdvancedAuthModal.tsx type AdvancedAuthFormData (line 8) | interface AdvancedAuthFormData extends UserCreate { type CreateUserAdvancedAuthModalProps (line 14) | interface CreateUserAdvancedAuthModalProps { function CreateUserAdvancedAuthModal (line 24) | function CreateUserAdvancedAuthModal({ FILE: frontend/src/components/Dashboard.tsx type DashboardWidget (line 22) | interface DashboardWidget { type DashboardProps (line 31) | interface DashboardProps { type LayoutState (line 46) | interface LayoutState { function SortableWidget (line 52) | function SortableWidget({ function Dashboard (line 141) | function Dashboard({ widgets, storageKey, columns = 4, stackBelow, hideC... FILE: frontend/src/components/EditArchiveModal.tsx constant FAILURE_REASON_KEYS (line 10) | const FAILURE_REASON_KEYS = [ constant ARCHIVE_STATUS_KEYS (line 25) | const ARCHIVE_STATUS_KEYS = ['completed', 'failed', 'aborted', 'printing... type EditArchiveModalProps (line 27) | interface EditArchiveModalProps { function EditArchiveModal (line 33) | function EditArchiveModal({ archive, onClose, existingTags = [] }: EditA... FILE: frontend/src/components/EmailSettings.tsx constant SECURITY_PORT_MAP (line 13) | const SECURITY_PORT_MAP: Record = { constant PORT_SECURITY_MAP (line 19) | const PORT_SECURITY_MAP: Record = { function EmailSettings (line 25) | function EmailSettings() { FILE: frontend/src/components/EmbeddedCameraViewer.tsx type EmbeddedCameraViewerProps (line 11) | interface EmbeddedCameraViewerProps { constant STORAGE_KEY_PREFIX (line 18) | const STORAGE_KEY_PREFIX = 'embeddedCameraState_'; constant MAX_RECONNECT_ATTEMPTS (line 19) | const MAX_RECONNECT_ATTEMPTS = 5; constant INITIAL_RECONNECT_DELAY (line 20) | const INITIAL_RECONNECT_DELAY = 2000; constant MAX_RECONNECT_DELAY (line 21) | const MAX_RECONNECT_DELAY = 30000; constant STALL_CHECK_INTERVAL (line 22) | const STALL_CHECK_INTERVAL = 5000; type CameraState (line 24) | interface CameraState { constant DEFAULT_STATE (line 31) | const DEFAULT_STATE: CameraState = { function EmbeddedCameraViewer (line 38) | function EmbeddedCameraViewer({ printerId, printerName, viewerIndex = 0,... FILE: frontend/src/components/ExternalLinksSettings.tsx function ExternalLinksSettings (line 13) | function ExternalLinksSettings() { FILE: frontend/src/components/FailureDetectionSettings.tsx type TestResult (line 11) | type TestResult = { ok: boolean; message: string } | null; function FailureDetectionSettings (line 13) | function FailureDetectionSettings() { FILE: frontend/src/components/FilamentHoverCard.tsx type FilamentData (line 6) | interface FilamentData { type SpoolmanConfig (line 18) | interface SpoolmanConfig { type InventoryConfig (line 27) | interface InventoryConfig { type ConfigureSlotConfig (line 33) | interface ConfigureSlotConfig { type FilamentHoverCardProps (line 38) | interface FilamentHoverCardProps { function FilamentHoverCard (line 52) | function FilamentHoverCard({ data, children, disabled, className = '', s... type EmptySlotHoverCardProps (line 467) | interface EmptySlotHoverCardProps { function EmptySlotHoverCard (line 477) | function EmptySlotHoverCard({ children, className = '', configureSlot, i... FILE: frontend/src/components/FilamentSlotCircle.tsx type FilamentSlotCircleProps (line 14) | interface FilamentSlotCircleProps { function isLightFilamentColor (line 21) | function isLightFilamentColor(hex: string): boolean { function FilamentSlotCircle (line 29) | function FilamentSlotCircle({ trayColor, trayType, isEmpty, slotNumber }... FILE: frontend/src/components/FilamentTrends.tsx type FilamentTrendsProps (line 20) | interface FilamentTrendsProps { constant COLORS (line 27) | const COLORS = ['#00ae42', '#3b82f6', '#f59e0b', '#ef4444', '#8b5cf6', '... constant DAY_NAMES (line 29) | const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; constant HOUR_SUFFIXES (line 30) | const HOUR_SUFFIXES = ['12am', '1am', '2am', '3am', '4am', '5am', '6am',... function FilamentTrends (line 32) | function FilamentTrends({ archives, currency = '$', dateFrom, dateTo }: ... FILE: frontend/src/components/FileManagerModal.tsx type FileManagerModalProps (line 35) | interface FileManagerModalProps { type PrinterViewerTab (line 41) | type PrinterViewerTab = '3d' | 'gcode'; type PrinterFileViewerModalProps (line 43) | interface PrinterFileViewerModalProps { function PrinterFileViewerModal (line 50) | function PrinterFileViewerModal({ printerId, filePath, filename, onClose... function formatStorageSize (line 240) | function formatStorageSize(bytes: number): string { function getFileIcon (line 250) | function getFileIcon(filename: string, isDirectory: boolean) { type SortOption (line 271) | type SortOption = 'name-asc' | 'name-desc' | 'size-asc' | 'size-desc' | ... constant SORT_OPTIONS (line 273) | const SORT_OPTIONS: { value: SortOption; label: string }[] = [ function FileManagerModal (line 282) | function FileManagerModal({ printerId, printerName, onClose }: FileManag... FILE: frontend/src/components/FileUploadModal.tsx type UploadFile (line 18) | interface UploadFile { type FileUploadModalProps (line 27) | interface FileUploadModalProps { function FileUploadModal (line 41) | function FileUploadModal({ folderId, onClose, onUploadComplete, onFileUp... FILE: frontend/src/components/GcodeViewer.tsx type GcodeViewerProps (line 6) | interface GcodeViewerProps { function GcodeViewer (line 13) | function GcodeViewer({ FILE: frontend/src/components/GitHubBackupSettings.tsx function formatDateTime (line 43) | function formatDateTime(dateStr: string | null): string { type StatusBadgeProps (line 50) | interface StatusBadgeProps { function StatusBadge (line 54) | function StatusBadge({ status }: StatusBadgeProps) { function GitHubBackupSettings (line 79) | function GitHubBackupSettings() { FILE: frontend/src/components/HMSErrorModal.tsx type HMSErrorModalProps (line 11) | interface HMSErrorModalProps { constant ERROR_DESCRIPTIONS (line 21) | const ERROR_DESCRIPTIONS: Record = { function getSeverityInfo (line 877) | function getSeverityInfo(severity: number): { label: string; color: stri... function getShortCode (line 891) | function getShortCode(attr: number, code: number): string { function filterKnownHMSErrors (line 900) | function filterKnownHMSErrors(errors: HMSError[]): HMSError[] { function getHMSHomeUrl (line 908) | function getHMSHomeUrl(): string { function HMSErrorModal (line 912) | function HMSErrorModal({ printerName, errors, onClose, printerId, hasPer... FILE: frontend/src/components/IconPicker.tsx constant AVAILABLE_ICONS (line 37) | const AVAILABLE_ICONS: { name: string; icon: LucideIcon }[] = [ function getIconByName (line 71) | function getIconByName(name: string): LucideIcon { type IconPickerProps (line 76) | interface IconPickerProps { function IconPicker (line 81) | function IconPicker({ value, onChange }: IconPickerProps) { FILE: frontend/src/components/KProfilesView.tsx type KProfileCardProps (line 29) | interface KProfileCardProps { function KProfileCard (line 80) | function KProfileCard({ profile, onEdit, onCopy, selectionMode, isSelect... type KProfileModalProps (line 148) | interface KProfileModalProps { function KProfileModal (line 163) | function KProfileModal({ type ExtruderFilter (line 696) | type ExtruderFilter = 'all' | 'left' | 'right'; type FlowTypeFilter (line 697) | type FlowTypeFilter = 'all' | 'hf' | 's'; type SortOption (line 698) | type SortOption = 'name' | 'k_value' | 'filament'; constant STORAGE_KEYS (line 701) | const STORAGE_KEYS = { function KProfilesView (line 706) | function KProfilesView() { FILE: frontend/src/components/KeyboardShortcutsModal.tsx type NavItem (line 6) | interface NavItem { type SidebarItem (line 12) | interface SidebarItem { type KeyboardShortcutsModalProps (line 18) | interface KeyboardShortcutsModalProps { function getShortcuts (line 24) | function getShortcuts( function KeyBadge (line 72) | function KeyBadge({ children }: { children: string }) { function KeyboardShortcutsModal (line 80) | function KeyboardShortcutsModal({ onClose, navItems, sidebarItems }: Key... FILE: frontend/src/components/LDAPSettings.tsx constant SECURITY_PORT_MAP (line 13) | const SECURITY_PORT_MAP: Record = { type LDAPFormState (line 18) | interface LDAPFormState { function LDAPSettings (line 30) | function LDAPSettings() { FILE: frontend/src/components/Layout.tsx type NavItem (line 21) | interface NavItem { function getSidebarOrder (line 45) | function getSidebarOrder(): string[] { function saveSidebarOrder (line 58) | function saveSidebarOrder(order: string[]) { function isExternalLinkId (line 63) | function isExternalLinkId(id: string): boolean { function getDefaultView (line 68) | function getDefaultView(): string { function setDefaultView (line 73) | function setDefaultView(path: string) { function Layout (line 77) | function Layout() { FILE: frontend/src/components/LinkSpoolModal.tsx type LinkSpoolModalProps (line 10) | interface LinkSpoolModalProps { function LinkSpoolModal (line 20) | function LinkSpoolModal({ isOpen, onClose, tagUid, trayUuid, printerId, ... FILE: frontend/src/components/LocalProfilesView.tsx constant MATERIAL_TYPES (line 25) | const MATERIAL_TYPES = ['PLA', 'PETG', 'PCTG', 'ABS', 'ASA', 'TPU', 'PC'... constant FILAMENT_TYPE_COLORS (line 27) | const FILAMENT_TYPE_COLORS: Record = { function parseMaterialFromName (line 34) | function parseMaterialFromName(name: string): string | null { function parseVendorFromName (line 43) | function parseVendorFromName(name: string): string | null { function PresetCard (line 58) | function PresetCard({ function LocalProfilesView (line 221) | function LocalProfilesView() { FILE: frontend/src/components/LogViewer.tsx constant LOG_LEVELS (line 19) | const LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR'] as const; type LogLevel (line 20) | type LogLevel = (typeof LOG_LEVELS)[number]; function LogViewer (line 36) | function LogViewer() { FILE: frontend/src/components/MQTTDebugModal.tsx type MQTTDebugModalProps (line 8) | interface MQTTDebugModalProps { function MQTTDebugModal (line 14) | function MQTTDebugModal({ printerId, printerName, onClose }: MQTTDebugMo... FILE: frontend/src/components/MetricToggle.tsx type Metric (line 3) | type Metric = 'weight' | 'prints' | 'time'; constant METRICS (line 5) | const METRICS: Metric[] = ['weight', 'prints', 'time']; type MetricToggleProps (line 7) | interface MetricToggleProps { function MetricToggle (line 13) | function MetricToggle({ value, onChange, exclude }: MetricToggleProps) { FILE: frontend/src/components/ModelViewer.tsx type BuildVolume (line 12) | interface BuildVolume { type ModelViewerProps (line 18) | interface ModelViewerProps { type MeshData (line 27) | interface MeshData { type ObjectData (line 33) | interface ObjectData { type BuildItem (line 40) | interface BuildItem { type Parsed3MFData (line 47) | interface Parsed3MFData { function parseTransform3MF (line 55) | function parseTransform3MF(transformStr: string | null): THREE.Matrix4 { function parseMeshFromDoc (line 82) | async function parseMeshFromDoc(doc: Document, defaultExtruder: number =... function parsePlateIdFromAttributes (line 118) | function parsePlateIdFromAttributes(element: Element): number | null { function parse3MF (line 136) | async function parse3MF(arrayBuffer: ArrayBuffer): Promise { function createGeometryFromMesh (line 442) | function createGeometryFromMesh(mesh: MeshData): THREE.BufferGeometry { function disposeGroup (line 463) | function disposeGroup(group: THREE.Group) { function buildModelGroup (line 478) | function buildModelGroup( function ModelViewer (line 582) | function ModelViewer({ FILE: frontend/src/components/ModelViewerModal.tsx type ViewTab (line 12) | type ViewTab = '3d' | 'gcode'; type ModelViewerModalProps (line 14) | interface ModelViewerModalProps { type Capabilities (line 22) | interface Capabilities { function ModelViewerModal (line 30) | function ModelViewerModal({ archiveId, libraryFileId, title, fileType, o... FILE: frontend/src/components/NotificationLogViewer.tsx constant EVENT_COLORS (line 11) | const EVENT_COLORS: Record = { type NotificationLogViewerProps (line 24) | interface NotificationLogViewerProps { function NotificationLogViewer (line 28) | function NotificationLogViewer({ onClose }: NotificationLogViewerProps) { function LogEntry (line 208) | function LogEntry({ FILE: frontend/src/components/NotificationProviderCard.tsx type NotificationProviderCardProps (line 13) | interface NotificationProviderCardProps { function NotificationProviderCard (line 18) | function NotificationProviderCard({ provider, onEdit }: NotificationProv... FILE: frontend/src/components/NotificationTemplateEditor.tsx type NotificationTemplateEditorProps (line 9) | interface NotificationTemplateEditorProps { function NotificationTemplateEditor (line 14) | function NotificationTemplateEditor({ template, onClose }: NotificationT... FILE: frontend/src/components/OIDCProviderSettings.tsx constant EMPTY_FORM (line 13) | const EMPTY_FORM: OIDCProviderCreate = { function ProviderForm (line 26) | function ProviderForm({ function OIDCProviderSettings (line 138) | function OIDCProviderSettings() { FILE: frontend/src/components/PendingUploadsPanel.tsx function formatTimeAgo (line 13) | function formatTimeAgo(dateStr: string): string { type PendingUploadItemProps (line 27) | interface PendingUploadItemProps { function PendingUploadItem (line 36) | function PendingUploadItem({ function PendingUploadsPanel (line 171) | function PendingUploadsPanel() { FILE: frontend/src/components/PhotoGalleryModal.tsx type PhotoGalleryModalProps (line 7) | interface PhotoGalleryModalProps { function PhotoGalleryModal (line 15) | function PhotoGalleryModal({ FILE: frontend/src/components/PrintCalendar.tsx type PrintCalendarProps (line 3) | interface PrintCalendarProps { function PrintCalendar (line 8) | function PrintCalendar({ printDates, months = 3 }: PrintCalendarProps) { FILE: frontend/src/components/PrintModal/FilamentMapping.tsx function FilamentMapping (line 15) | function FilamentMapping({ FILE: frontend/src/components/PrintModal/FilamentOverride.tsx type FilamentOverrideProps (line 8) | interface FilamentOverrideProps { function FilamentOverride (line 25) | function FilamentOverride({ FILE: frontend/src/components/PrintModal/PlateSelector.tsx function PlateSelector (line 13) | function PlateSelector({ FILE: frontend/src/components/PrintModal/PrintOptions.tsx constant PRINT_OPTIONS_CONFIG (line 5) | const PRINT_OPTIONS_CONFIG = [ function PrintOptionsPanel (line 17) | function PrintOptionsPanel({ FILE: frontend/src/components/PrintModal/PrinterSelector.tsx type PrinterSelectorWithMappingProps (line 26) | interface PrinterSelectorWithMappingProps extends PrinterSelectorProps { constant AVAILABLE_STATES (line 52) | const AVAILABLE_STATES = new Set(['IDLE', 'FINISH', 'FAILED']); function InlineMappingEditor (line 57) | function InlineMappingEditor({ function PrinterSelector (line 204) | function PrinterSelector({ FILE: frontend/src/components/PrintModal/ScheduleOptions.tsx function ScheduleOptionsPanel (line 22) | function ScheduleOptionsPanel({ FILE: frontend/src/components/PrintModal/index.tsx function PrintModal (line 42) | function PrintModal({ FILE: frontend/src/components/PrintModal/types.ts type PrintModalMode (line 9) | type PrintModalMode = 'reprint' | 'add-to-queue' | 'edit-queue-item'; type PrintModalProps (line 18) | interface PrintModalProps { type PrintOptions (line 45) | interface PrintOptions { constant DEFAULT_PRINT_OPTIONS (line 56) | const DEFAULT_PRINT_OPTIONS: PrintOptions = { type ScheduleType (line 67) | type ScheduleType = 'asap' | 'scheduled' | 'manual'; type ScheduleOptions (line 72) | interface ScheduleOptions { constant DEFAULT_SCHEDULE_OPTIONS (line 86) | const DEFAULT_SCHEDULE_OPTIONS: ScheduleOptions = { type PlateInfo (line 100) | interface PlateInfo { type PlatesResponse (line 117) | interface PlatesResponse { type AssignmentMode (line 127) | type AssignmentMode = 'printer' | 'model'; type PrinterSelectorProps (line 132) | interface PrinterSelectorProps { type PlateSelectorProps (line 161) | interface PlateSelectorProps { type FilamentReqsData (line 175) | interface FilamentReqsData { type FilamentMappingProps (line 189) | interface FilamentMappingProps { type PrintOptionsProps (line 202) | interface PrintOptionsProps { type ScheduleOptionsProps (line 211) | interface ScheduleOptionsProps { FILE: frontend/src/components/PrinterInfoModal.tsx type PrinterInfoModalProps (line 9) | interface PrinterInfoModalProps { function CopyButton (line 16) | function CopyButton({ value }: { value: string }) { function PrinterInfoModal (line 41) | function PrinterInfoModal({ printer, status, totalPrintHours, onClose }:... FILE: frontend/src/components/PrinterQueueWidget.tsx type PrinterQueueWidgetProps (line 9) | interface PrinterQueueWidgetProps { function PrinterQueueWidget (line 16) | function PrinterQueueWidget({ printerId, printerModel, loadedFilamentTyp... FILE: frontend/src/components/ProjectPageModal.tsx type ProjectPageModalProps (line 20) | interface ProjectPageModalProps { function ProjectPageModal (line 26) | function ProjectPageModal({ archiveId, archiveName, onClose }: ProjectPa... FILE: frontend/src/components/QRCodeModal.tsx type QRCodeModalProps (line 6) | interface QRCodeModalProps { function QRCodeModal (line 12) | function QRCodeModal({ archiveId, archiveName, onClose }: QRCodeModalPro... FILE: frontend/src/components/QueueStatsBar.tsx function formatWeight (line 4) | function formatWeight(g: number): string { function QueueStatsBar (line 9) | function QueueStatsBar({ FILE: frontend/src/components/QueueTimelineView.tsx type FilterMode (line 8) | type FilterMode = 'all' | 'printing' | 'queued'; type ScheduleEvent (line 10) | interface ScheduleEvent { type QueueTimelineViewProps (line 18) | interface QueueTimelineViewProps { function getStartOfDay (line 25) | function getStartOfDay(date: Date): Date { function formatDateLabel (line 31) | function formatDateLabel(date: Date): string { function formatTimeOnly (line 35) | function formatTimeOnly(date: Date): string { function formatTimeLeft (line 39) | function formatTimeLeft(ms: number, t: (key: string, opts?: Record = { function SpoolUsageHistory (line 24) | function SpoolUsageHistory({ spoolId }: SpoolUsageHistoryProps) { FILE: frontend/src/components/SpoolmanSettings.tsx function SpoolmanSettings (line 12) | function SpoolmanSettings() { FILE: frontend/src/components/SwitchbarPopover.tsx type SwitchbarPopoverProps (line 9) | interface SwitchbarPopoverProps { function SwitchItem (line 13) | function SwitchItem({ plug }: { plug: SmartPlug }) { function SwitchbarPopover (line 149) | function SwitchbarPopover({ onClose }: SwitchbarPopoverProps) { FILE: frontend/src/components/TagManagementModal.tsx type TagManagementModalProps (line 10) | interface TagManagementModalProps { function TagManagementModal (line 14) | function TagManagementModal({ onClose }: TagManagementModalProps) { FILE: frontend/src/components/TimelapseEditorModal.tsx type TimelapseEditorModalProps (line 23) | interface TimelapseEditorModalProps { constant SPEED_OPTIONS (line 30) | const SPEED_OPTIONS = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]; function TimelapseEditorModal (line 32) | function TimelapseEditorModal({ FILE: frontend/src/components/TimelapseViewer.tsx type TimelapseViewerProps (line 7) | interface TimelapseViewerProps { constant SPEED_OPTIONS (line 16) | const SPEED_OPTIONS = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]; function TimelapseViewer (line 18) | function TimelapseViewer({ FILE: frontend/src/components/Toggle.tsx type ToggleProps (line 1) | interface ToggleProps { function Toggle (line 7) | function Toggle({ checked, onChange, disabled }: ToggleProps) { FILE: frontend/src/components/TwoFactorSettings.tsx function CodeInput (line 12) | function CodeInput({ function BackupCodesDisplay (line 37) | function BackupCodesDisplay({ codes, onDone }: { codes: string[]; onDone... function TOTPSetupWizard (line 73) | function TOTPSetupWizard({ onDone }: { onDone: () => void }) { function TwoFactorSettings (line 173) | function TwoFactorSettings() { FILE: frontend/src/components/UploadModal.tsx type FileWithStatus (line 11) | interface FileWithStatus { type UploadModalProps (line 18) | interface UploadModalProps { function UploadModal (line 23) | function UploadModal({ onClose, initialFiles }: UploadModalProps) { FILE: frontend/src/components/VirtualKeyboard.tsx constant FOCUSABLE_TYPES (line 6) | const FOCUSABLE_TYPES = new Set(['text', 'password', 'email', 'search', ... function setNativeValue (line 12) | function setNativeValue(input: HTMLInputElement | HTMLTextAreaElement, v... function VirtualKeyboard (line 20) | function VirtualKeyboard({ onVisibilityChange }: { onVisibilityChange?: ... FILE: frontend/src/components/VirtualPrinterAddDialog.tsx type Mode (line 10) | type Mode = 'immediate' | 'review' | 'print_queue' | 'proxy'; constant MODE_LABELS (line 12) | const MODE_LABELS: Record = { type VirtualPrinterAddDialogProps (line 19) | interface VirtualPrinterAddDialogProps { function VirtualPrinterAddDialog (line 23) | function VirtualPrinterAddDialog({ onClose }: VirtualPrinterAddDialogPro... FILE: frontend/src/components/VirtualPrinterCard.tsx type LocalMode (line 15) | type LocalMode = 'immediate' | 'review' | 'print_queue' | 'proxy'; constant MODE_LABELS (line 17) | const MODE_LABELS: Record = { type VirtualPrinterCardProps (line 24) | interface VirtualPrinterCardProps { function VirtualPrinterCard (line 29) | function VirtualPrinterCard({ printer, models }: VirtualPrinterCardProps) { FILE: frontend/src/components/VirtualPrinterList.tsx function VirtualPrinterList (line 11) | function VirtualPrinterList() { FILE: frontend/src/components/VirtualPrinterSettings.tsx type LocalMode (line 10) | type LocalMode = 'immediate' | 'review' | 'print_queue' | 'proxy'; function VirtualPrinterSettings (line 12) | function VirtualPrinterSettings() { FILE: frontend/src/components/icons/ChamberLight.tsx type ChamberLightProps (line 1) | interface ChamberLightProps { function ChamberLight (line 12) | function ChamberLight({ on, className = "w-5 h-5" }: ChamberLightProps) { FILE: frontend/src/components/icons/PlateClearedIcon.tsx type PlateClearedIconProps (line 1) | interface PlateClearedIconProps { function PlateClearedIcon (line 5) | function PlateClearedIcon({ className = "w-4 h-4" }: PlateClearedIconPro... FILE: frontend/src/components/icons/WifiSignal.tsx type WifiSignalProps (line 1) | interface WifiSignalProps { function WifiSignal (line 14) | function WifiSignal({ signal, className = "w-4 h-4" }: WifiSignalProps) { FILE: frontend/src/components/spool-form/AdditionalSection.tsx function SpoolWeightPicker (line 7) | function SpoolWeightPicker({ function AdditionalSection (line 171) | function AdditionalSection({ FILE: frontend/src/components/spool-form/ColorSection.tsx function ColorSection (line 7) | function ColorSection({ FILE: frontend/src/components/spool-form/FilamentSection.tsx function FilamentSection (line 8) | function FilamentSection({ FILE: frontend/src/components/spool-form/PAProfileSection.tsx function PAProfileSection (line 6) | function PAProfileSection({ FILE: frontend/src/components/spool-form/constants.ts constant MATERIALS (line 4) | const MATERIALS = [ constant WEIGHTS (line 10) | const WEIGHTS = [250, 500, 750, 1000, 2000, 3000]; constant DEFAULT_BRANDS (line 13) | const DEFAULT_BRANDS = [ constant KNOWN_VARIANTS (line 19) | const KNOWN_VARIANTS = [ constant QUICK_COLORS (line 29) | const QUICK_COLORS: ColorPreset[] = [ constant EXTENDED_COLORS (line 45) | const EXTENDED_COLORS: ColorPreset[] = [ constant ALL_COLORS (line 97) | const ALL_COLORS: ColorPreset[] = [...QUICK_COLORS, ...EXTENDED_COLORS]; constant RECENT_COLORS_KEY (line 100) | const RECENT_COLORS_KEY = 'bambuddy-recent-colors'; constant MAX_RECENT_COLORS (line 101) | const MAX_RECENT_COLORS = 8; FILE: frontend/src/components/spool-form/types.ts type CatalogDisplayColor (line 5) | interface CatalogDisplayColor { type SpoolFormData (line 13) | interface SpoolFormData { type PrinterWithCalibrations (line 44) | interface PrinterWithCalibrations { type CalibrationProfile (line 50) | interface CalibrationProfile { type FilamentOption (line 62) | interface FilamentOption { type ColorPreset (line 71) | interface ColorPreset { type SectionProps (line 77) | interface SectionProps { type FilamentSectionProps (line 83) | interface FilamentSectionProps extends SectionProps { type ColorSectionProps (line 99) | interface ColorSectionProps extends SectionProps { type AdditionalSectionProps (line 106) | interface AdditionalSectionProps extends SectionProps { type PAProfileSectionProps (line 112) | interface PAProfileSectionProps extends SectionProps { type ValidationResult (line 121) | interface ValidationResult { function validateForm (line 126) | function validateForm(formData: SpoolFormData, quickAdd = false): Valida... type SavedKProfile (line 162) | interface SavedKProfile extends SpoolKProfile { FILE: frontend/src/components/spool-form/utils.ts constant FALLBACK_PRESETS (line 6) | const FALLBACK_PRESETS: FilamentOption[] = [ function parsePresetName (line 27) | function parsePresetName(name: string): { brand: string; material: strin... function extractBrandsFromPresets (line 95) | function extractBrandsFromPresets(presets: SlicerSetting[], localPresets... function buildLocalFilamentOptions (line 123) | function buildLocalFilamentOptions(localPresets: LocalPreset[]): Filamen... function buildFilamentOptions (line 149) | function buildFilamentOptions( function findPresetOption (line 211) | function findPresetOption( function loadRecentColors (line 235) | function loadRecentColors(): ColorPreset[] { function saveRecentColor (line 247) | function saveRecentColor(color: ColorPreset, currentRecent: ColorPreset[... function isMatchingCalibration (line 263) | function isMatchingCalibration( FILE: frontend/src/components/spoolbuddy/AmsUnitCard.tsx function trayColorToCSS (line 4) | function trayColorToCSS(color: string | null): string { function isTrayEmpty (line 9) | function isTrayEmpty(tray: AMSTray): boolean { function getAmsName (line 13) | function getAmsName(id: number): string { function WaterDropEmpty (line 21) | function WaterDropEmpty({ className }: { className?: string }) { function WaterDropHalf (line 29) | function WaterDropHalf({ className }: { className?: string }) { function WaterDropFull (line 38) | function WaterDropFull({ className }: { className?: string }) { function ThermometerEmpty (line 47) | function ThermometerEmpty({ className }: { className?: string }) { function ThermometerHalf (line 56) | function ThermometerHalf({ className }: { className?: string }) { function ThermometerFull (line 66) | function ThermometerFull({ className }: { className?: string }) { function HumidityIndicator (line 78) | function HumidityIndicator({ humidity, goodThreshold = 40, fairThreshold... function TemperatureIndicator (line 101) | function TemperatureIndicator({ temp, goodThreshold = 28, fairThreshold ... function NozzleBadge (line 126) | function NozzleBadge({ side }: { side: 'L' | 'R' }) { type SpoolSlotProps (line 139) | interface SpoolSlotProps { function SpoolSlot (line 148) | function SpoolSlot({ tray, slotIndex, isActive, fillOverride, spoolmanFi... type AmsThresholds (line 206) | interface AmsThresholds { type AmsUnitCardProps (line 213) | interface AmsUnitCardProps { function AmsUnitCard (line 224) | function AmsUnitCard({ unit, activeSlot, onConfigureSlot, isDualNozzle, ... FILE: frontend/src/components/spoolbuddy/AssignToAmsModal.tsx function getAmsName (line 11) | function getAmsName(id: number): string { function isTrayEmpty (line 17) | function isTrayEmpty(tray: AMSTray): boolean { function trayColorToCSS (line 21) | function trayColorToCSS(color: string | null): string { function checkMaterialMatch (line 30) | function checkMaterialMatch( function checkProfileMatch (line 44) | function checkProfileMatch( type AssignToAmsModalProps (line 54) | interface AssignToAmsModalProps { function AssignToAmsModal (line 61) | function AssignToAmsModal({ isOpen, onClose, spool, printerId }: AssignT... FILE: frontend/src/components/spoolbuddy/DiagnosticModal.tsx type DiagnosticModalProps (line 6) | interface DiagnosticModalProps { function DiagnosticModal (line 12) | function DiagnosticModal({ type, deviceId, onClose }: DiagnosticModalPro... FILE: frontend/src/components/spoolbuddy/InventorySpoolInfoCard.tsx constant DEFAULT_CORE_WEIGHT_KEY (line 9) | const DEFAULT_CORE_WEIGHT_KEY = 'spoolbuddy-default-core-weight'; function getDefaultCoreWeight (line 11) | function getDefaultCoreWeight(): number { type InventorySpoolInfoCardProps (line 24) | interface InventorySpoolInfoCardProps { function InventorySpoolInfoCard (line 34) | function InventorySpoolInfoCard({ FILE: frontend/src/components/spoolbuddy/LinkSpoolModal.tsx type LinkSpoolModalProps (line 7) | interface LinkSpoolModalProps { function LinkSpoolModal (line 15) | function LinkSpoolModal({ FILE: frontend/src/components/spoolbuddy/SpoolBuddyBottomNav.tsx function SpoolBuddyBottomNav (line 59) | function SpoolBuddyBottomNav() { FILE: frontend/src/components/spoolbuddy/SpoolBuddyLayout.tsx function SpoolBuddyLayout (line 14) | function SpoolBuddyLayout() { type SpoolBuddyOutletContext (line 240) | interface SpoolBuddyOutletContext { FILE: frontend/src/components/spoolbuddy/SpoolBuddyQuickMenu.tsx type SpoolBuddyQuickMenuProps (line 7) | interface SpoolBuddyQuickMenuProps { type SystemCommand (line 14) | type SystemCommand = 'reboot' | 'shutdown' | 'restart_daemon' | 'restart... type PendingConfirm (line 16) | type PendingConfirm = type PlugState (line 20) | interface PlugState { function SpoolBuddyQuickMenu (line 27) | function SpoolBuddyQuickMenu({ isOpen, onClose, deviceId, deviceOnline }... function SystemButton (line 290) | function SystemButton({ FILE: frontend/src/components/spoolbuddy/SpoolBuddyStatusBar.tsx type Alert (line 3) | interface Alert { type SpoolBuddyStatusBarProps (line 8) | interface SpoolBuddyStatusBarProps { function SpoolBuddyStatusBar (line 12) | function SpoolBuddyStatusBar({ alert }: SpoolBuddyStatusBarProps) { FILE: frontend/src/components/spoolbuddy/SpoolBuddyTopBar.tsx type SpoolBuddyTopBarProps (line 8) | interface SpoolBuddyTopBarProps { function SpoolBuddyTopBar (line 14) | function SpoolBuddyTopBar({ selectedPrinterId, onPrinterChange, deviceOn... FILE: frontend/src/components/spoolbuddy/SpoolIcon.tsx type SpoolIconProps (line 1) | interface SpoolIconProps { function SpoolIcon (line 7) | function SpoolIcon({ color, isEmpty, size = 32 }: SpoolIconProps) { FILE: frontend/src/components/spoolbuddy/SpoolInfoCard.tsx constant DEFAULT_CORE_WEIGHT_KEY (line 9) | const DEFAULT_CORE_WEIGHT_KEY = 'spoolbuddy-default-core-weight'; function getDefaultCoreWeight (line 11) | function getDefaultCoreWeight(): number { type SpoolInfoCardProps (line 24) | interface SpoolInfoCardProps { function SpoolInfoCard (line 32) | function SpoolInfoCard({ spool, scaleWeight, onClose, onSyncWeight, onAs... type UnknownTagCardProps (line 215) | interface UnknownTagCardProps { function UnknownTagCard (line 224) | function UnknownTagCard({ tagUid, scaleWeight, coreWeight, onLinkSpool, ... FILE: frontend/src/components/spoolbuddy/TagDetectedModal.tsx constant DEFAULT_CORE_WEIGHT_KEY (line 9) | const DEFAULT_CORE_WEIGHT_KEY = 'spoolbuddy-default-core-weight'; function getDefaultCoreWeight (line 11) | function getDefaultCoreWeight(): number { type TagDetectedModalProps (line 24) | interface TagDetectedModalProps { function TagDetectedModal (line 37) | function TagDetectedModal({ type KnownSpoolViewProps (line 124) | interface KnownSpoolViewProps { function KnownSpoolView (line 135) | function KnownSpoolView({ spool, scaleWeight, weightStable, syncing, syn... type UnknownTagViewProps (line 293) | interface UnknownTagViewProps { function UnknownTagView (line 301) | function UnknownTagView({ tagUid, scaleWeight, onAddToInventory, onLinkS... FILE: frontend/src/components/spoolbuddy/WeightDisplay.tsx type WeightDisplayProps (line 4) | interface WeightDisplayProps { function WeightDisplay (line 11) | function WeightDisplay({ weight, weightStable, deviceOnline, deviceId }:... FILE: frontend/src/contexts/AuthContext.tsx type AuthContextType (line 5) | interface AuthContextType { function AuthProvider (line 26) | function AuthProvider({ children }: { children: React.ReactNode }) { function useAuth (line 242) | function useAuth() { FILE: frontend/src/contexts/ColorCatalogContext.tsx function ColorCatalogProvider (line 16) | function ColorCatalogProvider({ children }: { children: ReactNode }) { FILE: frontend/src/contexts/ThemeContext.tsx type ThemeMode (line 4) | type ThemeMode = 'light' | 'dark'; type ThemeStyle (line 5) | type ThemeStyle = 'classic' | 'glow' | 'vibrant'; type DarkBackground (line 6) | type DarkBackground = 'neutral' | 'warm' | 'cool' | 'oled' | 'slate' | '... type LightBackground (line 7) | type LightBackground = 'neutral' | 'warm' | 'cool'; type ThemeAccent (line 8) | type ThemeAccent = 'green' | 'teal' | 'blue' | 'orange' | 'purple' | 'red'; type ThemeContextType (line 10) | interface ThemeContextType { function ThemeProvider (line 33) | function ThemeProvider({ children }: { children: ReactNode }) { function useTheme (line 174) | function useTheme() { FILE: frontend/src/contexts/ToastContext.tsx type ToastType (line 7) | type ToastType = 'success' | 'error' | 'warning' | 'info' | 'loading'; type ShowPersistentToast (line 9) | type ShowPersistentToast = (id: string, message: string, type?: ToastTyp... type Toast (line 11) | interface Toast { type DispatchJobStatus (line 19) | type DispatchJobStatus = 'dispatched' | 'processing' | 'completed' | 'fa... type DispatchToastJob (line 21) | interface DispatchToastJob { type DispatchToastData (line 32) | interface DispatchToastData { type ToastContextType (line 41) | interface ToastContextType { function useToast (line 49) | function useToast() { function ToastProvider (line 73) | function ToastProvider({ children }: { children: ReactNode }) { FILE: frontend/src/hooks/useCameraStreamToken.ts function rewriteMediaSrcWithToken (line 11) | function rewriteMediaSrcWithToken(root: ParentNode, token: string): numb... function useStreamTokenSync (line 43) | function useStreamTokenSync() { function useCameraStreamToken (line 109) | function useCameraStreamToken() { FILE: frontend/src/hooks/useColorCatalogVersion.ts function useColorCatalogVersion (line 13) | function useColorCatalogVersion(): number { FILE: frontend/src/hooks/useFilamentMapping.ts function buildLoadedFilaments (line 16) | function buildLoadedFilaments(printerStatus: PrinterStatus | undefined):... function computeAmsMapping (line 89) | function computeAmsMapping( type LoadedFilament (line 218) | interface LoadedFilament { type FilamentRequirement (line 241) | interface FilamentRequirement { type FilamentStatus (line 255) | type FilamentStatus = 'match' | 'type_only' | 'mismatch' | 'empty'; type FilamentComparison (line 260) | interface FilamentComparison extends FilamentRequirement { type FilamentRequirementsResponse (line 269) | interface FilamentRequirementsResponse { type UseFilamentMappingResult (line 273) | interface UseFilamentMappingResult { function useLoadedFilaments (line 290) | function useLoadedFilaments( function useFilamentMapping (line 306) | function useFilamentMapping( FILE: frontend/src/hooks/useIsMobile.ts constant MOBILE_BREAKPOINT (line 3) | const MOBILE_BREAKPOINT = 768; function useIsMobile (line 5) | function useIsMobile(): boolean { FILE: frontend/src/hooks/useIsSidebarCompact.ts constant SIDEBAR_COMPACT_BREAKPOINT (line 3) | const SIDEBAR_COMPACT_BREAKPOINT = 1144; function useIsSidebarCompact (line 5) | function useIsSidebarCompact(): boolean { FILE: frontend/src/hooks/useLongPress.ts type LongPressOptions (line 3) | interface LongPressOptions { function useLongPress (line 9) | function useLongPress({ onLongPress, onClick, delay = 500 }: LongPressOp... FILE: frontend/src/hooks/useMultiPrinterFilamentMapping.ts type PrinterMatchStatus (line 19) | type PrinterMatchStatus = 'full' | 'partial' | 'missing'; type PerPrinterConfig (line 24) | interface PerPrinterConfig { type PrinterMappingResult (line 36) | interface PrinterMappingResult { type UseMultiPrinterFilamentMappingResult (line 66) | interface UseMultiPrinterFilamentMappingResult { function computeMatchDetails (line 88) | function computeMatchDetails( function computeMappingWithOverrides (line 192) | function computeMappingWithOverrides( constant DEFAULT_PRINTER_CONFIG (line 275) | const DEFAULT_PRINTER_CONFIG: PerPrinterConfig = { function useMultiPrinterFilamentMapping (line 285) | function useMultiPrinterFilamentMapping( FILE: frontend/src/hooks/useSpoolBuddyState.ts type MatchedSpool (line 3) | interface MatchedSpool { type SpoolBuddyState (line 16) | interface SpoolBuddyState { type Action (line 26) | type Action = function reducer (line 44) | function reducer(state: SpoolBuddyState, action: Action): SpoolBuddyState { function useSpoolBuddyState (line 94) | function useSpoolBuddyState() { FILE: frontend/src/hooks/useWebSocket.ts type WebSocketMessage (line 6) | interface WebSocketMessage { function useWebSocket (line 14) | function useWebSocket() { FILE: frontend/src/lib/settingsSearch.ts type SettingsSearchTab (line 11) | type SettingsSearchTab = type SettingsSearchSubTab (line 25) | type SettingsSearchSubTab = 'users' | 'email' | 'ldap' | 'oidc' | 'twofa'; type SettingsSearchEntry (line 27) | interface SettingsSearchEntry { function registerSettingsSearch (line 42) | function registerSettingsSearch(entry: SettingsSearchEntry): void { function getSettingsSearchEntries (line 46) | function getSettingsSearchEntries(): SettingsSearchEntry[] { FILE: frontend/src/pages/ArchivesPage.tsx type TFunction (line 85) | type TFunction = (key: string, options?: Record) => str... function isSlicedFile (line 93) | function isSlicedFile(archive: { filename?: string | null; total_layers?... function getArchiveFileType (line 104) | function getArchiveFileType(filename: string | null | undefined): string... function openInSlicerWithToken (line 120) | async function openInSlicerWithToken( function ArchiveCard (line 145) | function ArchiveCard({ function ArchiveListRow (line 1423) | function ArchiveListRow({ type SortOption (line 2319) | type SortOption = 'date-desc' | 'date-asc' | 'name-asc' | 'name-desc' | ... type ViewMode (line 2320) | type ViewMode = 'grid' | 'list' | 'calendar' | 'log'; type Collection (line 2321) | type Collection = 'all' | 'recent' | 'this-week' | 'this-month' | 'favor... function ArchivesPage (line 2333) | function ArchivesPage() { function ArchivePaginationBar (line 3706) | function ArchivePaginationBar({ FILE: frontend/src/pages/CameraPage.tsx constant MAX_RECONNECT_ATTEMPTS (line 13) | const MAX_RECONNECT_ATTEMPTS = 5; constant INITIAL_RECONNECT_DELAY (line 14) | const INITIAL_RECONNECT_DELAY = 2000; constant MAX_RECONNECT_DELAY (line 15) | const MAX_RECONNECT_DELAY = 30000; constant STALL_CHECK_INTERVAL (line 16) | const STALL_CHECK_INTERVAL = 5000; function CameraPage (line 18) | function CameraPage() { FILE: frontend/src/pages/ExternalLinkPage.tsx function ExternalLinkPage (line 8) | function ExternalLinkPage() { FILE: frontend/src/pages/FileManagerPage.tsx type SortField (line 66) | type SortField = 'name' | 'date' | 'size' | 'type' | 'prints'; type SortDirection (line 67) | type SortDirection = 'asc' | 'desc'; type TFunction (line 68) | type TFunction = (key: string, options?: Record) => str... type NewFolderModalProps (line 71) | interface NewFolderModalProps { function NewFolderModal (line 79) | function NewFolderModal({ parentId, onClose, onSave, isLoading, t }: New... type ExternalFolderModalProps (line 123) | interface ExternalFolderModalProps { function ExternalFolderModal (line 130) | function ExternalFolderModal({ onClose, onSave, isLoading, t }: External... type RenameModalProps (line 221) | interface RenameModalProps { function RenameModal (line 230) | function RenameModal({ type, currentName, onClose, onSave, isLoading, t ... type MoveFilesModalProps (line 285) | interface MoveFilesModalProps { function MoveFilesModal (line 295) | function MoveFilesModal({ folders, selectedFiles, currentFolderId, onClo... type LinkFolderModalProps (line 354) | interface LinkFolderModalProps { function LinkFolderModal (line 362) | function LinkFolderModal({ folder, onClose, onLink, isLoading, t }: Link... type FolderTreeItemProps (line 519) | interface FolderTreeItemProps { function FolderTreeItem (line 533) | function FolderTreeItem({ folder, selectedFolderId, onSelect, onDelete, ... function isSlicedFilename (line 680) | function isSlicedFilename(filename: string): boolean { type FileCardProps (line 686) | interface FileCardProps { function FileCard (line 705) | function FileCard({ file, isSelected, isMobile, onSelect, onDelete, onDo... function FileManagerPage (line 888) | function FileManagerPage() { FILE: frontend/src/pages/GroupEditPage.tsx function GroupEditPage (line 12) | function GroupEditPage() { FILE: frontend/src/pages/InventoryPage.tsx type ArchiveFilter (line 22) | type ArchiveFilter = 'active' | 'archived'; type UsageFilter (line 23) | type UsageFilter = 'all' | 'used' | 'new' | 'lowstock'; type ViewMode (line 24) | type ViewMode = 'table' | 'cards'; type SortDirection (line 25) | type SortDirection = 'asc' | 'desc'; type SortState (line 26) | type SortState = { column: string; direction: SortDirection } | null; type DisplayItem (line 28) | type DisplayItem = function spoolGroupKey (line 32) | function spoolGroupKey(s: InventorySpool): string { constant COLUMN_CONFIG_KEY (line 37) | const COLUMN_CONFIG_KEY = 'bambuddy-inventory-columns'; constant DEFAULT_COLUMNS (line 39) | const DEFAULT_COLUMNS: ColumnConfig[] = [ function loadColumnConfig (line 70) | function loadColumnConfig(): ColumnConfig[] { function saveColumnConfig (line 89) | function saveColumnConfig(config: ColumnConfig[]) { function formatWeight (line 97) | function formatWeight(g: number, useKg = false): string { constant MATERIAL_COLORS (line 103) | const MATERIAL_COLORS: Record = { type TFn (line 114) | type TFn = (key: string, opts?: Record) => string; function formatInventoryDate (line 116) | function formatInventoryDate(dateStr: string | null, dateFormat: DateFor... type CellCtx (line 123) | type CellCtx = { constant SORT_STATE_KEY (line 390) | const SORT_STATE_KEY = 'bambuddy-inventory-sort'; function loadSortState (line 392) | function loadSortState(): SortState { function saveSortState (line 400) | function saveSortState(state: SortState) { function InventoryPageRouter (line 411) | function InventoryPageRouter() { function InventoryPage (line 432) | function InventoryPage() { function PaginationBar (line 1509) | function PaginationBar({ function SpoolCard (line 1586) | function SpoolCard({ function SpoolTableRow (line 1661) | function SpoolTableRow({ function SpoolTableGroup (line 1716) | function SpoolTableGroup({ function EmptyFilterState (line 1796) | function EmptyFilterState({ FILE: frontend/src/pages/LoginPage.tsx type LoginStep (line 13) | type LoginStep = 'credentials' | '2fa' | 'reset-password'; function LoginPage (line 15) | function LoginPage() { FILE: frontend/src/pages/MaintenancePage.tsx function getIcon (line 74) | function getIcon(iconName: string | null) { type TFunction (line 79) | type TFunction = (key: string, options?: Record) => str... function formatDuration (line 81) | function formatDuration(value: number, type: 'hours' | 'days', t?: TFunc... function formatIntervalLabel (line 114) | function formatIntervalLabel(value: number, type: 'hours' | 'days', t?: ... function MaintenanceCard (line 131) | function MaintenanceCard({ function PrinterSection (line 289) | function PrinterSection({ function SettingsSection (line 458) | function SettingsSection({ type TabType (line 1084) | type TabType = 'status' | 'settings'; function MaintenancePage (line 1086) | function MaintenancePage() { FILE: frontend/src/pages/NotificationsPage.tsx function NotificationsPage (line 12) | function NotificationsPage() { FILE: frontend/src/pages/PrintersPage.tsx function formatKValue (line 95) | function formatKValue(k: number | null | undefined): string { function NozzleBadge (line 101) | function NozzleBadge({ side }: { side: 'L' | 'R' }) { function nozzleTypeName (line 118) | function nozzleTypeName(type: string, t: (key: string) => string): string { function nozzleFlowName (line 142) | function nozzleFlowName(type: string, t: (key: string) => string): string { function NozzleSlotHoverCard (line 151) | function NozzleSlotHoverCard({ slot, index, activeStatus, filamentName, ... function DualNozzleHoverCard (line 321) | function DualNozzleHoverCard({ leftSlot, rightSlot, activeNozzle, filame... function NozzleRackCard (line 486) | function NozzleRackCard({ slots, filamentInfo }: { slots: import('../api... function WaterDropEmpty (line 538) | function WaterDropEmpty({ className }: { className?: string }) { function WaterDropHalf (line 547) | function WaterDropHalf({ className }: { className?: string }) { function WaterDropFull (line 557) | function WaterDropFull({ className }: { className?: string }) { function ThermometerEmpty (line 567) | function ThermometerEmpty({ className }: { className?: string }) { function ThermometerHalf (line 577) | function ThermometerHalf({ className }: { className?: string }) { function ThermometerFull (line 588) | function ThermometerFull({ className }: { className?: string }) { type HeaterThermometerProps (line 599) | interface HeaterThermometerProps { function HeaterThermometer (line 605) | function HeaterThermometer({ className, color, isHeating }: HeaterThermo... type HumidityIndicatorProps (line 641) | interface HumidityIndicatorProps { function HumidityIndicator (line 649) | function HumidityIndicator({ humidity, goodThreshold = 40, fairThreshold... type TemperatureIndicatorProps (line 699) | interface TemperatureIndicatorProps { function TemperatureIndicator (line 707) | function TemperatureIndicator({ temp, goodThreshold = 28, fairThreshold ... function getAmsLabel (line 746) | function getAmsLabel(amsId: number | string, trayCount: number): string { function isBambuLabSpool (line 764) | function isBambuLabSpool(tray: { function CoverImage (line 784) | function CoverImage({ url, printName }: { url: string | null; printName?... type PrinterMaintenanceInfo (line 848) | interface PrinterMaintenanceInfo { function StatusSummaryBar (line 855) | function StatusSummaryBar({ printers }: { printers: Printer[] | undefine... type SortOption (line 980) | type SortOption = 'name' | 'status' | 'model' | 'location'; type ViewMode (line 981) | type ViewMode = 'expanded' | 'compact'; constant STATUS_GROUP_ORDER (line 983) | const STATUS_GROUP_ORDER: string[] = ['error', 'printing', 'paused', 'fi... constant STATUS_GROUP_META (line 985) | const STATUS_GROUP_META: Record) => str... type ProfileTab (line 56) | type ProfileTab = 'cloud' | 'local' | 'kprofiles'; type LoginStep (line 57) | type LoginStep = 'email' | 'code' | 'token'; type PresetType (line 58) | type PresetType = 'all' | 'filament' | 'printer' | 'process'; function extractMetadata (line 61) | function extractMetadata(name: string, inherits?: string): { function isUserPreset (line 89) | function isUserPreset(settingId: string): boolean { function LoginForm (line 97) | function LoginForm({ onSuccess, t }: { onSuccess: () => void; t: TFuncti... function FilterDropdown (line 308) | function FilterDropdown({ function ScrollToTop (line 362) | function ScrollToTop() { function PresetListItem (line 395) | function PresetListItem({ function formatJsonForDisplay (line 476) | function formatJsonForDisplay(obj: unknown, indent = 0): string { function PresetDetailModal (line 520) | function PresetDetailModal({ type EditorTab (line 666) | type EditorTab = 'common' | 'fields' | 'json'; type CustomTemplate (line 668) | interface CustomTemplate { function loadCustomTemplates (line 678) | function loadCustomTemplates(): CustomTemplate[] { function saveCustomTemplates (line 688) | function saveCustomTemplates(templates: CustomTemplate[]) { function TemplatesModal (line 696) | function TemplatesModal({ type DiffEntry (line 987) | type DiffEntry = { function DiffModal (line 994) | function DiffModal({ function CreatePresetModal (line 1270) | function CreatePresetModal({ function CloudProfilesView (line 2246) | function CloudProfilesView({ function ProfilesPage (line 2817) | function ProfilesPage() { FILE: frontend/src/pages/ProjectDetailPage.tsx function isSlicedFilename (line 54) | function isSlicedFilename(filename: string): boolean { function formatFilament (line 59) | function formatFilament(grams: number): string { type TFunction (line 66) | type TFunction = (key: string, options?: Record) => str... function StatusBadge (line 68) | function StatusBadge({ status, t }: { status: string; t: TFunction }) { function StatCard (line 89) | function StatCard({ function ArchiveGrid (line 122) | function ArchiveGrid({ archives, t }: { archives: Archive[]; t: TFunctio... function PriorityBadge (line 174) | function PriorityBadge({ priority, t }: { priority: string; t: TFunction... function getDueDateStatus (line 191) | function getDueDateStatus(dateString: string | null, t: TFunction): { co... function ProjectDetailPage (line 204) | function ProjectDetailPage() { FILE: frontend/src/pages/ProjectsPage.tsx constant PROJECT_COLORS (line 31) | const PROJECT_COLORS = [ type TFunction (line 43) | type TFunction = (key: string, options?: Record) => str... type ProjectModalProps (line 45) | interface ProjectModalProps { function ProjectModal (line 54) | function ProjectModal({ project, onClose, onSave, isLoading, currencySym... type ProjectCardProps (line 271) | interface ProjectCardProps { function ProjectCard (line 280) | function ProjectCard({ project, onClick, onEdit, onDelete, hasPermission... function ProjectsPage (line 603) | function ProjectsPage() { FILE: frontend/src/pages/QueuePage.tsx function formatWeight (line 71) | function formatWeight(g: number, useKg = false): string { function StatusBadge (line 76) | function StatusBadge({ status, waitingReason, printerState, t }: { statu... function BulkEditModal (line 117) | function BulkEditModal({ function TriStateToggle (line 241) | function TriStateToggle({ function SortableQueueItem (line 285) | function SortableQueueItem({ function QueuePage (line 706) | function QueuePage() { FILE: frontend/src/pages/SettingsPage.tsx type TabType (line 45) | type TabType = typeof validTabs[number]; type UsersSubTab (line 46) | type UsersSubTab = 'users' | 'email' | 'ldap' | 'twofa' | 'oidc'; constant STORAGE_CATEGORY_COLORS (line 114) | const STORAGE_CATEGORY_COLORS: Record = { constant STORAGE_FALLBACK_COLORS (line 132) | const STORAGE_FALLBACK_COLORS = [ function SettingsPage (line 146) | function SettingsPage() { FILE: frontend/src/pages/SetupPage.tsx function SetupPage (line 11) | function SetupPage() { FILE: frontend/src/pages/StatsPage.tsx type TimeframePreset (line 46) | type TimeframePreset = 'today' | 'this-week' | 'this-month' | 'last-7' |... type TimeframeState (line 48) | interface TimeframeState { function computeDateRange (line 54) | function computeDateRange(preset: TimeframePreset): { dateFrom?: string;... constant TIMEFRAME_PRESETS (line 85) | const TIMEFRAME_PRESETS: TimeframePreset[] = [ constant DAY_LABELS (line 92) | const DAY_LABELS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; constant HOUR_LABELS (line 94) | const HOUR_LABELS = [ constant DURATION_BUCKETS (line 101) | const DURATION_BUCKETS = [ constant RECHARTS_TOOLTIP_STYLE (line 112) | const RECHARTS_TOOLTIP_STYLE = { function QuickStatsWidget (line 119) | function QuickStatsWidget({ function SuccessRateWidget (line 184) | function SuccessRateWidget({ function TimeAccuracyWidget (line 270) | function TimeAccuracyWidget({ function HourlyHeatmap (line 375) | function HourlyHeatmap({ printDates, dateFrom, dateTo }: { printDates: s... function PrintActivityWidget (line 476) | function PrintActivityWidget({ function PrinterStatsWidget (line 509) | function PrinterStatsWidget({ function FilamentTrendsWidget (line 713) | function FilamentTrendsWidget({ function FailureAnalysisWidget (line 731) | function FailureAnalysisWidget({ size = 1, dateFrom, dateTo, createdById... function RecordsWidget (line 822) | function RecordsWidget({ archives, currency }: { archives: ArchiveSlim[]... function StatsPage (line 947) | function StatsPage() { FILE: frontend/src/pages/StreamOverlayPage.tsx type TFunction (line 10) | type TFunction = (key: string, options?: Record) => str... type OverlaySize (line 12) | type OverlaySize = 'small' | 'medium' | 'large'; type OverlayConfig (line 14) | interface OverlayConfig { function formatPrintName (line 26) | function formatPrintName(name: string | null, gcodeFile: string | null |... function parseConfig (line 36) | function parseConfig(params: URLSearchParams): OverlayConfig { function getStatusText (line 60) | function getStatusText(status: PrinterStatus, t: TFunction): string { function getSizeClasses (line 73) | function getSizeClasses(size: OverlaySize) { function StreamOverlayPage (line 109) | function StreamOverlayPage() { FILE: frontend/src/pages/SystemInfoPage.tsx function formatBytes (line 30) | function formatBytes(bytes: number): string { function StatCard (line 37) | function StatCard({ function ProgressBar (line 64) | function ProgressBar({ percent, color = 'bg-bambu-green' }: { percent: n... function Section (line 75) | function Section({ function SystemInfoPage (line 95) | function SystemInfoPage() { FILE: frontend/src/pages/UsersPage.tsx type FormData (line 15) | interface FormData extends UserCreate { function UsersPage (line 21) | function UsersPage() { FILE: frontend/src/pages/spoolbuddy/SpoolBuddyAmsPage.tsx function getAmsName (line 17) | function getAmsName(amsId: number): string { function mapModelCode (line 23) | function mapModelCode(ssdpModel: string | null): string { function isTrayEmpty (line 37) | function isTrayEmpty(tray: AMSTray): boolean { function trayColorToCSS (line 41) | function trayColorToCSS(color: string | null): string { function SpoolBuddyAmsPage (line 46) | function SpoolBuddyAmsPage() { FILE: frontend/src/pages/spoolbuddy/SpoolBuddyCalibrationPage.tsx function ScaleCalibration (line 8) | function ScaleCalibration({ device, weight, weightStable, rawAdc }: { function SpoolBuddyCalibrationPage (line 173) | function SpoolBuddyCalibrationPage() { FILE: frontend/src/pages/spoolbuddy/SpoolBuddyDashboard.tsx function normalizeHexTag (line 13) | function normalizeHexTag(value: string | null | undefined): string { function tagsEquivalent (line 18) | function tagsEquivalent(a: string | null | undefined, b: string | null |... constant SPOOL_COLORS (line 28) | const SPOOL_COLORS = [ function IdleSpool (line 34) | function IdleSpool() { function DeviceOfflineState (line 104) | function DeviceOfflineState() { function SpoolBuddyDashboard (line 138) | function SpoolBuddyDashboard() { FILE: frontend/src/pages/spoolbuddy/SpoolBuddyInventoryPage.tsx type FilterMode (line 14) | type FilterMode = 'all' | 'in_ams' | string; function spoolColor (line 16) | function spoolColor(spool: InventorySpool): string { function spoolRemaining (line 21) | function spoolRemaining(spool: InventorySpool): number { function spoolPct (line 25) | function spoolPct(spool: InventorySpool): number { function spoolDisplayName (line 30) | function spoolDisplayName(spool: InventorySpool): string { function assignmentLabel (line 36) | function assignmentLabel(a: SpoolAssignment): string { function SpoolCircle (line 43) | function SpoolCircle({ color, size = 56 }: { color: string; size?: numbe... function SpoolBuddyInventoryPage (line 55) | function SpoolBuddyInventoryPage() { function FilterPill (line 259) | function FilterPill({ active, onClick, label, green }: { function CatalogCard (line 282) | function CatalogCard({ spool, assignment, onClick }: { function SpoolDetailModal (line 340) | function SpoolDetailModal({ spool, assignment, sbState, onSyncWeight, on... FILE: frontend/src/pages/spoolbuddy/SpoolBuddySettingsPage.tsx function formatUptime (line 11) | function formatUptime(seconds: number): string { function formatDateTime (line 19) | function formatDateTime(iso: string | null): string { constant BLANK_OPTIONS (line 30) | const BLANK_OPTIONS = [ function DeviceTab (line 41) | function DeviceTab({ device }: { device: SpoolBuddyDevice }) { function DisplayTab (line 227) | function DisplayTab({ device, onBrightnessChange }: { function StepIndicator (line 342) | function StepIndicator({ step, labels }: { step: 'tare' | 'weight'; labe... function ScaleTab (line 379) | function ScaleTab({ device, weight, weightStable, rawAdc }: { function UpdatesTab (line 595) | function UpdatesTab({ device }: { device: SpoolBuddyDevice }) { function UsageBar (line 787) | function UsageBar({ percent, color }: { percent: number; color: string }) { function formatSystemUptime (line 798) | function formatSystemUptime(seconds: number): string { function SystemTab (line 807) | function SystemTab({ device }: { device: SpoolBuddyDevice }) { type SettingsTab (line 948) | type SettingsTab = 'device' | 'display' | 'scale' | 'updates' | 'system'; function SpoolBuddySettingsPage (line 950) | function SpoolBuddySettingsPage() { FILE: frontend/src/pages/spoolbuddy/SpoolBuddyWriteTagPage.tsx type Tab (line 31) | type Tab = 'existing' | 'new' | 'replace'; type WriteStatus (line 32) | type WriteStatus = 'idle' | 'selected' | 'writing' | 'success' | 'error'; constant SIMPLE_COMMON_MATERIALS (line 33) | const SIMPLE_COMMON_MATERIALS = ['PLA', 'PETG', 'ABS', 'ASA', 'TPU', 'PA... function SpoolBuddyWriteTagPage (line 35) | function SpoolBuddyWriteTagPage() { function isReplaceTagged (line 318) | function isReplaceTagged(spool: InventorySpool): boolean { function SpoolListItem (line 323) | function SpoolListItem({ spool, selected, showTag, onClick }: { type NewSpoolSubTab (line 374) | type NewSpoolSubTab = 'filament' | 'pa-profile'; type NewSpoolViewMode (line 375) | type NewSpoolViewMode = 'simple' | 'full'; function NewSpoolTouchForm (line 378) | function NewSpoolTouchForm({ currencySymbol, onCreated, selectedSpool, t... function NfcStatusPanel (line 902) | function NfcStatusPanel({ writeStatus, writeMessage, selectedSpool, tagO... function NfcIcon (line 1084) | function NfcIcon({ className }: { className?: string }) { FILE: frontend/src/types/plates.ts type PlateFilament (line 1) | interface PlateFilament { type PlateMetadata (line 9) | interface PlateMetadata { type ArchivePlatesResponse (line 21) | interface ArchivePlatesResponse { type LibraryFilePlatesResponse (line 28) | interface LibraryFilePlatesResponse { type ViewerPlateSelectionState (line 35) | interface ViewerPlateSelectionState { type PlateAssignment (line 39) | interface PlateAssignment { FILE: frontend/src/utils/amsHelpers.ts function normalizeColor (line 13) | function normalizeColor(color: string | null | undefined): string { function normalizeColorForCompare (line 23) | function normalizeColorForCompare(color: string | undefined): string { constant FILAMENT_TYPE_GROUPS (line 33) | const FILAMENT_TYPE_GROUPS: string[][] = [ function canonicalFilamentType (line 49) | function canonicalFilamentType(type: string | undefined): string { function filamentTypesCompatible (line 58) | function filamentTypesCompatible(a: string | undefined, b: string | unde... function colorsAreSimilar (line 69) | function colorsAreSimilar( function formatSlotLabel (line 99) | function formatSlotLabel( function getGlobalTrayId (line 121) | function getGlobalTrayId( function getFillBarColor (line 136) | function getFillBarColor(fillLevel: number): string { function getSpoolmanFillLevel (line 146) | function getSpoolmanFillLevel( function toFixedHex (line 156) | function toFixedHex(value: number, width: number): string { function hashSerialToHex32 (line 162) | function hashSerialToHex32(serial: string): string { function getFallbackSpoolTag (line 176) | function getFallbackSpoolTag(printerSerial: string, amsId: number, trayI... function getMinDateTime (line 184) | function getMinDateTime(): string { function isPlaceholderDate (line 194) | function isPlaceholderDate(scheduledTime: string | null | undefined): bo... function autoMatchFilament (line 204) | function autoMatchFilament( function filterFilamentsByNozzle (line 247) | function filterFilamentsByNozzle( FILE: frontend/src/utils/colors.ts function setColorCatalog (line 16) | function setColorCatalog(map: Record): void { function subscribeColorCatalog (line 34) | function subscribeColorCatalog(listener: () => void): () => void { function getColorCatalogVersion (line 41) | function getColorCatalogVersion(): number { function __resetColorCatalogForTests (line 46) | function __resetColorCatalogForTests(): void { function hexToColorName (line 56) | function hexToColorName(hex: string | null | undefined): string { function getColorName (line 104) | function getColorName(hexColor: string): string { function resolveSpoolColorName (line 118) | function resolveSpoolColorName(colorName: string | null, rgba: string | ... function parseFilamentColor (line 137) | function parseFilamentColor(rgba: string): string | null { function isLightColor (line 151) | function isLightColor(hex: string | null): boolean { FILE: frontend/src/utils/currency.ts constant CURRENCY_SYMBOLS (line 1) | const CURRENCY_SYMBOLS: Record = { function getCurrencySymbol (line 33) | function getCurrencySymbol(currencyCode: string): string { constant SUPPORTED_CURRENCIES (line 37) | const SUPPORTED_CURRENCIES = Object.entries(CURRENCY_SYMBOLS).map(([code... FILE: frontend/src/utils/date.ts type TimeFormat (line 9) | type TimeFormat = 'system' | '12h' | '24h'; type DateFormat (line 10) | type DateFormat = 'system' | 'us' | 'eu' | 'iso'; function getDatePlaceholder (line 15) | function getDatePlaceholder(dateFormat: DateFormat = 'system'): string { function getTimePlaceholder (line 28) | function getTimePlaceholder(timeFormat: TimeFormat = 'system'): string { function formatDateInput (line 48) | function formatDateInput(date: Date, dateFormat: DateFormat = 'system'):... function formatTimeInput (line 69) | function formatTimeInput(date: Date, timeFormat: TimeFormat = 'system'):... function splitDateParts (line 90) | function splitDateParts(value: string): string[] | null { function detectSystemDateFormat (line 98) | function detectSystemDateFormat(): 'us' | 'eu' | 'iso' { function parseDateInput (line 110) | function parseDateInput(value: string, dateFormat: DateFormat = 'system'... function parseTimeInput (line 149) | function parseTimeInput(value: string): { hours: number; minutes: number... function toDateTimeLocalValue (line 173) | function toDateTimeLocalValue(date: Date): string { function applyTimeFormat (line 186) | function applyTimeFormat( function parseUTCDate (line 206) | function parseUTCDate(dateStr: string | null | undefined): Date | null { function formatDate (line 225) | function formatDate( function formatDateOnly (line 250) | function formatDateOnly( function formatDateTime (line 274) | function formatDateTime( function formatTimeOnly (line 302) | function formatTimeOnly( function formatETA (line 324) | function formatETA( function formatDuration (line 352) | function formatDuration(seconds: number | null | undefined): string { type TranslateFunction (line 361) | type TranslateFunction = (key: string, options?: Record... function formatRelativeTime (line 371) | function formatRelativeTime( function formatMediaTime (line 428) | function formatMediaTime(seconds: number): string { function formatDurationFromHours (line 440) | function formatDurationFromHours(hours: number): string { FILE: frontend/src/utils/file.ts function formatFileSize (line 7) | function formatFileSize(bytes: number): string { FILE: frontend/src/utils/firmwareVersion.ts function compareFwVersions (line 7) | function compareFwVersions(a: string, b: string): number { FILE: frontend/src/utils/maintenanceWikiUrls.ts function getMaintenanceWikiUrl (line 13) | function getMaintenanceWikiUrl(typeName: string, printerModel: string | ... FILE: frontend/src/utils/printName.ts function formatPrintName (line 9) | function formatPrintName( FILE: frontend/src/utils/printer.ts function getPrinterImage (line 1) | function getPrinterImage(model: string | null | undefined): string { function getWifiStrength (line 20) | function getWifiStrength(rssi: number): { labelKey: string; color: strin... function filterCompatibleQueueItems (line 38) | function filterCompatibleQueueItems( FILE: frontend/src/utils/slicer.ts type SlicerType (line 23) | type SlicerType = 'bambu_studio' | 'orcaslicer'; type Platform (line 25) | type Platform = 'windows' | 'macos' | 'linux' | 'unknown'; function detectPlatform (line 30) | function detectPlatform(): Platform { function openInSlicer (line 51) | function openInSlicer(downloadUrl: string, slicer: SlicerType = 'bambu_s... function buildDownloadUrl (line 87) | function buildDownloadUrl(path: string): string { function openArchiveInSlicer (line 96) | function openArchiveInSlicer(path: string, slicer: SlicerType = 'bambu_s... FILE: frontend/src/utils/weight.ts function formatWeight (line 1) | function formatWeight(grams: number): string { FILE: scripts/debug_preset.py function get_token_from_db (line 21) | def get_token_from_db() -> str | None: function test_preset (line 35) | async def test_preset(setting_id: str, token: str, base_url: str = "http... function main (line 62) | async def main(): FILE: scripts/import_spoolman.py function fetch_spoolman_spools (line 16) | def fetch_spoolman_spools(spoolman_url: str) -> list[dict]: function map_spool (line 24) | def map_spool(sm_spool: dict) -> dict: function create_bambuddy_spool (line 98) | def create_bambuddy_spool(bambuddy_url: str, spool_data: dict, api_key: ... function main (line 109) | def main(): FILE: scripts/mqtt_sniffer.py function on_connect (line 22) | def on_connect(client, userdata, flags, rc): function on_message (line 39) | def on_message(client, userdata, msg): function on_disconnect (line 75) | def on_disconnect(client, userdata, rc): function main (line 80) | def main(): FILE: scripts/update_archive_date.py function update_archive_date (line 17) | def update_archive_date(archive_id: int, new_date: datetime) -> bool: function main (line 48) | def main(): FILE: scripts/update_archive_quantities.py function extract_object_count_from_3mf (line 37) | def extract_object_count_from_3mf(file_path: Path) -> int | None: function update_archive_quantities (line 69) | async def update_archive_quantities(dry_run: bool = False): function main (line 142) | def main(): FILE: spoolbuddy/daemon/__init__.py function _read_app_version (line 5) | def _read_app_version() -> str: FILE: spoolbuddy/daemon/api_client.py class APIClient (line 14) | class APIClient: method __init__ (line 15) | def __init__(self, backend_url: str, api_key: str): method close (line 24) | async def close(self): method _post (line 27) | async def _post(self, path: str, data: dict) -> dict | None: method _get (line 41) | async def _get(self, path: str) -> dict | None: method _flush_buffer (line 50) | async def _flush_buffer(self): method register_device (line 60) | async def register_device( method heartbeat (line 100) | async def heartbeat( method tag_scanned (line 133) | async def tag_scanned( method tag_removed (line 152) | async def tag_removed(self, device_id: str, tag_uid: str) -> dict | None: method update_tare (line 161) | async def update_tare(self, device_id: str, tare_offset: int) -> dict ... method scale_reading (line 167) | async def scale_reading( method write_tag_result (line 180) | async def write_tag_result( method report_update_status (line 194) | async def report_update_status(self, device_id: str, status: str, mess... method diagnostic_result (line 200) | async def diagnostic_result( method system_command_result (line 218) | async def system_command_result( FILE: spoolbuddy/daemon/config.py class Config (line 22) | class Config: method load (line 39) | def load(cls) -> "Config": function _get_mac_id (line 63) | def _get_mac_id() -> str: FILE: spoolbuddy/daemon/display_control.py class DisplayControl (line 24) | class DisplayControl: method __init__ (line 25) | def __init__(self): method _find_backlight (line 37) | def _find_backlight(self) -> Path | None: method _read_max_brightness (line 46) | def _read_max_brightness(self) -> int: method has_backlight (line 55) | def has_backlight(self) -> bool: method set_brightness (line 58) | def set_brightness(self, pct: int): method set_blank_timeout (line 75) | def set_blank_timeout(self, seconds: int): method wake (line 79) | def wake(self): method tick (line 91) | def tick(self): method _signal_wake (line 101) | def _signal_wake(self) -> None: FILE: spoolbuddy/daemon/main.py function _spoolbuddy_env_path (line 29) | def _spoolbuddy_env_path() -> Path: function _set_env_value (line 37) | def _set_env_value(path: Path, key: str, value: str): function _get_ip (line 58) | def _get_ip() -> str: function _deploy_ssh_key (line 69) | def _deploy_ssh_key(public_key: str) -> None: function nfc_poll_loop (line 93) | async def nfc_poll_loop(config: Config, api: APIClient, shared: dict): function scale_poll_loop (line 164) | async def scale_poll_loop(config: Config, api: APIClient, shared: dict): function heartbeat_loop (line 210) | async def heartbeat_loop(config: Config, api: APIClient, start_time: flo... function main (line 394) | async def main(): FILE: spoolbuddy/daemon/nau7802.py function _env_int (line 17) | def _env_int(name: str, default: int) -> int: class NAU7802 (line 53) | class NAU7802: method __init__ (line 54) | def __init__(self, bus: int = I2C_BUS, addr: int = NAU7802_ADDR): method close (line 63) | def close(self): method read_reg (line 66) | def read_reg(self, reg: int) -> int: method write_reg (line 69) | def write_reg(self, reg: int, val: int): method _update_bits (line 72) | def _update_bits(self, reg: int, mask: int, value: int): method _set_bit (line 76) | def _set_bit(self, reg: int, bit: int, enabled: bool): method _set_field (line 80) | def _set_field(self, reg: int, shift: int, width: int, value: int): method init (line 84) | def init(self): method begin_calibrate_afe (line 167) | def begin_calibrate_afe(self, mode: int = 0) -> None: method wait_for_calibrate_afe (line 180) | def wait_for_calibrate_afe(self, timeout_ms: int = 1000) -> bool: method calibrate_afe (line 192) | def calibrate_afe(self, timeout_ms: int = 1000, mode: int = 0) -> None: method wait_data_ready (line 209) | def wait_data_ready(self, timeout_s: float = 1.0) -> bool: method flush_readings (line 217) | def flush_readings(self, count: int = 4, timeout_s: float = 1.0) -> None: method data_ready (line 225) | def data_ready(self) -> bool: method read_raw (line 228) | def read_raw(self) -> int: FILE: spoolbuddy/daemon/nfc_reader.py class NFCState (line 13) | class NFCState(Enum): class NFCReader (line 18) | class NFCReader: method __init__ (line 19) | def __init__(self): method _init_rf (line 40) | def _init_rf(self): method _full_reset (line 49) | def _full_reset(self): method reader_type (line 61) | def reader_type(self) -> str: method connection (line 66) | def connection(self) -> str: method ok (line 71) | def ok(self) -> bool: method state (line 75) | def state(self) -> NFCState: method current_uid (line 79) | def current_uid(self) -> str | None: method close (line 82) | def close(self): method current_sak (line 90) | def current_sak(self) -> int | None: method write_ntag (line 93) | def write_ntag(self, data: bytes) -> tuple[bool, str]: method poll (line 127) | def poll(self) -> tuple[str, dict | None]: function _extract_tray_uuid (line 241) | def _extract_tray_uuid(blocks: dict[int, bytes]) -> str | None: FILE: spoolbuddy/daemon/pn5180.py function _env_int (line 24) | def _env_int(name: str, default: int) -> int: function hkdf_derive_keys (line 68) | def hkdf_derive_keys(uid: bytes) -> bytes: function get_sector_key (line 87) | def get_sector_key(keys: bytes, block: int) -> bytes: function _find_gpio_chip (line 93) | def _find_gpio_chip(): class PN5180 (line 105) | class PN5180: method __init__ (line 106) | def __init__(self): method close (line 126) | def close(self): method _cs_low (line 131) | def _cs_low(self): method _cs_high (line 135) | def _cs_high(self): method _wait_busy (line 139) | def _wait_busy(self, timeout_s=1.0): method _cmd (line 154) | def _cmd(self, data): method _read_response (line 160) | def _read_response(self, n): method write_reg (line 168) | def write_reg(self, reg, val): method write_reg_or (line 171) | def write_reg_or(self, reg, mask): method write_reg_and (line 174) | def write_reg_and(self, reg, mask): method read_reg (line 177) | def read_reg(self, reg): method read_eeprom (line 182) | def read_eeprom(self, addr, length): method reset (line 189) | def reset(self): method load_rf_config (line 197) | def load_rf_config(self, tx, rx): method rf_on (line 203) | def rf_on(self): method rf_off (line 207) | def rf_off(self): method set_pin (line 211) | def set_pin(self, pin: int, value: bool) -> None: method get_pin (line 217) | def get_pin(self, pin: int) -> bool: method set_transceive_mode (line 223) | def set_transceive_mode(self): method send_data (line 229) | def send_data(self, data, valid_bits=0x00): method read_data (line 236) | def read_data(self, length): method activate_type_a (line 242) | def activate_type_a(self): method mfc_authenticate (line 323) | def mfc_authenticate(self, block: int, key: bytes, uid: bytes) -> bool: method mfc_read_block (line 360) | def mfc_read_block(self, block: int) -> bytes | None: method ntag_read_pages (line 388) | def ntag_read_pages(self, start_page: int, num_pages: int) -> bytes | ... method reactivate_card (line 436) | def reactivate_card(self) -> tuple[bytes, int] | None: method read_bambu_tag (line 450) | def read_bambu_tag(self, uid: bytes) -> dict[int, bytes] | None: method ntag_write_page (line 500) | def ntag_write_page(self, page: int, data: bytes) -> bool: method ntag_write_pages (line 533) | def ntag_write_pages(self, start_page: int, data: bytes) -> bool: method read_ntag (line 559) | def read_ntag(self, uid: bytes) -> bytes | None: FILE: spoolbuddy/daemon/scale_reader.py class ScaleReader (line 12) | class ScaleReader: method __init__ (line 13) | def __init__(self, tare_offset: int = 0, calibration_factor: float = 1... method ok (line 39) | def ok(self) -> bool: method last_raw (line 43) | def last_raw(self) -> int: method close (line 46) | def close(self): method update_calibration (line 53) | def update_calibration(self, tare_offset: int, calibration_factor: flo... method tare (line 58) | def tare(self): method read (line 67) | def read(self) -> tuple[float, bool, int] | None: FILE: spoolbuddy/daemon/system_stats.py function _read_file (line 7) | def _read_file(path: str) -> str | None: function _cpu_temp (line 15) | def _cpu_temp() -> float | None: function _memory_info (line 25) | def _memory_info() -> dict | None: function _disk_info (line 50) | def _disk_info() -> dict | None: function _load_avg (line 68) | def _load_avg() -> list[float] | None: function _cpu_count (line 76) | def _cpu_count() -> int | None: function _os_info (line 80) | def _os_info() -> dict: function _system_uptime (line 97) | def _system_uptime() -> int | None: function collect (line 107) | def collect() -> dict: FILE: spoolbuddy/daemon/tag_parser.py function parse_bambu_blocks (line 13) | def parse_bambu_blocks(blocks: dict[int, bytes]) -> dict: FILE: spoolbuddy/install/generate_splash.py function radial_gradient (line 32) | def radial_gradient(size, center_color, edge_color): function create_light_rays (line 54) | def create_light_rays(size, num_rays, opacity): function create_vignette (line 83) | def create_vignette(size, strength): function create_glow (line 104) | def create_glow(logo_img, color, radius, intensity=1.5): function generate_splash (line 129) | def generate_splash(output_path): FILE: spoolbuddy/scripts/pn5180_diag.py function _check_spi_device_access (line 61) | def _check_spi_device_access() -> str: function _self_test_control_pins (line 72) | def _self_test_control_pins(nfc: PN5180): function run_diagnostics (line 95) | def run_diagnostics(): FILE: spoolbuddy/scripts/read_tag.py function _env_int (line 23) | def _env_int(name: str, default: int) -> int: function hkdf_derive_keys (line 67) | def hkdf_derive_keys(uid: bytes) -> bytes: function get_sector_key (line 86) | def get_sector_key(keys: bytes, block: int) -> bytes: function _find_gpio_chip (line 92) | def _find_gpio_chip(): class PN5180 (line 104) | class PN5180: method __init__ (line 105) | def __init__(self): method close (line 125) | def close(self): method _cs_low (line 130) | def _cs_low(self): method _cs_high (line 134) | def _cs_high(self): method _wait_busy (line 138) | def _wait_busy(self, timeout_s=1.0): method _cmd (line 153) | def _cmd(self, data): method _read_response (line 159) | def _read_response(self, n): method write_reg (line 167) | def write_reg(self, reg, val): method write_reg_or (line 170) | def write_reg_or(self, reg, mask): method write_reg_and (line 173) | def write_reg_and(self, reg, mask): method read_reg (line 176) | def read_reg(self, reg): method read_eeprom (line 181) | def read_eeprom(self, addr, length): method reset (line 188) | def reset(self): method load_rf_config (line 196) | def load_rf_config(self, tx, rx): method rf_on (line 202) | def rf_on(self): method rf_off (line 206) | def rf_off(self): method set_transceive_mode (line 210) | def set_transceive_mode(self): method send_data (line 216) | def send_data(self, data, valid_bits=0x00): method read_data (line 223) | def read_data(self, length): method activate_type_a (line 229) | def activate_type_a(self): method mfc_authenticate (line 310) | def mfc_authenticate(self, block: int, key: bytes, uid: bytes) -> bool: method mfc_read_block (line 347) | def mfc_read_block(self, block: int) -> bytes | None: method _ntag_reactivate (line 375) | def _ntag_reactivate(self) -> bool: method ntag_read_pages (line 391) | def ntag_read_pages(self, start_page: int, num_pages: int) -> bytes | ... method reactivate_card (line 440) | def reactivate_card(self) -> tuple[bytes, int] | None: method read_bambu_tag (line 454) | def read_bambu_tag(self, uid: bytes) -> dict[int, bytes] | None: method ntag_write_page (line 504) | def ntag_write_page(self, page: int, data: bytes) -> bool: method ntag_write_pages (line 535) | def ntag_write_pages(self, start_page: int, data: bytes) -> bool: method read_ntag (line 561) | def read_ntag(self, uid: bytes) -> bytes | None: function _print_hex_dump (line 575) | def _print_hex_dump(data: bytes, label: str, bytes_per_line: int = 16): function main (line 584) | def main(): FILE: spoolbuddy/scripts/scale_diag.py function _env_int (line 19) | def _env_int(name: str, default: int) -> int: function main (line 55) | def main(): FILE: spoolbuddy/tests/test_api_client.py function api (line 12) | def api(): class TestAPIClientInit (line 16) | class TestAPIClientInit: method test_base_url_construction (line 17) | def test_base_url_construction(self, api): method test_base_url_strips_trailing_slash (line 20) | def test_base_url_strips_trailing_slash(self): method test_api_key_in_headers (line 24) | def test_api_key_in_headers(self): method test_no_api_key_empty_headers (line 28) | def test_no_api_key_empty_headers(self): class TestPost (line 33) | class TestPost: method test_post_success (line 35) | async def test_post_success(self, api): method test_post_failure_buffers_request (line 51) | async def test_post_failure_buffers_request(self, api): method test_post_failure_logs_connection_lost_once (line 61) | async def test_post_failure_logs_connection_lost_once(self, api): method test_post_success_resets_backoff (line 73) | async def test_post_success_resets_backoff(self, api): method test_buffer_max_size (line 85) | async def test_buffer_max_size(self, api): class TestHeartbeat (line 96) | class TestHeartbeat: method test_heartbeat_posts_to_correct_path (line 98) | async def test_heartbeat_posts_to_correct_path(self, api): method test_heartbeat_flushes_buffer_on_success (line 118) | async def test_heartbeat_flushes_buffer_on_success(self, api): method test_heartbeat_returns_none_on_failure (line 133) | async def test_heartbeat_returns_none_on_failure(self, api): class TestRegisterDevice (line 141) | class TestRegisterDevice: method test_register_retries_until_success (line 143) | async def test_register_retries_until_success(self, api): method test_register_sends_all_fields (line 173) | async def test_register_sends_all_fields(self, api): class TestReportUpdateStatus (line 200) | class TestReportUpdateStatus: method test_report_update_status (line 202) | async def test_report_update_status(self, api): method test_report_update_status_failure_returns_none (line 218) | async def test_report_update_status_failure_returns_none(self, api): FILE: spoolbuddy/tests/test_config.py class TestConfigLoad (line 7) | class TestConfigLoad: method test_load_with_all_env_vars (line 10) | def test_load_with_all_env_vars(self, monkeypatch): method test_load_missing_backend_url_raises (line 23) | def test_load_missing_backend_url_raises(self, monkeypatch): method test_load_missing_api_key_raises (line 30) | def test_load_missing_api_key_raises(self, monkeypatch): method test_load_both_missing_raises_backend_url_first (line 37) | def test_load_both_missing_raises_backend_url_first(self, monkeypatch): method test_load_defaults_device_id_from_mac (line 44) | def test_load_defaults_device_id_from_mac(self, monkeypatch, tmp_path): method test_load_defaults_hostname_from_socket (line 64) | def test_load_defaults_hostname_from_socket(self, monkeypatch): method test_load_default_intervals (line 77) | def test_load_default_intervals(self, monkeypatch): class TestGetMacId (line 92) | class TestGetMacId: method test_reads_first_non_lo_interface (line 95) | def test_reads_first_non_lo_interface(self, monkeypatch, tmp_path): method test_skips_loopback (line 116) | def test_skips_loopback(self, monkeypatch, tmp_path): method test_skips_all_zero_mac (line 143) | def test_skips_all_zero_mac(self, monkeypatch, tmp_path): method test_fallback_to_uuid_when_no_interfaces (line 150) | def test_fallback_to_uuid_when_no_interfaces(self, monkeypatch): FILE: spoolbuddy/tests/test_display_control.py class TestDisplayControlNoBacklight (line 8) | class TestDisplayControlNoBacklight: method test_no_backlight_detected (line 11) | def test_no_backlight_detected(self, monkeypatch, tmp_path): method test_no_backlight_dir_missing (line 23) | def test_no_backlight_dir_missing(self, monkeypatch, tmp_path): method test_set_brightness_noop_without_backlight (line 32) | def test_set_brightness_noop_without_backlight(self, monkeypatch, tmp_... class TestDisplayControlWithBacklight (line 47) | class TestDisplayControlWithBacklight: method display (line 51) | def display(self, monkeypatch, tmp_path): method test_has_backlight_true (line 63) | def test_has_backlight_true(self, display): method test_set_brightness_100 (line 67) | def test_set_brightness_100(self, display): method test_set_brightness_0 (line 72) | def test_set_brightness_0(self, display): method test_set_brightness_50 (line 77) | def test_set_brightness_50(self, display): method test_set_brightness_clamped_above_100 (line 84) | def test_set_brightness_clamped_above_100(self, display): method test_set_brightness_clamped_below_0 (line 89) | def test_set_brightness_clamped_below_0(self, display): method test_max_brightness_fallback_on_missing_file (line 94) | def test_max_brightness_fallback_on_missing_file(self, monkeypatch, tm... class TestDisplayControlBlanking (line 109) | class TestDisplayControlBlanking: method display (line 113) | def display(self, monkeypatch, tmp_path): method test_blank_timeout_default_disabled (line 122) | def test_blank_timeout_default_disabled(self, display): method test_set_blank_timeout (line 125) | def test_set_blank_timeout(self, display): method test_set_blank_timeout_negative_clamped (line 129) | def test_set_blank_timeout_negative_clamped(self, display): method test_tick_does_not_blank_when_disabled (line 133) | def test_tick_does_not_blank_when_disabled(self, display): method test_tick_blanks_after_timeout (line 138) | def test_tick_blanks_after_timeout(self, display, monkeypatch): method test_tick_does_not_blank_before_timeout (line 145) | def test_tick_does_not_blank_before_timeout(self, display): method test_wake_unblanks (line 151) | def test_wake_unblanks(self, display): method test_tick_unblanks_when_timeout_disabled_while_blanked (line 160) | def test_tick_unblanks_when_timeout_disabled_while_blanked(self, displ... method test_wake_resets_activity_timer (line 171) | def test_wake_resets_activity_timer(self, display): FILE: spoolbuddy/tests/test_main.py function _make_config (line 13) | def _make_config(**overrides): function _make_api (line 26) | def _make_api(): function _mock_process (line 34) | def _mock_process(returncode=0, stdout=b"", stderr=b""): class TestPerformUpdate (line 41) | class TestPerformUpdate: method test_successful_update (line 43) | async def test_successful_update(self): method test_git_fetch_failure (line 78) | async def test_git_fetch_failure(self): method test_git_reset_failure (line 101) | async def test_git_reset_failure(self): class TestHeartbeatLoopCommands (line 133) | class TestHeartbeatLoopCommands: method test_update_command_triggers_perform_update (line 137) | async def test_update_command_triggers_perform_update(self): method test_update_command_reports_error_on_exception (line 173) | async def test_update_command_reports_error_on_exception(self): method test_tare_command_executes_scale_tare (line 206) | async def test_tare_command_executes_scale_tare(self): method test_tare_command_no_scale_logs_warning (line 242) | async def test_tare_command_no_scale_logs_warning(self): method test_write_tag_command_sets_pending_write (line 273) | async def test_write_tag_command_sets_pending_write(self): method test_display_settings_applied_from_heartbeat (line 313) | async def test_display_settings_applied_from_heartbeat(self): method test_calibration_sync_from_heartbeat (line 347) | async def test_calibration_sync_from_heartbeat(self): FILE: spoolbuddy/tests/test_tag_parser.py class TestParseBambuBlocks (line 6) | class TestParseBambuBlocks: method test_empty_dict_returns_empty (line 9) | def test_empty_dict_returns_empty(self): method test_tray_uuid_from_blocks_4_and_5 (line 13) | def test_tray_uuid_from_blocks_4_and_5(self): method test_tray_uuid_missing_block_4 (line 25) | def test_tray_uuid_missing_block_4(self): method test_tray_uuid_missing_block_5 (line 30) | def test_tray_uuid_missing_block_5(self): method test_material_raw_from_block_1 (line 35) | def test_material_raw_from_block_1(self): method test_block2_raw_from_block_2 (line 43) | def test_block2_raw_from_block_2(self): method test_all_blocks_present (line 51) | def test_all_blocks_present(self): method test_extra_blocks_ignored (line 64) | def test_extra_blocks_ignored(self): method test_tray_uuid_hex_uppercase (line 70) | def test_tray_uuid_hex_uppercase(self): FILE: static/assets/index-NbcE7Ots.js function Fde (line 1) | function Fde(t,e){for(var n=0;n{this.observers[r]||(this.observe... method off (line 9) | off(e,n){if(this.observers[e]){if(!n){delete this.observers[e];return}th... method emit (line 9) | emit(e,...n){this.observers[e]&&Array.from(this.observers[e].entries()).... class H8 (line 9) | class H8 extends IP{constructor(e,n={ns:["translation"],defaultNS:"trans... method constructor (line 9) | constructor(e,n={ns:["translation"],defaultNS:"translation"}){super(),... method addNamespaces (line 9) | addNamespaces(e){this.options.ns.indexOf(e)<0&&this.options.ns.push(e)} method removeNamespaces (line 9) | removeNamespaces(e){const n=this.options.ns.indexOf(e);n>-1&&this.opti... method getResource (line 9) | getResource(e,n,r,i={}){const s=i.keySeparator!==void 0?i.keySeparator... method addResource (line 9) | addResource(e,n,r,i,s={silent:!1}){const o=s.keySeparator!==void 0?s.k... method addResources (line 9) | addResources(e,n,r,i={silent:!1}){for(const s in r)(Hn(r[s])||Array.is... method addResourceBundle (line 9) | addResourceBundle(e,n,r,i,s,o={silent:!1,skipCopy:!1}){let l=[e,n];e.i... method removeResourceBundle (line 9) | removeResourceBundle(e,n){this.hasResourceBundle(e,n)&&delete this.dat... method hasResourceBundle (line 9) | hasResourceBundle(e,n){return this.getResource(e,n)!==void 0} method getResourceBundle (line 9) | getResourceBundle(e,n){return n||(n=this.options.defaultNS),this.getRe... method getDataByLanguage (line 9) | getDataByLanguage(e){return this.data[e]} method hasLanguageSomeTranslations (line 9) | hasLanguageSomeTranslations(e){const n=this.getDataByLanguage(e);retur... method toJSON (line 9) | toJSON(){return this.data} method addPostProcessor (line 9) | addPostProcessor(t){this.processors[t.name]=t} method handle (line 9) | handle(t,e,n,r,i){return t.forEach(s=>{e=this.processors[s]?.process(e,n... function nue (line 9) | function nue(){const t=[],e=Object.create(null);let n;return e.get=(r,i)... function q3 (line 9) | function q3(t,e){const{[qY]:n}=t(nue());return n.join(e?.keySeparator??"... class pN (line 9) | class pN extends IP{constructor(e,n={}){super(),Vde(["resourceStore","la... method constructor (line 9) | constructor(e,n={}){super(),Vde(["resourceStore","languageUtils","plur... method changeLanguage (line 9) | changeLanguage(e){e&&(this.language=e)} method exists (line 9) | exists(e,n={interpolation:{}}){const r={...n};if(e==null)return!1;cons... method extractFromKey (line 9) | extractFromKey(e,n){let r=n.nsSeparator!==void 0?n.nsSeparator:this.op... method translate (line 9) | translate(e,n,r){let i=typeof n=="object"?{...n}:n;if(typeof i!="objec... method extendTranslation (line 9) | extendTranslation(e,n,r,i,s){if(this.i18nFormat?.parse)e=this.i18nForm... method resolve (line 9) | resolve(e,n={}){let r,i,s,o,l;return Hn(e)&&(e=[e]),e.forEach(c=>{if(t... method isValidLookup (line 9) | isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===nu... method getResource (line 9) | getResource(e,n,r,i={}){return this.i18nFormat?.getResource?this.i18nF... method getUsedParamsDetails (line 9) | getUsedParamsDetails(e={}){const n=["defaultValue","ordinal","context"... method hasDefaultValue (line 9) | static hasDefaultValue(e){const n="defaultValue";for(const r in e)if(O... class $8 (line 9) | class $8{constructor(e){this.options=e,this.supportedLngs=this.options.s... method constructor (line 9) | constructor(e){this.options=e,this.supportedLngs=this.options.supporte... method getScriptPartFromCode (line 9) | getScriptPartFromCode(e){if(e=ew(e),!e||e.indexOf("-")<0)return null;c... method getLanguagePartFromCode (line 9) | getLanguagePartFromCode(e){if(e=ew(e),!e||e.indexOf("-")<0)return e;co... method formatLanguageCode (line 9) | formatLanguageCode(e){if(Hn(e)&&e.indexOf("-")>-1){let n;try{n=Intl.ge... method isSupportedCode (line 9) | isSupportedCode(e){return(this.options.load==="languageOnly"||this.opt... method getBestMatchFromCodes (line 9) | getBestMatchFromCodes(e){if(!e)return null;let n;return e.forEach(r=>{... method getFallbackCodes (line 9) | getFallbackCodes(e,n){if(!e)return[];if(typeof e=="function"&&(e=e(n))... method toResolveHierarchy (line 9) | toResolveHierarchy(e,n){const r=this.getFallbackCodes((n===!1?[]:n)||t... class rue (line 9) | class rue{constructor(e,n={}){this.languageUtils=e,this.options=n,this.l... method constructor (line 9) | constructor(e,n={}){this.languageUtils=e,this.options=n,this.logger=Ad... method addRule (line 9) | addRule(e,n){this.rules[e]=n} method clearCache (line 9) | clearCache(){this.pluralRulesCache={}} method getRule (line 9) | getRule(e,n={}){const r=ew(e==="dev"?"en":e),i=n.ordinal?"ordinal":"ca... method needsPlural (line 9) | needsPlural(e,n={}){let r=this.getRule(e,n);return r||(r=this.getRule(... method getPluralFormsOfKey (line 9) | getPluralFormsOfKey(e,n,r={}){return this.getSuffixes(e,r).map(i=>`${n... method getSuffixes (line 9) | getSuffixes(e,n={}){let r=this.getRule(e,n);return r||(r=this.getRule(... method getSuffix (line 9) | getSuffix(e,n,r={}){const i=this.getRule(e,r);return i?`${this.options... class aue (line 9) | class aue{constructor(e={}){this.logger=Ad.create("interpolator"),this.o... method constructor (line 9) | constructor(e={}){this.logger=Ad.create("interpolator"),this.options=e... method init (line 9) | init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{e... method reset (line 9) | reset(){this.options&&this.init(this.options)} method resetRegExp (line 9) | resetRegExp(){const e=(n,r)=>n?.source===r?(n.lastIndex=0,n):new RegEx... method interpolate (line 9) | interpolate(e,n,r,i){let s,o,l;const c=this.options&&this.options.inte... method nest (line 9) | nest(e,n,r={}){let i,s,o;const l=(c,d)=>{const u=this.nestingOptionsSe... class oue (line 9) | class oue{constructor(e={}){this.logger=Ad.create("formatter"),this.opti... method constructor (line 9) | constructor(e={}){this.logger=Ad.create("formatter"),this.options=e,th... method init (line 9) | init(e,n={interpolation:{}}){this.formatSeparator=n.interpolation.form... method add (line 9) | add(e,n){this.formats[e.toLowerCase().trim()]=n} method addCached (line 9) | addCached(e,n){this.formats[e.toLowerCase().trim()]=K8(n)} method format (line 9) | format(e,n,r,i={}){const s=n.split(this.formatSeparator);if(s.length>1... class cue (line 9) | class cue extends IP{constructor(e,n,r,i={}){super(),this.backend=e,this... method constructor (line 9) | constructor(e,n,r,i={}){super(),this.backend=e,this.store=n,this.servi... method queueLoad (line 9) | queueLoad(e,n,r,i){const s={},o={},l={},c={};return e.forEach(d=>{let ... method loaded (line 9) | loaded(e,n,r){const i=e.split("|"),s=i[0],o=i[1];n&&this.emit("failedL... method read (line 9) | read(e,n,r,i=0,s=this.retryTimeout,o){if(!e.length)return o(null,{});i... method prepareLoading (line 9) | prepareLoading(e,n,r={},i){if(!this.backend)return this.logger.warn("N... method load (line 9) | load(e,n,r){this.prepareLoading(e,n,{},r)} method reload (line 9) | reload(e,n,r){this.prepareLoading(e,n,{reload:!0},r)} method loadOne (line 9) | loadOne(e,n=""){const r=e.split("|"),i=r[0],s=r[1];this.read(i,s,"read... method saveMissing (line 9) | saveMissing(e,n,r,i,s,o={},l=()=>{}){if(this.services?.utils?.hasLoade... class T0 (line 9) | class T0 extends IP{constructor(e={},n){if(super(),this.options=Y8(e),th... method constructor (line 9) | constructor(e={},n){if(super(),this.options=Y8(e),this.services={},thi... method init (line 9) | init(e={},n){this.isInitializing=!0,typeof e=="function"&&(n=e,e={}),e... method loadResources (line 9) | loadResources(e,n=K_){let r=n;const i=Hn(e)?e:this.language;if(typeof ... method reloadResources (line 9) | reloadResources(e,n,r){const i=jv();return typeof e=="function"&&(r=e,... method use (line 9) | use(e){if(!e)throw new Error("You are passing an undefined module! Ple... method setResolvedLanguage (line 9) | setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].i... method changeLanguage (line 9) | changeLanguage(e,n){this.isLanguageChangingTo=e;const r=jv();this.emit... method getFixedT (line 9) | getFixedT(e,n,r){const i=(s,o,...l)=>{let c;typeof o!="object"?c=this.... method t (line 9) | t(...e){return this.translator?.translate(...e)} method exists (line 9) | exists(...e){return this.translator?.exists(...e)} method setDefaultNamespace (line 9) | setDefaultNamespace(e){this.options.defaultNS=e} method hasLoadedNamespace (line 9) | hasLoadedNamespace(e,n={}){if(!this.isInitialized)return this.logger.w... method loadNamespaces (line 9) | loadNamespaces(e,n){const r=jv();return this.options.ns?(Hn(e)&&(e=[e]... method loadLanguages (line 9) | loadLanguages(e,n){const r=jv();Hn(e)&&(e=[e]);const i=this.options.pr... method dir (line 9) | dir(e){if(e||(e=this.resolvedLanguage||(this.languages?.length>0?this.... method createInstance (line 9) | static createInstance(e={},n){const r=new T0(e,n);return r.createInsta... method cloneInstance (line 9) | cloneInstance(e={},n=K_){const r=e.forkResourceStore;r&&delete e.forkR... method toJSON (line 9) | toJSON(){return{options:this.options,store:this.store,language:this.la... method init (line 9) | init(t){xue(t.options.react),vue(t)} class kue (line 9) | class kue{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.fo... method constructor (line 9) | constructor(){this.usedNamespaces={}} method addUsedNamespaces (line 9) | addUsedNamespaces(e){e.forEach(n=>{this.usedNamespaces[n]||(this.usedN... method getUsedNamespaces (line 9) | getUsedNamespaces(){return Object.keys(this.usedNamespaces)} function Nue (line 9) | function Nue(){if(J8)return kM;J8=1;var t=Rg();function e(m,p){return m=... function WY (line 9) | function WY(){return eH||(eH=1,_M.exports=Nue()),_M.exports} function Mue (line 9) | function Mue(t){return jue.call(Aue.call(arguments,1),e=>{if(e)for(const... function Eue (line 9) | function Eue(t){return typeof t!="string"?!1:[/<\s*script.*?>/i,/<\s*\/\... method create (line 9) | create(t,e,n,r){let i=arguments.length>4&&arguments[4]!==void 0?argument... method read (line 9) | read(t){const e=`${t}=`,n=document.cookie.split(";");for(let r=0;r"u")return;const... method lookup (line 9) | lookup(t){let{lookupFromSubdomainIndex:e}=t;const n=typeof e=="number"?e... class YY (line 9) | class YY{constructor(e){let n=arguments.length>1&&arguments[1]!==void 0?... method constructor (line 9) | constructor(e){let n=arguments.length>1&&arguments[1]!==void 0?argumen... method init (line 9) | init(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{l... method addDetector (line 9) | addDetector(e){return this.detectors[e.name]=e,this} method detect (line 9) | detect(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:... method cacheUserLanguage (line 9) | cacheUserLanguage(e){let n=arguments.length>1&&arguments[1]!==void 0?a... function Jue (line 33) | function Jue(t={}){function e(r,i){let{pathname:s,search:o,hash:l}=r.loc... function ja (line 33) | function ja(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)} function lc (line 33) | function lc(t,e){if(!t){typeof console<"u"&&console.warn(e);try{throw ne... function eme (line 33) | function eme(){return Math.random().toString(36).substring(2,10)} function oH (line 33) | function oH(t,e){return{usr:t.state,key:t.key,idx:e}} function G3 (line 33) | function G3(t,e,n=null,r){return{pathname:typeof t=="string"?t:t.pathnam... function tw (line 33) | function tw({pathname:t="/",search:e="",hash:n=""}){return e&&e!=="?"&&(... function gy (line 33) | function gy(t){let e={};if(t){let n=t.indexOf("#");n>=0&&(e.hash=t.subst... function tme (line 33) | function tme(t,e,n,r={}){let{window:i=document.defaultView,v5Compat:s=!1... function nme (line 33) | function nme(t,e=!1){let n="http://localhost";typeof window<"u"&&(n=wind... function QY (line 33) | function QY(t,e,n="/"){return rme(t,e,n,!1)} function rme (line 33) | function rme(t,e,n,r){let i=typeof e=="string"?gy(e):e,s=fm(i.pathname||... function ZY (line 33) | function ZY(t,e=[],n=[],r="",i=!1){let s=(o,l,c=i,d)=>{let u={relativePa... function JY (line 33) | function JY(t){let e=t.split("/");if(e.length===0)return[];let[n,...r]=e... function ame (line 33) | function ame(t){t.sort((e,n)=>e.score!==n.score?n.score-e.score:mme(e.ro... function ume (line 33) | function ume(t,e){let n=t.split("/"),r=n.length;return n.some(lH)&&(r+=d... function mme (line 33) | function mme(t,e){return t.length===e.length&&t.slice(0,-1).every((r,i)=... function hme (line 33) | function hme(t,e,n=!1){let{routesMeta:r}=t,i={},s="/",o=[];for(let l=0;l... function fN (line 33) | function fN(t,e){typeof t=="string"&&(t={path:t,caseSensitive:!1,end:!0}... function pme (line 33) | function pme(t,e=!1,n=!0){lc(t==="*"||!t.endsWith("*")||t.endsWith("/*")... function fme (line 33) | function fme(t){try{return t.split("/").map(e=>decodeURIComponent(e).rep... function fm (line 33) | function fm(t,e){if(e==="/")return t;if(!t.toLowerCase().startsWith(e.to... function bme (line 33) | function bme(t,e="/"){let{pathname:n,search:r="",hash:i=""}=typeof t=="s... function cH (line 33) | function cH(t,e){let n=e.replace(/\/+$/,"").split("/");return t.split("/... function NM (line 33) | function NM(t,e,n,r){return`Cannot include a '${t}' character in a manua... function xme (line 33) | function xme(t){return t.filter((e,n)=>n===0||e.route.path&&e.route.path... function pO (line 33) | function pO(t){let e=xme(t);return e.map((n,r)=>r===e.length-1?n.pathnam... function fO (line 33) | function fO(t,e,n,r=!1){let i;typeof t=="string"?i=gy(t):(i={...t},ja(!i... method constructor (line 33) | constructor(t,e,n,r=!1){this.status=t,this.statusText=e||"",this.interna... function _me (line 33) | function _me(t){return t!=null&&typeof t.status=="number"&&typeof t.stat... function kme (line 33) | function kme(t){return t.map(e=>e.route.path).filter(Boolean).join("/").... function tQ (line 33) | function tQ(t,e){let n=t;if(typeof n!="string"||!gme.test(n))return{abso... function Mme (line 33) | function Mme(t){if(t.startsWith(`${aQ}:${Ame}:{`))try{let e=JSON.parse(t... function Eme (line 33) | function Eme(t){if(t.startsWith(`${aQ}:${jme}:{`))try{let e=JSON.parse(t... function Dme (line 33) | function Dme(t,{relative:e}={}){ja(xy(),"useHref() may be used only in t... function xy (line 33) | function xy(){return w.useContext(Xw)!=null} function td (line 33) | function td(){return ja(xy(),"useLocation() may be used only in the cont... function sQ (line 33) | function sQ(t){w.useContext(Sl).static||w.useLayoutEffect(t)} function qo (line 33) | function qo(){let{isDataRoute:t}=w.useContext(xc);return t?Wme():Fme()} function Fme (line 33) | function Fme(){ja(xy(),"useNavigate() may be used only in the context of... function yy (line 33) | function yy(){return w.useContext(oQ)} function Rme (line 33) | function Rme(t){let e=w.useContext(xc).outlet;return w.useMemo(()=>e&&w.... function Yw (line 33) | function Yw(){let{matches:t}=w.useContext(xc),e=t[t.length-1];return e?e... function Qw (line 33) | function Qw(t,{relative:e}={}){let{matches:n}=w.useContext(xc),{pathname... function Lme (line 33) | function Lme(t,e){return lQ(t,e)} function lQ (line 33) | function lQ(t,e,n,r,i){ja(xy(),"useRoutes() may be used only in the cont... function Ome (line 35) | function Ome(){let t=Gme(),e=_me(t)?`${t.status} ${t.statusText}`:t inst... method constructor (line 35) | constructor(t){super(t),this.state={location:t.location,revalidation:t.r... method getDerivedStateFromError (line 35) | static getDerivedStateFromError(t){return{error:t}} method getDerivedStateFromProps (line 35) | static getDerivedStateFromProps(t,e){return e.location!==t.location||e.r... method componentDidCatch (line 35) | componentDidCatch(t,e){this.props.onError?this.props.onError(t,e):consol... method render (line 35) | render(){let t=this.state.error;if(this.context&&typeof t=="object"&&t&&... function zme (line 35) | function zme({children:t,error:e}){let{basename:n}=w.useContext(Sl);if(t... function Ume (line 35) | function Ume({routeContext:t,match:e,children:n}){let r=w.useContext(by)... function Bme (line 35) | function Bme(t,e=[],n=null,r=null,i=null){if(t==null){if(!n)return null;... function bO (line 35) | function bO(t){return`${t} must be used within a data router. See https... function Hme (line 35) | function Hme(t){let e=w.useContext(by);return ja(e,bO(t)),e} function qme (line 35) | function qme(t){let e=w.useContext(zP);return ja(e,bO(t)),e} function $me (line 35) | function $me(t){let e=w.useContext(xc);return ja(e,bO(t)),e} function xO (line 35) | function xO(t){let e=$me(t),n=e.matches[e.matches.length-1];return ja(n.... function Vme (line 35) | function Vme(){return xO("useRouteId")} function Gme (line 35) | function Gme(){let t=w.useContext(gO),e=qme("useRouteError"),n=xO("useRo... function Wme (line 35) | function Wme(){let{router:t}=Hme("useNavigate"),e=xO("useNavigate"),n=w.... function dQ (line 35) | function dQ(t,e,n){!e&&!dH[t]&&(dH[t]=!0,lc(!1,n))} function Kme (line 35) | function Kme({routes:t,future:e,state:n,onError:r}){return lQ(t,void 0,n... function Bx (line 35) | function Bx({to:t,replace:e,state:n,relative:r}){ja(xy()," may... function uQ (line 35) | function uQ(t){return Rme(t.context)} function Or (line 35) | function Or(t){ja(!1,"A is only ever to be used as the child of ... function Xme (line 35) | function Xme({basename:t="/",children:e=null,location:n,navigationType:r... function Yme (line 35) | function Yme({children:t,location:e}){return Lme(W3(t),e)} function W3 (line 35) | function W3(t,e=[]){let n=[];return w.Children.forEach(t,(r,i)=>{if(!w.i... function UP (line 35) | function UP(t){return typeof HTMLElement<"u"&&t instanceof HTMLElement} function Qme (line 35) | function Qme(t){return UP(t)&&t.tagName.toLowerCase()==="button"} function Zme (line 35) | function Zme(t){return UP(t)&&t.tagName.toLowerCase()==="form"} function Jme (line 35) | function Jme(t){return UP(t)&&t.tagName.toLowerCase()==="input"} function ehe (line 35) | function ehe(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)} function the (line 35) | function the(t,e){return t.button===0&&(!e||e==="_self")&&!ehe(t)} function K3 (line 35) | function K3(t=""){return new URLSearchParams(typeof t=="string"||Array.i... function nhe (line 35) | function nhe(t,e){let n=K3(t);return e&&e.forEach((r,i)=>{n.has(i)||e.ge... function rhe (line 35) | function rhe(){if(X_===null)try{new FormData(document.createElement("for... function PM (line 35) | function PM(t){return t!=null&&!ahe.has(t)?(lc(!1,`"${t}" is not a valid... function ihe (line 35) | function ihe(t,e){let n,r,i,s,o;if(Zme(t)){let l=t.getAttribute("action"... function yO (line 35) | function yO(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)} function she (line 35) | function she(t,e,n,r){let i=typeof t=="string"?new URL(t,typeof window>"... function ohe (line 35) | async function ohe(t,e){if(t.id in e)return e[t.id];try{let n=await impo... function lhe (line 35) | function lhe(t){return t==null?!1:t.href==null?t.rel==="preload"&&typeof... function che (line 35) | async function che(t,e,n){let r=await Promise.all(t.map(async i=>{let s=... function uH (line 35) | function uH(t,e,n,r,i,s){let o=(c,d)=>n[d]?c.route.id!==n[d].route.id:!0... function dhe (line 35) | function dhe(t,e,{includeHydrateFallback:n}={}){return uhe(t.map(r=>{let... function uhe (line 35) | function uhe(t){return[...new Set(t)]} function mhe (line 35) | function mhe(t){let e={},n=Object.keys(t).sort();for(let r of n)e[r]=t[r... function hhe (line 35) | function hhe(t,e){let n=new Set;return new Set(e),t.reduce((r,i)=>{let s... function mQ (line 35) | function mQ(){let t=w.useContext(by);return yO(t,"You must render this e... function phe (line 35) | function phe(){let t=w.useContext(zP);return yO(t,"You must render this ... function hQ (line 35) | function hQ(){let t=w.useContext(vO);return yO(t,"You must render this e... function fhe (line 35) | function fhe(t,e){let n=w.useContext(vO),[r,i]=w.useState(!1),[s,o]=w.us... function Mv (line 35) | function Mv(t,e){return n=>{t&&t(n),n.defaultPrevented||e(n)}} function ghe (line 35) | function ghe({page:t,...e}){let{router:n}=mQ(),r=w.useMemo(()=>QY(n.rout... function bhe (line 35) | function bhe(t){let{manifest:e,routeModules:n}=hQ(),[r,i]=w.useState([])... function xhe (line 35) | function xhe({page:t,matches:e,...n}){let r=td(),{future:i,manifest:s,ro... function yhe (line 35) | function yhe(...t){return e=>{t.forEach(n=>{typeof n=="function"?n(e):n!... function whe (line 35) | function whe({basename:t,children:e,unstable_useTransitions:n,window:r})... function F (line 35) | function F(D){e&&e(D),D.defaultPrevented||T(D)} function _he (line 35) | function _he(t){return`${t} must be used within a data router. See http... function fQ (line 35) | function fQ(t){let e=w.useContext(by);return ja(e,_he(t)),e} function khe (line 35) | function khe(t,{target:e,replace:n,state:r,preventScrollReset:i,relative... function BP (line 35) | function BP(t){lc(typeof URLSearchParams<"u","You cannot use the `useSea... function Phe (line 35) | function Phe(){let{router:t}=fQ("useSubmit"),{basename:e}=w.useContext(S... function The (line 35) | function The(t,{relative:e}={}){let{basename:n}=w.useContext(Sl),r=w.use... function Ahe (line 35) | function Ahe(t,{relative:e}={}){let n=w.useContext(rQ);ja(n!=null,"`useV... method constructor (line 35) | constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(... method subscribe (line 35) | subscribe(t){return this.listeners.add(t),this.onSubscribe(),()=>{this.l... method hasListeners (line 35) | hasListeners(){return this.listeners.size>0} method onSubscribe (line 35) | onSubscribe(){} method onUnsubscribe (line 35) | onUnsubscribe(){} method setTimeoutProvider (line 35) | setTimeoutProvider(t){this.#t=t} method setTimeout (line 35) | setTimeout(t,e){return this.#t.setTimeout(t,e)} method clearTimeout (line 35) | clearTimeout(t){this.#t.clearTimeout(t)} method setInterval (line 35) | setInterval(t,e){return this.#t.setInterval(t,e)} method clearInterval (line 35) | clearInterval(t){this.#t.clearInterval(t)} function Dhe (line 35) | function Dhe(t){setTimeout(t,0)} function Is (line 35) | function Is(){} function Fhe (line 35) | function Fhe(t,e){return typeof t=="function"?t(e):t} function X3 (line 35) | function X3(t){return typeof t=="number"&&t>=0&&t!==1/0} function gQ (line 35) | function gQ(t,e){return Math.max(t+(e||0)-Date.now(),0)} function Qh (line 35) | function Qh(t,e){return typeof t=="function"?t(e):t} function Vl (line 35) | function Vl(t,e){return typeof t=="function"?t(e):t} function mH (line 35) | function mH(t,e){const{type:n="all",exact:r,fetchStatus:i,predicate:s,qu... function hH (line 35) | function hH(t,e){const{exact:n,status:r,predicate:i,mutationKey:s}=t;if(... function wO (line 35) | function wO(t,e){return(e?.queryKeyHashFn||lg)(t)} function lg (line 35) | function lg(t){return JSON.stringify(t,(e,n)=>Y3(n)?Object.keys(n).sort(... function nw (line 35) | function nw(t,e){return t===e?!0:typeof t!=typeof e?!1:t&&e&&typeof t=="... function SO (line 35) | function SO(t,e,n=0){if(t===e)return t;if(n>500)return e;const r=pH(t)&&... function rw (line 35) | function rw(t,e){if(!e||Object.keys(t).length!==Object.keys(e).length)re... function pH (line 35) | function pH(t){return Array.isArray(t)&&t.length===Object.keys(t).length} function Y3 (line 35) | function Y3(t){if(!fH(t))return!1;const e=t.constructor;if(e===void 0)re... function fH (line 35) | function fH(t){return Object.prototype.toString.call(t)==="[object Objec... function Lhe (line 35) | function Lhe(t){return new Promise(e=>{Ff.setTimeout(e,t)})} function Q3 (line 35) | function Q3(t,e,n){return typeof n.structuralSharing=="function"?n.struc... function Ohe (line 35) | function Ohe(t,e,n=0){const r=[...t,e];return n&&r.length>n?r.slice(1):r} function Ihe (line 35) | function Ihe(t,e,n=0){const r=[e,...t];return n&&r.length>n?r.slice(0,-1... function bQ (line 35) | function bQ(t,e){return!t.queryFn&&e?.initialPromise?()=>e.initialPromis... function kO (line 35) | function kO(t,e){return typeof t=="function"?t(...e):!!t} function zhe (line 35) | function zhe(t,e,n){let r=!1,i;return Object.defineProperty(t,"signal",{... method constructor (line 35) | constructor(){super(),this.#n=t=>{if(!og&&window.addEventListener){const... method onSubscribe (line 35) | onSubscribe(){this.#e||this.setEventListener(this.#n)} method onUnsubscribe (line 35) | onUnsubscribe(){this.hasListeners()||(this.#e?.(),this.#e=void 0)} method setEventListener (line 35) | setEventListener(t){this.#n=t,this.#e?.(),this.#e=t(e=>{typeof e=="boole... method setFocused (line 35) | setFocused(t){this.#t!==t&&(this.#t=t,this.onFocus())} method onFocus (line 35) | onFocus(){const t=this.isFocused();this.listeners.forEach(e=>{e(t)})} method isFocused (line 35) | isFocused(){return typeof this.#t=="boolean"?this.#t:globalThis.document... function Z3 (line 35) | function Z3(){let t,e;const n=new Promise((i,s)=>{t=i,e=s});n.status="pe... function Hhe (line 35) | function Hhe(){let t=[],e=0,n=l=>{l()},r=l=>{l()},i=Bhe;const s=l=>{e?t.... method constructor (line 35) | constructor(){super(),this.#n=t=>{if(!og&&window.addEventListener){const... method onSubscribe (line 35) | onSubscribe(){this.#e||this.setEventListener(this.#n)} method onUnsubscribe (line 35) | onUnsubscribe(){this.hasListeners()||(this.#e?.(),this.#e=void 0)} method setEventListener (line 35) | setEventListener(t){this.#n=t,this.#e?.(),this.#e=t(this.setOnline.bind(... method setOnline (line 35) | setOnline(t){this.#t!==t&&(this.#t=t,this.listeners.forEach(n=>{n(t)}))} method isOnline (line 35) | isOnline(){return this.#t} function $he (line 35) | function $he(t){return Math.min(1e3*2**t,3e4)} function xQ (line 35) | function xQ(t){return(t??"online")==="online"?gN.isOnline():!0} method constructor (line 35) | constructor(t){super("CancelledError"),this.revert=t?.revert,this.silent... function yQ (line 35) | function yQ(t){let e=!1,n=0,r;const i=Z3(),s=()=>i.status!=="pending",o=... method destroy (line 35) | destroy(){this.clearGcTimeout()} method scheduleGc (line 35) | scheduleGc(){this.clearGcTimeout(),X3(this.gcTime)&&(this.#t=Ff.setTimeo... method updateGcTime (line 35) | updateGcTime(t){this.gcTime=Math.max(this.gcTime||0,t??(og?1/0:300*1e3))} method clearGcTimeout (line 35) | clearGcTimeout(){this.#t&&(Ff.clearTimeout(this.#t),this.#t=void 0)} method constructor (line 35) | constructor(t){super(),this.#o=!1,this.#i=t.defaultOptions,this.setOptio... method meta (line 35) | get meta(){return this.options.meta} method promise (line 35) | get promise(){return this.#r?.promise} method setOptions (line 35) | setOptions(t){if(this.options={...this.#i,...t},this.updateGcTime(this.o... method optionalRemove (line 35) | optionalRemove(){!this.observers.length&&this.state.fetchStatus==="idle"... method setData (line 35) | setData(t,e){const n=Q3(this.state.data,t,this.options);return this.#s({... method setState (line 35) | setState(t,e){this.#s({type:"setState",state:t,setStateOptions:e})} method cancel (line 35) | cancel(t){const e=this.#r?.promise;return this.#r?.cancel(t),e?e.then(Is... method destroy (line 35) | destroy(){super.destroy(),this.cancel({silent:!0})} method reset (line 35) | reset(){this.destroy(),this.setState(this.#t)} method isActive (line 35) | isActive(){return this.observers.some(t=>Vl(t.options.enabled,this)!==!1)} method isDisabled (line 35) | isDisabled(){return this.getObserversCount()>0?!this.isActive():this.opt... method isStatic (line 35) | isStatic(){return this.getObserversCount()>0?this.observers.some(t=>Qh(t... method isStale (line 35) | isStale(){return this.getObserversCount()>0?this.observers.some(t=>t.get... method isStaleByTime (line 35) | isStaleByTime(t=0){return this.state.data===void 0?!0:t==="static"?!1:th... method onFocus (line 35) | onFocus(){this.observers.find(e=>e.shouldFetchOnWindowFocus())?.refetch(... method onOnline (line 35) | onOnline(){this.observers.find(e=>e.shouldFetchOnReconnect())?.refetch({... method addObserver (line 35) | addObserver(t){this.observers.includes(t)||(this.observers.push(t),this.... method removeObserver (line 35) | removeObserver(t){this.observers.includes(t)&&(this.observers=this.obser... method getObserversCount (line 35) | getObserversCount(){return this.observers.length} method invalidate (line 35) | invalidate(){this.state.isInvalidated||this.#s({type:"invalidate"})} method fetch (line 35) | async fetch(t,e){if(this.state.fetchStatus!=="idle"&&this.#r?.status()!=... method #s (line 35) | #s(t){const e=n=>{switch(t.type){case"failed":return{...n,fetchFailureCo... function wQ (line 35) | function wQ(t,e){return{fetchFailureCount:0,fetchFailureReason:null,fetc... function gH (line 35) | function gH(t,e){return{data:t,dataUpdatedAt:e??Date.now(),error:null,is... function bH (line 35) | function bH(t){const e=typeof t.initialData=="function"?t.initialData():... method constructor (line 35) | constructor(t,e){super(),this.options=e,this.#t=t,this.#s=null,this.#o=Z... method bindMethods (line 35) | bindMethods(){this.refetch=this.refetch.bind(this)} method onSubscribe (line 35) | onSubscribe(){this.listeners.size===1&&(this.#e.addObserver(this),xH(thi... method onUnsubscribe (line 35) | onUnsubscribe(){this.hasListeners()||this.destroy()} method shouldFetchOnReconnect (line 35) | shouldFetchOnReconnect(){return eF(this.#e,this.options,this.options.ref... method shouldFetchOnWindowFocus (line 35) | shouldFetchOnWindowFocus(){return eF(this.#e,this.options,this.options.r... method destroy (line 35) | destroy(){this.listeners=new Set,this.#v(),this.#w(),this.#e.removeObser... method setOptions (line 35) | setOptions(t){const e=this.options,n=this.#e;if(this.options=this.#t.def... method getOptimisticResult (line 35) | getOptimisticResult(t){const e=this.#t.getQueryCache().build(this.#t,t),... method getCurrentResult (line 35) | getCurrentResult(){return this.#a} method trackResult (line 35) | trackResult(t,e){return new Proxy(t,{get:(n,r)=>(this.trackProp(r),e?.(r... method trackProp (line 35) | trackProp(t){this.#h.add(t)} method getCurrentQuery (line 35) | getCurrentQuery(){return this.#e} method refetch (line 35) | refetch({...t}={}){return this.fetch({...t})} method fetchOptimistic (line 35) | fetchOptimistic(t){const e=this.#t.defaultQueryOptions(t),n=this.#t.getQ... method fetch (line 35) | fetch(t){return this.#f({...t,cancelRefetch:t.cancelRefetch??!0}).then((... method #f (line 35) | #f(t){this.#S();let e=this.#e.fetch(this.options,t);return t?.throwOnErr... method #g (line 35) | #g(){this.#v();const t=Qh(this.options.staleTime,this.#e);if(og||this.#a... method #b (line 35) | #b(){return(typeof this.options.refetchInterval=="function"?this.options... method #x (line 35) | #x(t){this.#w(),this.#l=t,!(og||Vl(this.options.enabled,this.#e)===!1||!... method #y (line 35) | #y(){this.#g(),this.#x(this.#b())} method #v (line 35) | #v(){this.#c&&(Ff.clearTimeout(this.#c),this.#c=void 0)} method #w (line 35) | #w(){this.#d&&(Ff.clearInterval(this.#d),this.#d=void 0)} method createResult (line 35) | createResult(t,e){const n=this.#e,r=this.options,i=this.#a,s=this.#r,o=t... method updateResult (line 35) | updateResult(){const t=this.#a,e=this.createResult(this.#e,this.options)... method #S (line 35) | #S(){const t=this.#t.getQueryCache().build(this.#t,this.options);if(t===... method onQueryUpdate (line 35) | onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()} method #_ (line 35) | #_(t){Qa.batch(()=>{t.listeners&&this.listeners.forEach(e=>{e(this.#a)})... function Ghe (line 35) | function Ghe(t,e){return Vl(e.enabled,t)!==!1&&t.state.data===void 0&&!(... function xH (line 35) | function xH(t,e){return Ghe(t,e)||t.state.data!==void 0&&eF(t,e,e.refetc... function eF (line 35) | function eF(t,e,n){if(Vl(e.enabled,t)!==!1&&Qh(e.staleTime,t)!=="static"... function yH (line 35) | function yH(t,e,n,r){return(t!==e||Vl(r.enabled,t)===!1)&&(!n.suspense||... function PO (line 35) | function PO(t,e){return Vl(e.enabled,t)!==!1&&t.isStaleByTime(Qh(e.stale... function Whe (line 35) | function Whe(t,e){return!rw(t.getCurrentResult(),e)} function vH (line 35) | function vH(t){return{onFetch:(e,n)=>{const r=e.options,i=e.fetchOptions... function wH (line 35) | function wH(t,{pages:e,pageParams:n}){const r=e.length-1;return e.length... function Khe (line 35) | function Khe(t,{pages:e,pageParams:n}){return e.length>0?t.getPreviousPa... method constructor (line 35) | constructor(t){super(),this.#t=t.client,this.mutationId=t.mutationId,thi... method setOptions (line 35) | setOptions(t){this.options=t,this.updateGcTime(this.options.gcTime)} method meta (line 35) | get meta(){return this.options.meta} method addObserver (line 35) | addObserver(t){this.#e.includes(t)||(this.#e.push(t),this.clearGcTimeout... method removeObserver (line 35) | removeObserver(t){this.#e=this.#e.filter(e=>e!==t),this.scheduleGc(),thi... method optionalRemove (line 35) | optionalRemove(){this.#e.length||(this.state.status==="pending"?this.sch... method continue (line 35) | continue(){return this.#a?.continue()??this.execute(this.state.variables)} method execute (line 35) | async execute(t){const e=()=>{this.#r({type:"continue"})},n={client:this... method #r (line 35) | #r(t){const e=n=>{switch(t.type){case"failed":return{...n,failureCount:t... function SQ (line 35) | function SQ(){return{context:void 0,data:void 0,error:null,failureCount:... method constructor (line 35) | constructor(t={}){super(),this.config=t,this.#t=new Set,this.#e=new Map,... method build (line 35) | build(t,e,n){const r=new Xhe({client:t,mutationCache:this,mutationId:++t... method add (line 35) | add(t){this.#t.add(t);const e=Y_(t);if(typeof e=="string"){const n=this.... method remove (line 35) | remove(t){if(this.#t.delete(t)){const e=Y_(t);if(typeof e=="string"){con... method canRun (line 35) | canRun(t){const e=Y_(t);if(typeof e=="string"){const r=this.#e.get(e)?.f... method runNext (line 35) | runNext(t){const e=Y_(t);return typeof e=="string"?this.#e.get(e)?.find(... method clear (line 35) | clear(){Qa.batch(()=>{this.#t.forEach(t=>{this.notify({type:"removed",mu... method getAll (line 35) | getAll(){return Array.from(this.#t)} method find (line 35) | find(t){const e={exact:!0,...t};return this.getAll().find(n=>hH(e,n))} method findAll (line 35) | findAll(t={}){return this.getAll().filter(e=>hH(t,e))} method notify (line 35) | notify(t){Qa.batch(()=>{this.listeners.forEach(e=>{e(t)})})} method resumePausedMutations (line 35) | resumePausedMutations(){const t=this.getAll().filter(e=>e.state.isPaused... function Y_ (line 35) | function Y_(t){return t.options.scope?.id} method constructor (line 35) | constructor(e,n){super(),this.#t=e,this.setOptions(n),this.bindMethods()... method bindMethods (line 35) | bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.b... method setOptions (line 35) | setOptions(e){const n=this.options;this.options=this.#t.defaultMutationO... method onUnsubscribe (line 35) | onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)} method onMutationUpdate (line 35) | onMutationUpdate(e){this.#r(),this.#i(e)} method getCurrentResult (line 35) | getCurrentResult(){return this.#e} method reset (line 35) | reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#r(),this.#i()} method mutate (line 35) | mutate(e,n){return this.#a=n,this.#n?.removeObserver(this),this.#n=this.... method #r (line 35) | #r(){const e=this.#n?.state??SQ();this.#e={...e,isPending:e.status==="pe... method #i (line 35) | #i(e){Qa.batch(()=>{if(this.#a&&this.hasListeners()){const n=this.#e.var... function SH (line 35) | function SH(t,e){const n=new Set(e);return t.filter(r=>!n.has(r))} function Zhe (line 35) | function Zhe(t,e,n){const r=t.slice(0);return r[e]=n,r} method constructor (line 35) | constructor(t,e,n){super(),this.#t=t,this.#a=n,this.#n=[],this.#r=[],thi... method onSubscribe (line 35) | onSubscribe(){this.listeners.size===1&&this.#r.forEach(t=>{t.subscribe(e... method onUnsubscribe (line 35) | onUnsubscribe(){this.listeners.size||this.destroy()} method destroy (line 35) | destroy(){this.listeners=new Set,this.#r.forEach(t=>{t.destroy()})} method setQueries (line 35) | setQueries(t,e){this.#n=t,this.#a=e,Qa.batch(()=>{const n=this.#r,r=this... method getCurrentResult (line 35) | getCurrentResult(){return this.#e} method getQueries (line 35) | getQueries(){return this.#r.map(t=>t.getCurrentQuery())} method getObservers (line 35) | getObservers(){return this.#r} method getOptimisticResult (line 35) | getOptimisticResult(t,e){const n=this.#d(t),r=n.map(s=>s.observer.getOpt... method #m (line 35) | #m(t,e){return e.map((n,r)=>{const i=t[r];return n.defaultedQueryOptions... method #c (line 35) | #c(t,e,n){if(e){const r=this.#p,i=n!==void 0&&r!==void 0&&(r.length!==n.... method #d (line 35) | #d(t){const e=new Map;this.#r.forEach(r=>{const i=r.options.queryHash;if... method #l (line 35) | #l(t,e){const n=this.#r.indexOf(t);n!==-1&&(this.#e=Zhe(this.#e,n,e),thi... method #h (line 35) | #h(){if(this.hasListeners()){const t=this.#i,e=this.#m(this.#e,this.#u),... method constructor (line 35) | constructor(t={}){super(),this.config=t,this.#t=new Map} method build (line 35) | build(t,e,n){const r=e.queryKey,i=e.queryHash??wO(r,e);let s=this.get(i)... method add (line 35) | add(t){this.#t.has(t.queryHash)||(this.#t.set(t.queryHash,t),this.notify... method remove (line 35) | remove(t){const e=this.#t.get(t.queryHash);e&&(t.destroy(),e===t&&this.#... method clear (line 35) | clear(){Qa.batch(()=>{this.getAll().forEach(t=>{this.remove(t)})})} method get (line 35) | get(t){return this.#t.get(t)} method getAll (line 35) | getAll(){return[...this.#t.values()]} method find (line 35) | find(t){const e={exact:!0,...t};return this.getAll().find(n=>mH(e,n))} method findAll (line 35) | findAll(t={}){const e=this.getAll();return Object.keys(t).length>0?e.fil... method notify (line 35) | notify(t){Qa.batch(()=>{this.listeners.forEach(e=>{e(t)})})} method onFocus (line 35) | onFocus(){Qa.batch(()=>{this.getAll().forEach(t=>{t.onFocus()})})} method onOnline (line 35) | onOnline(){Qa.batch(()=>{this.getAll().forEach(t=>{t.onOnline()})})} method constructor (line 35) | constructor(t={}){this.#t=t.queryCache||new epe,this.#e=t.mutationCache|... method mount (line 35) | mount(){this.#i++,this.#i===1&&(this.#o=NO.subscribe(async t=>{t&&(await... method unmount (line 35) | unmount(){this.#i--,this.#i===0&&(this.#o?.(),this.#o=void 0,this.#s?.()... method isFetching (line 35) | isFetching(t){return this.#t.findAll({...t,fetchStatus:"fetching"}).length} method isMutating (line 35) | isMutating(t){return this.#e.findAll({...t,status:"pending"}).length} method getQueryData (line 35) | getQueryData(t){const e=this.defaultQueryOptions({queryKey:t});return th... method ensureQueryData (line 35) | ensureQueryData(t){const e=this.defaultQueryOptions(t),n=this.#t.build(t... method getQueriesData (line 35) | getQueriesData(t){return this.#t.findAll(t).map(({queryKey:e,state:n})=>... method setQueryData (line 35) | setQueryData(t,e,n){const r=this.defaultQueryOptions({queryKey:t}),s=thi... method setQueriesData (line 35) | setQueriesData(t,e,n){return Qa.batch(()=>this.#t.findAll(t).map(({query... method getQueryState (line 35) | getQueryState(t){const e=this.defaultQueryOptions({queryKey:t});return t... method removeQueries (line 35) | removeQueries(t){const e=this.#t;Qa.batch(()=>{e.findAll(t).forEach(n=>{... method resetQueries (line 35) | resetQueries(t,e){const n=this.#t;return Qa.batch(()=>(n.findAll(t).forE... method cancelQueries (line 35) | cancelQueries(t,e={}){const n={revert:!0,...e},r=Qa.batch(()=>this.#t.fi... method invalidateQueries (line 35) | invalidateQueries(t,e={}){return Qa.batch(()=>(this.#t.findAll(t).forEac... method refetchQueries (line 35) | refetchQueries(t,e={}){const n={...e,cancelRefetch:e.cancelRefetch??!0},... method fetchQuery (line 35) | fetchQuery(t){const e=this.defaultQueryOptions(t);e.retry===void 0&&(e.r... method prefetchQuery (line 35) | prefetchQuery(t){return this.fetchQuery(t).then(Is).catch(Is)} method fetchInfiniteQuery (line 35) | fetchInfiniteQuery(t){return t.behavior=vH(t.pages),this.fetchQuery(t)} method prefetchInfiniteQuery (line 35) | prefetchInfiniteQuery(t){return this.fetchInfiniteQuery(t).then(Is).catc... method ensureInfiniteQueryData (line 35) | ensureInfiniteQueryData(t){return t.behavior=vH(t.pages),this.ensureQuer... method resumePausedMutations (line 35) | resumePausedMutations(){return gN.isOnline()?this.#e.resumePausedMutatio... method getQueryCache (line 35) | getQueryCache(){return this.#t} method getMutationCache (line 35) | getMutationCache(){return this.#e} method getDefaultOptions (line 35) | getDefaultOptions(){return this.#n} method setDefaultOptions (line 35) | setDefaultOptions(t){this.#n=t} method setQueryDefaults (line 35) | setQueryDefaults(t,e){this.#a.set(lg(t),{queryKey:t,defaultOptions:e})} method getQueryDefaults (line 35) | getQueryDefaults(t){const e=[...this.#a.values()],n={};return e.forEach(... method setMutationDefaults (line 35) | setMutationDefaults(t,e){this.#r.set(lg(t),{mutationKey:t,defaultOptions... method getMutationDefaults (line 35) | getMutationDefaults(t){const e=[...this.#r.values()],n={};return e.forEa... method defaultQueryOptions (line 35) | defaultQueryOptions(t){if(t._defaulted)return t;const e={...this.#n.quer... method defaultMutationOptions (line 35) | defaultMutationOptions(t){return t?._defaulted?t:{...this.#n.mutations,.... method clear (line 35) | clear(){this.#t.clear(),this.#e.clear()} function rpe (line 35) | function rpe(){let t=!1;return{clearReset:()=>{t=!1},reset:()=>{t=!0},is... function Pp (line 35) | function Pp({queries:t,...e},n){const r=nn(),i=NQ(),s=CQ(),o=w.useMemo((... function ipe (line 35) | function ipe(t,e,n){const r=NQ(),i=CQ(),s=nn(),o=s.defaultQueryOptions(t... function Xe (line 35) | function Xe(t,e){return ipe(t,CO)} function it (line 35) | function it(t,e){const n=nn(),[r]=w.useState(()=>new Qhe(n,t));w.useEffe... function kh (line 35) | function kh(t,e=!1){Cn=t,t?(sessionStorage.setItem("auth_token",t),e&&lo... function vm (line 35) | function vm(){return Cn} function jH (line 35) | function jH(t){CN=t} function QQ (line 35) | function QQ(){return CN} function Ga (line 35) | function Ga(t){if(!CN)return t;const e=t.includes("?")?"&":"?";return`${... function _f (line 35) | function _f(t){if(!t)return null;const e=t.match(/filename\*=(?:UTF-8|ut... function Ee (line 35) | async function Ee(t,e={}){const n={"Content-Type":"application/json",...... function gye (line 35) | function gye({children:t}){const[e,n]=w.useState(()=>{const T=localStora... function zg (line 35) | function zg(){const t=w.useContext(ZQ);if(!t)throw new Error("useTheme m... function bye (line 35) | function bye({density:t,children:e}){return a.jsx(UO.Provider,{value:t,c... function Tt (line 35) | function Tt({children:t,className:e="",onClick:n,onContextMenu:r,...i}){... function gn (line 35) | function gn({children:t,className:e="",dense:n}){const r=w.useContext(UO... function Mt (line 35) | function Mt({children:t,className:e="",dense:n}){const r=w.useContext(UO... function xye (line 35) | function xye(t,e,n){return[{category:"Navigation",items:t?t.slice(0,9).m... function MH (line 35) | function MH({children:t}){return a.jsx("kbd",{className:"px-2 py-1 text-... function yye (line 35) | function yye({onClose:t,navItems:e,sidebarItems:n}){const{t:r}=Ft(),i=xy... function De (line 35) | function De({variant:t="primary",size:e="md",className:n="",children:r,.... function yn (line 35) | function yn({title:t,message:e,confirmText:n,cancelText:r,cancelVariant:... function vye (line 35) | function vye({plug:t}){const e=nn(),[n,r]=w.useState(null),{data:i,isLoa... function EH (line 35) | function EH({onClose:t}){const{t:e}=Ft(),{data:n,isLoading:r}=Xe({queryK... function WP (line 35) | function WP(t){return JQ.find(n=>n.name===t)?.icon||Sy} function wye (line 35) | function wye({value:t,onChange:e}){const[n,r]=w.useState(!1),i=WP(t);ret... function Sye (line 35) | function Sye(){const[t,e]=w.useState(()=>typeof window<"u"?window.innerW... function _ye (line 35) | function _ye(t){const e={};for(const[n,r]of Object.entries(t)){if(!n||!r... function kye (line 35) | function kye(t){return uF.add(t),()=>{uF.delete(t)}} function FH (line 35) | function FH(){return eZ} function RH (line 35) | function RH(t){if(!t||t.length<6)return"Unknown";const e=t.replace("#","... function rc (line 35) | function rc(t){if(!t)return RH(t);const e=t.replace("#","").toLowerCase(... function KP (line 35) | function KP(t,e){if(t&&!/^[A-Z]\d+-[A-Z]\d+$/.test(t))return t;if(e&&e.l... function HO (line 35) | function HO(t){if(!t||t==="00000000"||t.length<6)return null;const e=t.s... function tZ (line 35) | function tZ(t){if(!t||t.length<6)return!1;const e=t.replace("#",""),n=pa... function nZ (line 35) | function nZ(){return w.useSyncExternalStore(kye,FH,FH)} function Nye (line 35) | function Nye({children:t}){const[e,n]=w.useState(null),[r,i]=w.useState(... function kr (line 35) | function kr(){const t=w.useContext(rZ);if(t===void 0)throw new Error("us... function Lo (line 35) | function Lo(t){if(!Number.isFinite(t)||t<=0)return"0 B";const e=["B","KB... function hn (line 35) | function hn(){const t=w.useContext(aZ);if(!t)throw new Error("useToast m... function Pye (line 35) | function Pye({children:t}){const{t:e}=Ft(),[n,r]=w.useState([]),[i,s]=w.... function Tye (line 35) | function Tye(t="system"){const e=t==="system"?iZ():t;switch(e){case"us":... function Aye (line 35) | function Aye(t="system"){switch(t){case"12h":return"HH:MM AM/PM";case"24... function mF (line 35) | function mF(t,e="system"){const n=String(t.getDate()).padStart(2,"0"),r=... function OH (line 35) | function OH(t,e="system"){const n=t.getHours(),r=String(t.getMinutes()).... function jye (line 35) | function jye(t){for(const e of["/",".","-"]){const n=t.split(e);if(n.len... function iZ (line 35) | function iZ(){const t=new Date(2e3,11,31).toLocaleDateString();return t.... function Mye (line 35) | function Mye(t,e="system"){if(!t)return null;const n=jye(t);if(!n)return... function Eye (line 35) | function Eye(t){if(!t)return null;const n=t.trim().match(/^(\d{1,2}):(\d... function hF (line 35) | function hF(t){const e=t.getFullYear(),n=String(t.getMonth()+1).padStart... function ow (line 35) | function ow(t,e="system"){return e==="12h"?t.hour12=!0:e==="24h"&&(t.hou... function Zn (line 35) | function Zn(t){return t?t.endsWith("Z")||/[+-]\d{2}:\d{2}$/.test(t)?new ... function hg (line 35) | function hg(t,e){const n=Zn(t);if(!n)return"";const r={year:"numeric",mo... function pg (line 35) | function pg(t,e="system",n){const r=Zn(t);if(!r)return"";const s=ow(n??{... function sZ (line 35) | function sZ(t,e="system",n){const i=ow({...{hour:"2-digit",minute:"2-dig... function qO (line 35) | function qO(t,e="system",n){const r=new Date,i=new Date(r.getTime()+t*60... function ws (line 35) | function ws(t){if(t==null||t<0)return"--";const e=Math.floor(t/3600),n=M... function ap (line 35) | function ap(t,e="system",n){if(!t)return n?.("time.unknown")??"-";const ... function Ch (line 35) | function Ch(t){const e=Math.floor(t/60),n=Math.floor(t%60);return`${e}:$... function Dye (line 35) | function Dye(t){if(t<1)return`${Math.round(t*60)}m`;const e=Math.floor(t... function Lye (line 35) | function Lye(t){return new Promise((e,n)=>{const r=new Image;r.onload=()... function Oye (line 35) | function Oye(t){const e=Math.floor(t/60),n=t%60;return`${e.toString().pa... function Iye (line 35) | function Iye(){const{t}=Ft(),[e,n]=w.useState(!1),[r,i]=w.useState("form... function zye (line 35) | function zye(){const t=localStorage.getItem("sidebarOrder");if(t)try{ret... function IH (line 35) | function IH(t){localStorage.setItem("sidebarOrder",JSON.stringify(t))} function Q_ (line 35) | function Q_(t){return t.startsWith("ext-")} function oZ (line 35) | function oZ(){return localStorage.getItem("defaultView")||"/"} function Uye (line 35) | function Uye(t){localStorage.setItem("defaultView",t)} function Bye (line 35) | function Bye(){const t=qo(),e=td(),{mode:n,toggleMode:r}=zg(),{t:i}=Ft()... function Hye (line 35) | function Hye(t,e){const n=t.split(".").map(i=>parseInt(i,10)||0),r=e.spl... function zH (line 35) | function zH(t,e,n,r){if(!t)return"";if(r)return`${t} — ${r}`;if(!e)retur... function qye (line 35) | function qye(t){switch(t){case 1:return{label:"Fatal",color:"text-red-50... function fF (line 35) | function fF(t,e){const n=t>>16&65535||(t>>8&255)<<8|t&255,r=e&65535;retu... function om (line 35) | function om(t){return t.filter(e=>{const n=parseInt(e.code.replace("0x",... function $ye (line 35) | function $ye(){return"https://wiki.bambulab.com/en/hms/home"} function Vye (line 35) | function Vye({printerName:t,errors:e,onClose:n,printerId:r,hasPermission... function Wye (line 35) | function Wye({selectedIds:t,printers:e,onClose:n,onSelectAll:r,onSelectB... function yZ (line 35) | function yZ(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;ret... function jN (line 35) | function jN(t){return document.createElementNS("http://www.w3.org/1999/x... function Rve (line 35) | function Rve(){const t=jN("canvas");return t.style.display="block",t} function KH (line 35) | function KH(...t){const e="THREE."+t.shift();console.log(e,...t)} function qn (line 35) | function qn(...t){const e="THREE."+t.shift();console.warn(e,...t)} function oi (line 35) | function oi(...t){const e="THREE."+t.shift();console.error(e,...t)} function mw (line 35) | function mw(...t){const e=t.join(" ");e in WH||(WH[e]=!0,qn(...t))} function Lve (line 35) | function Lve(t,e,n){return new Promise(function(r,i){function s(){switch... method addEventListener (line 35) | addEventListener(e,n){this._listeners===void 0&&(this._listeners={});con... method hasEventListener (line 35) | hasEventListener(e,n){const r=this._listeners;return r===void 0?!1:r[e]!... method removeEventListener (line 35) | removeEventListener(e,n){const r=this._listeners;if(r===void 0)return;co... method dispatchEvent (line 35) | dispatchEvent(e){const n=this._listeners;if(n===void 0)return;const r=n[... function lS (line 35) | function lS(){const t=Math.random()*4294967295|0,e=Math.random()*4294967... function fr (line 35) | function fr(t,e,n){return Math.max(e,Math.min(n,t))} function Ove (line 35) | function Ove(t,e){return(t%e+e)%e} function DM (line 35) | function DM(t,e,n){return(1-n)*t+n*e} function Ev (line 35) | function Ev(t,e){switch(e.constructor){case Float32Array:return t;case U... function jo (line 35) | function jo(t,e){switch(e.constructor){case Float32Array:return t;case U... method constructor (line 35) | constructor(e=0,n=0){vZ.prototype.isVector2=!0,this.x=e,this.y=n} method width (line 35) | get width(){return this.x} method width (line 35) | set width(e){this.x=e} method height (line 35) | get height(){return this.y} method height (line 35) | set height(e){this.y=e} method set (line 35) | set(e,n){return this.x=e,this.y=n,this} method setScalar (line 35) | setScalar(e){return this.x=e,this.y=e,this} method setX (line 35) | setX(e){return this.x=e,this} method setY (line 35) | setY(e){return this.y=e,this} method setComponent (line 35) | setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;... method getComponent (line 35) | getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;defa... method clone (line 35) | clone(){return new this.constructor(this.x,this.y)} method copy (line 35) | copy(e){return this.x=e.x,this.y=e.y,this} method add (line 35) | add(e){return this.x+=e.x,this.y+=e.y,this} method addScalar (line 35) | addScalar(e){return this.x+=e,this.y+=e,this} method addVectors (line 35) | addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this} method addScaledVector (line 35) | addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this} method sub (line 35) | sub(e){return this.x-=e.x,this.y-=e.y,this} method subScalar (line 35) | subScalar(e){return this.x-=e,this.y-=e,this} method subVectors (line 35) | subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this} method multiply (line 35) | multiply(e){return this.x*=e.x,this.y*=e.y,this} method multiplyScalar (line 35) | multiplyScalar(e){return this.x*=e,this.y*=e,this} method divide (line 35) | divide(e){return this.x/=e.x,this.y/=e.y,this} method divideScalar (line 35) | divideScalar(e){return this.multiplyScalar(1/e)} method applyMatrix3 (line 35) | applyMatrix3(e){const n=this.x,r=this.y,i=e.elements;return this.x=i[0]*... method min (line 35) | min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this} method max (line 35) | max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this} method clamp (line 35) | clamp(e,n){return this.x=fr(this.x,e.x,n.x),this.y=fr(this.y,e.y,n.y),this} method clampScalar (line 35) | clampScalar(e,n){return this.x=fr(this.x,e,n),this.y=fr(this.y,e,n),this} method clampLength (line 35) | clampLength(e,n){const r=this.length();return this.divideScalar(r||1).mu... method floor (line 35) | floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this} method ceil (line 35) | ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this} method round (line 35) | round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this} method roundToZero (line 35) | roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y)... method negate (line 35) | negate(){return this.x=-this.x,this.y=-this.y,this} method dot (line 35) | dot(e){return this.x*e.x+this.y*e.y} method cross (line 35) | cross(e){return this.x*e.y-this.y*e.x} method lengthSq (line 35) | lengthSq(){return this.x*this.x+this.y*this.y} method length (line 35) | length(){return Math.sqrt(this.x*this.x+this.y*this.y)} method manhattanLength (line 35) | manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)} method normalize (line 35) | normalize(){return this.divideScalar(this.length()||1)} method angle (line 35) | angle(){return Math.atan2(-this.y,-this.x)+Math.PI} method angleTo (line 35) | angleTo(e){const n=Math.sqrt(this.lengthSq()*e.lengthSq());if(n===0)retu... method distanceTo (line 35) | distanceTo(e){return Math.sqrt(this.distanceToSquared(e))} method distanceToSquared (line 35) | distanceToSquared(e){const n=this.x-e.x,r=this.y-e.y;return n*n+r*r} method manhattanDistanceTo (line 35) | manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)} method setLength (line 35) | setLength(e){return this.normalize().multiplyScalar(e)} method lerp (line 35) | lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this} method lerpVectors (line 35) | lerpVectors(e,n,r){return this.x=e.x+(n.x-e.x)*r,this.y=e.y+(n.y-e.y)*r,... method equals (line 35) | equals(e){return e.x===this.x&&e.y===this.y} method fromArray (line 35) | fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this} method toArray (line 35) | toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e} method fromBufferAttribute (line 35) | fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this} method rotateAround (line 35) | rotateAround(e,n){const r=Math.cos(n),i=Math.sin(n),s=this.x-e.x,o=this.... method random (line 35) | random(){return this.x=Math.random(),this.y=Math.random(),this} method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this.x,yield this.y} method constructor (line 35) | constructor(e=0,n=0,r=0,i=1){this.isQuaternion=!0,this._x=e,this._y=n,th... method slerpFlat (line 35) | static slerpFlat(e,n,r,i,s,o,l){let c=r[i+0],d=r[i+1],u=r[i+2],m=r[i+3],... method multiplyQuaternionsFlat (line 35) | static multiplyQuaternionsFlat(e,n,r,i,s,o){const l=r[i],c=r[i+1],d=r[i+... method x (line 35) | get x(){return this._x} method x (line 35) | set x(e){this._x=e,this._onChangeCallback()} method y (line 35) | get y(){return this._y} method y (line 35) | set y(e){this._y=e,this._onChangeCallback()} method z (line 35) | get z(){return this._z} method z (line 35) | set z(e){this._z=e,this._onChangeCallback()} method w (line 35) | get w(){return this._w} method w (line 35) | set w(e){this._w=e,this._onChangeCallback()} method set (line 35) | set(e,n,r,i){return this._x=e,this._y=n,this._z=r,this._w=i,this._onChan... method clone (line 35) | clone(){return new this.constructor(this._x,this._y,this._z,this._w)} method copy (line 35) | copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._onC... method setFromEuler (line 35) | setFromEuler(e,n=!0){const r=e._x,i=e._y,s=e._z,o=e._order,l=Math.cos,c=... method setFromAxisAngle (line 35) | setFromAxisAngle(e,n){const r=n/2,i=Math.sin(r);return this._x=e.x*i,thi... method setFromRotationMatrix (line 35) | setFromRotationMatrix(e){const n=e.elements,r=n[0],i=n[4],s=n[8],o=n[1],... method setFromUnitVectors (line 35) | setFromUnitVectors(e,n){let r=e.dot(n)+1;return r<1e-8?(r=0,Math.abs(e.x... method angleTo (line 35) | angleTo(e){return 2*Math.acos(Math.abs(fr(this.dot(e),-1,1)))} method rotateTowards (line 35) | rotateTowards(e,n){const r=this.angleTo(e);if(r===0)return this;const i=... method identity (line 35) | identity(){return this.set(0,0,0,1)} method invert (line 35) | invert(){return this.conjugate()} method conjugate (line 35) | conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCal... method dot (line 35) | dot(e){return this._x*e._x+this._y*e._y+this._z*e._z+this._w*e._w} method lengthSq (line 35) | lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._... method length (line 35) | length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._... method normalize (line 35) | normalize(){let e=this.length();return e===0?(this._x=0,this._y=0,this._... method multiply (line 35) | multiply(e){return this.multiplyQuaternions(this,e)} method premultiply (line 35) | premultiply(e){return this.multiplyQuaternions(e,this)} method multiplyQuaternions (line 35) | multiplyQuaternions(e,n){const r=e._x,i=e._y,s=e._z,o=e._w,l=n._x,c=n._y... method slerp (line 35) | slerp(e,n){if(n<=0)return this;if(n>=1)return this.copy(e);let r=e._x,i=... method slerpQuaternions (line 35) | slerpQuaternions(e,n,r){return this.copy(e).slerp(n,r)} method random (line 35) | random(){const e=2*Math.PI*Math.random(),n=2*Math.PI*Math.random(),r=Mat... method equals (line 35) | equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._w===... method fromArray (line 35) | fromArray(e,n=0){return this._x=e[n],this._y=e[n+1],this._z=e[n+2],this.... method toArray (line 35) | toArray(e=[],n=0){return e[n]=this._x,e[n+1]=this._y,e[n+2]=this._z,e[n+... method fromBufferAttribute (line 35) | fromBufferAttribute(e,n){return this._x=e.getX(n),this._y=e.getY(n),this... method toJSON (line 35) | toJSON(){return this.toArray()} method _onChange (line 35) | _onChange(e){return this._onChangeCallback=e,this} method _onChangeCallback (line 35) | _onChangeCallback(){} method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield thi... method constructor (line 35) | constructor(e=0,n=0,r=0){wZ.prototype.isVector3=!0,this.x=e,this.y=n,thi... method set (line 35) | set(e,n,r){return r===void 0&&(r=this.z),this.x=e,this.y=n,this.z=r,this} method setScalar (line 35) | setScalar(e){return this.x=e,this.y=e,this.z=e,this} method setX (line 35) | setX(e){return this.x=e,this} method setY (line 35) | setY(e){return this.y=e,this} method setZ (line 35) | setZ(e){return this.z=e,this} method setComponent (line 35) | setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;... method getComponent (line 35) | getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case... method clone (line 35) | clone(){return new this.constructor(this.x,this.y,this.z)} method copy (line 35) | copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this} method add (line 35) | add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this} method addScalar (line 35) | addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this} method addVectors (line 35) | addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this.z=e.z+n.z,this} method addScaledVector (line 35) | addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,this} method sub (line 35) | sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this} method subScalar (line 35) | subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this} method subVectors (line 35) | subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this.z=e.z-n.z,this} method multiply (line 35) | multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this} method multiplyScalar (line 35) | multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this} method multiplyVectors (line 35) | multiplyVectors(e,n){return this.x=e.x*n.x,this.y=e.y*n.y,this.z=e.z*n.z... method applyEuler (line 35) | applyEuler(e){return this.applyQuaternion(XH.setFromEuler(e))} method applyAxisAngle (line 35) | applyAxisAngle(e,n){return this.applyQuaternion(XH.setFromAxisAngle(e,n))} method applyMatrix3 (line 35) | applyMatrix3(e){const n=this.x,r=this.y,i=this.z,s=e.elements;return thi... method applyNormalMatrix (line 35) | applyNormalMatrix(e){return this.applyMatrix3(e).normalize()} method applyMatrix4 (line 35) | applyMatrix4(e){const n=this.x,r=this.y,i=this.z,s=e.elements,o=1/(s[3]*... method applyQuaternion (line 35) | applyQuaternion(e){const n=this.x,r=this.y,i=this.z,s=e.x,o=e.y,l=e.z,c=... method project (line 35) | project(e){return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e... method unproject (line 35) | unproject(e){return this.applyMatrix4(e.projectionMatrixInverse).applyMa... method transformDirection (line 35) | transformDirection(e){const n=this.x,r=this.y,i=this.z,s=e.elements;retu... method divide (line 35) | divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this} method divideScalar (line 35) | divideScalar(e){return this.multiplyScalar(1/e)} method min (line 35) | min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),th... method max (line 35) | max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),th... method clamp (line 35) | clamp(e,n){return this.x=fr(this.x,e.x,n.x),this.y=fr(this.y,e.y,n.y),th... method clampScalar (line 35) | clampScalar(e,n){return this.x=fr(this.x,e,n),this.y=fr(this.y,e,n),this... method clampLength (line 35) | clampLength(e,n){const r=this.length();return this.divideScalar(r||1).mu... method floor (line 35) | floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.... method ceil (line 35) | ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=M... method round (line 35) | round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.... method roundToZero (line 35) | roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y)... method negate (line 35) | negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this} method dot (line 35) | dot(e){return this.x*e.x+this.y*e.y+this.z*e.z} method lengthSq (line 35) | lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z} method length (line 35) | length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)} method manhattanLength (line 35) | manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this... method normalize (line 35) | normalize(){return this.divideScalar(this.length()||1)} method setLength (line 35) | setLength(e){return this.normalize().multiplyScalar(e)} method lerp (line 35) | lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this.z+=(... method lerpVectors (line 35) | lerpVectors(e,n,r){return this.x=e.x+(n.x-e.x)*r,this.y=e.y+(n.y-e.y)*r,... method cross (line 35) | cross(e){return this.crossVectors(this,e)} method crossVectors (line 35) | crossVectors(e,n){const r=e.x,i=e.y,s=e.z,o=n.x,l=n.y,c=n.z;return this.... method projectOnVector (line 35) | projectOnVector(e){const n=e.lengthSq();if(n===0)return this.set(0,0,0);... method projectOnPlane (line 35) | projectOnPlane(e){return FM.copy(this).projectOnVector(e),this.sub(FM)} method reflect (line 35) | reflect(e){return this.sub(FM.copy(e).multiplyScalar(2*this.dot(e)))} method angleTo (line 35) | angleTo(e){const n=Math.sqrt(this.lengthSq()*e.lengthSq());if(n===0)retu... method distanceTo (line 35) | distanceTo(e){return Math.sqrt(this.distanceToSquared(e))} method distanceToSquared (line 35) | distanceToSquared(e){const n=this.x-e.x,r=this.y-e.y,i=this.z-e.z;return... method manhattanDistanceTo (line 35) | manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)+... method setFromSpherical (line 35) | setFromSpherical(e){return this.setFromSphericalCoords(e.radius,e.phi,e.... method setFromSphericalCoords (line 35) | setFromSphericalCoords(e,n,r){const i=Math.sin(n)*e;return this.x=i*Math... method setFromCylindrical (line 35) | setFromCylindrical(e){return this.setFromCylindricalCoords(e.radius,e.th... method setFromCylindricalCoords (line 35) | setFromCylindricalCoords(e,n,r){return this.x=e*Math.sin(n),this.y=r,thi... method setFromMatrixPosition (line 35) | setFromMatrixPosition(e){const n=e.elements;return this.x=n[12],this.y=n... method setFromMatrixScale (line 35) | setFromMatrixScale(e){const n=this.setFromMatrixColumn(e,0).length(),r=t... method setFromMatrixColumn (line 35) | setFromMatrixColumn(e,n){return this.fromArray(e.elements,n*4)} method setFromMatrix3Column (line 35) | setFromMatrix3Column(e,n){return this.fromArray(e.elements,n*3)} method setFromEuler (line 35) | setFromEuler(e){return this.x=e._x,this.y=e._y,this.z=e._z,this} method setFromColor (line 35) | setFromColor(e){return this.x=e.r,this.y=e.g,this.z=e.b,this} method equals (line 35) | equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z} method fromArray (line 35) | fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this} method toArray (line 35) | toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e} method fromBufferAttribute (line 35) | fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this.z... method random (line 35) | random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.ra... method randomDirection (line 35) | randomDirection(){const e=Math.random()*Math.PI*2,n=Math.random()*2-1,r=... method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this.x,yield this.y,yield this.z} method constructor (line 35) | constructor(e,n,r,i,s,o,l,c,d){SZ.prototype.isMatrix3=!0,this.elements=[... method set (line 35) | set(e,n,r,i,s,o,l,c,d){const u=this.elements;return u[0]=e,u[1]=i,u[2]=l... method identity (line 35) | identity(){return this.set(1,0,0,0,1,0,0,0,1),this} method copy (line 35) | copy(e){const n=this.elements,r=e.elements;return n[0]=r[0],n[1]=r[1],n[... method extractBasis (line 35) | extractBasis(e,n,r){return e.setFromMatrix3Column(this,0),n.setFromMatri... method setFromMatrix4 (line 35) | setFromMatrix4(e){const n=e.elements;return this.set(n[0],n[4],n[8],n[1]... method multiply (line 35) | multiply(e){return this.multiplyMatrices(this,e)} method premultiply (line 35) | premultiply(e){return this.multiplyMatrices(e,this)} method multiplyMatrices (line 35) | multiplyMatrices(e,n){const r=e.elements,i=n.elements,s=this.elements,o=... method multiplyScalar (line 35) | multiplyScalar(e){const n=this.elements;return n[0]*=e,n[3]*=e,n[6]*=e,n... method determinant (line 35) | determinant(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4],l... method invert (line 35) | invert(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4],l=e[5]... method transpose (line 35) | transpose(){let e;const n=this.elements;return e=n[1],n[1]=n[3],n[3]=e,e... method getNormalMatrix (line 35) | getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()} method transposeIntoArray (line 35) | transposeIntoArray(e){const n=this.elements;return e[0]=n[0],e[1]=n[3],e... method setUvTransform (line 35) | setUvTransform(e,n,r,i,s,o,l){const c=Math.cos(s),d=Math.sin(s);return t... method scale (line 35) | scale(e,n){return this.premultiply(RM.makeScale(e,n)),this} method rotate (line 35) | rotate(e){return this.premultiply(RM.makeRotation(-e)),this} method translate (line 35) | translate(e,n){return this.premultiply(RM.makeTranslation(e,n)),this} method makeTranslation (line 35) | makeTranslation(e,n){return e.isVector2?this.set(1,0,e.x,0,1,e.y,0,0,1):... method makeRotation (line 35) | makeRotation(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,-r,0... method makeScale (line 35) | makeScale(e,n){return this.set(e,0,0,0,n,0,0,0,1),this} method equals (line 35) | equals(e){const n=this.elements,r=e.elements;for(let i=0;i<9;i++)if(n[i]... method fromArray (line 35) | fromArray(e,n=0){for(let r=0;r<9;r++)this.elements[r]=e[r+n];return this} method toArray (line 35) | toArray(e=[],n=0){const r=this.elements;return e[n]=r[0],e[n+1]=r[1],e[n... method clone (line 35) | clone(){return new this.constructor().fromArray(this.elements)} function zve (line 35) | function zve(){const t={enabled:!0,workingColorSpace:Kx,spaces:{},conver... function cm (line 35) | function cm(t){return t<.04045?t*.0773993808:Math.pow(t*.9478672986+.052... function jx (line 35) | function jx(t){return t<.0031308?t*12.92:1.055*Math.pow(t,.41666)-.055} method getDataURL (line 35) | static getDataURL(e,n="image/png"){if(/^data:/i.test(e.src)||typeof HTML... method sRGBToLinear (line 35) | static sRGBToLinear(e){if(typeof HTMLImageElement<"u"&&e instanceof HTML... method constructor (line 35) | constructor(e=null){this.isSource=!0,Object.defineProperty(this,"id",{va... method getSize (line 35) | getSize(e){const n=this.data;return typeof HTMLVideoElement<"u"&&n insta... method needsUpdate (line 35) | set needsUpdate(e){e===!0&&this.version++} method toJSON (line 35) | toJSON(e){const n=e===void 0||typeof e=="string";if(!n&&e.images[this.uu... function LM (line 35) | function LM(t){return typeof HTMLImageElement<"u"&&t instanceof HTMLImag... method constructor (line 35) | constructor(e=Vk.DEFAULT_IMAGE,n=Vk.DEFAULT_MAPPING,r=Ju,i=Ju,s=ec,o=Rf,... method width (line 35) | get width(){return this.source.getSize(OM).x} method height (line 35) | get height(){return this.source.getSize(OM).y} method depth (line 35) | get depth(){return this.source.getSize(OM).z} method image (line 35) | get image(){return this.source.data} method image (line 35) | set image(e=null){this.source.data=e} method updateMatrix (line 35) | updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,th... method addUpdateRange (line 35) | addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})} method clearUpdateRanges (line 35) | clearUpdateRanges(){this.updateRanges.length=0} method clone (line 35) | clone(){return new this.constructor().copy(this)} method copy (line 35) | copy(e){return this.name=e.name,this.source=e.source,this.mipmaps=e.mipm... method setValues (line 35) | setValues(e){for(const n in e){const r=e[n];if(r===void 0){qn(`Texture.s... method toJSON (line 35) | toJSON(e){const n=e===void 0||typeof e=="string";if(!n&&e.textures[this.... method dispose (line 35) | dispose(){this.dispatchEvent({type:"dispose"})} method transformUv (line 35) | transformUv(e){if(this.mapping!==cZ)return e;if(e.applyMatrix3(this.matr... method needsUpdate (line 35) | set needsUpdate(e){e===!0&&(this.version++,this.source.needsUpdate=!0)} method needsPMREMUpdate (line 35) | set needsPMREMUpdate(e){e===!0&&this.pmremVersion++} method constructor (line 35) | constructor(e=0,n=0,r=0,i=1){_Z.prototype.isVector4=!0,this.x=e,this.y=n... method width (line 35) | get width(){return this.z} method width (line 35) | set width(e){this.z=e} method height (line 35) | get height(){return this.w} method height (line 35) | set height(e){this.w=e} method set (line 35) | set(e,n,r,i){return this.x=e,this.y=n,this.z=r,this.w=i,this} method setScalar (line 35) | setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this} method setX (line 35) | setX(e){return this.x=e,this} method setY (line 35) | setY(e){return this.y=e,this} method setZ (line 35) | setZ(e){return this.z=e,this} method setW (line 35) | setW(e){return this.w=e,this} method setComponent (line 35) | setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;break;... method getComponent (line 35) | getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case... method clone (line 35) | clone(){return new this.constructor(this.x,this.y,this.z,this.w)} method copy (line 35) | copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w!==void 0?e.w:... method add (line 35) | add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this} method addScalar (line 35) | addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this} method addVectors (line 35) | addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this.z=e.z+n.z,this... method addScaledVector (line 35) | addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,th... method sub (line 35) | sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this} method subScalar (line 35) | subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this} method subVectors (line 35) | subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this.z=e.z-n.z,this... method multiply (line 35) | multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this} method multiplyScalar (line 35) | multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this} method applyMatrix4 (line 35) | applyMatrix4(e){const n=this.x,r=this.y,i=this.z,s=this.w,o=e.elements;r... method divide (line 35) | divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.w/=e.w,this} method divideScalar (line 35) | divideScalar(e){return this.multiplyScalar(1/e)} method setAxisAngleFromQuaternion (line 35) | setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);const n=Math.sqrt(... method setAxisAngleFromRotationMatrix (line 35) | setAxisAngleFromRotationMatrix(e){let n,r,i,s;const c=e.elements,d=c[0],... method setFromMatrixPosition (line 35) | setFromMatrixPosition(e){const n=e.elements;return this.x=n[12],this.y=n... method min (line 35) | min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),th... method max (line 35) | max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),th... method clamp (line 35) | clamp(e,n){return this.x=fr(this.x,e.x,n.x),this.y=fr(this.y,e.y,n.y),th... method clampScalar (line 35) | clampScalar(e,n){return this.x=fr(this.x,e,n),this.y=fr(this.y,e,n),this... method clampLength (line 35) | clampLength(e,n){const r=this.length();return this.divideScalar(r||1).mu... method floor (line 35) | floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.... method ceil (line 35) | ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=M... method round (line 35) | round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.... method roundToZero (line 35) | roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y)... method negate (line 35) | negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-thi... method dot (line 35) | dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w} method lengthSq (line 35) | lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w} method length (line 35) | length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this... method manhattanLength (line 35) | manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this... method normalize (line 35) | normalize(){return this.divideScalar(this.length()||1)} method setLength (line 35) | setLength(e){return this.normalize().multiplyScalar(e)} method lerp (line 35) | lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this.z+=(... method lerpVectors (line 35) | lerpVectors(e,n,r){return this.x=e.x+(n.x-e.x)*r,this.y=e.y+(n.y-e.y)*r,... method equals (line 35) | equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z&&e.w===this.w} method fromArray (line 35) | fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this.w=e... method toArray (line 35) | toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=... method fromBufferAttribute (line 35) | fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this.z... method random (line 35) | random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.ra... method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this.x,yield this.y,yield this.z,yield this.w} method constructor (line 35) | constructor(e=1,n=1,r={}){super(),r=Object.assign({generateMipmaps:!1,in... method _setTextureOptions (line 35) | _setTextureOptions(e={}){const n={minFilter:ec,generateMipmaps:!1,flipY:... method texture (line 35) | get texture(){return this.textures[0]} method texture (line 35) | set texture(e){this.textures[0]=e} method depthTexture (line 35) | set depthTexture(e){this._depthTexture!==null&&(this._depthTexture.rende... method depthTexture (line 35) | get depthTexture(){return this._depthTexture} method setSize (line 35) | setSize(e,n,r=1){if(this.width!==e||this.height!==n||this.depth!==r){thi... method clone (line 35) | clone(){return new this.constructor().copy(this)} method copy (line 35) | copy(e){this.width=e.width,this.height=e.height,this.depth=e.depth,this.... method dispose (line 35) | dispose(){this.dispatchEvent({type:"dispose"})} method constructor (line 35) | constructor(e=1,n=1,r={}){super(e,n,r),this.isWebGLRenderTarget=!0} method constructor (line 35) | constructor(e=null,n=1,r=1,i=1){super(null),this.isDataArrayTexture=!0,t... method addLayerUpdate (line 35) | addLayerUpdate(e){this.layerUpdates.add(e)} method clearLayerUpdates (line 35) | clearLayerUpdates(){this.layerUpdates.clear()} method constructor (line 35) | constructor(e=null,n=1,r=1,i=1){super(null),this.isData3DTexture=!0,this... method constructor (line 35) | constructor(e=new Ct(1/0,1/0,1/0),n=new Ct(-1/0,-1/0,-1/0)){this.isBox3=... method set (line 35) | set(e,n){return this.min.copy(e),this.max.copy(n),this} method setFromArray (line 35) | setFromArray(e){this.makeEmpty();for(let n=0,r=e.length;n=this.min.x&&e.x<=this.max.x&&e.y>=this.min.... method containsBox (line 35) | containsBox(e){return this.min.x<=e.min.x&&e.max.x<=this.max.x&&this.min... method getParameter (line 35) | getParameter(e,n){return n.set((e.x-this.min.x)/(this.max.x-this.min.x),... method intersectsBox (line 35) | intersectsBox(e){return e.max.x>=this.min.x&&e.min.x<=this.max.x&&e.max.... method intersectsSphere (line 35) | intersectsSphere(e){return this.clampPoint(e.center,Mc),Mc.distanceToSqu... method intersectsPlane (line 35) | intersectsPlane(e){let n,r;return e.normal.x>0?(n=e.normal.x*this.min.x,... method intersectsTriangle (line 35) | intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(Dv),e1.s... method clampPoint (line 35) | clampPoint(e,n){return n.copy(e).clamp(this.min,this.max)} method distanceToPoint (line 35) | distanceToPoint(e){return this.clampPoint(e,Mc).distanceTo(e)} method getBoundingSphere (line 35) | getBoundingSphere(e){return this.isEmpty()?e.makeEmpty():(this.getCenter... method intersect (line 35) | intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmpty... method union (line 35) | union(e){return this.min.min(e.min),this.max.max(e.max),this} method applyMatrix4 (line 35) | applyMatrix4(e){return this.isEmpty()?this:(_u[0].set(this.min.x,this.mi... method translate (line 35) | translate(e){return this.min.add(e),this.max.add(e),this} method equals (line 35) | equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)} method toJSON (line 35) | toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}} method fromJSON (line 35) | fromJSON(e){return this.min.fromArray(e.min),this.max.fromArray(e.max),t... function IM (line 35) | function IM(t,e,n,r,i){for(let s=0,o=t.length-3;s<=o;s+=3){cf.fromArray(... method constructor (line 35) | constructor(e=new Ct,n=-1){this.isSphere=!0,this.center=e,this.radius=n} method set (line 35) | set(e,n){return this.center.copy(e),this.radius=n,this} method setFromPoints (line 35) | setFromPoints(e,n){const r=this.center;n!==void 0?r.copy(n):Vve.setFromP... method copy (line 35) | copy(e){return this.center.copy(e.center),this.radius=e.radius,this} method isEmpty (line 35) | isEmpty(){return this.radius<0} method makeEmpty (line 35) | makeEmpty(){return this.center.set(0,0,0),this.radius=-1,this} method containsPoint (line 35) | containsPoint(e){return e.distanceToSquared(this.center)<=this.radius*th... method distanceToPoint (line 35) | distanceToPoint(e){return e.distanceTo(this.center)-this.radius} method intersectsSphere (line 35) | intersectsSphere(e){const n=this.radius+e.radius;return e.center.distanc... method intersectsBox (line 35) | intersectsBox(e){return e.intersectsSphere(this)} method intersectsPlane (line 35) | intersectsPlane(e){return Math.abs(e.distanceToPoint(this.center))<=this... method clampPoint (line 35) | clampPoint(e,n){const r=this.center.distanceToSquared(e);return n.copy(e... method getBoundingBox (line 35) | getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.ce... method applyMatrix4 (line 35) | applyMatrix4(e){return this.center.applyMatrix4(e),this.radius=this.radi... method translate (line 35) | translate(e){return this.center.add(e),this} method expandByPoint (line 35) | expandByPoint(e){if(this.isEmpty())return this.center.copy(e),this.radiu... method union (line 35) | union(e){return e.isEmpty()?this:this.isEmpty()?(this.copy(e),this):(thi... method equals (line 35) | equals(e){return e.center.equals(this.center)&&e.radius===this.radius} method clone (line 35) | clone(){return new this.constructor().copy(this)} method toJSON (line 35) | toJSON(){return{radius:this.radius,center:this.center.toArray()}} method fromJSON (line 35) | fromJSON(e){return this.radius=e.radius,this.center.fromArray(e.center),... method constructor (line 35) | constructor(e=new Ct,n=new Ct(0,0,-1)){this.origin=e,this.direction=n} method set (line 35) | set(e,n){return this.origin.copy(e),this.direction.copy(n),this} method copy (line 35) | copy(e){return this.origin.copy(e.origin),this.direction.copy(e.directio... method at (line 35) | at(e,n){return n.copy(this.origin).addScaledVector(this.direction,e)} method lookAt (line 35) | lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),this} method recast (line 35) | recast(e){return this.origin.copy(this.at(e,ku)),this} method closestPointToPoint (line 35) | closestPointToPoint(e,n){n.subVectors(e,this.origin);const r=n.dot(this.... method distanceToPoint (line 35) | distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))} method distanceSqToPoint (line 35) | distanceSqToPoint(e){const n=ku.subVectors(e,this.origin).dot(this.direc... method distanceSqToSegment (line 35) | distanceSqToSegment(e,n,r,i){UM.copy(e).add(n).multiplyScalar(.5),n1.cop... method intersectSphere (line 35) | intersectSphere(e,n){ku.subVectors(e.center,this.origin);const r=ku.dot(... method intersectsSphere (line 35) | intersectsSphere(e){return e.radius<0?!1:this.distanceSqToPoint(e.center... method distanceToPlane (line 35) | distanceToPlane(e){const n=e.normal.dot(this.direction);if(n===0)return ... method intersectPlane (line 35) | intersectPlane(e,n){const r=this.distanceToPlane(e);return r===null?null... method intersectsPlane (line 35) | intersectsPlane(e){const n=e.distanceToPoint(this.origin);return n===0||... method intersectBox (line 35) | intersectBox(e,n){let r,i,s,o,l,c;const d=1/this.direction.x,u=1/this.di... method intersectsBox (line 35) | intersectsBox(e){return this.intersectBox(e,ku)!==null} method intersectTriangle (line 35) | intersectTriangle(e,n,r,i,s){BM.subVectors(n,e),r1.subVectors(r,e),HM.cr... method applyMatrix4 (line 35) | applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.transf... method equals (line 35) | equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this.d... method clone (line 35) | clone(){return new this.constructor().copy(this)} method constructor (line 35) | constructor(e,n,r,i,s,o,l,c,d,u,m,p,f,y,v,b){aR.prototype.isMatrix4=!0,t... method set (line 35) | set(e,n,r,i,s,o,l,c,d,u,m,p,f,y,v,b){const g=this.elements;return g[0]=e... method identity (line 35) | identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this} method clone (line 35) | clone(){return new aR().fromArray(this.elements)} method copy (line 35) | copy(e){const n=this.elements,r=e.elements;return n[0]=r[0],n[1]=r[1],n[... method copyPosition (line 35) | copyPosition(e){const n=this.elements,r=e.elements;return n[12]=r[12],n[... method setFromMatrix3 (line 35) | setFromMatrix3(e){const n=e.elements;return this.set(n[0],n[3],n[6],0,n[... method extractBasis (line 35) | extractBasis(e,n,r){return e.setFromMatrixColumn(this,0),n.setFromMatrix... method makeBasis (line 35) | makeBasis(e,n,r){return this.set(e.x,n.x,r.x,0,e.y,n.y,r.y,0,e.z,n.z,r.z... method extractRotation (line 35) | extractRotation(e){const n=this.elements,r=e.elements,i=1/Tb.setFromMatr... method makeRotationFromEuler (line 35) | makeRotationFromEuler(e){const n=this.elements,r=e.x,i=e.y,s=e.z,o=Math.... method makeRotationFromQuaternion (line 35) | makeRotationFromQuaternion(e){return this.compose(Gve,e,Wve)} method lookAt (line 35) | lookAt(e,n,r){const i=this.elements;return rl.subVectors(e,n),rl.lengthS... method multiply (line 35) | multiply(e){return this.multiplyMatrices(this,e)} method premultiply (line 35) | premultiply(e){return this.multiplyMatrices(e,this)} method multiplyMatrices (line 35) | multiplyMatrices(e,n){const r=e.elements,i=n.elements,s=this.elements,o=... method multiplyScalar (line 35) | multiplyScalar(e){const n=this.elements;return n[0]*=e,n[4]*=e,n[8]*=e,n... method determinant (line 35) | determinant(){const e=this.elements,n=e[0],r=e[4],i=e[8],s=e[12],o=e[1],... method transpose (line 35) | transpose(){const e=this.elements;let n;return n=e[1],e[1]=e[4],e[4]=n,n... method setPosition (line 35) | setPosition(e,n,r){const i=this.elements;return e.isVector3?(i[12]=e.x,i... method invert (line 35) | invert(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4],l=e[5]... method scale (line 35) | scale(e){const n=this.elements,r=e.x,i=e.y,s=e.z;return n[0]*=r,n[4]*=i,... method getMaxScaleOnAxis (line 35) | getMaxScaleOnAxis(){const e=this.elements,n=e[0]*e[0]+e[1]*e[1]+e[2]*e[2... method makeTranslation (line 35) | makeTranslation(e,n,r){return e.isVector3?this.set(1,0,0,e.x,0,1,0,e.y,0... method makeRotationX (line 35) | makeRotationX(e){const n=Math.cos(e),r=Math.sin(e);return this.set(1,0,0... method makeRotationY (line 35) | makeRotationY(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,0,r... method makeRotationZ (line 35) | makeRotationZ(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,-r,... method makeRotationAxis (line 35) | makeRotationAxis(e,n){const r=Math.cos(n),i=Math.sin(n),s=1-r,o=e.x,l=e.... method makeScale (line 35) | makeScale(e,n,r){return this.set(e,0,0,0,0,n,0,0,0,0,r,0,0,0,0,1),this} method makeShear (line 35) | makeShear(e,n,r,i,s,o){return this.set(1,r,s,0,e,1,o,0,n,i,1,0,0,0,0,1),... method compose (line 35) | compose(e,n,r){const i=this.elements,s=n._x,o=n._y,l=n._z,c=n._w,d=s+s,u... method decompose (line 35) | decompose(e,n,r){const i=this.elements;let s=Tb.set(i[0],i[1],i[2]).leng... method makePerspective (line 35) | makePerspective(e,n,r,i,s,o,l=Md,c=!1){const d=this.elements,u=2*s/(n-e)... method makeOrthographic (line 35) | makeOrthographic(e,n,r,i,s,o,l=Md,c=!1){const d=this.elements,u=2/(n-e),... method equals (line 35) | equals(e){const n=this.elements,r=e.elements;for(let i=0;i<16;i++)if(n[i... method fromArray (line 35) | fromArray(e,n=0){for(let r=0;r<16;r++)this.elements[r]=e[r+n];return this} method toArray (line 35) | toArray(e=[],n=0){const r=this.elements;return e[n]=r[0],e[n+1]=r[1],e[n... method constructor (line 35) | constructor(e=0,n=0,r=0,i=NZ.DEFAULT_ORDER){this.isEuler=!0,this._x=e,th... method x (line 35) | get x(){return this._x} method x (line 35) | set x(e){this._x=e,this._onChangeCallback()} method y (line 35) | get y(){return this._y} method y (line 35) | set y(e){this._y=e,this._onChangeCallback()} method z (line 35) | get z(){return this._z} method z (line 35) | set z(e){this._z=e,this._onChangeCallback()} method order (line 35) | get order(){return this._order} method order (line 35) | set order(e){this._order=e,this._onChangeCallback()} method set (line 35) | set(e,n,r,i=this._order){return this._x=e,this._y=n,this._z=r,this._orde... method clone (line 35) | clone(){return new this.constructor(this._x,this._y,this._z,this._order)} method copy (line 35) | copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._ord... method setFromRotationMatrix (line 35) | setFromRotationMatrix(e,n=this._order,r=!0){const i=e.elements,s=i[0],o=... method setFromQuaternion (line 35) | setFromQuaternion(e,n,r){return ZH.makeRotationFromQuaternion(e),this.se... method setFromVector3 (line 35) | setFromVector3(e,n=this._order){return this.set(e.x,e.y,e.z,n)} method reorder (line 35) | reorder(e){return JH.setFromEuler(this),this.setFromQuaternion(JH,e)} method equals (line 35) | equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._orde... method fromArray (line 35) | fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],e[3]!==void 0... method toArray (line 35) | toArray(e=[],n=0){return e[n]=this._x,e[n+1]=this._y,e[n+2]=this._z,e[n+... method _onChange (line 35) | _onChange(e){return this._onChangeCallback=e,this} method _onChangeCallback (line 35) | _onChangeCallback(){} method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield thi... method constructor (line 35) | constructor(){this.mask=1} method set (line 35) | set(e){this.mask=(1<>>0} method enable (line 35) | enable(e){this.mask|=1<1){for(let n=0;n1){for(let r=0;r1&&(n-=1),n<1/6?t+(e-t)*6*n:n<1/... method constructor (line 35) | constructor(e,n,r){return this.isColor=!0,this.r=1,this.g=1,this.b=1,thi... method set (line 35) | set(e,n,r){if(n===void 0&&r===void 0){const i=e;i&&i.isColor?this.copy(i... method setScalar (line 35) | setScalar(e){return this.r=e,this.g=e,this.b=e,this} method setHex (line 35) | setHex(e,n=ol){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>... method setRGB (line 35) | setRGB(e,n,r,i=Mr.workingColorSpace){return this.r=e,this.g=n,this.b=r,M... method setHSL (line 35) | setHSL(e,n,r,i=Mr.workingColorSpace){if(e=Ove(e,1),n=fr(n,0,1),r=fr(r,0,... method setStyle (line 35) | setStyle(e,n=ol){function r(s){s!==void 0&&parseFloat(s)<1&&qn("Color: A... method setColorName (line 35) | setColorName(e,n=ol){const r=PZ[e.toLowerCase()];return r!==void 0?this.... method clone (line 35) | clone(){return new this.constructor(this.r,this.g,this.b)} method copy (line 35) | copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this} method copySRGBToLinear (line 35) | copySRGBToLinear(e){return this.r=cm(e.r),this.g=cm(e.g),this.b=cm(e.b),... method copyLinearToSRGB (line 35) | copyLinearToSRGB(e){return this.r=jx(e.r),this.g=jx(e.g),this.b=jx(e.b),... method convertSRGBToLinear (line 35) | convertSRGBToLinear(){return this.copySRGBToLinear(this),this} method convertLinearToSRGB (line 35) | convertLinearToSRGB(){return this.copyLinearToSRGB(this),this} method getHex (line 35) | getHex(e=ol){return Mr.workingToColorSpace(Es.copy(this),e),Math.round(f... method getHexString (line 35) | getHexString(e=ol){return("000000"+this.getHex(e).toString(16)).slice(-6)} method getHSL (line 35) | getHSL(e,n=Mr.workingColorSpace){Mr.workingToColorSpace(Es.copy(this),n)... method getRGB (line 35) | getRGB(e,n=Mr.workingColorSpace){return Mr.workingToColorSpace(Es.copy(t... method getStyle (line 35) | getStyle(e=ol){Mr.workingToColorSpace(Es.copy(this),e);const n=Es.r,r=Es... method offsetHSL (line 35) | offsetHSL(e,n,r){return this.getHSL(hh),this.setHSL(hh.h+e,hh.s+n,hh.l+r)} method add (line 35) | add(e){return this.r+=e.r,this.g+=e.g,this.b+=e.b,this} method addColors (line 35) | addColors(e,n){return this.r=e.r+n.r,this.g=e.g+n.g,this.b=e.b+n.b,this} method addScalar (line 35) | addScalar(e){return this.r+=e,this.g+=e,this.b+=e,this} method sub (line 35) | sub(e){return this.r=Math.max(0,this.r-e.r),this.g=Math.max(0,this.g-e.g... method multiply (line 35) | multiply(e){return this.r*=e.r,this.g*=e.g,this.b*=e.b,this} method multiplyScalar (line 35) | multiplyScalar(e){return this.r*=e,this.g*=e,this.b*=e,this} method lerp (line 35) | lerp(e,n){return this.r+=(e.r-this.r)*n,this.g+=(e.g-this.g)*n,this.b+=(... method lerpColors (line 35) | lerpColors(e,n,r){return this.r=e.r+(n.r-e.r)*r,this.g=e.g+(n.g-e.g)*r,t... method lerpHSL (line 35) | lerpHSL(e,n){this.getHSL(hh),e.getHSL(s1);const r=DM(hh.h,s1.h,n),i=DM(h... method setFromVector3 (line 35) | setFromVector3(e){return this.r=e.x,this.g=e.y,this.b=e.z,this} method applyMatrix3 (line 35) | applyMatrix3(e){const n=this.r,r=this.g,i=this.b,s=e.elements;return thi... method equals (line 35) | equals(e){return e.r===this.r&&e.g===this.g&&e.b===this.b} method fromArray (line 35) | fromArray(e,n=0){return this.r=e[n],this.g=e[n+1],this.b=e[n+2],this} method toArray (line 35) | toArray(e=[],n=0){return e[n]=this.r,e[n+1]=this.g,e[n+2]=this.b,e} method fromBufferAttribute (line 35) | fromBufferAttribute(e,n){return this.r=e.getX(n),this.g=e.getY(n),this.b... method toJSON (line 35) | toJSON(){return this.getHex()} method [Symbol.iterator] (line 35) | *[Symbol.iterator](){yield this.r,yield this.g,yield this.b} method constructor (line 35) | constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id"... method alphaTest (line 35) | get alphaTest(){return this._alphaTest} method alphaTest (line 35) | set alphaTest(e){this._alphaTest>0!=e>0&&this.version++,this._alphaTest=e} method onBeforeRender (line 35) | onBeforeRender(){} method onBeforeCompile (line 35) | onBeforeCompile(){} method customProgramCacheKey (line 35) | customProgramCacheKey(){return this.onBeforeCompile.toString()} method setValues (line 35) | setValues(e){if(e!==void 0)for(const n in e){const r=e[n];if(r===void 0)... method toJSON (line 35) | toJSON(e){const n=e===void 0||typeof e=="string";n&&(e={textures:{},imag... method clone (line 35) | clone(){return new this.constructor().copy(this)} method copy (line 35) | copy(e){this.name=e.name,this.blending=e.blending,this.side=e.side,this.... method dispose (line 35) | dispose(){this.dispatchEvent({type:"dispose"})} method needsUpdate (line 35) | set needsUpdate(e){e===!0&&this.version++} method constructor (line 35) | constructor(e){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicM... method copy (line 35) | copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,thi... method constructor (line 35) | constructor(e,n,r=!1){if(Array.isArray(e))throw new TypeError("THREE.Buf... method onUploadCallback (line 35) | onUploadCallback(){} method needsUpdate (line 35) | set needsUpdate(e){e===!0&&this.version++} method setUsage (line 35) | setUsage(e){return this.usage=e,this} method addUpdateRange (line 35) | addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})} method clearUpdateRanges (line 35) | clearUpdateRanges(){this.updateRanges.length=0} method copy (line 35) | copy(e){return this.name=e.name,this.array=new e.array.constructor(e.arr... method copyAt (line 35) | copyAt(e,n,r){e*=this.itemSize,r*=n.itemSize;for(let i=0,s=this.itemSize... method copyArray (line 35) | copyArray(e){return this.array.set(e),this} method applyMatrix3 (line 35) | applyMatrix3(e){if(this.itemSize===2)for(let n=0,r=this.count;n0)return t;const i=e*n;let s=... function Mi (line 3878) | function Mi(t,e){if(t.length!==e.length)return!1;for(let n=0,r=t.length;... function Ei (line 3878) | function Ei(t,e){for(let n=0,r=e.length;n{const i=r.name.... function Rke (line 3982) | async function Rke(t){let e;try{e=await Dke.loadAsync(t)}catch{throw new... function Q6 (line 3982) | function Q6(t){const e=new uc,n=new Float32Array(t.vertices.length);for(... function Lke (line 3982) | function Lke(t){t.traverse(e=>{if(e instanceof mc)if(e.geometry.dispose(... function Oke (line 3982) | function Oke(t,e,n){const{objects:r,buildItems:i}=t,s=new vx,o=m=>{const... function KZ (line 3982) | function KZ({url:t,fileType:e,buildVolume:n={x:256,y:256,z:256},filament... class Bg (line 3982) | class Bg{addEventListener(e,n){this._listeners===void 0&&(this._listener... method addEventListener (line 3982) | addEventListener(e,n){this._listeners===void 0&&(this._listeners={});c... method hasEventListener (line 3982) | hasEventListener(e,n){if(this._listeners===void 0)return!1;const r=thi... method removeEventListener (line 3982) | removeEventListener(e,n){if(this._listeners===void 0)return;const i=th... method dispatchEvent (line 3982) | dispatchEvent(e){if(this._listeners===void 0)return;const r=this._list... function dm (line 3982) | function dm(){const t=Math.random()*4294967295|0,e=Math.random()*4294967... function xs (line 3982) | function xs(t,e,n){return Math.max(e,Math.min(n,t))} function dI (line 3982) | function dI(t,e){return(t%e+e)%e} function LNe (line 3982) | function LNe(t,e,n,r,i){return r+(t-e)*(i-r)/(n-e)} function ONe (line 3982) | function ONe(t,e,n){return t!==e?(n-t)/(e-t):0} function M0 (line 3982) | function M0(t,e,n){return(1-n)*t+n*e} function INe (line 3982) | function INe(t,e,n,r){return M0(t,e,1-Math.exp(-n*r))} function zNe (line 3982) | function zNe(t,e=1){return e-Math.abs(dI(t,e*2)-e)} function UNe (line 3982) | function UNe(t,e,n){return t<=e?0:t>=n?1:(t=(t-e)/(n-e),t*t*(3-2*t))} function BNe (line 3982) | function BNe(t,e,n){return t<=e?0:t>=n?1:(t=(t-e)/(n-e),t*t*t*(t*(t*6-15... function HNe (line 3982) | function HNe(t,e){return t+Math.floor(Math.random()*(e-t+1))} function qNe (line 3982) | function qNe(t,e){return t+Math.random()*(e-t)} function $Ne (line 3982) | function $Ne(t){return t*(.5-Math.random())} function VNe (line 3982) | function VNe(t){t!==void 0&&(Eq=t);let e=Eq+=1831565813;return e=Math.im... function GNe (line 3982) | function GNe(t){return t*j0} function WNe (line 3982) | function WNe(t){return t*gw} function pR (line 3982) | function pR(t){return(t&t-1)===0&&t!==0} function KNe (line 3982) | function KNe(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))} function ON (line 3982) | function ON(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))} function XNe (line 3982) | function XNe(t,e,n,r,i){const s=Math.cos,o=Math.sin,l=s(n/2),c=o(n/2),d=... function Td (line 3982) | function Td(t,e){switch(e.constructor){case Float32Array:return t;case U... function Zr (line 3982) | function Zr(t,e){switch(e.constructor){case Float32Array:return t;case U... class Vn (line 3982) | class Vn{constructor(e=0,n=0){Vn.prototype.isVector2=!0,this.x=e,this.y=... method constructor (line 3982) | constructor(e=0,n=0){Vn.prototype.isVector2=!0,this.x=e,this.y=n} method width (line 3982) | get width(){return this.x} method width (line 3982) | set width(e){this.x=e} method height (line 3982) | get height(){return this.y} method height (line 3982) | set height(e){this.y=e} method set (line 3982) | set(e,n){return this.x=e,this.y=n,this} method setScalar (line 3982) | setScalar(e){return this.x=e,this.y=e,this} method setX (line 3982) | setX(e){return this.x=e,this} method setY (line 3982) | setY(e){return this.y=e,this} method setComponent (line 3982) | setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;brea... method getComponent (line 3982) | getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;de... method clone (line 3982) | clone(){return new this.constructor(this.x,this.y)} method copy (line 3982) | copy(e){return this.x=e.x,this.y=e.y,this} method add (line 3982) | add(e){return this.x+=e.x,this.y+=e.y,this} method addScalar (line 3982) | addScalar(e){return this.x+=e,this.y+=e,this} method addVectors (line 3982) | addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this} method addScaledVector (line 3982) | addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this} method sub (line 3982) | sub(e){return this.x-=e.x,this.y-=e.y,this} method subScalar (line 3982) | subScalar(e){return this.x-=e,this.y-=e,this} method subVectors (line 3982) | subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this} method multiply (line 3982) | multiply(e){return this.x*=e.x,this.y*=e.y,this} method multiplyScalar (line 3982) | multiplyScalar(e){return this.x*=e,this.y*=e,this} method divide (line 3982) | divide(e){return this.x/=e.x,this.y/=e.y,this} method divideScalar (line 3982) | divideScalar(e){return this.multiplyScalar(1/e)} method applyMatrix3 (line 3982) | applyMatrix3(e){const n=this.x,r=this.y,i=e.elements;return this.x=i[0... method min (line 3982) | min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),... method max (line 3982) | max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),... method clamp (line 3982) | clamp(e,n){return this.x=Math.max(e.x,Math.min(n.x,this.x)),this.y=Mat... method clampScalar (line 3982) | clampScalar(e,n){return this.x=Math.max(e,Math.min(n,this.x)),this.y=M... method clampLength (line 3982) | clampLength(e,n){const r=this.length();return this.divideScalar(r||1).... method floor (line 3982) | floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this} method ceil (line 3982) | ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this} method round (line 3982) | round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this} method roundToZero (line 3982) | roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.... method negate (line 3982) | negate(){return this.x=-this.x,this.y=-this.y,this} method dot (line 3982) | dot(e){return this.x*e.x+this.y*e.y} method cross (line 3982) | cross(e){return this.x*e.y-this.y*e.x} method lengthSq (line 3982) | lengthSq(){return this.x*this.x+this.y*this.y} method length (line 3982) | length(){return Math.sqrt(this.x*this.x+this.y*this.y)} method manhattanLength (line 3982) | manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)} method normalize (line 3982) | normalize(){return this.divideScalar(this.length()||1)} method angle (line 3982) | angle(){return Math.atan2(-this.y,-this.x)+Math.PI} method angleTo (line 3982) | angleTo(e){const n=Math.sqrt(this.lengthSq()*e.lengthSq());if(n===0)re... method distanceTo (line 3982) | distanceTo(e){return Math.sqrt(this.distanceToSquared(e))} method distanceToSquared (line 3982) | distanceToSquared(e){const n=this.x-e.x,r=this.y-e.y;return n*n+r*r} method manhattanDistanceTo (line 3982) | manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)} method setLength (line 3982) | setLength(e){return this.normalize().multiplyScalar(e)} method lerp (line 3982) | lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this} method lerpVectors (line 3982) | lerpVectors(e,n,r){return this.x=e.x+(n.x-e.x)*r,this.y=e.y+(n.y-e.y)*... method equals (line 3982) | equals(e){return e.x===this.x&&e.y===this.y} method fromArray (line 3982) | fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this} method toArray (line 3982) | toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e} method fromBufferAttribute (line 3982) | fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this} method rotateAround (line 3982) | rotateAround(e,n){const r=Math.cos(n),i=Math.sin(n),s=this.x-e.x,o=thi... method random (line 3982) | random(){return this.x=Math.random(),this.y=Math.random(),this} method [Symbol.iterator] (line 3982) | *[Symbol.iterator](){yield this.x,yield this.y} class mr (line 3982) | class mr{constructor(e,n,r,i,s,o,l,c,d){mr.prototype.isMatrix3=!0,this.e... method constructor (line 3982) | constructor(e,n,r,i,s,o,l,c,d){mr.prototype.isMatrix3=!0,this.elements... method set (line 3982) | set(e,n,r,i,s,o,l,c,d){const u=this.elements;return u[0]=e,u[1]=i,u[2]... method identity (line 3982) | identity(){return this.set(1,0,0,0,1,0,0,0,1),this} method copy (line 3982) | copy(e){const n=this.elements,r=e.elements;return n[0]=r[0],n[1]=r[1],... method extractBasis (line 3982) | extractBasis(e,n,r){return e.setFromMatrix3Column(this,0),n.setFromMat... method setFromMatrix4 (line 3982) | setFromMatrix4(e){const n=e.elements;return this.set(n[0],n[4],n[8],n[... method multiply (line 3982) | multiply(e){return this.multiplyMatrices(this,e)} method premultiply (line 3982) | premultiply(e){return this.multiplyMatrices(e,this)} method multiplyMatrices (line 3982) | multiplyMatrices(e,n){const r=e.elements,i=n.elements,s=this.elements,... method multiplyScalar (line 3982) | multiplyScalar(e){const n=this.elements;return n[0]*=e,n[3]*=e,n[6]*=e... method determinant (line 3982) | determinant(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4]... method invert (line 3982) | invert(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4],l=e[... method transpose (line 3982) | transpose(){let e;const n=this.elements;return e=n[1],n[1]=n[3],n[3]=e... method getNormalMatrix (line 3982) | getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()} method transposeIntoArray (line 3982) | transposeIntoArray(e){const n=this.elements;return e[0]=n[0],e[1]=n[3]... method setUvTransform (line 3982) | setUvTransform(e,n,r,i,s,o,l){const c=Math.cos(s),d=Math.sin(s);return... method scale (line 3982) | scale(e,n){return this.premultiply(bE.makeScale(e,n)),this} method rotate (line 3982) | rotate(e){return this.premultiply(bE.makeRotation(-e)),this} method translate (line 3982) | translate(e,n){return this.premultiply(bE.makeTranslation(e,n)),this} method makeTranslation (line 3982) | makeTranslation(e,n){return e.isVector2?this.set(1,0,e.x,0,1,e.y,0,0,1... method makeRotation (line 3982) | makeRotation(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,-r... method makeScale (line 3982) | makeScale(e,n){return this.set(e,0,0,0,n,0,0,0,1),this} method equals (line 3982) | equals(e){const n=this.elements,r=e.elements;for(let i=0;i<9;i++)if(n[... method fromArray (line 3982) | fromArray(e,n=0){for(let r=0;r<9;r++)this.elements[r]=e[r+n];return this} method toArray (line 3982) | toArray(e=[],n=0){const r=this.elements;return e[n]=r[0],e[n+1]=r[1],e... method clone (line 3982) | clone(){return new this.constructor().fromArray(this.elements)} function lJ (line 3982) | function lJ(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;ret... function IN (line 3982) | function IN(t){return document.createElementNS("http://www.w3.org/1999/x... function YNe (line 3982) | function YNe(){const t=IN("canvas");return t.style.display="block",t} function E0 (line 3982) | function E0(t){t in Dq||(Dq[t]=!0,console.warn(t))} method legacyMode (line 3982) | get legacyMode(){return console.warn("THREE.ColorManagement: .legacyMode... method legacyMode (line 3982) | set legacyMode(t){console.warn("THREE.ColorManagement: .legacyMode=false... method workingColorSpace (line 3982) | get workingColorSpace(){return this._workingColorSpace} method workingColorSpace (line 3982) | set workingColorSpace(t){if(!QNe.has(t))throw new Error(`Unsupported wor... function Ex (line 3982) | function Ex(t){return t<.04045?t*.0773993808:Math.pow(t*.9478672986+.052... function xE (line 3982) | function xE(t){return t<.0031308?t*12.92:1.055*Math.pow(t,.41666)-.055} class cJ (line 3982) | class cJ{static getDataURL(e){if(/^data:/i.test(e.src)||typeof HTMLCanva... method getDataURL (line 3982) | static getDataURL(e){if(/^data:/i.test(e.src)||typeof HTMLCanvasElemen... method sRGBToLinear (line 3982) | static sRGBToLinear(e){if(typeof HTMLImageElement<"u"&&e instanceof HT... class dJ (line 3982) | class dJ{constructor(e=null){this.isSource=!0,Object.defineProperty(this... method constructor (line 3982) | constructor(e=null){this.isSource=!0,Object.defineProperty(this,"id",{... method needsUpdate (line 3982) | set needsUpdate(e){e===!0&&this.version++} method toJSON (line 3982) | toJSON(e){const n=e===void 0||typeof e=="string";if(!n&&e.images[this.... function yE (line 3982) | function yE(t){return typeof HTMLImageElement<"u"&&t instanceof HTMLImag... class Bo (line 3982) | class Bo extends Bg{constructor(e=Bo.DEFAULT_IMAGE,n=Bo.DEFAULT_MAPPING,... method constructor (line 3982) | constructor(e=Bo.DEFAULT_IMAGE,n=Bo.DEFAULT_MAPPING,r=Uc,i=Uc,s=Xl,o=h... method image (line 3982) | get image(){return this.source.data} method image (line 3982) | set image(e=null){this.source.data=e} method updateMatrix (line 3982) | updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,... method clone (line 3982) | clone(){return new this.constructor().copy(this)} method copy (line 3982) | copy(e){return this.name=e.name,this.source=e.source,this.mipmaps=e.mi... method toJSON (line 3982) | toJSON(e){const n=e===void 0||typeof e=="string";if(!n&&e.textures[thi... method dispose (line 3982) | dispose(){this.dispatchEvent({type:"dispose"})} method transformUv (line 3982) | transformUv(e){if(this.mapping!==YZ)return e;if(e.applyMatrix3(this.ma... method needsUpdate (line 3982) | set needsUpdate(e){e===!0&&(this.version++,this.source.needsUpdate=!0)} method encoding (line 3982) | get encoding(){return E0("THREE.Texture: Property .encoding has been r... method encoding (line 3982) | set encoding(e){E0("THREE.Texture: Property .encoding has been replace... class ta (line 3982) | class ta{constructor(e=0,n=0,r=0,i=1){ta.prototype.isVector4=!0,this.x=e... method constructor (line 3982) | constructor(e=0,n=0,r=0,i=1){ta.prototype.isVector4=!0,this.x=e,this.y... method width (line 3982) | get width(){return this.z} method width (line 3982) | set width(e){this.z=e} method height (line 3982) | get height(){return this.w} method height (line 3982) | set height(e){this.w=e} method set (line 3982) | set(e,n,r,i){return this.x=e,this.y=n,this.z=r,this.w=i,this} method setScalar (line 3982) | setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this} method setX (line 3982) | setX(e){return this.x=e,this} method setY (line 3982) | setY(e){return this.y=e,this} method setZ (line 3982) | setZ(e){return this.z=e,this} method setW (line 3982) | setW(e){return this.w=e,this} method setComponent (line 3982) | setComponent(e,n){switch(e){case 0:this.x=n;break;case 1:this.y=n;brea... method getComponent (line 3982) | getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;ca... method clone (line 3982) | clone(){return new this.constructor(this.x,this.y,this.z,this.w)} method copy (line 3982) | copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w!==void 0?e.... method add (line 3982) | add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this} method addScalar (line 3982) | addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this} method addVectors (line 3982) | addVectors(e,n){return this.x=e.x+n.x,this.y=e.y+n.y,this.z=e.z+n.z,th... method addScaledVector (line 3982) | addScaledVector(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,... method sub (line 3982) | sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this} method subScalar (line 3982) | subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this} method subVectors (line 3982) | subVectors(e,n){return this.x=e.x-n.x,this.y=e.y-n.y,this.z=e.z-n.z,th... method multiply (line 3982) | multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this} method multiplyScalar (line 3982) | multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this} method applyMatrix4 (line 3982) | applyMatrix4(e){const n=this.x,r=this.y,i=this.z,s=this.w,o=e.elements... method divideScalar (line 3982) | divideScalar(e){return this.multiplyScalar(1/e)} method setAxisAngleFromQuaternion (line 3982) | setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);const n=Math.sqr... method setAxisAngleFromRotationMatrix (line 3982) | setAxisAngleFromRotationMatrix(e){let n,r,i,s;const c=e.elements,d=c[0... method min (line 3982) | min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),... method max (line 3982) | max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),... method clamp (line 3982) | clamp(e,n){return this.x=Math.max(e.x,Math.min(n.x,this.x)),this.y=Mat... method clampScalar (line 3982) | clampScalar(e,n){return this.x=Math.max(e,Math.min(n,this.x)),this.y=M... method clampLength (line 3982) | clampLength(e,n){const r=this.length();return this.divideScalar(r||1).... method floor (line 3982) | floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),thi... method ceil (line 3982) | ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z... method round (line 3982) | round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),thi... method roundToZero (line 3982) | roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.... method negate (line 3982) | negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-t... method dot (line 3982) | dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w} method lengthSq (line 3982) | lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*thi... method length (line 3982) | length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+th... method manhattanLength (line 3982) | manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(th... method normalize (line 3982) | normalize(){return this.divideScalar(this.length()||1)} method setLength (line 3982) | setLength(e){return this.normalize().multiplyScalar(e)} method lerp (line 3982) | lerp(e,n){return this.x+=(e.x-this.x)*n,this.y+=(e.y-this.y)*n,this.z+... method lerpVectors (line 3982) | lerpVectors(e,n,r){return this.x=e.x+(n.x-e.x)*r,this.y=e.y+(n.y-e.y)*... method equals (line 3982) | equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z&&e.w===this.w} method fromArray (line 3982) | fromArray(e,n=0){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this.w... method toArray (line 3982) | toArray(e=[],n=0){return e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3... method fromBufferAttribute (line 3982) | fromBufferAttribute(e,n){return this.x=e.getX(n),this.y=e.getY(n),this... method random (line 3982) | random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.... method [Symbol.iterator] (line 3982) | *[Symbol.iterator](){yield this.x,yield this.y,yield this.z,yield this.w} class eCe (line 3982) | class eCe extends Bg{constructor(e=1,n=1,r={}){super(),this.isRenderTarg... method constructor (line 3982) | constructor(e=1,n=1,r={}){super(),this.isRenderTarget=!0,this.width=e,... method setSize (line 3982) | setSize(e,n,r=1){(this.width!==e||this.height!==n||this.depth!==r)&&(t... method clone (line 3982) | clone(){return new this.constructor().copy(this)} method copy (line 3982) | copy(e){this.width=e.width,this.height=e.height,this.depth=e.depth,thi... method dispose (line 3982) | dispose(){this.dispatchEvent({type:"dispose"})} class xg (line 3982) | class xg extends eCe{constructor(e=1,n=1,r={}){super(e,n,r),this.isWebGL... method constructor (line 3982) | constructor(e=1,n=1,r={}){super(e,n,r),this.isWebGLRenderTarget=!0} class uJ (line 3982) | class uJ extends Bo{constructor(e=null,n=1,r=1,i=1){super(null),this.isD... method constructor (line 3982) | constructor(e=null,n=1,r=1,i=1){super(null),this.isDataArrayTexture=!0... class tCe (line 3982) | class tCe extends Bo{constructor(e=null,n=1,r=1,i=1){super(null),this.is... method constructor (line 3982) | constructor(e=null,n=1,r=1,i=1){super(null),this.isData3DTexture=!0,th... class yg (line 3982) | class yg{constructor(e=0,n=0,r=0,i=1){this.isQuaternion=!0,this._x=e,thi... method constructor (line 3982) | constructor(e=0,n=0,r=0,i=1){this.isQuaternion=!0,this._x=e,this._y=n,... method slerpFlat (line 3982) | static slerpFlat(e,n,r,i,s,o,l){let c=r[i+0],d=r[i+1],u=r[i+2],m=r[i+3... method multiplyQuaternionsFlat (line 3982) | static multiplyQuaternionsFlat(e,n,r,i,s,o){const l=r[i],c=r[i+1],d=r[... method x (line 3982) | get x(){return this._x} method x (line 3982) | set x(e){this._x=e,this._onChangeCallback()} method y (line 3982) | get y(){return this._y} method y (line 3982) | set y(e){this._y=e,this._onChangeCallback()} method z (line 3982) | get z(){return this._z} method z (line 3982) | set z(e){this._z=e,this._onChangeCallback()} method w (line 3982) | get w(){return this._w} method w (line 3982) | set w(e){this._w=e,this._onChangeCallback()} method set (line 3982) | set(e,n,r,i){return this._x=e,this._y=n,this._z=r,this._w=i,this._onCh... method clone (line 3982) | clone(){return new this.constructor(this._x,this._y,this._z,this._w)} method copy (line 3982) | copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._o... method setFromEuler (line 3982) | setFromEuler(e,n){const r=e._x,i=e._y,s=e._z,o=e._order,l=Math.cos,c=M... method setFromAxisAngle (line 3982) | setFromAxisAngle(e,n){const r=n/2,i=Math.sin(r);return this._x=e.x*i,t... method setFromRotationMatrix (line 3982) | setFromRotationMatrix(e){const n=e.elements,r=n[0],i=n[4],s=n[8],o=n[1... method setFromUnitVectors (line 3982) | setFromUnitVectors(e,n){let r=e.dot(n)+1;return rthis.max.x||e.ythis.max.x||e.max... method intersectsSphere (line 3982) | intersectsSphere(e){return this.clampPoint(e.center,Fc),Fc.distanceToS... method intersectsPlane (line 3982) | intersectsPlane(e){let n,r;return e.normal.x>0?(n=e.normal.x*this.min.... method intersectsTriangle (line 3982) | intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(Uv),k1... method clampPoint (line 3982) | clampPoint(e,n){return n.copy(e).clamp(this.min,this.max)} method distanceToPoint (line 3982) | distanceToPoint(e){return this.clampPoint(e,Fc).distanceTo(e)} method getBoundingSphere (line 3982) | getBoundingSphere(e){return this.isEmpty()?e.makeEmpty():(this.getCent... method intersect (line 3982) | intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmp... method union (line 3982) | union(e){return this.min.min(e.min),this.max.max(e.max),this} method applyMatrix4 (line 3982) | applyMatrix4(e){return this.isEmpty()?this:(ju[0].set(this.min.x,this.... method translate (line 3982) | translate(e){return this.min.add(e),this.max.add(e),this} method equals (line 3982) | equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)} function wE (line 3982) | function wE(t,e,n,r,i){for(let s=0,o=t.length-3;s<=o;s+=3){ff.fromArray(... class Ld (line 3982) | class Ld{constructor(e=new ut,n=-1){this.center=e,this.radius=n}set(e,n)... method constructor (line 3982) | constructor(e=new ut,n=-1){this.center=e,this.radius=n} method set (line 3982) | set(e,n){return this.center.copy(e),this.radius=n,this} method setFromPoints (line 3982) | setFromPoints(e,n){const r=this.center;n!==void 0?r.copy(n):nCe.setFro... method copy (line 3982) | copy(e){return this.center.copy(e.center),this.radius=e.radius,this} method isEmpty (line 3982) | isEmpty(){return this.radius<0} method makeEmpty (line 3982) | makeEmpty(){return this.center.set(0,0,0),this.radius=-1,this} method containsPoint (line 3982) | containsPoint(e){return e.distanceToSquared(this.center)<=this.radius*... method distanceToPoint (line 3982) | distanceToPoint(e){return e.distanceTo(this.center)-this.radius} method intersectsSphere (line 3982) | intersectsSphere(e){const n=this.radius+e.radius;return e.center.dista... method intersectsBox (line 3982) | intersectsBox(e){return e.intersectsSphere(this)} method intersectsPlane (line 3982) | intersectsPlane(e){return Math.abs(e.distanceToPoint(this.center))<=th... method clampPoint (line 3982) | clampPoint(e,n){const r=this.center.distanceToSquared(e);return n.copy... method getBoundingBox (line 3982) | getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.... method applyMatrix4 (line 3982) | applyMatrix4(e){return this.center.applyMatrix4(e),this.radius=this.ra... method translate (line 3982) | translate(e){return this.center.add(e),this} method expandByPoint (line 3982) | expandByPoint(e){if(this.isEmpty())return this.center.copy(e),this.rad... method union (line 3982) | union(e){return e.isEmpty()?this:this.isEmpty()?(this.copy(e),this):(t... method equals (line 3982) | equals(e){return e.center.equals(this.center)&&e.radius===this.radius} method clone (line 3982) | clone(){return new this.constructor().copy(this)} class uI (line 3982) | class uI{constructor(e=new ut,n=new ut(0,0,-1)){this.origin=e,this.direc... method constructor (line 3982) | constructor(e=new ut,n=new ut(0,0,-1)){this.origin=e,this.direction=n} method set (line 3982) | set(e,n){return this.origin.copy(e),this.direction.copy(n),this} method copy (line 3982) | copy(e){return this.origin.copy(e.origin),this.direction.copy(e.direct... method at (line 3982) | at(e,n){return n.copy(this.origin).addScaledVector(this.direction,e)} method lookAt (line 3982) | lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),t... method recast (line 3982) | recast(e){return this.origin.copy(this.at(e,Mu)),this} method closestPointToPoint (line 3982) | closestPointToPoint(e,n){n.subVectors(e,this.origin);const r=n.dot(thi... method distanceToPoint (line 3982) | distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))} method distanceSqToPoint (line 3982) | distanceSqToPoint(e){const n=Mu.subVectors(e,this.origin).dot(this.dir... method distanceSqToSegment (line 3982) | distanceSqToSegment(e,n,r,i){_E.copy(e).add(n).multiplyScalar(.5),C1.c... method intersectSphere (line 3982) | intersectSphere(e,n){Mu.subVectors(e.center,this.origin);const r=Mu.do... method intersectsSphere (line 3982) | intersectsSphere(e){return this.distanceSqToPoint(e.center)<=e.radius*... method distanceToPlane (line 3982) | distanceToPlane(e){const n=e.normal.dot(this.direction);if(n===0)retur... method intersectPlane (line 3982) | intersectPlane(e,n){const r=this.distanceToPlane(e);return r===null?nu... method intersectsPlane (line 3982) | intersectsPlane(e){const n=e.distanceToPoint(this.origin);return n===0... method intersectBox (line 3982) | intersectBox(e,n){let r,i,s,o,l,c;const d=1/this.direction.x,u=1/this.... method intersectsBox (line 3982) | intersectsBox(e){return this.intersectBox(e,Mu)!==null} method intersectTriangle (line 3982) | intersectTriangle(e,n,r,i,s){kE.subVectors(n,e),P1.subVectors(r,e),NE.... method applyMatrix4 (line 3982) | applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.tran... method equals (line 3982) | equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this... method clone (line 3982) | clone(){return new this.constructor().copy(this)} class ba (line 3982) | class ba{constructor(e,n,r,i,s,o,l,c,d,u,m,p,f,y,v,b){ba.prototype.isMat... method constructor (line 3982) | constructor(e,n,r,i,s,o,l,c,d,u,m,p,f,y,v,b){ba.prototype.isMatrix4=!0... method set (line 3982) | set(e,n,r,i,s,o,l,c,d,u,m,p,f,y,v,b){const g=this.elements;return g[0]... method identity (line 3982) | identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this} method clone (line 3982) | clone(){return new ba().fromArray(this.elements)} method copy (line 3982) | copy(e){const n=this.elements,r=e.elements;return n[0]=r[0],n[1]=r[1],... method copyPosition (line 3982) | copyPosition(e){const n=this.elements,r=e.elements;return n[12]=r[12],... method setFromMatrix3 (line 3982) | setFromMatrix3(e){const n=e.elements;return this.set(n[0],n[3],n[6],0,... method extractBasis (line 3982) | extractBasis(e,n,r){return e.setFromMatrixColumn(this,0),n.setFromMatr... method makeBasis (line 3982) | makeBasis(e,n,r){return this.set(e.x,n.x,r.x,0,e.y,n.y,r.y,0,e.z,n.z,r... method extractRotation (line 3982) | extractRotation(e){const n=this.elements,r=e.elements,i=1/$b.setFromMa... method makeRotationFromEuler (line 3982) | makeRotationFromEuler(e){const n=this.elements,r=e.x,i=e.y,s=e.z,o=Mat... method makeRotationFromQuaternion (line 3982) | makeRotationFromQuaternion(e){return this.compose(rCe,e,aCe)} method lookAt (line 3982) | lookAt(e,n,r){const i=this.elements;return il.subVectors(e,n),il.lengt... method multiply (line 3982) | multiply(e){return this.multiplyMatrices(this,e)} method premultiply (line 3982) | premultiply(e){return this.multiplyMatrices(e,this)} method multiplyMatrices (line 3982) | multiplyMatrices(e,n){const r=e.elements,i=n.elements,s=this.elements,... method multiplyScalar (line 3982) | multiplyScalar(e){const n=this.elements;return n[0]*=e,n[4]*=e,n[8]*=e... method determinant (line 3982) | determinant(){const e=this.elements,n=e[0],r=e[4],i=e[8],s=e[12],o=e[1... method transpose (line 3982) | transpose(){const e=this.elements;let n;return n=e[1],e[1]=e[4],e[4]=n... method setPosition (line 3982) | setPosition(e,n,r){const i=this.elements;return e.isVector3?(i[12]=e.x... method invert (line 3982) | invert(){const e=this.elements,n=e[0],r=e[1],i=e[2],s=e[3],o=e[4],l=e[... method scale (line 3982) | scale(e){const n=this.elements,r=e.x,i=e.y,s=e.z;return n[0]*=r,n[4]*=... method getMaxScaleOnAxis (line 3982) | getMaxScaleOnAxis(){const e=this.elements,n=e[0]*e[0]+e[1]*e[1]+e[2]*e... method makeTranslation (line 3982) | makeTranslation(e,n,r){return e.isVector3?this.set(1,0,0,e.x,0,1,0,e.y... method makeRotationX (line 3982) | makeRotationX(e){const n=Math.cos(e),r=Math.sin(e);return this.set(1,0... method makeRotationY (line 3982) | makeRotationY(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,0... method makeRotationZ (line 3982) | makeRotationZ(e){const n=Math.cos(e),r=Math.sin(e);return this.set(n,-... method makeRotationAxis (line 3982) | makeRotationAxis(e,n){const r=Math.cos(n),i=Math.sin(n),s=1-r,o=e.x,l=... method makeScale (line 3982) | makeScale(e,n,r){return this.set(e,0,0,0,0,n,0,0,0,0,r,0,0,0,0,1),this} method makeShear (line 3982) | makeShear(e,n,r,i,s,o){return this.set(1,r,s,0,e,1,o,0,n,i,1,0,0,0,0,1... method compose (line 3982) | compose(e,n,r){const i=this.elements,s=n._x,o=n._y,l=n._z,c=n._w,d=s+s... method decompose (line 3982) | decompose(e,n,r){const i=this.elements;let s=$b.set(i[0],i[1],i[2]).le... method makePerspective (line 3982) | makePerspective(e,n,r,i,s,o,l=Ed){const c=this.elements,d=2*s/(n-e),u=... method makeOrthographic (line 3982) | makeOrthographic(e,n,r,i,s,o,l=Ed){const c=this.elements,d=1/(n-e),u=1... method equals (line 3982) | equals(e){const n=this.elements,r=e.elements;for(let i=0;i<16;i++)if(n... method fromArray (line 3982) | fromArray(e,n=0){for(let r=0;r<16;r++)this.elements[r]=e[r+n];return t... method toArray (line 3982) | toArray(e=[],n=0){const r=this.elements;return e[n]=r[0],e[n+1]=r[1],e... class cS (line 3982) | class cS{constructor(e=0,n=0,r=0,i=cS.DEFAULT_ORDER){this.isEuler=!0,thi... method constructor (line 3982) | constructor(e=0,n=0,r=0,i=cS.DEFAULT_ORDER){this.isEuler=!0,this._x=e,... method x (line 3982) | get x(){return this._x} method x (line 3982) | set x(e){this._x=e,this._onChangeCallback()} method y (line 3982) | get y(){return this._y} method y (line 3982) | set y(e){this._y=e,this._onChangeCallback()} method z (line 3982) | get z(){return this._z} method z (line 3982) | set z(e){this._z=e,this._onChangeCallback()} method order (line 3982) | get order(){return this._order} method order (line 3982) | set order(e){this._order=e,this._onChangeCallback()} method set (line 3982) | set(e,n,r,i=this._order){return this._x=e,this._y=n,this._z=r,this._or... method clone (line 3982) | clone(){return new this.constructor(this._x,this._y,this._z,this._order)} method copy (line 3982) | copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._o... method setFromRotationMatrix (line 3982) | setFromRotationMatrix(e,n=this._order,r=!0){const i=e.elements,s=i[0],... method setFromQuaternion (line 3982) | setFromQuaternion(e,n,r){return Oq.makeRotationFromQuaternion(e),this.... method setFromVector3 (line 3982) | setFromVector3(e,n=this._order){return this.set(e.x,e.y,e.z,n)} method reorder (line 3982) | reorder(e){return Iq.setFromEuler(this),this.setFromQuaternion(Iq,e)} method equals (line 3982) | equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._or... method fromArray (line 3982) | fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],e[3]!==void... method toArray (line 3982) | toArray(e=[],n=0){return e[n]=this._x,e[n+1]=this._y,e[n+2]=this._z,e[... method _onChange (line 3982) | _onChange(e){return this._onChangeCallback=e,this} method _onChangeCallback (line 3982) | _onChangeCallback(){} method [Symbol.iterator] (line 3982) | *[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield thi... class mJ (line 3982) | class mJ{constructor(){this.mask=1}set(e){this.mask=(1<>>0}enable(... method constructor (line 3982) | constructor(){this.mask=1} method set (line 3982) | set(e){this.mask=(1<>>0} method enable (line 3982) | enable(e){this.mask|=1<1){for(let n=0;n1){for(let r=0;r1&&(n-=1),n<1/6?t+(e-t)*6*n:n<1/... method constructor (line 3982) | constructor(e,n,r){return this.isColor=!0,this.r=1,this.g=1,this.b=1,thi... method set (line 3982) | set(e,n,r){if(n===void 0&&r===void 0){const i=e;i&&i.isColor?this.copy(i... method setScalar (line 3982) | setScalar(e){return this.r=e,this.g=e,this.b=e,this} method setHex (line 3982) | setHex(e,n=bs){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>... method setRGB (line 3982) | setRGB(e,n,r,i=Jr.workingColorSpace){return this.r=e,this.g=n,this.b=r,J... method setHSL (line 3982) | setHSL(e,n,r,i=Jr.workingColorSpace){if(e=dI(e,1),n=xs(n,0,1),r=xs(r,0,1... method setStyle (line 3982) | setStyle(e,n=bs){function r(s){s!==void 0&&parseFloat(s)<1&&console.warn... method setColorName (line 3982) | setColorName(e,n=bs){const r=hJ[e.toLowerCase()];return r!==void 0?this.... method clone (line 3982) | clone(){return new this.constructor(this.r,this.g,this.b)} method copy (line 3982) | copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this} method copySRGBToLinear (line 3982) | copySRGBToLinear(e){return this.r=Ex(e.r),this.g=Ex(e.g),this.b=Ex(e.b),... method copyLinearToSRGB (line 3982) | copyLinearToSRGB(e){return this.r=xE(e.r),this.g=xE(e.g),this.b=xE(e.b),... method convertSRGBToLinear (line 3982) | convertSRGBToLinear(){return this.copySRGBToLinear(this),this} method convertLinearToSRGB (line 3982) | convertLinearToSRGB(){return this.copyLinearToSRGB(this),this} method getHex (line 3982) | getHex(e=bs){return Jr.fromWorkingColorSpace(Fs.copy(this),e),Math.round... method getHexString (line 3982) | getHexString(e=bs){return("000000"+this.getHex(e).toString(16)).slice(-6)} method getHSL (line 3982) | getHSL(e,n=Jr.workingColorSpace){Jr.fromWorkingColorSpace(Fs.copy(this),... method getRGB (line 3982) | getRGB(e,n=Jr.workingColorSpace){return Jr.fromWorkingColorSpace(Fs.copy... method getStyle (line 3982) | getStyle(e=bs){Jr.fromWorkingColorSpace(Fs.copy(this),e);const n=Fs.r,r=... method offsetHSL (line 3982) | offsetHSL(e,n,r){return this.getHSL(yh),this.setHSL(yh.h+e,yh.s+n,yh.l+r)} method add (line 3982) | add(e){return this.r+=e.r,this.g+=e.g,this.b+=e.b,this} method addColors (line 3982) | addColors(e,n){return this.r=e.r+n.r,this.g=e.g+n.g,this.b=e.b+n.b,this} method addScalar (line 3982) | addScalar(e){return this.r+=e,this.g+=e,this.b+=e,this} method sub (line 3982) | sub(e){return this.r=Math.max(0,this.r-e.r),this.g=Math.max(0,this.g-e.g... method multiply (line 3982) | multiply(e){return this.r*=e.r,this.g*=e.g,this.b*=e.b,this} method multiplyScalar (line 3982) | multiplyScalar(e){return this.r*=e,this.g*=e,this.b*=e,this} method lerp (line 3982) | lerp(e,n){return this.r+=(e.r-this.r)*n,this.g+=(e.g-this.g)*n,this.b+=(... method lerpColors (line 3982) | lerpColors(e,n,r){return this.r=e.r+(n.r-e.r)*r,this.g=e.g+(n.g-e.g)*r,t... method lerpHSL (line 3982) | lerpHSL(e,n){this.getHSL(yh),e.getHSL(M1);const r=M0(yh.h,M1.h,n),i=M0(y... method setFromVector3 (line 3982) | setFromVector3(e){return this.r=e.x,this.g=e.y,this.b=e.z,this} method applyMatrix3 (line 3982) | applyMatrix3(e){const n=this.r,r=this.g,i=this.b,s=e.elements;return thi... method equals (line 3982) | equals(e){return e.r===this.r&&e.g===this.g&&e.b===this.b} method fromArray (line 3982) | fromArray(e,n=0){return this.r=e[n],this.g=e[n+1],this.b=e[n+2],this} method toArray (line 3982) | toArray(e=[],n=0){return e[n]=this.r,e[n+1]=this.g,e[n+2]=this.b,e} method fromBufferAttribute (line 3982) | fromBufferAttribute(e,n){return this.r=e.getX(n),this.g=e.getY(n),this.b... method toJSON (line 3982) | toJSON(){return this.getHex()} method [Symbol.iterator] (line 3982) | *[Symbol.iterator](){yield this.r,yield this.g,yield this.b} class Cy (line 3982) | class Cy extends Bg{constructor(){super(),this.isMaterial=!0,Object.defi... method constructor (line 3982) | constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"i... method alphaTest (line 3982) | get alphaTest(){return this._alphaTest} method alphaTest (line 3982) | set alphaTest(e){this._alphaTest>0!=e>0&&this.version++,this._alphaTes... method onBuild (line 3982) | onBuild(){} method onBeforeRender (line 3982) | onBeforeRender(){} method onBeforeCompile (line 3982) | onBeforeCompile(){} method customProgramCacheKey (line 3982) | customProgramCacheKey(){return this.onBeforeCompile.toString()} method setValues (line 3982) | setValues(e){if(e!==void 0)for(const n in e){const r=e[n];if(r===void ... method toJSON (line 3982) | toJSON(e){const n=e===void 0||typeof e=="string";n&&(e={textures:{},im... method clone (line 3982) | clone(){return new this.constructor().copy(this)} method copy (line 3982) | copy(e){this.name=e.name,this.blending=e.blending,this.side=e.side,thi... method dispose (line 3982) | dispose(){this.dispatchEvent({type:"dispose"})} method needsUpdate (line 3982) | set needsUpdate(e){e===!0&&this.version++} class pJ (line 3982) | class pJ extends Cy{constructor(e){super(),this.isMeshBasicMaterial=!0,t... method constructor (line 3982) | constructor(e){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasi... method copy (line 3982) | copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,t... class fl (line 3982) | class fl{constructor(e,n,r=!1){if(Array.isArray(e))throw new TypeError("... method constructor (line 3982) | constructor(e,n,r=!1){if(Array.isArray(e))throw new TypeError("THREE.B... method onUploadCallback (line 3982) | onUploadCallback(){} method needsUpdate (line 3982) | set needsUpdate(e){e===!0&&this.version++} method updateRange (line 3982) | get updateRange(){return console.warn('THREE.BufferAttribute: "updateR... method setUsage (line 3982) | setUsage(e){return this.usage=e,this} method addUpdateRange (line 3982) | addUpdateRange(e,n){this.updateRanges.push({start:e,count:n})} method clearUpdateRanges (line 3982) | clearUpdateRanges(){this.updateRanges.length=0} method copy (line 3982) | copy(e){return this.name=e.name,this.array=new e.array.constructor(e.a... method copyAt (line 3982) | copyAt(e,n,r){e*=this.itemSize,r*=n.itemSize;for(let i=0,s=this.itemSi... method copyArray (line 3982) | copyArray(e){return this.array.set(e),this} method applyMatrix3 (line 3982) | applyMatrix3(e){if(this.itemSize===2)for(let n=0,r=this.count;n0)return t;const i=e*n;let s=... function Di (line 7564) | function Di(t,e){if(t.length!==e.length)return!1;for(let n=0,r=t.length;... function Fi (line 7564) | function Fi(t,e){for(let n=0,r=e.length;n=r.length&&r.push({... method reset (line 7622) | reset(){this.list.length=0,this.index=0} function lMe (line 7622) | function lMe(t,e,n=0){const r=e.itemSize;if(t.isInterleavedBufferAttribu... class cMe (line 7622) | class cMe extends Wc{get maxGeometryCount(){return this._maxGeometryCoun... method maxGeometryCount (line 7622) | get maxGeometryCount(){return this._maxGeometryCount} method constructor (line 7622) | constructor(e,n,r=n*2,i){super(new Vs,i),this.isBatchedMesh=!0,this.pe... method _initMatricesTexture (line 7622) | _initMatricesTexture(){let e=Math.sqrt(this._maxGeometryCount*4);e=Mat... method _initializeGeometry (line 7622) | _initializeGeometry(e){const n=this.geometry,r=this._maxVertexCount,i=... method _validateGeometry (line 7622) | _validateGeometry(e){if(e.getAttribute(tx))throw new Error(`BatchedMes... method setCustomSort (line 7622) | setCustomSort(e){return this.customSort=e,this} method computeBoundingBox (line 7622) | computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new ac... method computeBoundingSphere (line 7622) | computeBoundingSphere(){this.boundingSphere===null&&(this.boundingSphe... method addGeometry (line 7622) | addGeometry(e,n=-1,r=-1){if(this._initializeGeometry(e),this._validate... method setGeometryAt (line 7622) | setGeometryAt(e,n){if(e>=this._geometryCount)throw new Error("BatchedM... method deleteGeometry (line 7622) | deleteGeometry(e){const n=this._active;return e>=n.length||n[e]===!1?t... method getBoundingBoxAt (line 7622) | getBoundingBoxAt(e,n){if(this._active[e]===!1)return this;const i=this... method getBoundingSphereAt (line 7622) | getBoundingSphereAt(e,n){if(this._active[e]===!1)return this;const i=t... method setMatrixAt (line 7622) | setMatrixAt(e,n){const r=this._active,i=this._matricesTexture,s=this._... method getMatrixAt (line 7622) | getMatrixAt(e,n){const r=this._active,i=this._matricesTexture.image.da... method setVisibleAt (line 7622) | setVisibleAt(e,n){const r=this._visibility,i=this._active,s=this._geom... method getVisibleAt (line 7622) | getVisibleAt(e){const n=this._visibility,r=this._active,i=this._geomet... method raycast (line 7622) | raycast(e,n){const r=this._visibility,i=this._active,s=this._drawRange... method copy (line 7622) | copy(e){return super.copy(e),this.geometry=e.geometry.clone(),this.per... method dispose (line 7622) | dispose(){return this.geometry.dispose(),this._matricesTexture.dispose... method onBeforeRender (line 7622) | onBeforeRender(e,n,r,i,s){if(!this._visibilityChanged&&!this.perObject... method onBeforeShadow (line 7622) | onBeforeShadow(e,n,r,i,s,o){this.onBeforeRender(e,null,i,s,o)} class uS (line 7622) | class uS extends Cy{constructor(e){super(),this.isLineBasicMaterial=!0,t... method constructor (line 7622) | constructor(e){super(),this.isLineBasicMaterial=!0,this.type="LineBasi... method copy (line 7622) | copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,t... method constructor (line 7622) | constructor(e=new Vs,n=new uS){super(),this.isLine=!0,this.type="Line",t... method copy (line 7622) | copy(e,n){return super.copy(e,n),this.material=Array.isArray(e.material)... method computeLineDistances (line 7622) | computeLineDistances(){const e=this.geometry;if(e.index===null){const n=... method raycast (line 7622) | raycast(e,n){const r=this.geometry,i=this.matrixWorld,s=e.params.Line.th... method updateMorphTargets (line 7622) | updateMorphTargets(){const n=this.geometry.morphAttributes,r=Object.keys... class aT (line 7622) | class aT extends dMe{constructor(e,n){super(e,n),this.isLineSegments=!0,... method constructor (line 7622) | constructor(e,n){super(e,n),this.isLineSegments=!0,this.type="LineSegm... method computeLineDistances (line 7622) | computeLineDistances(){const e=this.geometry;if(e.index===null){const ... class uMe (line 7622) | class uMe extends Vs{constructor(e=null){if(super(),this.type="Wireframe... method constructor (line 7622) | constructor(e=null){if(super(),this.type="WireframeGeometry",this.para... method copy (line 7622) | copy(e){return super.copy(e),this.parameters=Object.assign({},e.parame... function k$ (line 7622) | function k$(t,e,n){const r=`${t.x},${t.y},${t.z}-${e.x},${e.y},${e.z}`,i... class mMe (line 7622) | class mMe extends Cy{constructor(e){super(),this.isMeshLambertMaterial=!... method constructor (line 7622) | constructor(e){super(),this.isMeshLambertMaterial=!0,this.type="MeshLa... method copy (line 7622) | copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,t... class hMe (line 7622) | class hMe extends uS{constructor(e){super(),this.isLineDashedMaterial=!0... method constructor (line 7622) | constructor(e){super(),this.isLineDashedMaterial=!0,this.type="LineDas... method copy (line 7622) | copy(e){return super.copy(e),this.scale=e.scale,this.dashSize=e.dashSi... class PJ (line 7622) | class PJ extends lo{constructor(e,n=1){super(),this.isLight=!0,this.type... method constructor (line 7622) | constructor(e,n=1){super(),this.isLight=!0,this.type="Light",this.colo... method dispose (line 7622) | dispose(){} method copy (line 7622) | copy(e,n){return super.copy(e,n),this.color.copy(e.color),this.intensi... method toJSON (line 7622) | toJSON(e){const n=super.toJSON(e);return n.object.color=this.color.get... class pMe (line 7622) | class pMe{constructor(e){this.camera=e,this.bias=0,this.normalBias=0,thi... method constructor (line 7622) | constructor(e){this.camera=e,this.bias=0,this.normalBias=0,this.radius... method getViewportCount (line 7622) | getViewportCount(){return this._viewportCount} method getFrustum (line 7622) | getFrustum(){return this._frustum} method updateMatrices (line 7622) | updateMatrices(e){const n=this.camera,r=this.matrix;N$.setFromMatrixPo... method getViewport (line 7622) | getViewport(e){return this._viewports[e]} method getFrameExtents (line 7622) | getFrameExtents(){return this._frameExtents} method dispose (line 7622) | dispose(){this.map&&this.map.dispose(),this.mapPass&&this.mapPass.disp... method copy (line 7622) | copy(e){return this.camera=e.camera.clone(),this.bias=e.bias,this.radi... method clone (line 7622) | clone(){return new this.constructor().copy(this)} method toJSON (line 7622) | toJSON(){const e={};return this.bias!==0&&(e.bias=this.bias),this.norm... class fMe (line 7622) | class fMe extends pMe{constructor(){super(new ll(90,1,.5,500)),this.isPo... method constructor (line 7622) | constructor(){super(new ll(90,1,.5,500)),this.isPointLightShadow=!0,th... method updateMatrices (line 7622) | updateMatrices(e,n=0){const r=this.camera,i=this.matrix,s=e.distance||... class gMe (line 7622) | class gMe extends PJ{constructor(e,n,r=0,i=2){super(e,n),this.isPointLig... method constructor (line 7622) | constructor(e,n,r=0,i=2){super(e,n),this.isPointLight=!0,this.type="Po... method power (line 7622) | get power(){return this.intensity*4*Math.PI} method power (line 7622) | set power(e){this.intensity=e/(4*Math.PI)} method dispose (line 7622) | dispose(){this.shadow.dispose()} method copy (line 7622) | copy(e,n){return super.copy(e,n),this.distance=e.distance,this.decay=e... class bMe (line 7622) | class bMe extends PJ{constructor(e,n){super(e,n),this.isAmbientLight=!0,... method constructor (line 7622) | constructor(e,n){super(e,n),this.isAmbientLight=!0,this.type="AmbientL... class xMe (line 7622) | class xMe extends Vs{constructor(){super(),this.isInstancedBufferGeometr... method constructor (line 7622) | constructor(){super(),this.isInstancedBufferGeometry=!0,this.type="Ins... method copy (line 7622) | copy(e){return super.copy(e),this.instanceCount=e.instanceCount,this} method toJSON (line 7622) | toJSON(){const e=super.toJSON();return e.instanceCount=this.instanceCo... class bR (line 7622) | class bR extends nMe{constructor(e,n,r=1){super(e,n),this.isInstancedInt... method constructor (line 7622) | constructor(e,n,r=1){super(e,n),this.isInstancedInterleavedBuffer=!0,t... method copy (line 7622) | copy(e){return super.copy(e),this.meshPerAttribute=e.meshPerAttribute,... method clone (line 7622) | clone(e){const n=super.clone(e);return n.meshPerAttribute=this.meshPer... method toJSON (line 7622) | toJSON(e){const n=super.toJSON(e);return n.isInstancedInterleavedBuffe... class T$ (line 7622) | class T${constructor(e=1,n=0,r=0){return this.radius=e,this.phi=n,this.t... method constructor (line 7622) | constructor(e=1,n=0,r=0){return this.radius=e,this.phi=n,this.theta=r,... method set (line 7622) | set(e,n,r){return this.radius=e,this.phi=n,this.theta=r,this} method copy (line 7622) | copy(e){return this.radius=e.radius,this.phi=e.phi,this.theta=e.theta,... method makeSafe (line 7622) | makeSafe(){return this.phi=Math.max(1e-6,Math.min(Math.PI-1e-6,this.ph... method setFromVector3 (line 7622) | setFromVector3(e){return this.setFromCartesianCoords(e.x,e.y,e.z)} method setFromCartesianCoords (line 7622) | setFromCartesianCoords(e,n,r){return this.radius=Math.sqrt(e*e+n*n+r*r... method clone (line 7622) | clone(){return new this.constructor().copy(this)} class yMe (line 7622) | class yMe{constructor(e=new ut,n=new ut){this.start=e,this.end=n}set(e,n... method constructor (line 7622) | constructor(e=new ut,n=new ut){this.start=e,this.end=n} method set (line 7622) | set(e,n){return this.start.copy(e),this.end.copy(n),this} method copy (line 7622) | copy(e){return this.start.copy(e.start),this.end.copy(e.end),this} method getCenter (line 7622) | getCenter(e){return e.addVectors(this.start,this.end).multiplyScalar(.5)} method delta (line 7622) | delta(e){return e.subVectors(this.end,this.start)} method distanceSq (line 7622) | distanceSq(){return this.start.distanceToSquared(this.end)} method distance (line 7622) | distance(){return this.start.distanceTo(this.end)} method at (line 7622) | at(e,n){return this.delta(n).multiplyScalar(e).add(this.start)} method closestPointToPointParameter (line 7622) | closestPointToPointParameter(e,n){A$.subVectors(e,this.start),W1.subVe... method closestPointToPoint (line 7622) | closestPointToPoint(e,n,r){const i=this.closestPointToPointParameter(e... method applyMatrix4 (line 7622) | applyMatrix4(e){return this.start.applyMatrix4(e),this.end.applyMatrix... method equals (line 7622) | equals(e){return e.start.equals(this.start)&&e.end.equals(this.end)} method clone (line 7622) | clone(){return new this.constructor().copy(this)} class vMe (line 7622) | class vMe extends aT{constructor(e=1){const n=[0,0,0,e,0,0,0,0,0,0,e,0,0... method constructor (line 7622) | constructor(e=1){const n=[0,0,0,e,0,0,0,0,0,0,e,0,0,0,0,0,0,e],r=[1,0,... method setColors (line 7622) | setColors(e,n,r){const i=new Mn,s=this.geometry.attributes.color.array... method dispose (line 7622) | dispose(){this.geometry.dispose(),this.material.dispose()} class Od (line 7622) | class Od{constructor(e,n,r,i,s="div"){this.parent=e,this.object=n,this.p... method constructor (line 7622) | constructor(e,n,r,i,s="div"){this.parent=e,this.object=n,this.property... method name (line 7622) | name(e){return this._name=e,this.$name.textContent=e,this} method onChange (line 7622) | onChange(e){return this._onChange=e,this} method _callOnChange (line 7622) | _callOnChange(){this.parent._callOnChange(this),this._onChange!==void ... method onFinishChange (line 7622) | onFinishChange(e){return this._onFinishChange=e,this} method _callOnFinishChange (line 7622) | _callOnFinishChange(){this._changed&&(this.parent._callOnFinishChange(... method reset (line 7622) | reset(){return this.setValue(this.initialValue),this._callOnFinishChan... method enable (line 7622) | enable(e=!0){return this.disable(!e)} method disable (line 7622) | disable(e=!0){return e===this._disabled?this:(this._disabled=e,this.do... method show (line 7622) | show(e=!0){return this._hidden=!e,this.domElement.style.display=this._... method hide (line 7622) | hide(){return this.show(!1)} method options (line 7622) | options(e){const n=this.parent.add(this.object,this.property,e);return... method min (line 7622) | min(e){return this} method max (line 7622) | max(e){return this} method step (line 7622) | step(e){return this} method decimals (line 7622) | decimals(e){return this} method listen (line 7622) | listen(e=!0){return this._listening=e,this._listenCallbackID!==void 0&... method _listenCallback (line 7622) | _listenCallback(){this._listenCallbackID=requestAnimationFrame(this._l... method getValue (line 7622) | getValue(){return this.object[this.property]} method setValue (line 7622) | setValue(e){return this.getValue()!==e&&(this.object[this.property]=e,... method updateDisplay (line 7622) | updateDisplay(){return this} method load (line 7622) | load(e){return this.setValue(e),this._callOnFinishChange(),this} method save (line 7622) | save(){return this.getValue()} method destroy (line 7622) | destroy(){this.listen(!1),this.parent.children.splice(this.parent.chil... class wMe (line 7622) | class wMe extends Od{constructor(e,n,r){super(e,n,r,"boolean","label"),t... method constructor (line 7622) | constructor(e,n,r){super(e,n,r,"boolean","label"),this.$input=document... method updateDisplay (line 7622) | updateDisplay(){return this.$input.checked=this.getValue(),this} function xR (line 7622) | function xR(t){let e,n;return(e=t.match(/(#|0x)?([a-f0-9]{6})/i))?n=e[2]... method fromHexString (line 7622) | fromHexString(t,e,n=1){const r=bw.fromHexString(t);e[0]=(r>>16&255)/255*... method toHexString (line 7622) | toHexString([t,e,n],r=1){r=255/r;const i=t*r<<16^e*r<<8^n*r<<0;return bw... method fromHexString (line 7622) | fromHexString(t,e,n=1){const r=bw.fromHexString(t);e.r=(r>>16&255)/255*n... method toHexString (line 7622) | toHexString({r:t,g:e,b:n},r=1){r=255/r;const i=t*r<<16^e*r<<8^n*r<<0;ret... function CMe (line 7622) | function CMe(t){return NMe.find(e=>e.match(t))} class PMe (line 7622) | class PMe extends Od{constructor(e,n,r,i){super(e,n,r,"color"),this.$inp... method constructor (line 7622) | constructor(e,n,r,i){super(e,n,r,"color"),this.$input=document.createE... method reset (line 7622) | reset(){return this._setValueFromHexString(this._initialValueHexString... method _setValueFromHexString (line 7622) | _setValueFromHexString(e){if(this._format.isPrimitive){const n=this._f... method save (line 7622) | save(){return this._format.toHexString(this.getValue(),this._rgbScale)} method load (line 7622) | load(e){return this._setValueFromHexString(e),this._callOnFinishChange... method updateDisplay (line 7622) | updateDisplay(){return this.$input.value=this._format.toHexString(this... class VE (line 7622) | class VE extends Od{constructor(e,n,r){super(e,n,r,"function"),this.$but... method constructor (line 7622) | constructor(e,n,r){super(e,n,r,"function"),this.$button=document.creat... class TMe (line 7622) | class TMe extends Od{constructor(e,n,r,i,s,o){super(e,n,r,"number"),this... method constructor (line 7622) | constructor(e,n,r,i,s,o){super(e,n,r,"number"),this._initInput(),this.... method decimals (line 7622) | decimals(e){return this._decimals=e,this.updateDisplay(),this} method min (line 7622) | min(e){return this._min=e,this._onUpdateMinMax(),this} method max (line 7622) | max(e){return this._max=e,this._onUpdateMinMax(),this} method step (line 7622) | step(e,n=!0){return this._step=e,this._stepExplicit=n,this} method updateDisplay (line 7622) | updateDisplay(){const e=this.getValue();if(this._hasSlider){let n=(e-t... method _initInput (line 7622) | _initInput(){this.$input=document.createElement("input"),this.$input.s... method _initSlider (line 7622) | _initSlider(){this._hasSlider=!0,this.$slider=document.createElement("... method _setDraggingStyle (line 7622) | _setDraggingStyle(e,n="horizontal"){this.$slider&&this.$slider.classLi... method _getImplicitStep (line 7622) | _getImplicitStep(){return this._hasMin&&this._hasMax?(this._max-this._... method _onUpdateMinMax (line 7622) | _onUpdateMinMax(){!this._hasSlider&&this._hasMin&&this._hasMax&&(this.... method _normalizeMouseWheel (line 7622) | _normalizeMouseWheel(e){let{deltaX:n,deltaY:r}=e;return Math.floor(e.d... method _arrowKeyMultiplier (line 7622) | _arrowKeyMultiplier(e){let n=this._stepExplicit?1:10;return e.shiftKey... method _snap (line 7622) | _snap(e){const n=Math.round(e/this._step)*this._step;return parseFloat... method _clamp (line 7622) | _clamp(e){return ethis._max&&(e=this._max),e} method _snapClampSetValue (line 7622) | _snapClampSetValue(e){this.setValue(this._clamp(this._snap(e)))} method _hasScrollBar (line 7622) | get _hasScrollBar(){const e=this.parent.root.$children;return e.scroll... method _hasMin (line 7622) | get _hasMin(){return this._min!==void 0} method _hasMax (line 7622) | get _hasMax(){return this._max!==void 0} class AMe (line 7622) | class AMe extends Od{constructor(e,n,r,i){super(e,n,r,"option"),this.$se... method constructor (line 7622) | constructor(e,n,r,i){super(e,n,r,"option"),this.$select=document.creat... method options (line 7622) | options(e){return this._values=Array.isArray(e)?e:Object.values(e),thi... method updateDisplay (line 7622) | updateDisplay(){const e=this.getValue(),n=this._values.indexOf(e);retu... class jMe (line 7622) | class jMe extends Od{constructor(e,n,r){super(e,n,r,"string"),this.$inpu... method constructor (line 7622) | constructor(e,n,r){super(e,n,r,"string"),this.$input=document.createEl... method updateDisplay (line 7622) | updateDisplay(){return this.$input.value=this.getValue(),this} function EMe (line 8043) | function EMe(t){const e=document.createElement("style");e.innerHTML=t;co... class zN (line 8043) | class zN{constructor({parent:e,autoPlace:n=e===void 0,container:r,width:... method constructor (line 8043) | constructor({parent:e,autoPlace:n=e===void 0,container:r,width:i,title... method add (line 8043) | add(e,n,r,i,s){if(Object(r)===r)return new AMe(this,e,n,r);const o=e[n... method addColor (line 8046) | addColor(e,n,r=1){return new PMe(this,e,n,r)} method addFolder (line 8046) | addFolder(e){const n=new zN({parent:this,title:e});return this.root._c... method load (line 8046) | load(e,n=!0){return e.controllers&&this.controllers.forEach(r=>{r inst... method save (line 8046) | save(e=!0){const n={controllers:{},folders:{}};return this.controllers... method open (line 8046) | open(e=!0){return this._setClosed(!e),this.$title.setAttribute("aria-e... method close (line 8046) | close(){return this.open(!1)} method _setClosed (line 8046) | _setClosed(e){this._closed!==e&&(this._closed=e,this._callOnOpenClose(... method show (line 8046) | show(e=!0){return this._hidden=!e,this.domElement.style.display=this._... method hide (line 8046) | hide(){return this.show(!1)} method openAnimated (line 8046) | openAnimated(e=!0){return this._setClosed(!e),this.$title.setAttribute... method title (line 8046) | title(e){return this._title=e,this.$title.textContent=e,this} method reset (line 8046) | reset(e=!0){return(e?this.controllersRecursive():this.controllers).for... method onChange (line 8046) | onChange(e){return this._onChange=e,this} method _callOnChange (line 8046) | _callOnChange(e){this.parent&&this.parent._callOnChange(e),this._onCha... method onFinishChange (line 8046) | onFinishChange(e){return this._onFinishChange=e,this} method _callOnFinishChange (line 8046) | _callOnFinishChange(e){this.parent&&this.parent._callOnFinishChange(e)... method onOpenClose (line 8046) | onOpenClose(e){return this._onOpenClose=e,this} method _callOnOpenClose (line 8046) | _callOnOpenClose(e){this.parent&&this.parent._callOnOpenClose(e),this.... method destroy (line 8046) | destroy(){this.parent&&(this.parent.children.splice(this.parent.childr... method controllersRecursive (line 8046) | controllersRecursive(){let e=Array.from(this.controllers);return this.... method foldersRecursive (line 8046) | foldersRecursive(){let e=Array.from(this.folders);return this.folders.... function GE (line 8046) | function GE(t,e,n,r){return new(n||(n=Promise))((function(i,s){function ... class gI (line 8046) | class gI{constructor(e,n,r,i){this.size=e,this.width=n,this.height=r,thi... method constructor (line 8046) | constructor(e,n,r,i){this.size=e,this.width=n,this.height=r,this.charL... method parse (line 8046) | static parse(e){const n=e.split(" "),r=n[0],i=r.split("x");return new ... method src (line 8046) | get src(){return"data:image/jpeg;base64,"+this.chars} method isValid (line 8046) | get isValid(){return this.chars.length==this.charLength&&/^(?:[A-Za-z0... class bI (line 8046) | class bI{constructor(e,n,r,i){this.src=e,this.gcode=n,this.params=r,this... method constructor (line 8046) | constructor(e,n,r,i){this.src=e,this.gcode=n,this.params=r,this.commen... class M$ (line 8046) | class M$ extends bI{constructor(e,n,r,i){super(e,n,r,i),this.params=r}} method constructor (line 8046) | constructor(e,n,r,i){super(e,n,r,i),this.params=r} class wh (line 8046) | class wh extends bI{constructor(e,n,r,i){super(e,n,void 0,r),this.toolIn... method constructor (line 8046) | constructor(e,n,r,i){super(e,n,void 0,r),this.toolIndex=i} class E$ (line 8046) | class E${constructor(e,n,r,i=0){this.layer=e,this.commands=n,this.lineNu... method constructor (line 8046) | constructor(e,n,r,i=0){this.layer=e,this.commands=n,this.lineNumber=r,... class UN (line 8046) | class UN{constructor(e){this.lines=[],this.preamble=new E$(-1,[],0),this... method constructor (line 8046) | constructor(e){this.lines=[],this.preamble=new E$(-1,[],0),this.layers... method parseGCode (line 8046) | parseGCode(e){const n=Array.isArray(e)?e:e.split(` method lines2commands (line 8047) | lines2commands(e){return e.map((n=>this.parseCommand(n)))} method parseCommand (line 8047) | parseCommand(e,n=!0){var r;const i=e.trim().split(";"),s=i[0],o=n&&i[1... method parseMove (line 8047) | parseMove(e){return e.reduce(((n,r)=>{const i=r.charAt(0).toLowerCase(... method isAlpha (line 8047) | isAlpha(e){const n=e.charCodeAt(0);return n>=97&&n<=122||n>=65&&n<=90} method parseParams (line 8047) | parseParams(e){return e.reduce(((n,r,i,s)=>{if(i%2==0)return n;let o=s... method groupIntoLayers (line 8047) | groupIntoLayers(e){var n;for(let r=0;rthis.... method processGCode (line 8434) | processGCode(e){this.parser.parseGCode(e),this.render()} method initScene (line 8434) | initScene(){for(;this.scene.children.length>0;)this.scene.remove(this.... method createGroup (line 8434) | createGroup(e){const n=new p0;return n.name=e,n.quaternion.setFromEule... method render (line 8434) | render(){const e=performance.now();this.group=this.createGroup("allLay... method renderAnimated (line 8434) | renderAnimated(e=1){return GE(this,void 0,void 0,(function*(){return t... method renderFrameLoop (line 8434) | renderFrameLoop(e){return new Promise((n=>{const r=()=>{this.renderLay... method renderFrame (line 8434) | renderFrame(e){this.group=this.createGroup("layer"+this.renderLayerInd... method renderLayer (line 8434) | renderLayer(e){var n,r,i,s,o,l,c,d;if(e>this.maxLayerIndex)return;cons... method doRenderExtrusion (line 8434) | doRenderExtrusion(e,n){var r,i;if(this.renderExtrusion){let s=this.cur... method setInches (line 8434) | setInches(){this.beyondFirstMove?console.warn("Switching units after m... method drawBuildVolume (line 8434) | drawBuildVolume(){if(!this.buildVolume)return;this.scene.add(new LMe(t... method clear (line 8434) | clear(){this.resetState(),this.parser=new UN(this.minLayerThreshold)} method resetState (line 8434) | resetState(){var e;this.startLayer=1,this.endLayer=1/0,this.singleLaye... method resize (line 8434) | resize(){const[e,n]=[this.canvas.offsetWidth,this.canvas.offsetHeight]... method addLineSegment (line 8434) | addLineSegment(e,n,r,i){(i?e.extrusion:e.travel).push(n.x,n.y,n.z,r.x,... method addArcSegment (line 8434) | addArcSegment(e,n,r,i,s){const o=i?e.extrusion:e.travel,l=n.x,c=n.y,d=... method addLine (line 8434) | addLine(e,n){var r;if(typeof this.lineWidth=="number"&&this.lineWidth>... method addTubeLine (line 8434) | addTubeLine(e,n,r=.2){let i=[];const s=[];for(let o=0;oe.dispose())),this.disposables=... method cancelAnimation (line 8434) | cancelAnimation(){this.animationFrameId!==void 0&&cancelAnimationFrame... method _enableDropHandler (line 8434) | _enableDropHandler(){console.warn("Drag and drop is deprecated as a li... method batchGeometries (line 8434) | batchGeometries(){if(this._geometries)for(const e in this._geometries)... method createBatchMesh (line 8434) | createBatchMesh(e){var n;const r=this._geometries[e],i=new mMe({color:... method _readFromStream (line 8434) | _readFromStream(e){var n,r;return GE(this,void 0,void 0,(function*(){c... method initGui (line 8435) | initGui(){typeof this.devMode=="boolean"&&this.devMode===!0?this.devGu... method initStats (line 8435) | initStats(){var e;this.stats&&(typeof this.devMode=="object"&&(this.st... function jJ (line 8435) | function jJ({gcodeUrl:t,buildVolume:e={x:256,y:256,z:256},filamentColors... function UMe (line 8437) | function UMe({printerId:t,filePath:e,filename:n,onClose:r}){const[i,s]=w... function H$ (line 8437) | function H$(t){if(t===0)return"0 GB";const e=t/(1024*1024*1024);return e... function BMe (line 8437) | function BMe(t,e){if(e)return LQ;switch(t.toLowerCase().split(".").pop()... function qMe (line 8437) | function qMe({printerId:t,printerName:e,onClose:n}){const{t:r}=Ft(),{sho... function xI (line 8437) | function xI({on:t,className:e="w-5 h-5"}){const n=t?"#facc15":"none",r=t... function yI (line 8437) | function yI({printerId:t,isOpen:e,onClose:n}){const{t:r}=Ft(),{showToast... function KMe (line 8443) | function KMe({printerId:t,printerName:e,viewerIndex:n=0,onClose:r}){cons... function XMe (line 8443) | function XMe({printerId:t,printerName:e,onClose:n}){const{t:r}=Ft(),i=nn... function MJ (line 8443) | function MJ(t){if(!t)return"/img/printers/default.png";const e=t.toLower... function EJ (line 8443) | function EJ(t){return t>=-50?{labelKey:"printers.wifiSignal.excellent",c... function DJ (line 8443) | function DJ(t,e,n){return t.filter(r=>{if(r.required_filament_types&&r.r... function YMe (line 8443) | function YMe({printerId:t,printerModel:e,loadedFilamentTypes:n,loadedFil... function FJ (line 8443) | function FJ(t){var e,n,r="";if(typeof t=="string"||typeof t=="number")r+... function _r (line 8443) | function _r(){for(var t,e,n=0,r="",i=arguments.length;n=0))throw new Error(`invalid ... class dEe (line 8443) | class dEe{constructor(e){this._x0=this._y0=this._x1=this._y1=null,this._... method constructor (line 8443) | constructor(e){this._x0=this._y0=this._x1=this._y1=null,this._="",this... method moveTo (line 8443) | moveTo(e,n){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=... method closePath (line 8443) | closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this... method lineTo (line 8443) | lineTo(e,n){this._append`L${this._x1=+e},${this._y1=+n}`} method quadraticCurveTo (line 8443) | quadraticCurveTo(e,n,r,i){this._append`Q${+e},${+n},${this._x1=+r},${t... method bezierCurveTo (line 8443) | bezierCurveTo(e,n,r,i,s,o){this._append`C${+e},${+n},${+r},${+i},${thi... method arcTo (line 8443) | arcTo(e,n,r,i,s){if(e=+e,n=+n,r=+r,i=+i,s=+s,s<0)throw new Error(`nega... method arc (line 8443) | arc(e,n,r,i,s,o){if(e=+e,n=+n,r=+r,o=!!o,r<0)throw new Error(`negative... method rect (line 8443) | rect(e,n,r,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y... method toString (line 8443) | toString(){return this._} function SI (line 8443) | function SI(t){let e=3;return t.digits=function(n){if(!arguments.length)... function _I (line 8443) | function _I(t){return typeof t=="object"&&"length"in t?t:Array.from(t)} function UJ (line 8443) | function UJ(t){this._context=t} function oT (line 8443) | function oT(t){return new UJ(t)} function BJ (line 8443) | function BJ(t){return t[0]} function HJ (line 8443) | function HJ(t){return t[1]} function qJ (line 8443) | function qJ(t,e){var n=fa(!0),r=null,i=oT,s=null,o=SI(l);t=typeof t=="fu... function Z1 (line 8443) | function Z1(t,e,n){var r=null,i=fa(!0),s=null,o=oT,l=null,c=SI(d);t=type... class $J (line 8443) | class $J{constructor(e,n){this._context=e,this._x=n}areaStart(){this._li... method constructor (line 8443) | constructor(e,n){this._context=e,this._x=n} method areaStart (line 8443) | areaStart(){this._line=0} method areaEnd (line 8443) | areaEnd(){this._line=NaN} method lineStart (line 8443) | lineStart(){this._point=0} method lineEnd (line 8443) | lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context... method point (line 8443) | point(e,n){switch(e=+e,n=+n,this._point){case 0:{this._point=1,this._l... function uEe (line 8443) | function uEe(t){return new $J(t,!0)} function mEe (line 8443) | function mEe(t){return new $J(t,!1)} method draw (line 8443) | draw(t,e){const n=rd(e/HN);t.moveTo(n,0),t.arc(0,0,n,0,sT)} method draw (line 8443) | draw(t,e){const n=rd(e/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-... method draw (line 8443) | draw(t,e){const n=rd(e/pEe),r=n*VJ;t.moveTo(0,-n),t.lineTo(r,0),t.lineTo... method draw (line 8443) | draw(t,e){const n=rd(e),r=-n/2;t.rect(r,r,n,n)} method draw (line 8443) | draw(t,e){const n=rd(e*bEe),r=xEe*n,i=yEe*n;t.moveTo(0,-n),t.lineTo(r,i)... method draw (line 8443) | draw(t,e){const n=-rd(e/(ZE*3));t.moveTo(0,n*2),t.lineTo(-ZE*n,-n),t.lin... method draw (line 8443) | draw(t,e){const n=rd(e/SEe),r=n/2,i=n*_R,s=r,o=n*_R+n,l=-s,c=o;t.moveTo(... function kEe (line 8443) | function kEe(t,e){let n=null,r=SI(i);t=typeof t=="function"?t:fa(t||kI),... function qN (line 8443) | function qN(){} function $N (line 8443) | function $N(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t... function WJ (line 8443) | function WJ(t){this._context=t} function NEe (line 8443) | function NEe(t){return new WJ(t)} function KJ (line 8443) | function KJ(t){this._context=t} function CEe (line 8443) | function CEe(t){return new KJ(t)} function XJ (line 8443) | function XJ(t){this._context=t} function PEe (line 8443) | function PEe(t){return new XJ(t)} function YJ (line 8443) | function YJ(t){this._context=t} function TEe (line 8443) | function TEe(t){return new YJ(t)} function $$ (line 8443) | function $$(t){return t<0?-1:1} function V$ (line 8443) | function V$(t,e,n){var r=t._x1-t._x0,i=e-t._x1,s=(t._y1-t._y0)/(r||i<0&&... function G$ (line 8443) | function G$(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e} function JE (line 8443) | function JE(t,e,n){var r=t._x0,i=t._y0,s=t._x1,o=t._y1,l=(s-r)/3;t._cont... function VN (line 8443) | function VN(t){this._context=t} function QJ (line 8443) | function QJ(t){this._context=new ZJ(t)} function ZJ (line 8443) | function ZJ(t){this._context=t} function AEe (line 8443) | function AEe(t){return new VN(t)} function jEe (line 8443) | function jEe(t){return new QJ(t)} function JJ (line 8443) | function JJ(t){this._context=t} function W$ (line 8443) | function W$(t){var e,n=t.length-1,r,i=new Array(n),s=new Array(n),o=new ... function MEe (line 8443) | function MEe(t){return new JJ(t)} function lT (line 8443) | function lT(t,e){this._context=t,this._t=e} function EEe (line 8443) | function EEe(t){return new lT(t,.5)} function DEe (line 8443) | function DEe(t){return new lT(t,0)} function FEe (line 8443) | function FEe(t){return new lT(t,1)} function wg (line 8443) | function wg(t,e){if((o=t.length)>1)for(var n=1,r,i,s=t[e[0]],o,l=s.lengt... function kR (line 8443) | function kR(t){for(var e=t.length,n=new Array(e);--e>=0;)n[e]=e;return n} function REe (line 8443) | function REe(t,e){return t[e]} function LEe (line 8443) | function LEe(t){const e=[];return e.key=t,e} function OEe (line 8443) | function OEe(){var t=fa([]),e=kR,n=wg,r=REe;function i(s){var o=Array.fr... function IEe (line 8443) | function IEe(t,e){if((r=t.length)>0){for(var n,r,i=0,s=t[0].length,o;i0){for(var n=0,r=t[e[0]],i,s=r.length;... function UEe (line 8443) | function UEe(t,e){if(!(!((o=t.length)>0)||!((s=(i=t[e[0]]).length)>0))){... function BEe (line 8443) | function BEe(){return K$||(K$=1,(function(t){Object.defineProperty(t,Sym... function eee (line 8443) | function eee(){return X$||(X$=1,(function(t){Object.defineProperty(t,Sym... function NI (line 8443) | function NI(){return Y$||(Y$=1,(function(t){Object.defineProperty(t,Symb... function HEe (line 8443) | function HEe(){return Q$||(Q$=1,(function(t){Object.defineProperty(t,Sym... function CI (line 8443) | function CI(){return Z$||(Z$=1,(function(t){Object.defineProperty(t,Symb... function PI (line 8443) | function PI(){return J$||(J$=1,(function(t){Object.defineProperty(t,Symb... function qEe (line 8443) | function qEe(){return eV||(eV=1,s2=PI().get),s2} function Vh (line 8443) | function Vh(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments... function Ka (line 8443) | function Ka(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;rr&&(typeof e=="... function Oo (line 8443) | function Oo(t){return t!=null} function Tp (line 8443) | function Tp(){} function NR (line 8443) | function NR(){return NR=Object.assign?Object.assign.bind():function(t){f... function tV (line 8443) | function tV(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function nV (line 8443) | function nV(t){for(var e=1;e... function GN (line 8443) | function GN(){return GN=Object.assign?Object.assign.bind():function(t){f... function aV (line 8443) | function aV(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function l2e (line 8443) | function l2e(t){for(var e=1;ee?r=>{if(r!=null)r... function B2e (line 8446) | function B2e(t,e=`expected a function, instead received ${typeof t}`){if... function H2e (line 8446) | function H2e(t,e=`expected an object, instead received ${typeof t}`){if(... function q2e (line 8446) | function q2e(t,e="expected all items to be functions, instead received t... function $2e (line 8446) | function $2e(t){const e=Array.isArray(t[0])?t[0]:t;return q2e(e,"createS... function V2e (line 8446) | function V2e(t,e){const n=[],{length:r}=t;for(let i=0;i0&&arguments[0]!==void 0?arguments... function hs (line 8446) | function hs(t){return`Minified Redux error #${t}; visit https://redux.js... function DI (line 8446) | function DI(t){if(typeof t!="object"||t===null)return!1;let e=t;for(;Obj... function vee (line 8446) | function vee(t,e,n){if(typeof t!="function")throw new Error(hs(2));if(ty... function dDe (line 8446) | function dDe(t){Object.keys(t).forEach(e=>{const n=t[e];if(typeof n(void... function wee (line 8446) | function wee(t){const e=Object.keys(t),n={};for(let s=0;se:t.length===1?t[0]:t.reduce((e... function uDe (line 8446) | function uDe(...t){return e=>(n,r)=>{const i=e(n,r);let s=()=>{throw new... function See (line 8446) | function See(t){return DI(t)&&"type"in t&&typeof t.type=="string"} function Bc (line 8446) | function Bc(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Fu... function Jc (line 8446) | function Jc(t){return t?kee(t)||mT(t)||!!t[KV]||!!t[XN]?.[KV]||hT(t)||pT... function kee (line 8446) | function kee(t){if(!t||!FI(t))return!1;const e=ey(t);if(e===null||e===ml... function uT (line 8446) | function uT(t,e,n=!0){pS(t)===0?(n?Reflect.ownKeys(t):ml.keys(t)).forEac... function pS (line 8446) | function pS(t){const e=t[ho];return e?e.type_:mT(t)?1:hT(t)?2:pT(t)?3:0} function hDe (line 8446) | function hDe(t,e){return t===e?t!==0||1/t===1/e:t!==t&&e!==e} function pDe (line 8446) | function pDe(t){const e=+t;return Number.isInteger(e)&&String(e)===t} function TR (line 8446) | function TR(t,e){if(hT(t))return new Map(t);if(pT(t))return new Set(t);i... function LI (line 8446) | function LI(t,e=!1){return fT(t)||_m(t)||!Jc(t)||(pS(t)>1&&ml.defineProp... function fDe (line 8446) | function fDe(){Bc(2)} function fT (line 8446) | function fT(t){return t===null||!FI(t)?!0:ml.isFrozen(t)} function kg (line 8446) | function kg(t){const e=Nee[t];return e||Bc(0,t),e} function JV (line 8446) | function JV(t,e){e&&(t.patchPlugin_=kg(AR),t.patches_=[],t.inversePatche... function jR (line 8446) | function jR(t){MR(t),t.drafts_.forEach(bDe),t.drafts_=null} function MR (line 8446) | function MR(t){t===vw&&(vw=t.parent_)} function bDe (line 8446) | function bDe(t){const e=t[ho];e.type_===0||e.type_===1?e.revoke_():e.rev... function t7 (line 8446) | function t7(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_... function n7 (line 8446) | function n7(t,e){if(fT(e))return e;const n=e[ho];if(!n)return JN(e,t.han... function xDe (line 8446) | function xDe(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze... function Pee (line 8446) | function Pee(t){t.finalized_=!0,t.scope_.unfinalizedDrafts_--} function Tee (line 8446) | function Tee(t,e,n,r){const i=$u(t),s=t.type_;if(r!==void 0&&PR(i,r,s)==... function vDe (line 8446) | function vDe(t,e,n){t.callbacks_.push(function(i){const s=e;if(!s||!gT(s... function Aee (line 8446) | function Aee(t,e){if(t.modified_&&!t.finalized_&&(t.type_===3||t.type_==... function wDe (line 8446) | function wDe(t,e,n){const{scope_:r}=t;if(_m(n)){const i=n[ho];gT(i,r)&&i... function JN (line 8446) | function JN(t,e,n){return!n.immer_.autoFreeze_&&n.unfinalizedDrafts_<1||... function SDe (line 8446) | function SDe(t,e){const n=mT(t),r={type_:n?1:0,scope_:e?e.scope_:Cee(),m... method get (line 8446) | get(t,e){if(e===ho)return t;let n=t.scope_.arrayMethodsPlugin_;const r=t... method has (line 8446) | has(t,e){return e in $u(t)} method ownKeys (line 8446) | ownKeys(t){return Reflect.ownKeys($u(t))} method set (line 8446) | set(t,e,n){const r=jee($u(t),e);if(r?.set)return r.set.call(t.draft_,n),... method deleteProperty (line 8446) | deleteProperty(t,e){return Qk(t),K2(t.base_,e)!==void 0||e in t.base_?(t... method getOwnPropertyDescriptor (line 8446) | getOwnPropertyDescriptor(t,e){const n=$u(t),r=Reflect.getOwnPropertyDesc... method defineProperty (line 8446) | defineProperty(){Bc(11)} method getPrototypeOf (line 8446) | getPrototypeOf(t){return ey(t.base_)} method setPrototypeOf (line 8446) | setPrototypeOf(){Bc(12)} function K2 (line 8446) | function K2(t,e){const n=t[ho];return(n?$u(n):t)[e]} function _De (line 8446) | function _De(t,e,n){const r=jee(e,n);return r?yw in r?r[yw]:r.get?.call(... function jee (line 8446) | function jee(t,e){if(!(e in t))return;let n=ey(t);for(;n;){const r=Objec... function ER (line 8446) | function ER(t){t.modified_||(t.modified_=!0,t.parent_&&ER(t.parent_))} function Qk (line 8446) | function Qk(t){t.copy_||(t.assigned_=new Map,t.copy_=TR(t.base_,t.scope_... method constructor (line 8446) | constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.us... method createDraft (line 8446) | createDraft(e){Jc(e)||Bc(8),_m(e)&&(e=Xc(e));const n=e7(this),r=DR(n,e,v... method finishDraft (line 8446) | finishDraft(e,n){const r=e&&e[ho];(!r||!r.isManual_)&&Bc(9);const{scope_... method setAutoFreeze (line 8446) | setAutoFreeze(e){this.autoFreeze_=e} method setUseStrictShallowCopy (line 8446) | setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e} method setUseStrictIteration (line 8446) | setUseStrictIteration(e){this.useStrictIteration_=e} method shouldUseStrictIteration (line 8446) | shouldUseStrictIteration(){return this.useStrictIteration_} method applyPatches (line 8446) | applyPatches(e,n){let r;for(r=n.length-1;r>=0;r--){const s=n[r];if(s.pat... function DR (line 8446) | function DR(t,e,n,r){const[i,s]=hT(e)?kg(ZN).proxyMap_(e,n):pT(e)?kg(ZN)... function Xc (line 8446) | function Xc(t){return _m(t)||Bc(10,t),Mee(t)} function Mee (line 8446) | function Mee(t){if(!Jc(t)||fT(t))return t;const e=t[ho];let n,r=!0;if(e)... function Dee (line 8446) | function Dee(t){return({dispatch:n,getState:r})=>i=>s=>typeof s=="functi... function pc (line 8446) | function pc(t,e){function n(...r){if(e){let i=e(...r);if(!i)throw new Er... method constructor (line 8446) | constructor(...e){super(...e),Object.setPrototypeOf(this,f0.prototype)} method [Symbol.species] (line 8446) | static get[Symbol.species](){return f0} method concat (line 8446) | concat(...e){return super.concat.apply(this,e)} method prepend (line 8446) | prepend(...e){return e.length===1&&Array.isArray(e[0])?new f0(...e[0].co... function r7 (line 8446) | function r7(t){return Jc(t)?Eee(t,()=>{}):t} function nk (line 8446) | function nk(t,e,n){return t.has(e)?t.get(e):t.set(e,n(e)).get(e)} function ADe (line 8446) | function ADe(t){return typeof t=="boolean"} method subscribe (line 8446) | subscribe(u){const m=()=>i&&u(),p=r.subscribe(m);return l.add(u),()=>{p(... method dispatch (line 8446) | dispatch(u){try{return i=!u?.meta?.[Ree],s=!i,s&&(o||(o=!0,c(d))),r.disp... function EDe (line 8446) | function EDe(t){const e=jDe(),{reducer:n=void 0,middleware:r,devTools:i=... function Oee (line 8446) | function Oee(t){const e={},n=[];let r;const i={addCase(s,o){const l=type... function DDe (line 8446) | function DDe(t){return typeof t=="function"} function FDe (line 8446) | function FDe(t,e){let[n,r,i]=Oee(e),s;if(DDe(t))s=()=>r7(t());else{const... function IDe (line 8446) | function IDe(t,e){return`${t}/${e}`} function zDe (line 8446) | function zDe({creators:t}={}){const e=t?.asyncThunk?.[ODe];return functi... function UDe (line 8446) | function UDe(t,e,n,r){function i(s,...o){let l=e(s);return typeof l>"u"&... function BDe (line 8446) | function BDe(){function t(e,n){return{_reducerDefinitionType:"asyncThunk... function HDe (line 8446) | function HDe({type:t,reducerName:e,createNotation:n},r,i){let s,o;if("re... function qDe (line 8446) | function qDe(t){return t._reducerDefinitionType==="asyncThunk"} function $De (line 8446) | function $De(t){return t._reducerDefinitionType==="reducerWithPrepare"} function VDe (line 8446) | function VDe({type:t,reducerName:e},n,r,i){if(!i)throw new Error(gl(18))... function rk (line 8446) | function rk(){} method constructor (line 8446) | constructor(t){this.code=t,this.message=`${GDe} ${OI} (reason: ${t})`} function Hee (line 8446) | function Hee(t,e){let n=tC;return new Promise((r,i)=>{const s=()=>i(new ... method cancel (line 8446) | cancel(){s.abort(WDe)} function gl (line 8446) | function gl(t){return`Minified Redux Toolkit error #${t}; visit https://... method setLayout (line 8446) | setLayout(t,e){t.layoutType=e.payload} method setChartSize (line 8446) | setChartSize(t,e){t.width=e.payload.width,t.height=e.payload.height} method setMargin (line 8446) | setMargin(t,e){var n,r,i,s;t.margin.top=(n=e.payload.top)!==null&&n!==vo... method setScale (line 8446) | setScale(t,e){t.scale=e.payload} function Xee (line 8446) | function Xee(t,e,n){return Array.isArray(t)&&t&&e+n!==0?t.slice(e,n+1):t} function Gn (line 8446) | function Gn(t){return Number.isFinite(t)} function qd (line 8446) | function qd(t){return typeof t=="number"&&t>0&&Number.isFinite(t)} function l7 (line 8446) | function l7(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function Sx (line 8446) | function Sx(t){for(var e=1;e{if(r.orientation==="... function A3e (line 8446) | function A3e(t){var e=vT(t);return e.reduce((n,r)=>{if(r.orientation==="... function j3e (line 8446) | function j3e(t){var e=yT(t);return e.reduce((n,r)=>r.orientation==="top"... function M3e (line 8446) | function M3e(t){var e=yT(t);return e.reduce((n,r)=>r.orientation==="bott... function F3e (line 8446) | function F3e(){return p7||(p7=1,(function(t){Object.defineProperty(t,Sym... function R3e (line 8446) | function R3e(){return f7||(f7=1,(function(t){Object.defineProperty(t,Sym... function L3e (line 8446) | function L3e(){return g7||(g7=1,(function(t){Object.defineProperty(t,Sym... function O3e (line 8446) | function O3e(){return b7||(b7=1,Z2=L3e().throttle),Z2} function V3e (line 8446) | function V3e(t){var{width:e,height:n,aspect:r}=t,i=e,s=n;return i===void... function LR (line 8446) | function LR(){return LR=Object.assign?Object.assign.bind():function(t){f... function x7 (line 8446) | function x7(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function y7 (line 8446) | function y7(t){for(var e=1;e({wid... function BI (line 8449) | function BI(t){if(t)return{x:t.x,y:t.y,upperWidth:"upperWidth"in t?t.upp... function Hc (line 8449) | function Hc(t,...e){throw new Error(`[Immer] minified error nr: ${t}. Fu... function ty (line 8449) | function ty(t){return!!t&&!!t[wl]} function Ng (line 8449) | function Ng(t){return t?lte(t)||Array.isArray(t)||!!t[v7]||!!t.construct... function lte (line 8449) | function lte(t){if(!t||typeof t!="object")return!1;const e=Object.getPro... function iC (line 8449) | function iC(t,e,n=!0){_T(t)===0?(n?Reflect.ownKeys(t):Object.keys(t)).fo... function _T (line 8449) | function _T(t){const e=t[wl];return e?e.type_:Array.isArray(t)?1:yS(t)?2... function OR (line 8449) | function OR(t,e){return _T(t)===2?t.has(e):Object.prototype.hasOwnProper... function cte (line 8449) | function cte(t,e,n){const r=_T(t);r===2?t.set(e,n):r===3?t.add(n):t[e]=n} function tFe (line 8449) | function tFe(t,e){return t===e?t!==0||1/t===1/e:t!==t&&e!==e} function yS (line 8449) | function yS(t){return t instanceof Map} function kT (line 8449) | function kT(t){return t instanceof Set} function Cf (line 8449) | function Cf(t){return t.copy_||t.base_} function IR (line 8449) | function IR(t,e){if(yS(t))return new Map(t);if(kT(t))return new Set(t);i... function VI (line 8449) | function VI(t,e=!1){return NT(t)||ty(t)||!Ng(t)||(_T(t)>1&&Object.define... function nFe (line 8449) | function nFe(){Hc(2)} function NT (line 8449) | function NT(t){return t===null||typeof t!="object"?!0:Object.isFrozen(t)} function Cg (line 8449) | function Cg(t){const e=rFe[t];return e||Hc(0,t),e} function dte (line 8449) | function dte(){return _w} function aFe (line 8449) | function aFe(t,e){return{drafts_:[],parent_:t,immer_:e,canAutoFreeze_:!0... function S7 (line 8449) | function S7(t,e){e&&(Cg("Patches"),t.patches_=[],t.inversePatches_=[],t.... function zR (line 8449) | function zR(t){UR(t),t.drafts_.forEach(iFe),t.drafts_=null} function UR (line 8449) | function UR(t){t===_w&&(_w=t.parent_)} function _7 (line 8449) | function _7(t){return _w=aFe(_w,t)} function iFe (line 8449) | function iFe(t){const e=t[wl];e.type_===0||e.type_===1?e.revoke_():e.rev... function k7 (line 8449) | function k7(t,e){e.unfinalizedDrafts_=e.drafts_.length;const n=e.drafts_... function sC (line 8449) | function sC(t,e,n){if(NT(e))return e;const r=t.immer_.shouldUseStrictIte... function N7 (line 8449) | function N7(t,e,n,r,i,s,o){if(i==null||typeof i!="object"&&!o)return;con... function oC (line 8449) | function oC(t,e,n=!1){!t.parent_&&t.immer_.autoFreeze_&&t.canAutoFreeze_... function sFe (line 8449) | function sFe(t,e){const n=Array.isArray(t),r={type_:n?1:0,scope_:e?e.sco... method get (line 8449) | get(t,e){if(e===wl)return t;const n=Cf(t);if(!OR(n,e))return oFe(t,n,e);... method has (line 8449) | has(t,e){return e in Cf(t)} method ownKeys (line 8449) | ownKeys(t){return Reflect.ownKeys(Cf(t))} method set (line 8449) | set(t,e,n){const r=ute(Cf(t),e);if(r?.set)return r.set.call(t.draft_,n),... method deleteProperty (line 8449) | deleteProperty(t,e){return J2(t.base_,e)!==void 0||e in t.base_?(t.assig... method getOwnPropertyDescriptor (line 8449) | getOwnPropertyDescriptor(t,e){const n=Cf(t),r=Reflect.getOwnPropertyDesc... method defineProperty (line 8449) | defineProperty(){Hc(11)} method getPrototypeOf (line 8449) | getPrototypeOf(t){return Sw(t.base_)} method setPrototypeOf (line 8449) | setPrototypeOf(){Hc(12)} function J2 (line 8449) | function J2(t,e){const n=t[wl];return(n?Cf(n):t)[e]} function oFe (line 8449) | function oFe(t,e,n){const r=ute(e,n);return r?"value"in r?r.value:r.get?... function ute (line 8449) | function ute(t,e){if(!(e in t))return;let n=Sw(t);for(;n;){const r=Objec... function BR (line 8449) | function BR(t){t.modified_||(t.modified_=!0,t.parent_&&BR(t.parent_))} function eD (line 8449) | function eD(t){t.copy_||(t.copy_=IR(t.base_,t.scope_.immer_.useStrictSha... method constructor (line 8449) | constructor(t){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.us... method createDraft (line 8449) | createDraft(t){Ng(t)||Hc(8),ty(t)&&(t=cFe(t));const e=_7(this),n=HR(t,vo... method finishDraft (line 8449) | finishDraft(t,e){const n=t&&t[wl];(!n||!n.isManual_)&&Hc(9);const{scope_... method setAutoFreeze (line 8449) | setAutoFreeze(t){this.autoFreeze_=t} method setUseStrictShallowCopy (line 8449) | setUseStrictShallowCopy(t){this.useStrictShallowCopy_=t} method setUseStrictIteration (line 8449) | setUseStrictIteration(t){this.useStrictIteration_=t} method shouldUseStrictIteration (line 8449) | shouldUseStrictIteration(){return this.useStrictIteration_} method applyPatches (line 8449) | applyPatches(t,e){let n;for(n=e.length-1;n>=0;n--){const i=e[n];if(i.pat... function HR (line 8449) | function HR(t,e){const n=yS(t)?Cg("MapSet").proxyMap_(t,e):kT(t)?Cg("Map... function cFe (line 8449) | function cFe(t){return ty(t)||Hc(10,t),mte(t)} function mte (line 8449) | function mte(t){if(!Ng(t)||NT(t))return t;const e=t[wl];let n,r=!0;if(e)... method setLegendSize (line 8449) | setLegendSize(t,e){t.size.width=e.payload.width,t.size.height=e.payload.... method setLegendSettings (line 8449) | setLegendSettings(t,e){t.settings.align=e.payload.align,t.settings.layou... method reducer (line 8449) | reducer(t,e){t.payload.push(e.payload)} method reducer (line 8449) | reducer(t,e){var{prev:n,next:r}=e.payload,i=Xc(t).payload.indexOf(n);i>-... method reducer (line 8449) | reducer(t,e){var n=Xc(t).payload.indexOf(e.payload);n>-1&&t.payload.spli... function qR (line 8449) | function qR(){return qR=Object.assign?Object.assign.bind():function(t){f... function P7 (line 8449) | function P7(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function ny (line 8449) | function ny(t){for(var e=1;e{e(mFe(t))},[e,t]),null} function kFe (line 8449) | function kFe(t){var e=ua();return w.useEffect(()=>(e(C7(t)),()=>{e(C7({w... function NFe (line 8449) | function NFe(t,e,n,r){return t==="vertical"&&e!=null?{height:e}:t==="hor... function bte (line 8449) | function bte(t){var e=Ia(t,CFe),n=oDe(),r=oEe(),i=Z3e(),{width:s,height:... function $R (line 8449) | function $R(){return $R=Object.assign?Object.assign.bind():function(t){f... function T7 (line 8449) | function T7(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function Gv (line 8449) | function Gv(t){for(var e=1;eAi(Ai({},p),{},{[f]:{f... function cRe (line 8449) | function cRe(t,e,n,r,i,s,o){var l=null,c=i.reduce((m,p)=>{var f=t[p],y=e... function bRe (line 8449) | function bRe(t){var e,n=()=>null,r=!1,i=null,s=o=>{if(!r){if(Array.isArr... class xRe (line 8449) | class xRe{setTimeout(e){var n=arguments.length>1&&arguments[1]!==void 0?... method setTimeout (line 8449) | setTimeout(e){var n=arguments.length>1&&arguments[1]!==void 0?argument... function yRe (line 8449) | function yRe(){return bRe(new xRe)} function wRe (line 8449) | function wRe(t,e){var n=w.useContext(vRe);return w.useMemo(()=>e??n(t),[... function Ty (line 8449) | function Ty(t){var e=Ia(t,_Re),{isActive:n,canBegin:r,duration:i,easing:... function Ay (line 8449) | function Ay(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments... function J7 (line 8449) | function J7(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function eG (line 8449) | function eG(t){for(var e=1;ee?1:t>=e?0:NaN} function KRe (line 8476) | function KRe(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN} function WI (line 8476) | function WI(t){let e,n,r;t.length!==2?(e=dp,n=(l,c)=>dp(t(l),c),r=(l,c)=... function XRe (line 8476) | function XRe(){return 0} function Ate (line 8476) | function Ate(t){return t===null?NaN:+t} class bG (line 8476) | class bG extends Map{constructor(e,n=eLe){if(super(),Object.defineProper... method constructor (line 8476) | constructor(e,n=eLe){if(super(),Object.defineProperties(this,{_intern:... method get (line 8476) | get(e){return super.get(xG(this,e))} method has (line 8476) | has(e){return super.has(xG(this,e))} method set (line 8476) | set(e,n){return super.set(ZRe(this,e),n)} method delete (line 8476) | delete(e){return super.delete(JRe(this,e))} function xG (line 8476) | function xG({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):n} function ZRe (line 8476) | function ZRe({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r)... function JRe (line 8476) | function JRe({_intern:t,_key:e},n){const r=e(n);return t.has(r)&&(n=t.ge... function eLe (line 8476) | function eLe(t){return t!==null&&typeof t=="object"?t.valueOf():t} function tLe (line 8476) | function tLe(t=dp){if(t===dp)return jte;if(typeof t!="function")throw ne... function jte (line 8476) | function jte(t,e){return(t==null||!(t>=t))-(e==null||!(e>=e))||(t0))return[];if(t===e)return[t];... function QR (line 8476) | function QR(t,e,n){return e=+e,t=+t,n=+n,hC(t,e,n)[2]} function ZR (line 8476) | function ZR(t,e,n){e=+e,t=+t,n=+n;const r=e=r)... function vG (line 8476) | function vG(t,e){let n;for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)... function Mte (line 8476) | function Mte(t,e,n=0,r=1/0,i){if(e=Math.floor(e),n=Math.floor(Math.max(0... function Yv (line 8476) | function Yv(t,e,n){const r=t[e];t[e]=t[n],t[n]=r} function iLe (line 8476) | function iLe(t,e,n){if(t=Float64Array.from(YRe(t)),!(!(r=t.length)||isNa... function sLe (line 8476) | function sLe(t,e,n=Ate){if(!(!(r=t.length)||isNaN(e=+e))){if(e<=0||r<2)r... function oLe (line 8476) | function oLe(t,e,n){t=+t,e=+e,n=(i=arguments.length)<2?(e=t,t=0,1):i<3?1... function yc (line 8476) | function yc(t,e){switch(arguments.length){case 0:break;case 1:this.range... function Em (line 8476) | function Em(t,e){switch(arguments.length){case 0:break;case 1:{typeof t=... function KI (line 8476) | function KI(){var t=new bG,e=[],n=[],r=JR;function i(s){let o=t.get(s);i... function XI (line 8476) | function XI(){var t=KI().unknown(void 0),e=t.domain,n=t.range,r=0,i=1,s,... function Ete (line 8476) | function Ete(t){var e=t.copy;return t.padding=t.paddingOuter,delete t.pa... function lLe (line 8476) | function lLe(){return Ete(XI.apply(null,arguments).paddingInner(1))} function YI (line 8476) | function YI(t,e,n){t.prototype=e.prototype=n,n.constructor=t} function Dte (line 8476) | function Dte(t,e){var n=Object.create(t.prototype);for(var r in e)n[r]=e... function SS (line 8476) | function SS(){} method copy (line 8476) | copy(t){return Object.assign(new this.constructor,this,t)} method displayable (line 8476) | displayable(){return this.rgb().displayable()} function SG (line 8476) | function SG(){return this.rgb().formatHex()} function gLe (line 8476) | function gLe(){return this.rgb().formatHex8()} function bLe (line 8476) | function bLe(){return Fte(this).formatHsl()} function _G (line 8476) | function _G(){return this.rgb().formatRgb()} function Tw (line 8476) | function Tw(t){var e,n;return t=(t+"").trim().toLowerCase(),(e=cLe.exec(... function kG (line 8476) | function kG(t){return new Io(t>>16&255,t>>8&255,t&255,1)} function lk (line 8476) | function lk(t,e,n,r){return r<=0&&(t=e=n=NaN),new Io(t,e,n,r)} function xLe (line 8476) | function xLe(t){return t instanceof SS||(t=Tw(t)),t?(t=t.rgb(),new Io(t.... function eL (line 8476) | function eL(t,e,n,r){return arguments.length===1?xLe(t):new Io(t,e,n,r??1)} function Io (line 8476) | function Io(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r} method brighter (line 8476) | brighter(t){return t=t==null?pC:Math.pow(pC,t),new Io(this.r*t,this.g*t,... method darker (line 8476) | darker(t){return t=t==null?Cw:Math.pow(Cw,t),new Io(this.r*t,this.g*t,th... method rgb (line 8476) | rgb(){return this} method clamp (line 8476) | clamp(){return new Io(Zf(this.r),Zf(this.g),Zf(this.b),fC(this.opacity))} method displayable (line 8476) | displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5... function NG (line 8476) | function NG(){return`#${Of(this.r)}${Of(this.g)}${Of(this.b)}`} function yLe (line 8476) | function yLe(){return`#${Of(this.r)}${Of(this.g)}${Of(this.b)}${Of((isNa... function CG (line 8476) | function CG(){const t=fC(this.opacity);return`${t===1?"rgb(":"rgba("}${Z... function fC (line 8476) | function fC(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))} function Zf (line 8476) | function Zf(t){return Math.max(0,Math.min(255,Math.round(t)||0))} function Of (line 8476) | function Of(t){return t=Zf(t),(t<16?"0":"")+t.toString(16)} function PG (line 8476) | function PG(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=N... function Fte (line 8476) | function Fte(t){if(t instanceof qc)return new qc(t.h,t.s,t.l,t.opacity);... function vLe (line 8476) | function vLe(t,e,n,r){return arguments.length===1?Fte(t):new qc(t,e,n,r?... function qc (line 8476) | function qc(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r} method brighter (line 8476) | brighter(t){return t=t==null?pC:Math.pow(pC,t),new qc(this.h,this.s,this... method darker (line 8476) | darker(t){return t=t==null?Cw:Math.pow(Cw,t),new qc(this.h,this.s,this.l... method rgb (line 8476) | rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s... method clamp (line 8476) | clamp(){return new qc(TG(this.h),ck(this.s),ck(this.l),fC(this.opacity))} method displayable (line 8476) | displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&th... method formatHsl (line 8476) | formatHsl(){const t=fC(this.opacity);return`${t===1?"hsl(":"hsla("}${TG(... function TG (line 8476) | function TG(t){return t=(t||0)%360,t<0?t+360:t} function ck (line 8476) | function ck(t){return Math.max(0,Math.min(1,t||0))} function sD (line 8476) | function sD(t,e,n){return(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t... function wLe (line 8476) | function wLe(t,e){return function(n){return t+n*e}} function SLe (line 8476) | function SLe(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,funct... function _Le (line 8476) | function _Le(t){return(t=+t)==1?Rte:function(e,n){return n-e?SLe(e,n,t):... function Rte (line 8476) | function Rte(t,e){var n=e-t;return n?wLe(t,n):QI(isNaN(t)?e:t)} function r (line 8476) | function r(i,s){var o=n((i=eL(i)).r,(s=eL(s)).r),l=n(i.g,s.g),c=n(i.b,s.... function kLe (line 8476) | function kLe(t,e){e||(e=[]);var n=t?Math.min(e.length,t.length):0,r=e.sl... function NLe (line 8476) | function NLe(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)} function CLe (line 8476) | function CLe(t,e){var n=e?e.length:0,r=t?Math.min(n,t.length):0,i=new Ar... function PLe (line 8476) | function PLe(t,e){var n=new Date;return t=+t,e=+e,function(r){return n.s... function gC (line 8476) | function gC(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}} function TLe (line 8476) | function TLe(t,e){var n={},r={},i;(t===null||typeof t!="object")&&(t={})... function ALe (line 8476) | function ALe(t){return function(){return t}} function jLe (line 8476) | function jLe(t){return function(e){return t(e)+""}} function MLe (line 8476) | function MLe(t,e){var n=tL.lastIndex=oD.lastIndex=0,r,i,s,o=-1,l=[],c=[]... function jy (line 8476) | function jy(t,e){var n=typeof e,r;return e==null||n==="boolean"?QI(e):(n... function ZI (line 8476) | function ZI(t,e){return t=+t,e=+e,function(n){return Math.round(t*(1-n)+... function ELe (line 8476) | function ELe(t,e){e===void 0&&(e=t,t=jy);for(var n=0,r=e.length-1,i=e[0]... function DLe (line 8476) | function DLe(t){return function(){return t}} function bC (line 8476) | function bC(t){return+t} function ao (line 8476) | function ao(t){return t} function nL (line 8476) | function nL(t,e){return(e-=t=+t)?function(n){return(n-t)/e}:DLe(isNaN(e)... function FLe (line 8476) | function FLe(t,e){var n;return t>e&&(n=t,t=e,e=n),function(r){return Mat... function RLe (line 8476) | function RLe(t,e,n){var r=t[0],i=t[1],s=e[0],o=e[1];return i=1e21?t.toLocaleString(... function xC (line 8476) | function xC(t,e){if(!isFinite(t)||t===0)return null;var n=(t=e?t.toExpon... function ry (line 8476) | function ry(t){return t=xC(Math.abs(t)),t?t[1]:NaN} function ILe (line 8476) | function ILe(t,e){return function(n,r){for(var i=n.length,s=[],o=0,l=t[0... function zLe (line 8476) | function zLe(t){return function(e){return e.replace(/[0-9]/g,function(n)... function Aw (line 8476) | function Aw(t){if(!(e=ULe.exec(t)))throw new Error("invalid format: "+t)... function e4 (line 8476) | function e4(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.alig... function BLe (line 8476) | function BLe(t){e:for(var e=t.length,n=1,r=-1,i;nMath.pow(t,e)} function ZLe (line 8476) | function ZLe(t){return t===Math.E?Math.log:t===10&&Math.log10||t===2&&Ma... function IG (line 8476) | function IG(t){return(e,n)=>-t(-e,n)} function n4 (line 8476) | function n4(t){const e=t(LG,OG),n=e.domain;let r=10,i,s;function o(){ret... function Bte (line 8476) | function Bte(){const t=n4(CT()).domain([1,10]);return t.copy=()=>_S(t,Bt... function zG (line 8476) | function zG(t){return function(e){return Math.sign(e)*Math.log1p(Math.ab... function UG (line 8476) | function UG(t){return function(e){return Math.sign(e)*Math.expm1(Math.ab... function r4 (line 8476) | function r4(t){var e=1,n=t(zG(e),UG(e));return n.constant=function(r){re... function Hte (line 8476) | function Hte(){var t=r4(CT());return t.copy=function(){return _S(t,Hte()... function BG (line 8476) | function BG(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,... function JLe (line 8476) | function JLe(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)} function eOe (line 8476) | function eOe(t){return t<0?-t*t:t*t} function a4 (line 8476) | function a4(t){var e=t(ao,ao),n=1;function r(){return n===1?t(ao,ao):n==... function i4 (line 8476) | function i4(){var t=a4(CT());return t.copy=function(){return _S(t,i4()).... function tOe (line 8476) | function tOe(){return i4.apply(null,arguments).exponent(.5)} function HG (line 8476) | function HG(t){return Math.sign(t)*t*t} function nOe (line 8476) | function nOe(t){return Math.sign(t)*Math.sqrt(Math.abs(t))} function qte (line 8476) | function qte(){var t=JI(),e=[0,1],n=!1,r;function i(s){var o=nOe(t(s));r... function $te (line 8476) | function $te(){var t=[],e=[],n=[],r;function i(){var o=0,l=Math.max(1,e.... function Vte (line 8476) | function Vte(){var t=0,e=1,n=1,r=[.5],i=[0,1],s;function o(c){return c!=... function Gte (line 8476) | function Gte(){var t=[.5],e=[0,1],n,r=1;function i(s){return s!=null&&s<... function Oi (line 8476) | function Oi(t,e,n,r){function i(s){return t(s=arguments.length===0?new D... function Hg (line 8476) | function Hg(t){return Oi(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e... function qg (line 8476) | function qg(t){return Oi(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+... function Kte (line 8476) | function Kte(t,e,n,r,i,s){const o=[[If,1,nm],[If,5,5*nm],[If,15,15*nm],[... function uD (line 8476) | function uD(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S... function mD (line 8476) | function mD(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.... function Qv (line 8476) | function Qv(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}} function fOe (line 8476) | function fOe(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,s=t.days,... function Dr (line 8476) | function Dr(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",s=i.length;return r+(s... function xOe (line 8476) | function xOe(t){return t.replace(bOe,"\\$&")} function Zv (line 8476) | function Zv(t){return new RegExp("^(?:"+t.map(xOe).join("|")+")","i")} function Jv (line 8476) | function Jv(t){return new Map(t.map((e,n)=>[e.toLowerCase(),n]))} function yOe (line 8476) | function yOe(t,e,n){var r=ts.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+... function vOe (line 8476) | function vOe(t,e,n){var r=ts.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+... function wOe (line 8476) | function wOe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+... function SOe (line 8476) | function SOe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+... function _Oe (line 8476) | function _Oe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+... function VG (line 8476) | function VG(t,e,n){var r=ts.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r... function GG (line 8476) | function GG(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r... function kOe (line 8476) | function kOe(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,... function NOe (line 8476) | function NOe(t,e,n){var r=ts.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3... function COe (line 8476) | function COe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n... function WG (line 8476) | function WG(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r... function POe (line 8476) | function POe(t,e,n){var r=ts.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r... function KG (line 8476) | function KG(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r... function TOe (line 8476) | function TOe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+... function AOe (line 8476) | function AOe(t,e,n){var r=ts.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+... function jOe (line 8476) | function jOe(t,e,n){var r=ts.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+... function MOe (line 8476) | function MOe(t,e,n){var r=ts.exec(e.slice(n,n+6));return r?(t.L=Math.flo... function EOe (line 8476) | function EOe(t,e,n){var r=gOe.exec(e.slice(n,n+1));return r?n+r[0].lengt... function DOe (line 8476) | function DOe(t,e,n){var r=ts.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0]... function FOe (line 8476) | function FOe(t,e,n){var r=ts.exec(e.slice(n));return r?(t.s=+r[0],n+r[0]... function XG (line 8476) | function XG(t,e){return Dr(t.getDate(),e,2)} function ROe (line 8476) | function ROe(t,e){return Dr(t.getHours(),e,2)} function LOe (line 8476) | function LOe(t,e){return Dr(t.getHours()%12||12,e,2)} function OOe (line 8476) | function OOe(t,e){return Dr(1+kS.count(Nm(t),t),e,3)} function Xte (line 8476) | function Xte(t,e){return Dr(t.getMilliseconds(),e,3)} function IOe (line 8476) | function IOe(t,e){return Xte(t,e)+"000"} function zOe (line 8476) | function zOe(t,e){return Dr(t.getMonth()+1,e,2)} function UOe (line 8476) | function UOe(t,e){return Dr(t.getMinutes(),e,2)} function BOe (line 8476) | function BOe(t,e){return Dr(t.getSeconds(),e,2)} function HOe (line 8476) | function HOe(t){var e=t.getDay();return e===0?7:e} function qOe (line 8476) | function qOe(t,e){return Dr(TT.count(Nm(t)-1,t),e,2)} function Yte (line 8476) | function Yte(t){var e=t.getDay();return e>=4||e===0?ay(t):ay.ceil(t)} function $Oe (line 8476) | function $Oe(t,e){return t=Yte(t),Dr(ay.count(Nm(t),t)+(Nm(t).getDay()==... function VOe (line 8476) | function VOe(t){return t.getDay()} function GOe (line 8476) | function GOe(t,e){return Dr(wC.count(Nm(t)-1,t),e,2)} function WOe (line 8476) | function WOe(t,e){return Dr(t.getFullYear()%100,e,2)} function KOe (line 8476) | function KOe(t,e){return t=Yte(t),Dr(t.getFullYear()%100,e,2)} function XOe (line 8476) | function XOe(t,e){return Dr(t.getFullYear()%1e4,e,4)} function YOe (line 8476) | function YOe(t,e){var n=t.getDay();return t=n>=4||n===0?ay(t):ay.ceil(t)... function QOe (line 8476) | function QOe(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+... function YG (line 8476) | function YG(t,e){return Dr(t.getUTCDate(),e,2)} function ZOe (line 8476) | function ZOe(t,e){return Dr(t.getUTCHours(),e,2)} function JOe (line 8476) | function JOe(t,e){return Dr(t.getUTCHours()%12||12,e,2)} function eIe (line 8476) | function eIe(t,e){return Dr(1+PT.count(Cm(t),t),e,3)} function Qte (line 8476) | function Qte(t,e){return Dr(t.getUTCMilliseconds(),e,3)} function tIe (line 8476) | function tIe(t,e){return Qte(t,e)+"000"} function nIe (line 8476) | function nIe(t,e){return Dr(t.getUTCMonth()+1,e,2)} function rIe (line 8476) | function rIe(t,e){return Dr(t.getUTCMinutes(),e,2)} function aIe (line 8476) | function aIe(t,e){return Dr(t.getUTCSeconds(),e,2)} function iIe (line 8476) | function iIe(t){var e=t.getUTCDay();return e===0?7:e} function sIe (line 8476) | function sIe(t,e){return Dr(AT.count(Cm(t)-1,t),e,2)} function Zte (line 8476) | function Zte(t){var e=t.getUTCDay();return e>=4||e===0?iy(t):iy.ceil(t)} function oIe (line 8476) | function oIe(t,e){return t=Zte(t),Dr(iy.count(Cm(t),t)+(Cm(t).getUTCDay(... function lIe (line 8476) | function lIe(t){return t.getUTCDay()} function cIe (line 8476) | function cIe(t,e){return Dr(SC.count(Cm(t)-1,t),e,2)} function dIe (line 8476) | function dIe(t,e){return Dr(t.getUTCFullYear()%100,e,2)} function uIe (line 8476) | function uIe(t,e){return t=Zte(t),Dr(t.getUTCFullYear()%100,e,2)} function mIe (line 8476) | function mIe(t,e){return Dr(t.getUTCFullYear()%1e4,e,4)} function hIe (line 8476) | function hIe(t,e){var n=t.getUTCDay();return t=n>=4||n===0?iy(t):iy.ceil... function pIe (line 8476) | function pIe(){return"+0000"} function QG (line 8476) | function QG(){return"%"} function ZG (line 8476) | function ZG(t){return+t} function JG (line 8476) | function JG(t){return Math.floor(+t/1e3)} function fIe (line 8476) | function fIe(t){return rx=fOe(t),Jte=rx.format,rx.parse,ene=rx.utcFormat... function gIe (line 8476) | function gIe(t){return new Date(t)} function bIe (line 8476) | function bIe(t){return t instanceof Date?+t:+new Date(+t)} function h4 (line 8476) | function h4(t,e,n,r,i,s,o,l,c,d){var u=JI(),m=u.invert,p=u.domain,f=d(".... function xIe (line 8476) | function xIe(){return yc.apply(h4(hOe,pOe,Nm,u4,TT,kS,c4,o4,If,Jte).doma... function yIe (line 8476) | function yIe(){return yc.apply(h4(uOe,mOe,Cm,m4,AT,PT,d4,l4,If,ene).doma... function jT (line 8476) | function jT(){var t=0,e=1,n,r,i,s,o=ao,l=!1,c;function d(m){return m==nu... function Ep (line 8476) | function Ep(t,e){return e.domain(t.domain()).interpolator(t.interpolator... function tne (line 8476) | function tne(){var t=Mp(jT()(ao));return t.copy=function(){return Ep(t,t... function nne (line 8476) | function nne(){var t=n4(jT()).domain([1,10]);return t.copy=function(){re... function rne (line 8476) | function rne(){var t=r4(jT());return t.copy=function(){return Ep(t,rne()... function p4 (line 8476) | function p4(){var t=a4(jT());return t.copy=function(){return Ep(t,p4()).... function vIe (line 8476) | function vIe(){return p4.apply(null,arguments).exponent(.5)} function ane (line 8476) | function ane(){var t=[],e=ao;function n(r){if(r!=null&&!isNaN(r=+r))retu... function MT (line 8476) | function MT(){var t=0,e=.5,n=1,r=1,i,s,o,l,c,d=ao,u,m=!1,p;function f(v)... function ine (line 8476) | function ine(){var t=Mp(MT()(ao));return t.copy=function(){return Ep(t,i... function sne (line 8476) | function sne(){var t=n4(MT()).domain([.1,1,10]);return t.copy=function()... function one (line 8476) | function one(){var t=r4(MT());return t.copy=function(){return Ep(t,one()... function f4 (line 8476) | function f4(){var t=a4(MT());return t.copy=function(){return Ep(t,f4()).... function wIe (line 8476) | function wIe(){return f4.apply(null,arguments).exponent(.5)} function Pm (line 8476) | function Pm(t){if(Array.isArray(t)&&t.length===2){var[e,n]=t;if(Gn(e)&&G... function e9 (line 8476) | function e9(t,e,n){return n?t:[Math.min(t[0],e[0]),Math.max(t[1],e[1])]} function cne (line 8476) | function cne(t,e){if(e&&typeof t!="function"&&Array.isArray(t)&&t.length... function SIe (line 8476) | function SIe(t,e,n){if(!(!n&&e==null)){if(typeof t=="function"&&e!=null)... function une (line 8476) | function une(t,e){var n,r,i,s,o,l,c,d,u=t.constructor,m=u.precision;if(!... function $d (line 8476) | function $d(t,e,n){if(t!==~~t||tn)throw Error(Jf+t)} function Fd (line 8476) | function Fd(t){var e,n,r,i=t.length-1,s="",o=t[0];if(i>0){for(s+=o,e=1;e... function t (line 8476) | function t(r,i){var s,o=0,l=r.length;for(r=r.slice();l--;)s=r[l]*i+o,r[l... function e (line 8476) | function e(r,i,s,o){var l,c;if(s!=o)c=s>o?1:-1;else for(l=c=0;l=10;n/=10)e++;return e} function hD (line 8476) | function hD(t,e,n){if(e>t.LN10.sd())throw Aa=!0,n&&(t.precision=n),Error... function Ah (line 8476) | function Ah(t){for(var e="";t--;)e+="0";return e} function jw (line 8476) | function jw(t,e){var n,r,i,s,o,l,c,d,u,m=1,p=10,f=t,y=f.d,v=f.constructo... function t9 (line 8476) | function t9(t,e){var n,r,i;for((n=e.indexOf("."))>-1&&(e=e.replace(".","... function ca (line 8476) | function ca(t,e,n){var r,i,s,o,l,c,d,u,m=t.d;for(o=1,s=m[0];s>=10;s/=10)... function hne (line 8476) | function hne(t,e){var n,r,i,s,o,l,c,d,u,m,p=t.constructor,f=p.precision;... function Pg (line 8476) | function Pg(t,e,n){var r,i=ki(t),s=Fd(t.d),o=s.length;return e?(n&&(r=n-... function n9 (line 8476) | function n9(t,e){if(t.length>e)return t.length=e,!0} function pne (line 8476) | function pne(t){var e,n,r;function i(s){var o=this;if(!(o instanceof i))... function NIe (line 8476) | function NIe(t){if(!t||typeof t!="object")throw Error(fc+"Object expecte... function fne (line 8476) | function fne(t){var e;return t===0?e=1:e=Math.floor(new Vr(t).abs().log(... function gne (line 8476) | function gne(t,e,n){for(var r=new Vr(t),i=0,s=[];r.lt(e)&&i<1e5;)s.push(... function FT (line 8476) | function FT(t,e,n){if(n!=="auto")return n;if(t!=null)return ad(t,e)?"cat... function r9 (line 8476) | function r9(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function kC (line 8476) | function kC(t){for(var e=1;e{switch(t){case"xAxis":return"xAxisId"in n&&n... function Lne (line 8476) | function Lne(t,e){switch(t){case"xAxis":return e.direction==="x";case"yA... function Zk (line 8476) | function Zk(t){if(hc(t)||t instanceof Date){var e=Number(t);if(Gn(e))ret... function c9 (line 8476) | function c9(t){if(Array.isArray(t)){var e=[Zk(t[0]),Zk(t[1])];return Pm(... function Tm (line 8476) | function Tm(t){return t.map(Zk).filter(Oo)} function KIe (line 8476) | function KIe(t,e,n){return!n||typeof e!="number"||Zc(e)?[]:n.length?Tm(n... function e4e (line 8476) | function e4e(t){var{value:e}=t;if(hc(e)||e instanceof Date)return e} function o4e (line 8476) | function o4e(t){var e;if(t.x!=null)return Tm([t.x]);var n=(e=t.segment)=... function l4e (line 8476) | function l4e(t){var e;if(t.y!=null)return Tm([t.y]);var n=(e=t.segment)=... function h4e (line 8476) | function h4e(t){return t in g0} function z4 (line 8476) | function z4(t,e,n,r){if(!(n==null||r==null))return typeof t.scale=="func... function Kne (line 8476) | function Kne(t,e){return t.ide.id?1:0} function rre (line 8476) | function rre(t,e,n){if(t==null)return e;var r=t?"axis":"item";return n==... function V4 (line 8476) | function V4(t,e){var n=tre(t),r=nre(t);return rre(e,n,r)} function I4e (line 8476) | function I4e(t){return sn(e=>V4(e,t))} method reducer (line 8476) | reducer(t,e){t.tooltipItemPayloads.push(e.payload)} method reducer (line 8476) | reducer(t,e){var{prev:n,next:r}=e.payload,i=Xc(t).tooltipItemPayloads.in... method reducer (line 8476) | reducer(t,e){var n=Xc(t).tooltipItemPayloads.indexOf(e.payload);n>-1&&t.... method setTooltipSettingsState (line 8476) | setTooltipSettingsState(t,e){t.settings=e.payload} method setActiveMouseOverItemIndex (line 8476) | setActiveMouseOverItemIndex(t,e){t.syncInteraction.active=!1,t.keyboardI... method mouseLeaveChart (line 8476) | mouseLeaveChart(t){t.itemInteraction.hover.active=!1,t.axisInteraction.h... method mouseLeaveItem (line 8476) | mouseLeaveItem(t){t.itemInteraction.hover.active=!1} method setActiveClickItemIndex (line 8476) | setActiveClickItemIndex(t,e){t.syncInteraction.active=!1,t.itemInteracti... method setMouseOverAxisIndex (line 8476) | setMouseOverAxisIndex(t,e){t.syncInteraction.active=!1,t.axisInteraction... method setMouseClickAxisIndex (line 8476) | setMouseClickAxisIndex(t,e){t.syncInteraction.active=!1,t.keyboardIntera... method setSyncInteraction (line 8476) | setSyncInteraction(t,e){t.syncInteraction=e.payload} method setKeyboardInteraction (line 8476) | setKeyboardInteraction(t,e){t.keyboardInteraction.active=e.payload.activ... function m9 (line 8476) | function m9(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function uk (line 8476) | function uk(t){for(var e=1;e=e.left&&n<=e.left+e... function x9 (line 8476) | function x9(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function y9 (line 8476) | function y9(t){for(var e=1;e{if(t==null)... function B5e (line 8476) | function B5e(){var t=ua();w.useEffect(()=>{t(T5e())},[t]),z5e(),U5e()} function H5e (line 8476) | function H5e(t,e,n,r,i,s){var o=sn(f=>Xze(f,t,e)),l=sn(w4),c=sn(v4),d=sn... function N9 (line 8476) | function N9(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function C9 (line 8476) | function C9(t){for(var e=1;eQ9(i))... function _Be (line 8478) | function _Be(){return J9||(J9=1,(function(t){Object.defineProperty(t,Sym... function kBe (line 8478) | function kBe(){return eW||(eW=1,_D=_Be().isPlainObject),_D} function sW (line 8478) | function sW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function oW (line 8478) | function oW(t){for(var e=1;e-1&&t.carte... method reducer (line 8478) | reducer(t,e){t.polarItems.push(e.payload)} method reducer (line 8478) | reducer(t,e){var n=Xc(t).polarItems.indexOf(e.payload);n>-1&&t.polarItem... function e8e (line 8478) | function e8e(t){var e=ua();return w.useLayoutEffect(()=>(e(YBe(t)),()=>{... function uW (line 8478) | function uW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function Xa (line 8478) | function Xa(t){for(var e=1;esz(t.children,oy),[t.children]),n=sn... function b8e (line 8478) | function b8e(t){var{sectors:e,props:n,showLabels:r}=t,{label:i,labelLine... function x8e (line 8478) | function x8e(t){var{sectors:e,props:n,showLabels:r}=t,{label:i}=n;return... function y8e (line 8478) | function y8e(t){var{sectors:e,activeShape:n,inactiveShape:r,allOtherPieP... function v8e (line 8478) | function v8e(t){var e,{pieSettings:n,displayedData:r,cells:i,offset:s}=t... function w8e (line 8478) | function w8e(t){var{showLabels:e,sectors:n,children:r}=t,i=w.useMemo(()=... function S8e (line 8478) | function S8e(t){var{props:e,previousSectorsRef:n,id:r}=t,{sectors:i,isAn... function k8e (line 8478) | function k8e(t){var{id:e}=t,n=QT(t,r8e),{hide:r,className:i,rootTabIndex... function dL (line 8478) | function dL(t){var e=Ia(t,_8e),{id:n}=e,r=QT(e,a8e),i=mo(r);return w.cre... function mW (line 8478) | function mW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function ND (line 8478) | function ND(t){for(var e=1;e(e(hHe(t)),()=>{e(pHe(... function THe (line 8478) | function THe(t){var{xAxisId:e,yAxisId:n,shape:r,className:i,ifOverflow:s... function x0 (line 8478) | function x0(t){var e=Ia(t,AHe);return w.createElement(w.Fragment,null,w.... function sae (line 8478) | function sae(t,e){if(e<1)return[];if(e===1)return t;for(var n=[],r=0;rt*i)return!1;var s=n();return t*(... function EHe (line 8478) | function EHe(t,e){return sae(t,e+1)} function DHe (line 8478) | function DHe(t,e,n,r,i){for(var s=(r||[]).slice(),{start:o,end:l}=e,c=0,... function FHe (line 8478) | function FHe(t,e,n,r,i){var s=(r||[]).slice(),o=s.length;if(o===0)return... function wW (line 8478) | function wW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function Ls (line 8478) | function Ls(t){for(var e=1;eQd(d,t)),s=sn(d=>Zd(d,e)),o=(n=i?.allow... function gz (line 8478) | function gz(t){var{xAxisId:e,yAxisId:n,clipPathId:r}=t,i=ZT(),{needClipX... function N6e (line 8478) | function N6e(t){return t.type==="line"} function pae (line 8478) | function pae(t){var e=vg(t),n=3,r=2;if(e!=null){var{r:i,strokeWidth:s}=e... function T6e (line 8478) | function T6e(){if(kW)return TD;kW=1;var t=Rg();function e(c,d){return c=... function A6e (line 8478) | function A6e(){return NW||(NW=1,PD.exports=T6e()),PD.exports} function j6e (line 8478) | function j6e(t){t()} function M6e (line 8478) | function M6e(){let t=null,e=null;return{clear(){t=null,e=null},notify(){... method notify (line 8478) | notify(){} function E6e (line 8478) | function E6e(t,e){let n,r=CW,i=0,s=!1;function o(v){u();const b=r.subscr... function PW (line 8478) | function PW(t,e){return t===e?t!==0||e!==0||1/t===1/e:t!==t&&e!==e} function z6e (line 8478) | function z6e(t,e){if(PW(t,e))return!0;if(typeof t!="object"||t===null||t... function H6e (line 8478) | function H6e(){if(!w.createContext)return{};const t=B6e[U6e]??=new Map;l... function $6e (line 8478) | function $6e(t){const{children:e,context:n,serverState:r,store:i}=t,s=w.... function W6e (line 8478) | function W6e(t,e){return t==null&&e==null?!0:typeof t=="number"&&typeof ... function DS (line 8478) | function DS(t,e){var n=new Set([...Object.keys(t),...Object.keys(e)]);fo... function Dw (line 8478) | function Dw(){return Dw=Object.assign?Object.assign.bind():function(t){f... function TW (line 8478) | function TW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function Cd (line 8478) | function Cd(t){for(var e=1;e... function AW (line 8478) | function AW(t){var{clipPathId:e,pathRef:n,points:r,strokeDasharray:i,pro... function oqe (line 8478) | function oqe(t){try{return t&&t.getTotalLength&&t.getTotalLength()||0}ca... function lqe (line 8478) | function lqe(t){var{clipPathId:e,props:n,pathRef:r,previousPointsRef:i,l... function cqe (line 8478) | function cqe(t){var{clipPathId:e,props:n}=t,r=w.useRef(null),i=w.useRef(... class uqe (line 8478) | class uqe extends w.Component{render(){var{hide:e,dot:n,points:r,classNa... method render (line 8478) | render(){var{hide:e,dot:n,points:r,className:i,xAxisId:s,yAxisId:o,top... function mqe (line 8478) | function mqe(t){var e=Ia(t,gae),{activeDot:n,animateNewValues:r,animatio... function hqe (line 8478) | function hqe(t){var{layout:e,xAxis:n,yAxis:r,xAxisTicks:i,yAxisTicks:s,d... function pqe (line 8478) | function pqe(t){var e=Ia(t,gae),n=Li();return w.createElement(YT,{id:e.i... function Jd (line 8478) | function Jd(t,e){var n,r;return(n=(r=t.graphicalItems.cartesianItems.fin... function eu (line 8478) | function eu(t,e){var n,r;return(n=(r=t.graphicalItems.cartesianItems.fin... function eg (line 8478) | function eg(){return eg=Object.assign?Object.assign.bind():function(t){f... function kae (line 8478) | function kae(t,e){if(t==null)return{};var n,r,i=_qe(t,e);if(Object.getOw... function _qe (line 8478) | function _qe(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasO... function jW (line 8478) | function jW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function kx (line 8478) | function kx(t){for(var e=1;e{var ... function MW (line 8478) | function MW(t){var{points:e,baseLine:n,needClip:r,clipPathId:i,props:s}=... function Mqe (line 8478) | function Mqe(t){var e,n,{alpha:r,baseLine:i,points:s,strokeWidth:o}=t,l=... function Eqe (line 8478) | function Eqe(t){var e,n,{alpha:r,baseLine:i,points:s,strokeWidth:o}=t,l=... function Dqe (line 8478) | function Dqe(t){var{alpha:e,layout:n,points:r,baseLine:i,strokeWidth:s}=... function Fqe (line 8478) | function Fqe(t){var{needClip:e,clipPathId:n,props:r,previousPointsRef:i,... function Rqe (line 8478) | function Rqe(t){var{needClip:e,clipPathId:n,props:r}=t,i=w.useRef(null),... class Lqe (line 8478) | class Lqe extends w.PureComponent{render(){var{hide:e,dot:n,points:r,cla... method render (line 8478) | render(){var{hide:e,dot:n,points:r,className:i,top:s,left:o,needClip:l... function Oqe (line 8478) | function Oqe(t){var e,n=Ia(t,Nae),{activeDot:r,animationBegin:i,animatio... function zqe (line 8478) | function zqe(t){var{areaSettings:{connectNulls:e,baseValue:n,dataKey:r},... function Uqe (line 8478) | function Uqe(t){var e=Ia(t,Nae),n=Li();return w.createElement(YT,{id:e.i... function Hqe (line 8478) | function Hqe(t,e){throw new Error(Bqe)} function mL (line 8478) | function mL(){return mL=Object.assign?Object.assign.bind():function(t){f... function LC (line 8478) | function LC(t){return w.createElement(lz,mL({shapeType:"rectangle",activ... function hL (line 8478) | function hL(){return hL=Object.assign?Object.assign.bind():function(t){f... function l$e (line 8478) | function l$e(t,e){if(t==null)return{};var n,r,i=c$e(t,e);if(Object.getOw... function c$e (line 8478) | function c$e(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasO... function Am (line 8478) | function Am(){return Am=Object.assign?Object.assign.bind():function(t){f... function EW (line 8478) | function EW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function ro (line 8478) | function ro(t){for(var e=1;e{var ... function N$e (line 8478) | function N$e(t){var{shape:e,activeBar:n,baseProps:r,entry:i,index:s,data... function C$e (line 8478) | function C$e(t){var{shape:e,baseProps:n,entry:r,index:i,dataKey:s}=t;ret... function P$e (line 8478) | function P$e(t){var e,{data:n,props:r}=t,i=(e=mo(r))!==null&&e!==void 0?... function T$e (line 8478) | function T$e(t){var{props:e,previousRectanglesRef:n}=t,{data:r,layout:i,... function A$e (line 8478) | function A$e(t){var e=w.useRef(null);return w.createElement(T$e,{previou... class M$e (line 8478) | class M$e extends w.PureComponent{render(){var{hide:e,data:n,dataKey:r,c... method render (line 8478) | render(){var{hide:e,data:n,dataKey:r,className:i,xAxisId:s,yAxisId:o,n... function D$e (line 8478) | function D$e(t){var{xAxisId:e,yAxisId:n,hide:r,legendType:i,minPointSize... function F$e (line 8478) | function F$e(t){var{layout:e,barSettings:{dataKey:n,minPointSize:r},pos:... function R$e (line 8478) | function R$e(t){var e=Ia(t,E$e),n=d$e(e.stackId),r=Li();return w.createE... function DW (line 8478) | function DW(t,e){if(t==null)return{};var n,r,i=I$e(t,e);if(Object.getOwn... function I$e (line 8478) | function I$e(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasO... function FW (line 8478) | function FW(t,e){return t===e?!0:Array.isArray(t)&&t.length===2&&Array.i... function Mae (line 8478) | function Mae(t,e){if(t===e)return!0;var{domain:n,range:r}=t,i=DW(t,L$e),... function pL (line 8478) | function pL(){return pL=Object.assign?Object.assign.bind():function(t){f... function RW (line 8478) | function RW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function LW (line 8478) | function LW(t){for(var e=1;e{e(dVe(t))},[e,t]),null} function UW (line 8478) | function UW(t){var{zIndex:e,isPanorama:n}=t,r=w.useRef(null),i=ua();retu... function BW (line 8478) | function BW(t){var{children:e,isPanorama:n}=t,r=sn(r5e);if(!r||r.length=... function wVe (line 8478) | function wVe(t,e){if(t==null)return{};var n,r,i=SVe(t,e);if(Object.getOw... function SVe (line 8478) | function SVe(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasO... function IC (line 8478) | function IC(){return IC=Object.assign?Object.assign.bind():function(t){f... function CVe (line 8478) | function CVe(){var t=ua(),[e,n]=w.useState(null),r=sn(_3e);return w.useE... function qW (line 8478) | function qW(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function PVe (line 8478) | function PVe(t){for(var e=1;e{e(hVe(t))},[e,t]),null} function vL (line 8478) | function vL(){return vL=Object.assign?Object.assign.bind():function(t){f... function KVe (line 8478) | function KVe(t,e){if(t==null)return{};var n,r,i=XVe(t,e);if(Object.getOw... function XVe (line 8478) | function XVe(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasO... function $W (line 8478) | function $W(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){v... function VW (line 8478) | function VW(t){for(var e=1;e=128&&t<=135?(... function ED (line 8513) | function ED(t){const e=t.includes("_")?t.split("_")[0]:t;return e.starts... function XW (line 8513) | function XW(t){const e=t.replace(/@.+$/,"").trim(),n=e.toUpperCase(),r=n... function s7e (line 8513) | function s7e(t){return!t.startsWith("GF")&&!t.startsWith("P1")} function ZW (line 8513) | function ZW(t){const e=t.toLowerCase().trim();return o7e[e]||null} function l7e (line 8513) | function l7e(t){const e=t.indexOf("@");if(e<0)return null;const r=t.slic... function Xae (line 8513) | function Xae({isOpen:t,onClose:e,printerId:n,slotInfo:r,nozzleDiameter:i... function JW (line 8513) | function JW({className:t="w-4 h-4"}){return a.jsx("svg",{viewBox:"0 0 19... function Yae (line 8513) | function Yae({folderId:t,onClose:e,onUploadComplete:n,onFileUploaded:r,a... function eK (line 8513) | function eK(t){return t?`#${t.replace("#","").substring(0,6)}`:"#808080"} function Za (line 8513) | function Za(t){return t?t.replace("#","").toLowerCase().substring(0,6):""} function UC (line 8513) | function UC(t){if(!t)return"";const e=t.toUpperCase();return Qae[e]??e} function DD (line 8513) | function DD(t,e){return UC(t)===UC(e)} function zd (line 8513) | function zd(t,e,n=40){const r=Za(t),i=Za(e);if(!r||!i||r.length<6||i.len... function RS (line 8513) | function RS(t,e,n,r){if(r)return"Ext";const i=String.fromCharCode(65+(t>... function Ag (line 8513) | function Ag(t,e,n){return n?254+e:t>=128?t:t*4+e} function Ox (line 8513) | function Ox(t){return t>50?"#00ae42":t>=15?"#f59e0b":"#ef4444"} function tN (line 8513) | function tN(t){return!t?.remaining_weight||!t?.filament_weight||t.filame... function tK (line 8513) | function tK(t,e){return(Number.isFinite(t)?Math.max(0,Math.trunc(t)):0).... function d7e (line 8513) | function d7e(t){const e=(t||"").trim().toUpperCase();let n=2166136261;fo... function Vu (line 8513) | function Vu(t,e,n){return`${d7e(t)}${tK(e,4)}${tK(n,4)}`} function nK (line 8513) | function nK(t){if(!t)return!1;const e=Date.now()+4320*60*60*1e3;return(Z... function u7e (line 8513) | function u7e(t,e,n,r){let i=Zae(e,t.nozzle_id);r&&(i=[...i].sort((c,d)=>... function Zae (line 8513) | function Zae(t,e){return t.filter(n=>e==null||n.extruderId===e)} function LS (line 8513) | function LS(t){const e=[],n=t?.ams_extruder_map,r=n&&Object.keys(n).leng... function rK (line 8513) | function rK(t,e,n){if(!t?.filaments||t.filaments.length===0)return;const... function m7e (line 8513) | function m7e(t){return w.useMemo(()=>LS(t),[t])} function Jae (line 8513) | function Jae(t,e,n,r){const i=m7e(e),s=w.useMemo(()=>{if(!t?.filaments||... function h7e (line 8513) | function h7e(t,e,n,r){if(!t||t.length===0)return{exactMatches:0,typeOnly... function p7e (line 8513) | function p7e(t,e,n,r){if(!t?.filaments||t.filaments.length===0)return;co... function f7e (line 8513) | function f7e(t,e,n,r,i,s,o){const l=Pp({queries:t.map(v=>({queryKey:["pr... function Eo (line 8513) | function Eo(t){return eie[t.toUpperCase()]||t} function b7e (line 8513) | function b7e({printerId:t,filamentReqs:e,manualMappings:n,onManualMappin... function x7e (line 8513) | function x7e({filamentReqs:t,availableFilaments:e,overrides:n,onChange:r... function y7e (line 8513) | function y7e({plates:t,isMultiPlate:e,selectedPlates:n,onToggle:r,onSele... function w7e (line 8513) | function w7e({printerResult:t,filamentReqs:e,onUpdateConfig:n}){const r=... function S7e (line 8513) | function S7e({printers:t,selectedPrinterIds:e,onMultiSelect:n,isLoading:... function k7e (line 8513) | function k7e({options:t,onChange:e,defaultExpanded:n=!1}){const[r,i]=w.u... function N7e (line 8513) | function N7e({options:t,onChange:e,dateFormat:n="system",timeFormat:r="s... function ic (line 8513) | function ic({mode:t,archiveId:e,libraryFileId:n,archiveName:r,queueItem:... function iK (line 8514) | function iK({value:t}){const{t:e}=Ft(),[n,r]=w.useState(!1),i=async()=>{... function C7e (line 8514) | function C7e({printer:t,status:e,totalPrintHours:n,onClose:r}){const{t:i... function P7e (line 8514) | function P7e(t){if(!t||t.length<6)return!1;const e=parseInt(t.slice(0,2)... function RD (line 8514) | function RD({trayColor:t,trayType:e,isEmpty:n,slotNumber:r}){return a.js... function Sz (line 8514) | function Sz({summary:t,children:e,defaultOpen:n=!1,className:r="",summar... function LD (line 8514) | function LD(t){return(t??.02).toFixed(3)} function sK (line 8514) | function sK({side:t}){const{mode:e}=zg(),n=e==="dark"?"#1a4d2e":"#e7f5e9... function tie (line 8514) | function tie(t,e){if(!t)return"";if(t.includes("hardened"))return e("pri... function nie (line 8514) | function nie(t,e){return t?t.startsWith("HH")?e("printers.nozzleHighFlow... function rie (line 8514) | function rie({slot:t,index:e,activeStatus:n,filamentName:r,children:i}){... function T7e (line 8523) | function T7e({leftSlot:t,rightSlot:e,activeNozzle:n,filamentInfo:r,child... function A7e (line 8532) | function A7e({slots:t,filamentInfo:e}){const{t:n}=Ft(),r=t.filter(l=>l.i... function oK (line 8532) | function oK({className:t}){return a.jsx("svg",{className:t,viewBox:"0 0 ... function j7e (line 8532) | function j7e({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function M7e (line 8532) | function M7e({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function E7e (line 8532) | function E7e({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function D7e (line 8532) | function D7e({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function F7e (line 8532) | function F7e({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function OD (line 8532) | function OD({className:t,color:e,isHeating:n}){const i={"text-orange-400... function lK (line 8532) | function lK({humidity:t,goodThreshold:e=40,fairThreshold:n=60,onClick:r,... function cK (line 8532) | function cK({temp:t,goodThreshold:e=28,fairThreshold:n=35,onClick:r,comp... function Ul (line 8532) | function Ul(t,e){const n=typeof t=="string"?parseInt(t,10):t,r=isNaN(n)?... function ID (line 8532) | function ID(t){return t?!!(t.tray_uuid&&t.tray_uuid!=="00000000000000000... function R7e (line 8532) | function R7e({url:t,printName:e}){const{t:n}=Ft(),[r,i]=w.useState(!1),[... function L7e (line 8532) | function L7e({printers:t}){const{t:e}=Ft(),n=nn(),[r,i]=w.useState(0);w.... function uK (line 8532) | function uK(t){if(!t?.connected)return"offline";if((t.hms_errors?om(t.hm... function zD (line 8532) | function zD(t,e){if(e)return e;switch(t){case"RUNNING":return"Printing";... function O0 (line 8532) | function O0(t){return t?{O1D:"H2D",O1E:"H2D Pro",O2D:"H2D Pro",O1C:"H2C"... function mK (line 8532) | function mK({ams:t,printerId:e,label:n,amsLabels:r,canEdit:i,onSaved:s,c... function hK (line 8536) | function hK({printer:t,hideIfDisconnected:e,maintenanceInfo:n,viewMode:r... function I7e (line 8544) | function I7e({onClose:t,onAdd:e,existingSerials:n}){const{t:r}=Ft(),[i,s... function z7e (line 8544) | function z7e({printer:t,firmwareInfo:e,onClose:n}){const{t:r}=Ft(),i=nn(... function U7e (line 8544) | function U7e({printer:t,onClose:e}){const{t:n}=Ft(),r=nn(),{showToast:i}... function B7e (line 8544) | function B7e(t){const{data:e}=Xe({queryKey:["printerStatus",t],queryFn:(... function H7e (line 8544) | function H7e({printer:t,plug:e,onPowerOn:n,isPowering:r}){const i=B7e(t.... function q7e (line 8544) | function q7e(){const{t}=Ft(),[e,n]=w.useState(!1),[r,i]=w.useState(()=>l... function $7e (line 8544) | function $7e(){const t=navigator.userAgent.toLowerCase(),e=navigator.pla... function qf (line 8544) | function qf(t,e="bambu_studio"){let n;e==="orcaslicer"?n=`orcaslicer://o... function aie (line 8544) | function aie(){const[t,e]=w.useState(()=>typeof window<"u"?window.innerW... function _z (line 8544) | function _z({archiveId:t,libraryFileId:e,title:n,fileType:r,onClose:i}){... function V7e (line 8544) | function V7e({onClose:t,initialFiles:e}){const{t:n}=Ft(),r=nn(),{showToa... function iie (line 8544) | function iie({archive:t,onClose:e,existingTags:n=[]}){const{t:r}=Ft();w.... function sie (line 8544) | function sie({x:t,y:e,items:n,onClose:r}){const i=w.useRef(null),[s,o]=w... function K7e (line 8544) | function K7e({selectedIds:t,existingTags:e,onClose:n}){const r=nn(),{sho... function X7e (line 8544) | function X7e({selectedIds:t,onClose:e}){const n=nn(),{showToast:r}=hn(),... function Y7e (line 8544) | function Y7e(t,e){return new Date(t,e+1,0).getDate()} function Q7e (line 8544) | function Q7e(t,e){return new Date(t,e,1).getDay()} function eGe (line 8544) | function eGe({archives:t,onArchiveClick:e,highlightedArchiveId:n}){const... function oie (line 8544) | function oie({archiveId:t,archiveName:e,onClose:n}){const r=ue.getArchiv... function lie (line 8544) | function lie({archiveId:t,archiveName:e,photos:n,onClose:r,onDelete:i}){... function fo (line 8544) | function fo(t){return function(e){e instanceof RegExp&&(e.lastIndex=0);f... function lGe (line 8544) | function lGe(t){return function(){for(var e=arguments.length,n=new Array... function ur (line 8544) | function ur(t,e){let n=arguments.length>2&&arguments[2]!==void 0?argumen... function cGe (line 8544) | function cGe(t){for(let e=0;e0&&arguments[0]!==void 0?arguments... function ps (line 8545) | function ps(t){this.content=t} method size (line 8545) | get size(){return this.content.length>>1} function pie (line 8545) | function pie(t,e,n){for(let r=0;;r++){if(r==t.childCount||r==e.childCoun... function fie (line 8545) | function fie(t,e,n,r){for(let i=t.childCount,s=e.childCount;;){if(i==0||... class Vt (line 8545) | class Vt{constructor(e,n){if(this.content=e,this.size=n||0,n==null)for(l... method constructor (line 8545) | constructor(e,n){if(this.content=e,this.size=n||0,n==null)for(let r=0;... method nodesBetween (line 8545) | nodesBetween(e,n,r,i=0,s){for(let o=0,l=0;l"} method toStringInner (line 8545) | toStringInner(){return this.content.join(", ")} method toJSON (line 8545) | toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null} method fromJSON (line 8545) | static fromJSON(e,n){if(!n)return Vt.empty;if(!Array.isArray(n))throw ... method fromArray (line 8545) | static fromArray(e){if(!e.length)return Vt.empty;let n,r=0;for(let i=0... method from (line 8545) | static from(e){if(!e)return Vt.empty;if(e instanceof Vt)return e;if(Ar... function bk (line 8545) | function bk(t,e){return GD.index=t,GD.offset=e,GD} function BC (line 8545) | function BC(t,e){if(t===e)return!0;if(!(t&&typeof t=="object")||!(e&&typ... method constructor (line 8545) | constructor(e,n){this.type=e,this.attrs=n} method addToSet (line 8545) | addToSet(e){let n,r=!1;for(let i=0;it.depth)throw new HC("Inserted conten... function xie (line 8545) | function xie(t,e,n,r){let i=t.index(r),s=t.node(r);if(i==e.index(r)&&r=0&&t.isText&&t.sameMarkup(e[n])?e[n... function I0 (line 8545) | function I0(t,e,n,r){let i=(e||t).node(n),s=0,o=e?e.index(n):i.childCoun... function ng (line 8545) | function ng(t,e){return t.type.checkContent(e),t.copy(e)} function vie (line 8545) | function vie(t,e,n,r,i){let s=t.depth>i&&NL(t,e,i+1),o=r.depth>i&&NL(n,r... function qC (line 8545) | function qC(t,e,n){let r=[];if(I0(null,t,n,r),t.depth>n){let i=NL(t,e,n+... function _Ge (line 8545) | function _Ge(t,e){let n=e.depth-t.openStart,i=e.node(n).copy(t.content);... class Fw (line 8545) | class Fw{constructor(e,n,r){this.pos=e,this.path=n,this.parentOffset=r,t... method constructor (line 8545) | constructor(e,n,r){this.pos=e,this.path=n,this.parentOffset=r,this.dep... method resolveDepth (line 8545) | resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e} method parent (line 8545) | get parent(){return this.node(this.depth)} method doc (line 8545) | get doc(){return this.node(0)} method node (line 8545) | node(e){return this.path[this.resolveDepth(e)*3]} method index (line 8545) | index(e){return this.path[this.resolveDepth(e)*3+1]} method indexAfter (line 8545) | indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.dep... method start (line 8545) | start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1} method end (line 8545) | end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).conten... method before (line 8545) | before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is ... method after (line 8545) | after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is n... method textOffset (line 8545) | get textOffset(){return this.pos-this.path[this.path.length-1]} method nodeAfter (line 8545) | get nodeAfter(){let e=this.parent,n=this.index(this.depth);if(n==e.chi... method nodeBefore (line 8545) | get nodeBefore(){let e=this.index(this.depth),n=this.pos-this.path[thi... method posAtIndex (line 8545) | posAtIndex(e,n){n=this.resolveDepth(n);let r=this.path[n*3],i=n==0?0:t... method marks (line 8545) | marks(){let e=this.parent,n=this.index();if(e.content.size==0)return s... method marksAcross (line 8545) | marksAcross(e){let n=this.parent.maybeChild(this.index());if(!n||!n.is... method sharedDepth (line 8545) | sharedDepth(e){for(let n=this.depth;n>0;n--)if(this.start(n)<=e&&this.... method blockRange (line 8545) | blockRange(e=this,n){if(e.posthis.pos?e:this} method min (line 8545) | min(e){return e.pos=0&&n<=e.content.size))throw new RangeError... method resolveCached (line 8545) | static resolveCached(e,n){let r=_K.get(e);if(r)for(let s=0;se&&this.nodesBetween(e,n,s=>(r.i... method isBlock (line 8545) | get isBlock(){return this.type.isBlock} method isTextblock (line 8545) | get isTextblock(){return this.type.isTextblock} method inlineContent (line 8545) | get inlineContent(){return this.type.inlineContent} method isInline (line 8545) | get isInline(){return this.type.isInline} method isText (line 8545) | get isText(){return this.type.isText} method isLeaf (line 8545) | get isLeaf(){return this.type.isLeaf} method isAtom (line 8545) | get isAtom(){return this.type.isAtom} method toString (line 8545) | toString(){if(this.type.spec.toDebugString)return this.type.spec.toDeb... method contentMatchAt (line 8545) | contentMatchAt(e){let n=this.type.contentMatch.matchFragment(this.cont... method canReplace (line 8545) | canReplace(e,n,r=Vt.empty,i=0,s=r.childCount){let o=this.contentMatchA... method canReplaceWith (line 8545) | canReplaceWith(e,n,r,i){if(i&&!this.type.allowsMarks(i))return!1;let s... method canAppend (line 8545) | canAppend(e){return e.content.size?this.canReplace(this.childCount,thi... method check (line 8545) | check(){this.type.checkContent(this.content),this.type.checkAttrs(this... method toJSON (line 8545) | toJSON(){let e={type:this.type.name};for(let n in this.attrs){e.attrs=... method fromJSON (line 8545) | static fromJSON(e,n){if(!n)throw new RangeError("Invalid input for Nod... class VC (line 8545) | class VC extends Yc{constructor(e,n,r,i){if(super(e,n,null,i),!r)throw n... method constructor (line 8545) | constructor(e,n,r,i){if(super(e,n,null,i),!r)throw new RangeError("Emp... method toString (line 8545) | toString(){return this.type.spec.toDebugString?this.type.spec.toDebugS... method textContent (line 8545) | get textContent(){return this.text} method textBetween (line 8545) | textBetween(e,n){return this.text.slice(e,n)} method nodeSize (line 8545) | get nodeSize(){return this.text.length} method mark (line 8545) | mark(e){return e==this.marks?this:new VC(this.type,this.attrs,this.tex... method withText (line 8545) | withText(e){return e==this.text?this:new VC(this.type,this.attrs,e,thi... method cut (line 8545) | cut(e=0,n=this.text.length){return e==0&&n==this.text.length?this:this... method eq (line 8545) | eq(e){return this.sameMarkup(e)&&this.text==e.text} method toJSON (line 8545) | toJSON(){let e=super.toJSON();return e.text=this.text,e} function wie (line 8545) | function wie(t,e){for(let n=t.length-1;n>=0;n--)e=t[n].type.name+"("+e+"... class jg (line 8545) | class jg{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}s... method constructor (line 8545) | constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]} method parse (line 8545) | static parse(e,n){let r=new PGe(e,n);if(r.next==null)return jg.empty;l... method matchType (line 8545) | matchType(e){for(let n=0;n=this.next.length)throw new RangeError(`There's no ${e}th... method toString (line 8545) | toString(){let e=[];function n(r){e.push(r);for(let i=0;i-1} method whitespace (line 8546) | get whitespace(){return this.spec.whitespace||(this.spec.code?"pre":"nor... method hasRequiredAttrs (line 8546) | hasRequiredAttrs(){for(let e in this.attrs)if(this.attrs[e].isRequired)r... method compatibleContent (line 8546) | compatibleContent(e){return this==e||this.contentMatch.compatible(e.cont... method computeAttrs (line 8546) | computeAttrs(e){return!e&&this.defaultAttrs?this.defaultAttrs:Nie(this.a... method create (line 8546) | create(e=null,n,r){if(this.isText)throw new Error("NodeType.create can't... method createChecked (line 8546) | createChecked(e=null,n,r){return n=Vt.from(n),this.checkContent(n),new Y... method createAndFill (line 8546) | createAndFill(e=null,n,r){if(e=this.computeAttrs(e),n=Vt.from(n),n.size)... method validContent (line 8546) | validContent(e){let n=this.contentMatch.matchFragment(e);if(!n||!n.valid... method checkContent (line 8546) | checkContent(e){if(!this.validContent(e))throw new RangeError(`Invalid c... method checkAttrs (line 8546) | checkAttrs(e){Cie(this.attrs,e,"node",this.name)} method allowsMarkType (line 8546) | allowsMarkType(e){return this.markSet==null||this.markSet.indexOf(e)>-1} method allowsMarks (line 8546) | allowsMarks(e){if(this.markSet==null)return!0;for(let n=0;nr[s]=new ... function LGe (line 8546) | function LGe(t,e,n){let r=n.split("|");return i=>{let s=i===null?"null":... class OGe (line 8546) | class OGe{constructor(e,n,r){this.hasDefault=Object.prototype.hasOwnProp... method constructor (line 8546) | constructor(e,n,r){this.hasDefault=Object.prototype.hasOwnProperty.cal... method isRequired (line 8546) | get isRequired(){return!this.hasDefault} class eA (line 8546) | class eA{constructor(e,n,r,i){this.name=e,this.rank=n,this.schema=r,this... method constructor (line 8546) | constructor(e,n,r,i){this.name=e,this.rank=n,this.schema=r,this.spec=i... method create (line 8546) | create(e=null){return!e&&this.instance?this.instance:new sa(this,Nie(t... method compile (line 8546) | static compile(e,n){let r=Object.create(null),i=0;return e.forEach((s,... method removeFromSet (line 8546) | removeFromSet(e){for(var n=0;n-1} class Aie (line 8546) | class Aie{constructor(e){this.linebreakReplacement=null,this.cached=Obje... method constructor (line 8546) | constructor(e){this.linebreakReplacement=null,this.cached=Object.creat... method node (line 8546) | node(e,n=null,r,i){if(typeof e=="string")e=this.nodeType(e);else if(e ... method text (line 8546) | text(e,n){let r=this.nodes.text;return new VC(r,r.defaultAttrs,e,sa.se... method mark (line 8546) | mark(e,n){return typeof e=="string"&&(e=this.marks[e]),e.create(n)} method nodeType (line 8546) | nodeType(e){let n=this.nodes[e];if(!n)throw new RangeError("Unknown no... function PK (line 8546) | function PK(t,e){let n=[];for(let r=0;r=0;o--){let c=this.... method insertNode (line 8548) | insertNode(e,n,r){if(e.isInline&&this.needsBlock&&!this.top.type){let ... method enter (line 8548) | enter(e,n,r,i){let s=this.findPlace(e.create(n),r,!1);return s&&(s=thi... method enterInner (line 8548) | enterInner(e,n,r,i=!1,s){this.closeExtra();let o=this.top;o.match=o.ma... method closeExtra (line 8548) | closeExtra(e=!1){let n=this.nodes.length-1;if(n>this.open){for(;n>this... method finish (line 8548) | finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0]... method sync (line 8548) | sync(e){for(let n=this.open;n>=0;n--){if(this.nodes[n]==e)return this.... method currentPos (line 8548) | get currentPos(){this.closeExtra();let e=0;for(let n=this.open;n>=0;n-... method findAtPoint (line 8548) | findAtPoint(e,n){if(this.find)for(let r=0;r-1)return e.split(/\s*\|\s*/).some... method textblockFromContext (line 8548) | textblockFromContext(){let e=this.options.context;if(e)for(let n=e.dep... function BGe (line 8548) | function BGe(t){for(let e=t.firstChild,n=null;e;e=e.nextSibling){let r=e... function HGe (line 8548) | function HGe(t,e){return(t.matches||t.msMatchesSelector||t.webkitMatches... function jK (line 8548) | function jK(t){let e={};for(let n in t)e[n]=t[n];return e} function MK (line 8548) | function MK(t,e){let n=e.schema.nodes;for(let r in n){let i=n[r];if(!i.a... class $g (line 8548) | class $g{constructor(e,n){this.nodes=e,this.marks=n}serializeFragment(e,... method constructor (line 8548) | constructor(e,n){this.nodes=e,this.marks=n} method serializeFragment (line 8548) | serializeFragment(e,n={},r){r||(r=WD(n).createDocumentFragment());let ... method serializeNodeInner (line 8548) | serializeNodeInner(e,n){let{dom:r,contentDOM:i}=rN(WD(n),this.nodes[e.... method serializeNode (line 8548) | serializeNode(e,n={}){let r=this.serializeNodeInner(e,n);for(let i=e.m... method serializeMark (line 8548) | serializeMark(e,n,r={}){let i=this.marks[e.type.name];return i&&rN(WD(... method renderSpec (line 8548) | static renderSpec(e,n,r=null,i){return rN(e,n,r,i)} method fromSchema (line 8548) | static fromSchema(e){return e.cached.domSerializer||(e.cached.domSeria... method nodesFromSchema (line 8548) | static nodesFromSchema(e){let n=EK(e.nodes);return n.text||(n.text=r=>... method marksFromSchema (line 8548) | static marksFromSchema(e){return EK(e.marks)} function EK (line 8548) | function EK(t){let e={};for(let n in t){let r=t[n].spec.toDOM;r&&(e[n]=r... function WD (line 8548) | function WD(t){return t.document||window.document} function qGe (line 8548) | function qGe(t){let e=DK.get(t);return e===void 0&&DK.set(t,e=$Ge(t)),e} function $Ge (line 8548) | function $Ge(t){let e=null;function n(r){if(r&&typeof r=="object")if(Arr... function rN (line 8548) | function rN(t,e,n,r){if(typeof e=="string")return{dom:t.createTextNode(e... function VGe (line 8548) | function VGe(t,e){return t+e*Die} function FK (line 8548) | function FK(t){return t&Eie} function GGe (line 8548) | function GGe(t){return(t-(t&Eie))/Die} class TL (line 8548) | class TL{constructor(e,n,r){this.pos=e,this.delInfo=n,this.recover=r}get... method constructor (line 8548) | constructor(e,n,r){this.pos=e,this.delInfo=n,this.recover=r} method deleted (line 8548) | get deleted(){return(this.delInfo&Lie)>0} method deletedBefore (line 8548) | get deletedBefore(){return(this.delInfo&(Fie|aN))>0} method deletedAfter (line 8548) | get deletedAfter(){return(this.delInfo&(Rie|aN))>0} method deletedAcross (line 8548) | get deletedAcross(){return(this.delInfo&aN)>0} class dl (line 8548) | class dl{constructor(e,n=!1){if(this.ranges=e,this.inverted=n,!e.length&... method constructor (line 8548) | constructor(e,n=!1){if(this.ranges=e,this.inverted=n,!e.length&&dl.emp... method recover (line 8548) | recover(e){let n=0,r=FK(e);if(!this.inverted)for(let i=0;ii.m... method invert (line 8548) | invert(){return new Kh(this.from,this.to,this.mark)} method map (line 8548) | map(e){let n=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return... method merge (line 8548) | merge(e){return e instanceof Kc&&e.mark.eq(this.mark)&&this.from<=e.to... method toJSON (line 8548) | toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:thi... method fromJSON (line 8548) | static fromJSON(e,n){if(typeof n.from!="number"||typeof n.to!="number"... class Xh (line 8548) | class Xh extends Ws{constructor(e,n){super(),this.pos=e,this.mark=n}appl... method constructor (line 8548) | constructor(e,n){super(),this.pos=e,this.mark=n} method apply (line 8548) | apply(e){let n=e.nodeAt(this.pos);if(!n)return Si.fail("No node at mar... method invert (line 8548) | invert(e){let n=e.nodeAt(this.pos);if(n){let r=this.mark.addToSet(n.ma... method map (line 8548) | map(e){let n=e.mapResult(this.pos,1);return n.deletedAfter?null:new Xh... method toJSON (line 8548) | toJSON(){return{stepType:"addNodeMark",pos:this.pos,mark:this.mark.toJ... method fromJSON (line 8548) | static fromJSON(e,n){if(typeof n.pos!="number")throw new RangeError("I... class Mg (line 8548) | class Mg extends Ws{constructor(e,n){super(),this.pos=e,this.mark=n}appl... method constructor (line 8548) | constructor(e,n){super(),this.pos=e,this.mark=n} method apply (line 8548) | apply(e){let n=e.nodeAt(this.pos);if(!n)return Si.fail("No node at mar... method invert (line 8548) | invert(e){let n=e.nodeAt(this.pos);return!n||!this.mark.isInSet(n.mark... method map (line 8548) | map(e){let n=e.mapResult(this.pos,1);return n.deletedAfter?null:new Mg... method toJSON (line 8548) | toJSON(){return{stepType:"removeNodeMark",pos:this.pos,mark:this.mark.... method fromJSON (line 8548) | static fromJSON(e,n){if(typeof n.pos!="number")throw new RangeError("I... class Yi (line 8548) | class Yi extends Ws{constructor(e,n,r,i=!1){super(),this.from=e,this.to=... method constructor (line 8548) | constructor(e,n,r,i=!1){super(),this.from=e,this.to=n,this.slice=r,thi... method apply (line 8548) | apply(e){return this.structure&&AL(e,this.from,this.to)?Si.fail("Struc... method getMap (line 8548) | getMap(){return new dl([this.from,this.to-this.from,this.slice.size])} method invert (line 8548) | invert(e){return new Yi(this.from,this.from+this.slice.size,e.slice(th... method map (line 8548) | map(e){let n=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return... method merge (line 8548) | merge(e){if(!(e instanceof Yi)||e.structure||this.structure)return nul... method toJSON (line 8548) | toJSON(){let e={stepType:"replace",from:this.from,to:this.to};return t... method fromJSON (line 8548) | static fromJSON(e,n){if(typeof n.from!="number"||typeof n.to!="number"... class Zi (line 8548) | class Zi extends Ws{constructor(e,n,r,i,s,o,l=!1){super(),this.from=e,th... method constructor (line 8548) | constructor(e,n,r,i,s,o,l=!1){super(),this.from=e,this.to=n,this.gapFr... method apply (line 8548) | apply(e){if(this.structure&&(AL(e,this.from,this.gapFrom)||AL(e,this.g... method getMap (line 8548) | getMap(){return new dl([this.from,this.gapFrom-this.from,this.insert,t... method invert (line 8548) | invert(e){let n=this.gapTo-this.gapFrom;return new Zi(this.from,this.f... method map (line 8548) | map(e){let n=e.mapResult(this.from,1),r=e.mapResult(this.to,-1),i=this... method toJSON (line 8548) | toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gap... method fromJSON (line 8548) | static fromJSON(e,n){if(typeof n.from!="number"||typeof n.to!="number"... function AL (line 8548) | function AL(t,e,n){let r=t.resolve(e),i=n-e,s=r.depth;for(;i>0&&s>0&&r.i... function WGe (line 8548) | function WGe(t,e,n,r){let i=[],s=[],o,l;t.doc.nodesBetween(e,n,(c,d,u)=>... function KGe (line 8548) | function KGe(t,e,n,r){let i=[],s=0;t.doc.nodesBetween(e,n,(o,l)=>{if(!o.... function Nz (line 8548) | function Nz(t,e,n,r=n.contentMatch,i=!0){let s=t.doc.nodeAt(e),o=[],l=e+... function XGe (line 8548) | function XGe(t,e,n){return(e==0||t.canReplace(e,t.childCount))&&(n==t.ch... function zy (line 8548) | function zy(t){let n=t.parent.content.cutByIndex(t.startIndex,t.endIndex... function YGe (line 8548) | function YGe(t,e,n){let{$from:r,$to:i,depth:s}=e,o=r.before(s+1),l=i.aft... function Cz (line 8548) | function Cz(t,e,n=null,r=t){let i=QGe(t,e),s=i&&ZGe(r,e);return s?i.map(... function RK (line 8548) | function RK(t){return{type:t,attrs:null}} function QGe (line 8548) | function QGe(t,e){let{parent:n,startIndex:r,endIndex:i}=t,s=n.contentMat... function ZGe (line 8548) | function ZGe(t,e){let{parent:n,startIndex:r,endIndex:i}=t,s=n.child(r),o... function JGe (line 8548) | function JGe(t,e,n){let r=Vt.empty;for(let o=n.length-1;o>=0;o--){if(r.s... function e9e (line 8548) | function e9e(t,e,n,r,i){if(!r.isTextblock)throw new RangeError("Type giv... function Oie (line 8548) | function Oie(t,e,n,r){e.forEach((i,s)=>{if(i.isText){let o,l=/\r?\n|\r/g... function Iie (line 8548) | function Iie(t,e,n,r){e.forEach((i,s)=>{if(i.type==i.type.schema.linebre... function t9e (line 8549) | function t9e(t,e,n){let r=t.resolve(e),i=r.index();return r.parent.canRe... function n9e (line 8549) | function n9e(t,e,n,r,i){let s=t.doc.nodeAt(e);if(!s)throw new RangeError... function hm (line 8549) | function hm(t,e,n=1,r){let i=t.resolve(e),s=i.depth-n,o=r&&r[r.length-1]... function r9e (line 8549) | function r9e(t,e,n=1,r){let i=t.doc.resolve(e),s=Vt.empty,o=Vt.empty;for... function Fp (line 8549) | function Fp(t,e){let n=t.resolve(e),r=n.index();return zie(n.nodeBefore,... function a9e (line 8549) | function a9e(t,e){e.content.size||t.type.compatibleContent(e.type);let n... function zie (line 8549) | function zie(t,e){return!!(t&&e&&!t.isLeaf&&a9e(t,e))} function tA (line 8549) | function tA(t,e,n=-1){let r=t.resolve(e);for(let i=r.depth;;i--){let s,o... function i9e (line 8549) | function i9e(t,e,n){let r=null,{linebreakReplacement:i}=t.doc.type.schem... function s9e (line 8549) | function s9e(t,e,n){let r=t.resolve(e);if(r.parent.canReplaceWith(r.inde... function Uie (line 8549) | function Uie(t,e,n){let r=t.resolve(e);if(!n.content.size)return e;let i... function nA (line 8549) | function nA(t,e,n=e,r=an.empty){if(e==n&&!r.size)return null;let i=t.res... function Bie (line 8549) | function Bie(t,e,n){return!n.openStart&&!n.openEnd&&t.start()==e.start()... class o9e (line 8549) | class o9e{constructor(e,n,r){this.$from=e,this.$to=n,this.unplaced=r,thi... method constructor (line 8549) | constructor(e,n,r){this.$from=e,this.$to=n,this.unplaced=r,this.fronti... method depth (line 8549) | get depth(){return this.frontier.length-1} method fit (line 8549) | fit(){for(;this.unplaced.size;){let d=this.findFittable();d?this.place... method findFittable (line 8549) | findFittable(){let e=this.unplaced.openStart;for(let n=this.unplaced.c... method openMore (line 8549) | openMore(){let{content:e,openStart:n,openEnd:r}=this.unplaced,i=XD(e,n... method dropNode (line 8549) | dropNode(){let{content:e,openStart:n,openEnd:r}=this.unplaced,i=XD(e,n... method placeNodes (line 8549) | placeNodes({sliceDepth:e,frontierDepth:n,parent:r,inject:i,wrap:s}){fo... method mustMoveInline (line 8549) | mustMoveInline(){if(!this.$to.parent.isTextblock)return-1;let e=this.f... method findCloseLevel (line 8549) | findCloseLevel(e){e:for(let n=Math.min(this.depth,e.depth);n>=0;n--){l... method close (line 8549) | close(e){let n=this.findCloseLevel(e);if(!n)return null;for(;this.dept... method openFrontierNode (line 8549) | openFrontierNode(e,n=null,r){let i=this.frontier[this.depth];i.match=i... method closeFrontierNode (line 8549) | closeFrontierNode(){let n=this.frontier.pop().match.fillBefore(Vt.empt... function v0 (line 8549) | function v0(t,e,n){return e==0?t.cutByIndex(n,t.childCount):t.replaceChi... function w0 (line 8549) | function w0(t,e,n){return e==0?t.append(n):t.replaceChild(t.childCount-1... function XD (line 8549) | function XD(t,e){for(let n=0;n1&&(r=r.re... function YD (line 8549) | function YD(t,e,n,r,i){let s=t.node(e),o=i?t.indexAfter(e):t.index(e);if... function l9e (line 8549) | function l9e(t,e,n){for(let r=n;r=0;... class Ix (line 8549) | class Ix extends Ws{constructor(e,n,r){super(),this.pos=e,this.attr=n,th... method constructor (line 8549) | constructor(e,n,r){super(),this.pos=e,this.attr=n,this.value=r} method apply (line 8549) | apply(e){let n=e.nodeAt(this.pos);if(!n)return Si.fail("No node at att... method getMap (line 8549) | getMap(){return dl.empty} method invert (line 8549) | invert(e){return new Ix(this.pos,this.attr,e.nodeAt(this.pos).attrs[th... method map (line 8549) | map(e){let n=e.mapResult(this.pos,1);return n.deletedAfter?null:new Ix... method toJSON (line 8549) | toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this... method fromJSON (line 8549) | static fromJSON(e,n){if(typeof n.pos!="number"||typeof n.attr!="string... class Ow (line 8549) | class Ow extends Ws{constructor(e,n){super(),this.attr=e,this.value=n}ap... method constructor (line 8549) | constructor(e,n){super(),this.attr=e,this.value=n} method apply (line 8549) | apply(e){let n=Object.create(null);for(let i in e.attrs)n[i]=e.attrs[i... method getMap (line 8549) | getMap(){return dl.empty} method invert (line 8549) | invert(e){return new Ow(this.attr,e.attrs[this.attr])} method map (line 8549) | map(e){return this} method toJSON (line 8549) | toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}} method fromJSON (line 8549) | static fromJSON(e,n){if(typeof n.attr!="string")throw new RangeError("... class Vie (line 8549) | class Vie{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapp... method constructor (line 8549) | constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new Lw} method before (line 8549) | get before(){return this.docs.length?this.docs[0]:this.doc} method step (line 8549) | step(e){let n=this.maybeStep(e);if(n.failed)throw new ly(n.failed);ret... method maybeStep (line 8549) | maybeStep(e){let n=e.apply(this.doc);return n.failed||this.addStep(e,n... method docChanged (line 8549) | get docChanged(){return this.steps.length>0} method changedRange (line 8549) | changedRange(){let e=1e9,n=-1e9;for(let r=0;r0} method setStoredMarks (line 8549) | setStoredMarks(e){return this.storedMarks=e,this.updated|=yk,this} method ensureMarks (line 8549) | ensureMarks(e){return sa.sameSet(this.storedMarks||this.selection.$fro... method addStoredMark (line 8549) | addStoredMark(e){return this.ensureMarks(e.addToSet(this.storedMarks||... method removeStoredMark (line 8549) | removeStoredMark(e){return this.ensureMarks(e.removeFromSet(this.store... method storedMarksSet (line 8549) | get storedMarksSet(){return(this.updated&yk)>0} method addStep (line 8549) | addStep(e,n){super.addStep(e,n),this.updated=this.updated&~yk,this.sto... method setTime (line 8549) | setTime(e){return this.time=e,this} method replaceSelection (line 8549) | replaceSelection(e){return this.selection.replace(this,e),this} method replaceSelectionWith (line 8549) | replaceSelectionWith(e,n=!0){let r=this.selection;return n&&(e=e.mark(... method deleteSelection (line 8549) | deleteSelection(){return this.selection.replace(this),this} method insertText (line 8549) | insertText(e,n,r){let i=this.doc.type.schema;if(n==null)return e?this.... method setMeta (line 8549) | setMeta(e,n){return this.meta[typeof e=="string"?e:e.key]=n,this} method getMeta (line 8549) | getMeta(e){return this.meta[typeof e=="string"?e:e.key]} method isGeneric (line 8549) | get isGeneric(){for(let e in this.meta)return!1;return!0} method scrollIntoView (line 8549) | scrollIntoView(){return this.updated|=UK,this} method scrolledIntoView (line 8549) | get scrolledIntoView(){return(this.updated&UK)>0} function BK (line 8549) | function BK(t,e){return!e||!t?t:t.bind(e)} class S0 (line 8549) | class S0{constructor(e,n,r){this.name=e,this.init=BK(n.init,r),this.appl... method constructor (line 8549) | constructor(e,n,r){this.name=e,this.init=BK(n.init,r),this.apply=BK(n.... method init (line 8549) | init(t){return t.doc||t.schema.topNodeType.createAndFill()} method apply (line 8549) | apply(t){return t.doc} method init (line 8549) | init(t,e){return t.selection||rr.atStart(e.doc)} method apply (line 8549) | apply(t){return t.selection} method init (line 8549) | init(t){return t.storedMarks||null} method apply (line 8549) | apply(t,e,n,r){return r.selection.$cursor?t.storedMarks:null} method init (line 8549) | init(){return 0} method apply (line 8549) | apply(t,e){return t.scrolledIntoView?e+1:e} class ZD (line 8549) | class ZD{constructor(e,n){this.schema=e,this.plugins=[],this.pluginsByKe... method constructor (line 8549) | constructor(e,n){this.schema=e,this.plugins=[],this.pluginsByKey=Objec... class Nx (line 8549) | class Nx{constructor(e){this.config=e}get schema(){return this.config.sc... method constructor (line 8549) | constructor(e){this.config=e} method schema (line 8549) | get schema(){return this.config.schema} method plugins (line 8549) | get plugins(){return this.config.plugins} method apply (line 8549) | apply(e){return this.applyTransaction(e).state} method filterTransaction (line 8549) | filterTransaction(e,n=-1){for(let r=0;r=0... function Zie (line 8549) | function Zie(t,e){let{$cursor:n}=t.selection;return!n||(e?!e.endOfTextbl... function jz (line 8549) | function jz(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0... function Mz (line 8550) | function Mz(t){for(let e=0;e{let{$from:r,$to:i}=e.selection;if(e.select... function C9e (line 8550) | function C9e(t,e,n){let r=e.nodeBefore,i=e.nodeAfter,s=e.index();return!... function ase (line 8550) | function ase(t,e,n,r){let i=e.nodeBefore,s=e.nodeAfter,o,l,c=i.type.spec... function ise (line 8550) | function ise(t){return function(e,n){let r=e.selection,i=t<0?r.$from:r.$... function A9e (line 8550) | function A9e(t,e=null){return function(n,r){let{$from:i,$to:s}=n.selecti... function HK (line 8550) | function HK(t,e=null){return function(n,r){let i=!1;for(let s=0;s=2&&e.$... function E9e (line 8550) | function E9e(t,e,n,r,i){let s=Vt.empty;for(let u=n.length-1;u>=0;u--)s=V... function D9e (line 8550) | function D9e(t){return function(e,n){let{$from:r,$to:i}=e.selection,s=r.... function F9e (line 8550) | function F9e(t,e,n,r){let i=t.tr,s=r.end,o=r.$to.end(r.depth);s=e.left-1&&t.left<=e.right+1&&t.top>=e.to... function Q9e (line 8550) | function Q9e(t,e){let n=t.parentNode;return n&&/^li$/i.test(n.nodeName)&... function Z9e (line 8550) | function Z9e(t,e,n){let{node:r,offset:i}=use(e,n),s=-1;if(r.nodeType==1&... function J9e (line 8550) | function J9e(t,e,n,r){let i=-1;for(let s=e,o=!1;s!=t.dom;){let l=t.docVi... function mse (line 8550) | function mse(t,e,n){let r=t.childNodes.length;if(r&&n.top>1,l=Math.min(o,e.len... method findNodeMatch (line 8551) | findNodeMatch(e,n,r,i){let s=-1,o;if(i>=this.preMatch.index&&(o=this.p... method updateNodeAt (line 8551) | updateNodeAt(e,n,r,i,s){let o=this.top.children[i];return o.dirty==Kd&... method findIndexWithChild (line 8551) | findIndexWithChild(e){for(;;){let n=e.parentNode;if(!n)return-1;if(n==... method updateNextNode (line 8551) | updateNextNode(e,n,r,i,s,o){for(let l=this.index;li(t,e... function rX (line 8551) | function rX(t){return t.editable&&!t.hasFocus()?!1:Sse(t)} function Sse (line 8551) | function Sse(t){let e=t.domSelectionRange();if(!e.anchorNode)return!1;tr... function bWe (line 8551) | function bWe(t){let e=t.docView.domFromPos(t.state.selection.anchor,0),n... function LL (line 8551) | function LL(t,e){let{$anchor:n,$head:r}=t.selection,i=e>0?n.max(r):n.min... function Mh (line 8551) | function Mh(t,e){return t.dispatch(t.state.tr.setSelection(e).scrollInto... function aX (line 8551) | function aX(t,e,n){let r=t.state.selection;if(r instanceof $n)if(n.index... function WC (line 8551) | function WC(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length} function H0 (line 8551) | function H0(t,e){let n=t.pmViewDesc;return n&&n.size==0&&(e<0||t.nextSib... function lx (line 8551) | function lx(t,e){return e<0?xWe(t):yWe(t)} function xWe (line 8551) | function xWe(t){let e=t.domSelectionRange(),n=e.focusNode,r=e.focusOffse... function yWe (line 8551) | function yWe(t){let e=t.domSelectionRange(),n=e.focusNode,r=e.focusOffse... function _se (line 8551) | function _se(t){let e=t.pmViewDesc;return e&&e.node&&e.node.isBlock} function vWe (line 8551) | function vWe(t,e){for(;t&&e==t.childNodes.length&&!OS(t);)e=ys(t)+1,t=t.... function wWe (line 8551) | function wWe(t,e){for(;t&&!e&&!OS(t);)e=ys(t),t=t.parentNode;for(;t&&e;)... function OL (line 8551) | function OL(t,e,n){if(e.nodeType!=3){let s,o;(o=vWe(e,n))?(e=o,n=0):(s=w... function iX (line 8551) | function iX(t,e){let n=t.state.doc.resolve(e);if(!(ks||lse)&&n.parent.in... function sX (line 8551) | function sX(t,e,n){let r=t.state.selection;if(r instanceof $n&&!r.empty|... function oX (line 8551) | function oX(t,e){if(!(t.state.selection instanceof $n))return!0;let{$hea... function lX (line 8551) | function lX(t,e,n){t.domObserver.stop(),e.contentEditable=n,t.domObserve... function SWe (line 8551) | function SWe(t){if(!$s||t.state.selection.$head.parentOffset>0)return!1;... function _We (line 8551) | function _We(t){let e="";return t.ctrlKey&&(e+="c"),t.metaKey&&(e+="m"),... function kWe (line 8551) | function kWe(t,e){let n=e.keyCode,r=_We(e);if(n==8||Gl&&n==72&&r=="c")re... function Lz (line 8551) | function Lz(t,e){t.someProp("transformCopied",f=>{e=f(e,t)});let n=[],{c... function kse (line 8553) | function kse(t,e,n,r,i){let s=i.parent.type.spec.code,o,l;if(!n&&!e)retu... function CWe (line 8554) | function CWe(t,e){if(t.childCount<2)return t;for(let n=e.depth;n>=0;n--)... function Nse (line 8554) | function Nse(t,e,n=0){for(let r=e.length-1;r>=n;r--)t=e[r].create(null,V... function Cse (line 8554) | function Cse(t,e,n,r,i){if(i]*>)*/.exec(t);e&&(t=t.slice(e[0].l... function AWe (line 8554) | function AWe(t){let e=t.querySelectorAll(ks?"span:not([class]):not([styl... function jWe (line 8554) | function jWe(t,e){if(!t.size)return t;let n=t.content.firstChild.type.sc... class EWe (line 8554) | class EWe{constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKe... method constructor (line 8554) | constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKeyCode=nu... function DWe (line 8554) | function DWe(t){for(let e in go){let n=go[e];t.dom.addEventListener(e,t.... function Yh (line 8554) | function Yh(t,e){t.input.lastSelectionOrigin=e,t.input.lastSelectionTime... function FWe (line 8554) | function FWe(t){t.domObserver.stop();for(let e in t.input.eventHandlers)... function zL (line 8554) | function zL(t){t.someProp("handleDOMEvents",e=>{for(let n in e)t.input.e... function Oz (line 8554) | function Oz(t,e){return t.someProp("handleDOMEvents",n=>{let r=n[e.type]... function RWe (line 8554) | function RWe(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;... function LWe (line 8554) | function LWe(t,e){!Oz(t,e)&&go[e.type]&&(t.editable||!(e.type in bo))&&g... function sA (line 8554) | function sA(t){return{left:t.clientX,top:t.clientY}} function OWe (line 8554) | function OWe(t,e){let n=e.x-t.clientX,r=e.y-t.clientY;return n*n+r*r<100} function Iz (line 8554) | function Iz(t,e,n,r,i){if(r==-1)return!1;let s=t.state.doc.resolve(r);fo... function zx (line 8554) | function zx(t,e,n){if(t.focused||t.focus(),t.state.selection.eq(e))retur... function IWe (line 8554) | function IWe(t,e){if(e==-1)return!1;let n=t.state.doc.resolve(e),r=n.nod... function zWe (line 8554) | function zWe(t,e){if(e==-1)return!1;let n=t.state.selection,r,i;n instan... function UWe (line 8554) | function UWe(t,e,n,r,i){return Iz(t,"handleClickOn",e,n,r)||t.someProp("... function BWe (line 8554) | function BWe(t,e,n,r){return Iz(t,"handleDoubleClickOn",e,n,r)||t.somePr... function HWe (line 8554) | function HWe(t,e,n,r){return Iz(t,"handleTripleClickOn",e,n,r)||t.somePr... function qWe (line 8554) | function qWe(t,e,n){if(n.button!=0)return!1;let r=t.state.doc;if(e==-1)r... function zz (line 8554) | function zz(t){return KC(t)} class $We (line 8554) | class $We{constructor(e,n,r,i){this.view=e,this.pos=n,this.event=r,this.... method constructor (line 8554) | constructor(e,n,r,i){this.view=e,this.pos=n,this.event=r,this.flushed=... method done (line 8554) | done(){this.view.root.removeEventListener("mouseup",this.up),this.view... method up (line 8554) | up(e){if(this.done(),!this.view.dom.contains(e.target))return;let n=th... method move (line 8554) | move(e){this.updateAllowDefault(e),Yh(this.view,"pointer"),e.buttons==... method updateAllowDefault (line 8554) | updateAllowDefault(e){!this.allowDefault&&(Math.abs(this.event.x-e.cli... function Mse (line 8554) | function Mse(t,e){return t.composing?!0:$s&&Math.abs(e.timeStamp-t.input... function GWe (line 8554) | function GWe(t){let{focusNode:e,focusOffset:n}=t.domSelectionRange();if(... function Ese (line 8554) | function Ese(t,e){clearTimeout(t.input.composingTimeout),e>-1&&(t.input.... function Dse (line 8554) | function Dse(t){for(t.composing&&(t.input.composing=!1,t.input.compositi... function WWe (line 8554) | function WWe(t){let e=t.domSelectionRange();if(!e.focusNode)return null;... function KWe (line 8554) | function KWe(){let t=document.createEvent("Event");return t.initEvent("e... function KC (line 8554) | function KC(t,e=!1){if(!(am&&t.domObserver.flushingSoon>=0)){if(t.domObs... function XWe (line 8554) | function XWe(t,e){if(!t.dom.parentNode)return;let n=t.dom.parentNode.app... function YWe (line 8554) | function YWe(t){return t.openStart==0&&t.openEnd==0&&t.content.childCoun... function QWe (line 8554) | function QWe(t,e){if(!t.dom.parentNode)return;let n=t.input.shiftKey||t.... function zw (line 8554) | function zw(t,e,n,r,i){let s=kse(t,e,n,r,t.state.selection.$from);if(t.s... function Fse (line 8554) | function Fse(t){let e=t.getData("text/plain")||t.getData("Text");if(e)re... class Rse (line 8554) | class Rse{constructor(e,n,r){this.slice=e,this.move=n,this.node=r}} method constructor (line 8554) | constructor(e,n,r){this.slice=e,this.move=n,this.node=r} function Lse (line 8554) | function Lse(t,e){let n=t.someProp("dragCopies",r=>!r(e));return n??!e[Z... function JWe (line 8554) | function JWe(t,e,n){if(!e.dataTransfer)return;let r=t.posAtCoords(sA(e))... function Uw (line 8554) | function Uw(t,e){if(t==e)return!0;for(let n in t)if(t[n]!==e[n])return!1... class XC (line 8554) | class XC{constructor(e,n){this.toDOM=e,this.spec=n||rg,this.side=this.sp... method constructor (line 8554) | constructor(e,n){this.toDOM=e,this.spec=n||rg,this.side=this.spec.side... method map (line 8554) | map(e,n,r,i){let{pos:s,deleted:o}=e.mapResult(n.from+i,this.side<0?-1:... method valid (line 8554) | valid(){return!0} method eq (line 8554) | eq(e){return this==e||e instanceof XC&&(this.spec.key&&this.spec.key==... method destroy (line 8554) | destroy(e){this.spec.destroy&&this.spec.destroy(e)} class pp (line 8554) | class pp{constructor(e,n){this.attrs=e,this.spec=n||rg}map(e,n,r,i){let ... method constructor (line 8554) | constructor(e,n){this.attrs=e,this.spec=n||rg} method map (line 8554) | map(e,n,r,i){let s=e.map(n.from+i,this.spec.inclusiveStart?-1:1)-r,o=e... method valid (line 8554) | valid(e,n){return n.from{let d=c+r,u;if(u=Ise(n,l,d... method remove (line 8554) | remove(e){return e.length==0||this==Os?this:this.removeInner(e,0)} method removeInner (line 8554) | removeInner(e,n){let r=this.children,i=this.local;for(let s=0;si.map(e,n,rg));return Oh.from(r)} method forChild (line 8554) | forChild(e,n){if(n.isLeaf)return Fa.empty;let r=[];for(let i=0;i{let d=Ise(t,l,c+n);... function ag (line 8554) | function ag(t,e){return t.from-e.from||t.to-e.to} function Bz (line 8554) | function Bz(t){let e=t;for(let n=0;n0;)e++;t.splice(e,0,n)} function r3 (line 8554) | function r3(t){let e=[];return t.someProp("decorations",n=>{let r=n(t.st... class aKe (line 8554) | class aKe{constructor(){this.anchorNode=null,this.anchorOffset=0,this.fo... method constructor (line 8554) | constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=... method set (line 8554) | set(e){this.anchorNode=e.anchorNode,this.anchorOffset=e.anchorOffset,t... method clear (line 8554) | clear(){this.anchorNode=this.focusNode=null} method eq (line 8554) | eq(e){return e.anchorNode==this.anchorNode&&e.anchorOffset==this.ancho... class iKe (line 8554) | class iKe{constructor(e,n){this.view=e,this.handleDOMChange=n,this.queue... method constructor (line 8554) | constructor(e,n){this.view=e,this.handleDOMChange=n,this.queue=[],this... method flushSoon (line 8554) | flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(... method forceFlush (line 8554) | forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingS... method start (line 8554) | start(){this.observer&&(this.observer.takeRecords(),this.observer.obse... method stop (line 8554) | stop(){if(this.observer){let e=this.observer.takeRecords();if(e.length... method connectSelection (line 8554) | connectSelection(){this.view.dom.ownerDocument.addEventListener("selec... method disconnectSelection (line 8554) | disconnectSelection(){this.view.dom.ownerDocument.removeEventListener(... method suppressSelectionUpdates (line 8554) | suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTime... method onSelectionChange (line 8554) | onSelectionChange(){if(rX(this.view)){if(this.suppressingSelectionUpda... method setCurSelection (line 8554) | setCurSelection(){this.currentSelection.set(this.view.domSelectionRang... method ignoreSelectionChange (line 8554) | ignoreSelectionChange(e){if(!e.focusNode)return!0;let n=new Set,r;for(... method pendingRecords (line 8554) | pendingRecords(){if(this.observer)for(let e of this.observer.takeRecor... method flush (line 8554) | flush(){let{view:e}=this;if(!e.docView||this.flushingSoon>-1)return;le... method registerMutation (line 8554) | registerMutation(e,n){if(n.indexOf(e.target)>-1)return null;let r=this... function sKe (line 8554) | function sKe(t){if(!mX.has(t)&&(mX.set(t,null),["normal","nowrap","pre-l... function pX (line 8554) | function pX(t,e){let n=e.startContainer,r=e.startOffset,i=e.endContainer... function oKe (line 8554) | function oKe(t,e){if(e.getComposedRanges){let i=e.getComposedRanges(t.ro... function lKe (line 8554) | function lKe(t,e){for(let n=e.parentNode;n&&n!=t.dom;n=n.parentNode){let... function cKe (line 8554) | function cKe(t,e){var n;let{focusNode:r,focusOffset:i}=t.domSelectionRan... function dKe (line 8554) | function dKe(t,e,n){let{node:r,fromOffset:i,toOffset:s,from:o,to:l}=t.do... function uKe (line 8554) | function uKe(t){let e=t.pmViewDesc;if(e)return e.parseRule();if(t.nodeNa... function hKe (line 8554) | function hKe(t,e,n,r,i){let s=t.input.compositionPendingChanges||(t.comp... function fX (line 8554) | function fX(t,e,n){return Math.max(n.anchor,n.head)>e.content.size?null:... function pKe (line 8554) | function pKe(t,e){let n=t.firstChild.marks,r=e.firstChild.marks,i=n,s=r,... function fKe (line 8554) | function fKe(t,e,n,r,i){if(n-e<=i.pos-r.pos||a3(r,!0,!1)0&&(e||t.index... function gKe (line 8554) | function gKe(t,e,n,r,i){let s=t.findDiffStart(e,n);if(s==null)return nul... function gX (line 8554) | function gX(t){if(t.length!=2)return!1;let e=t.charCodeAt(0),n=t.charCod... class Use (line 8554) | class Use{constructor(e,n){this._root=null,this.focused=!1,this.trackWri... method constructor (line 8554) | constructor(e,n){this._root=null,this.focused=!1,this.trackWrites=null... method composing (line 8554) | get composing(){return this.input.composing} method props (line 8554) | get props(){if(this._props.state!=this.state){let e=this._props;this._... method update (line 8554) | update(e){e.handleDOMEvents!=this._props.handleDOMEvents&&zL(this);let... method setProps (line 8554) | setProps(e){let n={};for(let r in this._props)n[r]=this._props[r];n.st... method updateState (line 8554) | updateState(e){this.updateStateInner(e,this._props)} method updateStateInner (line 8554) | updateStateInner(e,n){var r;let i=this.state,s=!1,o=!1;e.storedMarks&&... method scrollToSelection (line 8554) | scrollToSelection(){let e=this.domSelectionRange().focusNode;if(!(!e||... method destroyPluginViews (line 8554) | destroyPluginViews(){let e;for(;e=this.pluginViews.pop();)e.destroy&&e... method updatePluginViews (line 8554) | updatePluginViews(e){if(!e||e.plugins!=this.state.plugins||this.direct... method updateDraggedNode (line 8554) | updateDraggedNode(e,n){let r=e.node,i=-1;if(this.state.doc.nodeAt(r.fr... method someProp (line 8554) | someProp(e,n){let r=this._props&&this._props[e],i;if(r!=null&&(i=n?n(r... method hasFocus (line 8554) | hasFocus(){if(Ho){let e=this.root.activeElement;if(e==this.dom)return!... method focus (line 8554) | focus(){this.domObserver.stop(),this.editable&&X9e(this.dom),pm(this),... method root (line 8554) | get root(){let e=this._root;if(e==null){for(let n=this.dom.parentNode;... method updateRoot (line 8554) | updateRoot(){this._root=null} method posAtCoords (line 8554) | posAtCoords(e){return eWe(this,e)} method coordsAtPos (line 8554) | coordsAtPos(e,n=1){return hse(this,e,n)} method domAtPos (line 8554) | domAtPos(e,n=0){return this.docView.domFromPos(e,n)} method nodeDOM (line 8554) | nodeDOM(e){let n=this.docView.descAt(e);return n?n.nodeDOM:null} method posAtDOM (line 8554) | posAtDOM(e,n,r=-1){let i=this.docView.posFromDOM(e,n,r);if(i==null)thr... method endOfTextblock (line 8554) | endOfTextblock(e,n){return iWe(this,n||this.state,e)} method pasteHTML (line 8554) | pasteHTML(e,n){return zw(this,"",e,!1,n||new ClipboardEvent("paste"))} method pasteText (line 8554) | pasteText(e,n){return zw(this,e,null,!0,n||new ClipboardEvent("paste"))} method serializeForClipboard (line 8554) | serializeForClipboard(e){return Lz(this,e)} method destroy (line 8554) | destroy(){this.docView&&(FWe(this),this.destroyPluginViews(),this.moun... method isDestroyed (line 8554) | get isDestroyed(){return this.docView==null} method dispatchEvent (line 8554) | dispatchEvent(e){return LWe(this,e)} method domSelectionRange (line 8554) | domSelectionRange(){let e=this.domSelection();return e?$s&&this.root.n... method domSelection (line 8554) | domSelection(){return this.root.getSelection()} function bX (line 8554) | function bX(t){let e=Object.create(null);return e.class="ProseMirror",e.... function xX (line 8554) | function xX(t){if(t.markCursor){let e=document.createElement("img");e.cl... function yX (line 8554) | function yX(t){return!t.someProp("editable",e=>e(t.state)===!1)} function bKe (line 8554) | function bKe(t,e){let n=Math.min(t.$anchor.sharedDepth(t.head),e.$anchor... function vX (line 8554) | function vX(t){let e=Object.create(null);function n(r){for(let i in r)Ob... function xKe (line 8554) | function xKe(t,e){let n=0,r=0;for(let i in t){if(t[i]!=e[i])return!0;n++... function wX (line 8554) | function wX(t){if(t.spec.state||t.spec.filterTransaction||t.spec.appendT... function wKe (line 8554) | function wKe(t){var e=yKe&&t.metaKey&&t.shiftKey&&!t.ctrlKey&&!t.altKey|... function kKe (line 8554) | function kKe(t){let e=t.split(/-(?!$)/),n=e[e.length-1];n=="Space"&&(n="... function NKe (line 8554) | function NKe(t){let e=Object.create(null);for(let n in t)e[kKe(n)]=t[n];... function s3 (line 8554) | function s3(t,e,n=!0){return e.altKey&&(t="Alt-"+t),e.ctrlKey&&(t="Ctrl-... function CKe (line 8554) | function CKe(t){return new Ua({props:{handleKeyDown:Bse(t)}})} function Bse (line 8554) | function Bse(t){let e=NKe(t);return function(n,r){let i=wKe(r),s,o=e[s3(... function oA (line 8554) | function oA(t){const{state:e,transaction:n}=t;let{selection:r}=n,{doc:i}... method constructor (line 8554) | constructor(t){this.editor=t.editor,this.rawCommands=this.editor.extensi... method hasCustomState (line 8554) | get hasCustomState(){return!!this.customState} method state (line 8554) | get state(){return this.customState||this.editor.state} method commands (line 8554) | get commands(){const{rawCommands:t,editor:e,state:n}=this,{view:r}=e,{tr... method chain (line 8554) | get chain(){return()=>this.createChain()} method can (line 8554) | get can(){return()=>this.createCan()} method createChain (line 8554) | createChain(t,e=!0){const{rawCommands:n,editor:r,state:i}=this,{view:s}=... method createCan (line 8554) | createCan(t){const{rawCommands:e,state:n}=this,r=!1,i=t||n.tr,s=this.bui... method buildProps (line 8554) | buildProps(t,e=!0){const{rawCommands:n,editor:r,state:i}=this,{view:s}=r... function Ni (line 8554) | function Ni(t,e){if(typeof t=="string"){if(!e.nodes[t])throw Error(`Ther... function qz (line 8554) | function qz(t){return Object.prototype.toString.call(t)==="[object RegEx... function ZC (line 8554) | function ZC(t,e,n={strict:!0}){const r=Object.keys(e);return r.length?r.... function qse (line 8554) | function qse(t,e,n={}){return t.find(r=>r.type===e&&ZC(Object.fromEntrie... function SX (line 8554) | function SX(t,e,n={}){return!!qse(t,e,n)} function $z (line 8554) | function $z(t,e,n){var r;if(!t||!e)return;let i=t.parent.childAfter(t.pa... function Rm (line 8554) | function Rm(t,e){if(typeof t=="string"){if(!e.marks[t])throw Error(`Ther... function $se (line 8554) | function $se(t){return t instanceof $n} function Gf (line 8554) | function Gf(t=0,e=0,n=0){return Math.min(Math.max(t,e),n)} function Vse (line 8554) | function Vse(t,e=null){if(!e)return null;const n=rr.atStart(t),r=rr.atEn... function _X (line 8554) | function _X(){return navigator.platform==="Android"||/android/i.test(nav... function JC (line 8554) | function JC(){return["iPad Simulator","iPhone Simulator","iPod Simulator... function HKe (line 8554) | function HKe(){return typeof navigator<"u"?/^((?!chrome|android).)*safar... function vk (line 8554) | function vk(t){if(typeof window>"u")throw new Error("[tiptap error]: the... function Bw (line 8554) | function Bw(t,e,n){if(t instanceof Yc||t instanceof Vt)return t;n={slice... function GKe (line 8554) | function GKe(t,e,n){const r=t.steps.length-1;if(r{r.steps.forEac... function xXe (line 8554) | function xXe(t){for(let e=0;e... function vXe (line 8554) | function vXe(t,e){for(let n=t.depth;n>0;n-=1){const r=t.node(n);if(e(r))... function dA (line 8554) | function dA(t){return e=>vXe(e.$from,t)} function Pn (line 8554) | function Pn(t,e,n){return t.config[e]===void 0&&t.parent?Pn(t.parent,e,n... function Vz (line 8554) | function Vz(t){return t.map(e=>{const n={name:e.name,options:e.options,s... function Gz (line 8554) | function Gz(t,e){const n=$g.fromSchema(e).serializeFragment(t),i=documen... function Yse (line 8554) | function Yse(t){return typeof t=="function"} function $r (line 8554) | function $r(t,e=void 0,...n){return Yse(t)?e?t.bind(e)(...n):t(...n):t} function wXe (line 8554) | function wXe(t={}){return Object.keys(t).length===0&&t.constructor===Obj... function my (line 8554) | function my(t){const e=t.filter(i=>i.type==="extension"),n=t.filter(i=>i... function Qse (line 8554) | function Qse(t){const e=[],{nodeExtensions:n,markExtensions:r}=my(t),i=[... function ni (line 8554) | function ni(...t){return t.filter(e=>!!e).reduce((e,n)=>{const r={...e};... function Hw (line 8554) | function Hw(t,e){return e.filter(n=>n.type===t.type.name).filter(n=>n.at... function SXe (line 8554) | function SXe(t){return typeof t!="string"?t:t.match(/^[+-]?(?:\d*\.)?\d+... function NX (line 8554) | function NX(t,e){return"style"in t?t:{...t,getAttrs:n=>{const r=t.getAtt... function CX (line 8554) | function CX(t){return Object.fromEntries(Object.entries(t).filter(([e,n]... function PX (line 8554) | function PX(t){var e,n;const r={};return!((e=t?.attribute)!=null&&e.isRe... function _Xe (line 8554) | function _Xe(t,e){var n;const r=Qse(t),{nodeExtensions:i,markExtensions:... function kXe (line 8554) | function kXe(t){const e=t.filter((n,r)=>t.indexOf(n)!==r);return Array.f... function eP (line 8554) | function eP(t){return t.sort((n,r)=>{const i=Pn(n,"priority")||100,s=Pn(... function Zse (line 8554) | function Zse(t){const e=eP(Vz(t)),n=kXe(e.map(r=>r.name));return n.lengt... function Jse (line 8554) | function Jse(t,e,n){const{from:r,to:i}=e,{blockSeparator:s=` function NXe (line 8556) | function NXe(t,e){const n={from:0,to:t.content.size};return Jse(t,n,e)} function eoe (line 8556) | function eoe(t){return Object.fromEntries(Object.entries(t.nodes).filter... function CXe (line 8556) | function CXe(t,e){const n=Ni(e,t.schema),{from:r,to:i}=t.selection,s=[];... function toe (line 8556) | function toe(t,e){const n=cA(typeof e=="string"?e:e.name,t.schema);retur... function PXe (line 8556) | function PXe(t,e=JSON.stringify){const n={};return t.filter(r=>{const i=... function TXe (line 8556) | function TXe(t){const e=PXe(t);return e.length===1?e:e.filter((n,r)=>!e.... function noe (line 8556) | function noe(t){const{mapping:e,steps:n}=t,r=[];return e.maps.forEach((i... function Wz (line 8556) | function Wz(t,e,n){const r=[];return t===e?n.resolve(t).marks().forEach(... function wk (line 8556) | function wk(t,e){return e.nodes[t]||e.marks[t]||null} function iN (line 8556) | function iN(t,e,n){return Object.fromEntries(Object.entries(n).filter(([... function BL (line 8556) | function BL(t,e,n={}){const{empty:r,ranges:i}=t.selection,s=e?Rm(e,t.sch... function MXe (line 8556) | function MXe(t,e,n={}){if(!e)return Np(t,null,n)||BL(t,null,n);const r=c... function TX (line 8556) | function TX(t,e){return Array.isArray(e)?e.some(n=>(typeof n=="string"?n... function AX (line 8556) | function AX(t,e){const{nodeExtensions:n}=my(e),r=n.find(o=>o.name===t);i... function uA (line 8556) | function uA(t,{checkChildren:e=!0,ignoreWhitespace:n=!1}={}){var r;if(n)... function roe (line 8556) | function roe(t){return t instanceof An} method constructor (line 8556) | constructor(e){this.position=e} method fromJSON (line 8556) | static fromJSON(e){return new ioe(e.position)} method toJSON (line 8556) | toJSON(){return{position:this.position}} function FXe (line 8556) | function FXe(t,e){const n=e.mapping.mapResult(t.position);return{positio... function RXe (line 8556) | function RXe(t){return new aoe(t)} function LXe (line 8556) | function LXe(t,e,n){var r;const{selection:i}=e;let s=null;if($se(i)&&(s=... function jX (line 8556) | function jX(t,e){const n=t.storedMarks||t.selection.$to.parentOffset&&t.... method constructor (line 8556) | constructor(){this.callbacks={}} method on (line 8556) | on(t,e){return this.callbacks[t]||(this.callbacks[t]=[]),this.callbacks[... method emit (line 8556) | emit(t,...e){const n=this.callbacks[t];return n&&n.forEach(r=>r.apply(th... method off (line 8556) | off(t,e){const n=this.callbacks[t];return n&&(e?this.callbacks[t]=n.filt... method once (line 8556) | once(t,e){const n=(...r)=>{this.off(t,n),e.apply(this,r)};return this.on... method removeAllListeners (line 8556) | removeAllListeners(){this.callbacks={}} method constructor (line 8556) | constructor(t){var e;this.find=t.find,this.handler=t.handler,this.undoab... function Sk (line 8556) | function Sk(t){var e;const{editor:n,from:r,to:i,text:s,rules:o,plugin:l}... function iYe (line 8556) | function iYe(t){const{editor:e,rules:n}=t,r=new Ua({state:{init(){return... function sYe (line 8557) | function sYe(t){return Object.prototype.toString.call(t).slice(8,-1)} function _k (line 8557) | function _k(t){return sYe(t)!=="Object"?!1:t.constructor===Object&&Objec... function soe (line 8557) | function soe(t,e){const n={...t};return _k(t)&&_k(e)&&Object.keys(e).for... method constructor (line 8557) | constructor(t={}){this.type="extendable",this.parent=null,this.child=nul... method options (line 8557) | get options(){return{...$r(Pn(this,"addOptions",{name:this.name}))||{}}} method storage (line 8557) | get storage(){return{...$r(Pn(this,"addStorage",{name:this.name,options:... method configure (line 8557) | configure(t={}){const e=this.extend({...this.config,addOptions:()=>soe(t... method extend (line 8557) | extend(t={}){const e=new this.constructor({...this.config,...t});return ... method constructor (line 8557) | constructor(){super(...arguments),this.type="mark"} method create (line 8557) | static create(e={}){const n=typeof e=="function"?e():e;return new ooe(n)} method handleExit (line 8557) | static handleExit({editor:e,mark:n}){const{tr:r}=e.state,i=e.state.selec... method configure (line 8557) | configure(e){return super.configure(e)} method extend (line 8557) | extend(e){const n=typeof e=="function"?e():e;return super.extend(n)} function oYe (line 8557) | function oYe(t){return typeof t=="number"} method constructor (line 8557) | constructor(t){this.find=t.find,this.handler=t.handler} function dYe (line 8557) | function dYe(t){const{editor:e,state:n,from:r,to:i,rule:s,pasteEvent:o,d... function mYe (line 8557) | function mYe(t){const{editor:e,rules:n}=t;let r=null,i=!1,s=!1,o=typeof ... method constructor (line 8557) | constructor(t,e){this.splittableMarks=[],this.editor=e,this.baseExtensio... method commands (line 8557) | get commands(){return this.extensions.reduce((t,e)=>{const n={name:e.nam... method plugins (line 8557) | get plugins(){const{editor:t}=this;return eP([...this.extensions].revers... method attributes (line 8557) | get attributes(){return Qse(this.extensions)} method nodeViews (line 8557) | get nodeViews(){const{editor:t}=this,{nodeExtensions:e}=my(this.extensio... method dispatchTransaction (line 8557) | dispatchTransaction(t){const{editor:e}=this;return eP([...this.extension... method markViews (line 8557) | get markViews(){const{editor:t}=this,{markExtensions:e}=my(this.extensio... method setupExtensions (line 8557) | setupExtensions(){const t=this.extensions;this.editor.extensionStorage=O... method constructor (line 8557) | constructor(){super(...arguments),this.type="extension"} method create (line 8557) | static create(e={}){const n=typeof e=="function"?e():e;return new loe(n)} method configure (line 8557) | configure(e){return super.configure(e)} method extend (line 8557) | extend(e){const n=typeof e=="function"?e():e;return super.extend(n)} method addOptions (line 8557) | addOptions(){return{blockSeparator:void 0}} method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("clipboardTextSerializ... method addCommands (line 8557) | addCommands(){return{...Hse}} method onUpdate (line 8557) | onUpdate({transaction:t,appendedTransactions:e}){var n,r,i;const s=()=>{... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("tiptapDrop"),props:{h... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("editable"),props:{edi... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){const{editor:t}=this;return[new Ua({key:poe,prop... method addKeyboardShortcuts (line 8557) | addKeyboardShortcuts(){const t=()=>this.editor.commands.first(({commands... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("clearDocument"),appen... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("tiptapPaste"),props:{... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("tabindex"),props:{att... method addOptions (line 8557) | addOptions(){return{direction:void 0}} method addGlobalAttributes (line 8557) | addGlobalAttributes(){if(!this.options.direction)return[];const{nodeExte... method addProseMirrorPlugins (line 8557) | addProseMirrorPlugins(){return[new Ua({key:new zi("textDirection"),props... method constructor (line 8557) | constructor(e,n,r=!1,i=null){this.currentNode=null,this.actualDepth=null... method name (line 8557) | get name(){return this.node.type.name} method node (line 8557) | get node(){return this.currentNode||this.resolvedPos.node()} method element (line 8557) | get element(){return this.editor.view.domAtPos(this.pos).node} method depth (line 8557) | get depth(){var e;return(e=this.actualDepth)!=null?e:this.resolvedPos.de... method pos (line 8557) | get pos(){return this.resolvedPos.pos} method content (line 8557) | get content(){return this.node.content} method content (line 8557) | set content(e){let n=this.from,r=this.to;if(this.isBlock){if(this.conten... method attributes (line 8557) | get attributes(){return this.node.attrs} method textContent (line 8557) | get textContent(){return this.node.textContent} method size (line 8557) | get size(){return this.node.nodeSize} method from (line 8557) | get from(){return this.isBlock?this.pos:this.resolvedPos.start(this.reso... method range (line 8557) | get range(){return{from:this.from,to:this.to}} method to (line 8557) | get to(){return this.isBlock?this.pos+this.size:this.resolvedPos.end(thi... method parent (line 8557) | get parent(){if(this.depth===0)return null;const e=this.resolvedPos.star... method before (line 8557) | get before(){let e=this.resolvedPos.doc.resolve(this.from-(this.isBlock?... method after (line 8557) | get after(){let e=this.resolvedPos.doc.resolve(this.to+(this.isBlock?2:1... method children (line 8557) | get children(){const e=[];return this.node.content.forEach((n,r)=>{const... method firstChild (line 8557) | get firstChild(){return this.children[0]||null} method lastChild (line 8557) | get lastChild(){const e=this.children;return e[e.length-1]||null} method closest (line 8557) | closest(e,n={}){let r=null,i=this.parent;for(;i&&!r;){if(i.node.type.nam... method querySelector (line 8557) | querySelector(e,n={}){return this.querySelectorAll(e,n,!0)[0]||null} method querySelectorAll (line 8557) | querySelectorAll(e,n={},r=!1){let i=[];if(!this.children||this.children.... method setAttribute (line 8557) | setAttribute(e){const{tr:n}=this.editor.state;n.setNodeMarkup(this.from,... function gYe (line 8627) | function gYe(t,e,n){const r=document.querySelector("style[data-tiptap-st... method constructor (line 8627) | constructor(t={}){super(),this.css=null,this.className="tiptap",this.edi... method mount (line 8627) | mount(t){if(typeof document>"u")throw new Error("[tiptap error]: The edi... method unmount (line 8627) | unmount(){if(this.editorView){const t=this.editorView.dom;t?.editor&&del... method storage (line 8627) | get storage(){return this.extensionStorage} method commands (line 8627) | get commands(){return this.commandManager.commands} method chain (line 8627) | chain(){return this.commandManager.chain()} method can (line 8627) | can(){return this.commandManager.can()} method injectCSS (line 8627) | injectCSS(){this.options.injectCSS&&typeof document<"u"&&(this.css=gYe(f... method setOptions (line 8627) | setOptions(t={}){this.options={...this.options,...t},!(!this.editorView|... method setEditable (line 8627) | setEditable(t,e=!0){this.setOptions({editable:t}),e&&this.emit("update",... method isEditable (line 8627) | get isEditable(){return this.options.editable&&this.view&&this.view.edit... method view (line 8627) | get view(){return this.editorView?this.editorView:new Proxy({state:this.... method state (line 8627) | get state(){return this.editorView&&(this.editorState=this.view.state),t... method registerPlugin (line 8627) | registerPlugin(t,e){const n=Yse(e)?e(t,[...this.state.plugins]):[...this... method unregisterPlugin (line 8627) | unregisterPlugin(t){if(this.isDestroyed)return;const e=this.state.plugin... method createExtensionManager (line 8627) | createExtensionManager(){var t,e;const r=[...this.options.enableCoreExte... method createCommandManager (line 8627) | createCommandManager(){this.commandManager=new lA({editor:this})} method createSchema (line 8627) | createSchema(){this.schema=this.extensionManager.schema} method createDoc (line 8627) | createDoc(){let t;try{t=UL(this.options.content,this.schema,this.options... method createView (line 8627) | createView(t){const{editorProps:e,enableExtensionDispatchTransaction:n}=... method createNodeViews (line 8627) | createNodeViews(){this.view.isDestroyed||this.view.setProps({markViews:t... method prependClass (line 8627) | prependClass(){this.view.dom.className=`${this.className} ${this.view.do... method captureTransaction (line 8627) | captureTransaction(t){this.isCapturingTransaction=!0,t(),this.isCapturin... method dispatchTransaction (line 8627) | dispatchTransaction(t){if(this.view.isDestroyed)return;if(this.isCapturi... method getAttributes (line 8627) | getAttributes(t){return toe(this.state,t)} method isActive (line 8627) | isActive(t,e){const n=typeof t=="string"?t:null,r=typeof t=="string"?e:t... method getJSON (line 8627) | getJSON(){return this.state.doc.toJSON()} method getHTML (line 8627) | getHTML(){return Gz(this.state.doc.content,this.schema)} method getText (line 8627) | getText(t){const{blockSeparator:e=` method isEmpty (line 8629) | get isEmpty(){return uA(this.state.doc)} method destroy (line 8629) | destroy(){this.emit("destroy"),this.unmount(),this.removeAllListeners()} method isDestroyed (line 8629) | get isDestroyed(){var t,e;return(e=(t=this.editorView)==null?void 0:t.is... method $node (line 8629) | $node(t,e){var n;return((n=this.$doc)==null?void 0:n.querySelector(t,e))... method $nodes (line 8629) | $nodes(t,e){var n;return((n=this.$doc)==null?void 0:n.querySelectorAll(t... method $pos (line 8629) | $pos(t){const e=this.state.doc.resolve(t);return new pYe(e,this)} method $doc (line 8629) | get $doc(){return this.$pos(0)} function hy (line 8629) | function hy(t){return new mA({find:t.find,handler:({state:e,range:n,matc... function voe (line 8629) | function voe(t){return new mA({find:t.find,handler:({state:e,range:n,mat... function HL (line 8629) | function HL(t){return new mA({find:t.find,handler:({state:e,range:n,matc... function py (line 8629) | function py(t){return new mA({find:t.find,handler:({state:e,range:n,matc... method constructor (line 8629) | constructor(t){this.directions=["bottom-left","bottom-right","top-left",... method dom (line 8629) | get dom(){return this.container} method contentDOM (line 8629) | get contentDOM(){var t;return(t=this.contentElement)!=null?t:null} method handleEditorUpdate (line 8629) | handleEditorUpdate(){const t=this.editor.isEditable;t!==this.lastEditabl... method update (line 8629) | update(t,e,n){return t.type!==this.node.type?!1:(this.node=t,this.onUpda... method destroy (line 8629) | destroy(){this.isResizing&&(this.container.dataset.resizeState="false",t... method createContainer (line 8629) | createContainer(){const t=document.createElement("div");return t.dataset... method createWrapper (line 8629) | createWrapper(){const t=document.createElement("div");return t.style.pos... method createHandle (line 8629) | createHandle(t){const e=document.createElement("div");return e.dataset.r... method positionHandle (line 8629) | positionHandle(t,e){const n=e.includes("top"),r=e.includes("bottom"),i=e... method attachHandles (line 8629) | attachHandles(){this.directions.forEach(t=>{let e;this.createCustomHandl... method removeHandles (line 8629) | removeHandles(){this.handleMap.forEach(t=>t.remove()),this.handleMap.cle... method applyInitialSize (line 8629) | applyInitialSize(){const t=this.node.attrs.width,e=this.node.attrs.heigh... method handleResizeStart (line 8629) | handleResizeStart(t,e){t.preventDefault(),t.stopPropagation(),this.isRes... method handleResize (line 8629) | handleResize(t,e){if(!this.activeHandle)return;const n=this.preserveAspe... method calculateNewDimensions (line 8629) | calculateNewDimensions(t,e,n){let r=this.startWidth,i=this.startHeight;c... method applyConstraints (line 8629) | applyConstraints(t,e,n){var r,i,s,o;if(!n){let d=Math.max(this.minSize.w... method applyAspectRatio (line 8629) | applyAspectRatio(t,e,n){const r=n==="left"||n==="right",i=n==="top"||n==... function vYe (line 8629) | function vYe(t,e){const{selection:n}=t,{$from:r}=n;if(n instanceof An){c... function Xz (line 8629) | function Xz(t){if(!t?.trim())return{};const e={},n=[],r=t.replace(/["'](... function Yz (line 8629) | function Yz(t){if(!t||Object.keys(t).length===0)return"";const e=[];retu... function SYe (line 8629) | function SYe(t){const{nodeName:e,name:n,parseAttributes:r=Xz,serializeAt... function _Ye (line 8629) | function _Ye(t){const{nodeName:e,name:n,getContent:r,parseAttributes:i=X... function kYe (line 8635) | function kYe(t){if(!t.trim())return{};const e={},n=/(\w+)=(?:"([^"]*)"|'... function NYe (line 8635) | function NYe(t){return Object.entries(t).filter(([,e])=>e!=null).map(([e... function CYe (line 8635) | function CYe(t){const{nodeName:e,name:n,getContent:r,parseAttributes:i=k... function qL (line 8635) | function qL(t,e,n){var r,i,s,o;const l=t.split(` function Qz (line 8641) | function Qz(t,e,n,r){if(!t||!Array.isArray(t.content))return"";const i=t... function PYe (line 8644) | function PYe(t,e,n={}){const{state:r}=e,{doc:i,tr:s}=r,o=t;i.descendants... method constructor (line 8644) | constructor(){super(...arguments),this.type="node"} method create (line 8644) | static create(e={}){const n=typeof e=="function"?e():e;return new woe(n)} method configure (line 8644) | configure(e){return super.configure(e)} method extend (line 8644) | extend(e){const n=typeof e=="function"?e():e;return super.extend(n)} function Fg (line 8644) | function Fg(t){return new lYe({find:t.find,handler:({state:e,range:n,mat... function c3 (line 8644) | function c3(t,e){return function(r,i,s){return t(r,i,s)&&e(r,i,s)}} function Nk (line 8644) | function Nk(t){return function(n,r,i){if(!n||!r||typeof n!="object"||typ... function MYe (line 8644) | function MYe(t){return t?.[Symbol.toStringTag]} function MX (line 8644) | function MX(t){return TYe(t).concat(AYe(t))} function Vg (line 8644) | function Vg(t,e){return t===e||!t&&!e&&t!==t&&e!==e} function LYe (line 8644) | function LYe(t,e){return t.byteLength===e.byteLength&&tP(new Uint8Array(... function OYe (line 8644) | function OYe(t,e,n){let r=t.length;if(e.length!==r)return!1;for(;r-- >0;... function IYe (line 8644) | function IYe(t,e){return t.byteLength===e.byteLength&&tP(new Uint8Array(... function zYe (line 8644) | function zYe(t,e){return Vg(t.getTime(),e.getTime())} function UYe (line 8644) | function UYe(t,e){return t.name===e.name&&t.message===e.message&&t.cause... function BYe (line 8644) | function BYe(t,e){return t===e} function FX (line 8644) | function FX(t,e,n){const r=t.size;if(r!==e.size)return!1;if(!r)return!0;... function qYe (line 8644) | function qYe(t,e,n){const r=DX(t);let i=r.length;if(DX(e).length!==i)ret... function o0 (line 8644) | function o0(t,e,n){const r=MX(t);let i=r.length;if(MX(e).length!==i)retu... function $Ye (line 8644) | function $Ye(t,e){return Vg(t.valueOf(),e.valueOf())} function VYe (line 8644) | function VYe(t,e){return t.source===e.source&&t.flags===e.flags} function RX (line 8644) | function RX(t,e,n){const r=t.size;if(r!==e.size)return!1;if(!r)return!0;... function tP (line 8644) | function tP(t,e){let n=t.byteLength;if(e.byteLength!==n||t.byteOffset!==... function GYe (line 8644) | function GYe(t,e){return t.hostname===e.hostname&&t.pathname===e.pathnam... function Soe (line 8644) | function Soe(t,e,n,r){return(r===RYe||r===FYe||r===DYe)&&(t.$$typeof||e.... function lQe (line 8644) | function lQe({areArrayBuffersEqual:t,areArraysEqual:e,areDataViewsEqual:... function cQe (line 8644) | function cQe({circular:t,createCustomConfig:e,strict:n}){let r={areArray... function dQe (line 8644) | function dQe(t){return function(e,n,r,i,s,o,l){return t(e,n,l)}} function uQe (line 8644) | function uQe({circular:t,comparator:e,createState:n,equals:r,strict:i}){... function Op (line 8644) | function Op(t={}){const{circular:e=!1,createInternalComparator:n,createS... function fQe (line 8644) | function fQe(){const t=new Set;let e={};return{subscribe(n){return t.add... method constructor (line 8644) | constructor(t){var e;super(t),this.editorContentRef=ia.createRef(),this.... method componentDidMount (line 8644) | componentDidMount(){this.init()} method componentDidUpdate (line 8644) | componentDidUpdate(){this.init()} method init (line 8644) | init(){var t;const e=this.props.editor;if(e&&!e.isDestroyed&&((t=e.view.... method componentWillUnmount (line 8644) | componentWillUnmount(){var t;const e=this.props.editor;if(e){this.initia... method render (line 8644) | render(){const{editor:t,innerRef:e,...n}=this.props;return a.jsxs(a.Frag... method constructor (line 8644) | constructor(t){this.transactionNumber=0,this.lastTransactionNumber=0,thi... method getSnapshot (line 8644) | getSnapshot(){return this.transactionNumber===this.lastTransactionNumber... method getServerSnapshot (line 8644) | getServerSnapshot(){return{editor:null,transactionNumber:0}} method subscribe (line 8644) | subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete... method watch (line 8644) | watch(t){if(this.editor=t,this.editor){const e=()=>{this.transactionNumb... function vQe (line 8644) | function vQe(t){var e;const[n]=w.useState(()=>new yQe(t.editor)),r=pee.u... method constructor (line 8644) | constructor(e){this.editor=null,this.subscriptions=new Set,this.isCompon... method setEditor (line 8644) | setEditor(e){this.editor=e,this.instanceId=Math.random().toString(36).sl... method getInitialEditor (line 8644) | getInitialEditor(){return this.options.current.immediatelyRender===void ... method createEditor (line 8644) | createEditor(){const e={...this.options.current,onBeforeCreate:(...r)=>{... method getEditor (line 8644) | getEditor(){return this.editor} method getServerSnapshot (line 8644) | getServerSnapshot(){return null} method subscribe (line 8644) | subscribe(e){return this.subscriptions.add(e),()=>{this.subscriptions.de... method compareOptions (line 8644) | static compareOptions(e,n){return Object.keys(e).every(r=>["onCreate","o... method onRender (line 8644) | onRender(e){return()=>(this.isComponentMounted=!0,clearTimeout(this.sche... method refreshEditorInstance (line 8644) | refreshEditorInstance(e){if(this.editor&&!this.editor.isDestroyed){if(th... method scheduleDestroy (line 8644) | scheduleDestroy(){const e=this.instanceId,n=this.editor;this.scheduledDe... function kQe (line 8644) | function kQe(t={},e=[]){const n=w.useRef(t);n.current=t;const[r]=w.useSt... method editor (line 8644) | get editor(){throw new Error("useTiptap must be used within a p... function Coe (line 8644) | function Coe({editor:t,instance:e,children:n}){const r=t??e;if(!r)throw ... function Poe (line 8644) | function Poe({...t}){const{editor:e}=PQe();return a.jsx(_oe,{editor:e,..... method addOptions (line 8644) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8644) | parseHTML(){return[{tag:"blockquote"}]} method renderHTML (line 8644) | renderHTML({HTMLAttributes:t}){return nP("blockquote",{...ni(this.option... method addCommands (line 8648) | addCommands(){return{setBlockquote:()=>({commands:t})=>t.wrapIn(this.nam... method addKeyboardShortcuts (line 8648) | addKeyboardShortcuts(){return{"Mod-Shift-b":()=>this.editor.commands.tog... method addInputRules (line 8648) | addInputRules(){return[py({find:TQe,type:this.type})]} method addOptions (line 8648) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8648) | parseHTML(){return[{tag:"strong"},{tag:"b",getAttrs:t=>t.style.fontWeigh... method renderHTML (line 8648) | renderHTML({HTMLAttributes:t}){return nP("strong",{...ni(this.options.HT... method addCommands (line 8648) | addCommands(){return{setBold:()=>({commands:t})=>t.setMark(this.name),to... method addKeyboardShortcuts (line 8648) | addKeyboardShortcuts(){return{"Mod-b":()=>this.editor.commands.toggleBol... method addInputRules (line 8648) | addInputRules(){return[hy({find:jQe,type:this.type}),hy({find:EQe,type:t... method addPasteRules (line 8648) | addPasteRules(){return[Fg({find:MQe,type:this.type}),Fg({find:DQe,type:t... method addOptions (line 8648) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8648) | parseHTML(){return[{tag:"code"}]} method renderHTML (line 8648) | renderHTML({HTMLAttributes:t}){return["code",ni(this.options.HTMLAttribu... method addCommands (line 8648) | addCommands(){return{setCode:()=>({commands:t})=>t.setMark(this.name),to... method addKeyboardShortcuts (line 8648) | addKeyboardShortcuts(){return{"Mod-e":()=>this.editor.commands.toggleCod... method addInputRules (line 8648) | addInputRules(){return[hy({find:RQe,type:this.type})]} method addPasteRules (line 8648) | addPasteRules(){return[Fg({find:LQe,type:this.type})]} method addOptions (line 8648) | addOptions(){return{languageClassPrefix:"language-",exitOnTripleEnter:!0... method addAttributes (line 8648) | addAttributes(){return{language:{default:this.options.defaultLanguage,pa... method parseHTML (line 8648) | parseHTML(){return[{tag:"pre",preserveWhitespace:"full"}]} method renderHTML (line 8648) | renderHTML({node:t,HTMLAttributes:e}){return["pre",ni(this.options.HTMLA... method addCommands (line 8651) | addCommands(){return{setCodeBlock:t=>({commands:e})=>e.setNode(this.name... method addKeyboardShortcuts (line 8651) | addKeyboardShortcuts(){return{"Mod-Alt-c":()=>this.editor.commands.toggl... method addInputRules (line 8664) | addInputRules(){return[HL({find:IQe,type:this.type,getAttributes:t=>({la... method addProseMirrorPlugins (line 8664) | addProseMirrorPlugins(){return[new Ua({key:new zi("codeBlockVSCodeHandle... method addOptions (line 8667) | addOptions(){return{keepMarks:!0,HTMLAttributes:{}}} method parseHTML (line 8667) | parseHTML(){return[{tag:"br"}]} method renderHTML (line 8667) | renderHTML({HTMLAttributes:t}){return["br",ni(this.options.HTMLAttribute... method renderText (line 8667) | renderText(){return` method addCommands (line 8669) | addCommands(){return{setHardBreak:()=>({commands:t,chain:e,state:n,edito... method addKeyboardShortcuts (line 8669) | addKeyboardShortcuts(){return{"Mod-Enter":()=>this.editor.commands.setHa... method addOptions (line 8669) | addOptions(){return{levels:[1,2,3,4,5,6],HTMLAttributes:{}}} method addAttributes (line 8669) | addAttributes(){return{level:{default:1,rendered:!1}}} method parseHTML (line 8669) | parseHTML(){return this.options.levels.map(t=>({tag:`h${t}`,attrs:{level... method renderHTML (line 8669) | renderHTML({node:t,HTMLAttributes:e}){return[`h${this.options.levels.inc... method addCommands (line 8669) | addCommands(){return{setHeading:t=>({commands:e})=>this.options.levels.i... method addKeyboardShortcuts (line 8669) | addKeyboardShortcuts(){return this.options.levels.reduce((t,e)=>({...t,[... method addInputRules (line 8669) | addInputRules(){return this.options.levels.map(t=>HL({find:new RegExp(`^... method addOptions (line 8669) | addOptions(){return{HTMLAttributes:{},nextNodeType:"paragraph"}} method parseHTML (line 8669) | parseHTML(){return[{tag:"hr"}]} method renderHTML (line 8669) | renderHTML({HTMLAttributes:t}){return["hr",ni(this.options.HTMLAttribute... method addCommands (line 8669) | addCommands(){return{setHorizontalRule:()=>({chain:t,state:e})=>{if(!vYe... method addInputRules (line 8669) | addInputRules(){return[voe({find:/^(?:---|—-|___\s|\*\*\*\s)$/,type:this... method addOptions (line 8669) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8669) | parseHTML(){return[{tag:"em"},{tag:"i",getAttrs:t=>t.style.fontStyle!=="... method renderHTML (line 8669) | renderHTML({HTMLAttributes:t}){return["em",ni(this.options.HTMLAttribute... method addCommands (line 8669) | addCommands(){return{setItalic:()=>({commands:t})=>t.setMark(this.name),... method addKeyboardShortcuts (line 8669) | addKeyboardShortcuts(){return{"Mod-i":()=>this.editor.commands.toggleIta... method addInputRules (line 8669) | addInputRules(){return[hy({find:VQe,type:this.type}),hy({find:WQe,type:t... method addPasteRules (line 8669) | addPasteRules(){return[Fg({find:GQe,type:this.type}),Fg({find:KQe,type:t... function eZe (line 8669) | function eZe(t,e){return t in e||(e[t]=[]),e[t]} function Wf (line 8669) | function Wf(t,e,n){e[VL]&&(e[q0]=!0,e[k0]=!0),e[GL]&&(e[q0]=!0,e[WL]=!0)... function tZe (line 8669) | function tZe(t,e){const n={};for(const r in e)e[r].indexOf(t)>=0&&(n[r]=... function Ro (line 8669) | function Ro(t=null){this.j={},this.jr=[],this.jd=null,this.t=t} method accepts (line 8669) | accepts(){return!!this.t} method go (line 8669) | go(t){const e=this,n=e.j[t];if(n)return n;for(let r=0;rl.toLowerCase())),r=... function iZe (line 8670) | function iZe(t){const e=[],n=t.length;let r=0;for(;r=2&&t[0].t!==qw&&t[1].t===Ih} function oZe (line 8670) | function oZe({groups:t}){const e=t.domain.concat([bP,yP,Eh,vP,wP,SP,_P,k... function lZe (line 8670) | function lZe(t,e,n){let r=n.length,i=0,s=[],o=[];for(;i{const e=t.getAttribute("h... method renderHTML (line 8673) | renderHTML({HTMLAttributes:t}){return this.options.isAllowedUri(t.href,{... method addCommands (line 8673) | addCommands(){return{setLink:t=>({chain:e})=>{const{href:n}=t;return thi... method addPasteRules (line 8673) | addPasteRules(){return[Fg({find:t=>{const e=[];if(t){const{protocols:n,d... method addProseMirrorPlugins (line 8673) | addProseMirrorPlugins(){const t=[],{protocols:e,defaultProtocol:n}=this.... method addOptions (line 8673) | addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:... method content (line 8673) | content(){return`${this.options.itemTypeName}+`} method parseHTML (line 8673) | parseHTML(){return[{tag:"ul"}]} method renderHTML (line 8673) | renderHTML({HTMLAttributes:t}){return["ul",ni(this.options.HTMLAttribute... method addCommands (line 8674) | addCommands(){return{toggleBulletList:()=>({commands:t,chain:e})=>this.o... method addKeyboardShortcuts (line 8674) | addKeyboardShortcuts(){return{"Mod-Shift-8":()=>this.editor.commands.tog... method addInputRules (line 8674) | addInputRules(){let t=py({find:$X,type:this.type});return(this.options.k... method addOptions (line 8674) | addOptions(){return{HTMLAttributes:{},bulletListTypeName:"bulletList",or... method parseHTML (line 8674) | parseHTML(){return[{tag:"li"}]} method renderHTML (line 8674) | renderHTML({HTMLAttributes:t}){return["li",ni(this.options.HTMLAttribute... method addKeyboardShortcuts (line 8674) | addKeyboardShortcuts(){return{Enter:()=>this.editor.commands.splitListIt... method addOptions (line 8674) | addOptions(){return{listTypes:[{itemName:"listItem",wrapperNames:["bulle... method addKeyboardShortcuts (line 8674) | addKeyboardShortcuts(){return{Delete:({editor:t})=>{let e=!1;return this... function PZe (line 8674) | function PZe(t){const e=[];let n=0,r=0;for(;n{if(n.type!=="list_item")return e.pars... method addOptions (line 8680) | addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:... method content (line 8680) | content(){return`${this.options.itemTypeName}+`} method addAttributes (line 8680) | addAttributes(){return{start:{default:1,parseHTML:t=>t.hasAttribute("sta... method parseHTML (line 8680) | parseHTML(){return[{tag:"ol"}]} method renderHTML (line 8680) | renderHTML({HTMLAttributes:t}){const{start:e,...n}=t;return e===1?["ol",... method addCommands (line 8683) | addCommands(){return{toggleOrderedList:()=>({commands:t,chain:e})=>this.... method addKeyboardShortcuts (line 8683) | addKeyboardShortcuts(){return{"Mod-Shift-7":()=>this.editor.commands.tog... method addInputRules (line 8683) | addInputRules(){let t=py({find:WX,type:this.type,getAttributes:e=>({star... method addOptions (line 8683) | addOptions(){return{nested:!1,HTMLAttributes:{},taskListTypeName:"taskLi... method content (line 8683) | content(){return this.options.nested?"paragraph block*":"paragraph+"} method addAttributes (line 8683) | addAttributes(){return{checked:{default:!1,keepOnSplit:!1,parseHTML:t=>{... method parseHTML (line 8683) | parseHTML(){return[{tag:`li[data-type="${this.name}"]`,priority:51}]} method renderHTML (line 8683) | renderHTML({node:t,HTMLAttributes:e}){return["li",ni(this.options.HTMLAt... method addKeyboardShortcuts (line 8683) | addKeyboardShortcuts(){const t={Enter:()=>this.editor.commands.splitList... method addNodeView (line 8683) | addNodeView(){return({node:t,HTMLAttributes:e,getPos:n,editor:r})=>{cons... method addInputRules (line 8683) | addInputRules(){return[py({find:jZe,type:this.type,getAttributes:t=>({ch... method addOptions (line 8683) | addOptions(){return{itemTypeName:"taskItem",HTMLAttributes:{}}} method content (line 8683) | content(){return`${this.options.itemTypeName}+`} method parseHTML (line 8683) | parseHTML(){return[{tag:`ul[data-type="${this.name}"]`,priority:51}]} method renderHTML (line 8683) | renderHTML({HTMLAttributes:t}){return["ul",ni(this.options.HTMLAttribute... method start (line 8684) | start(t){var e;const n=(e=t.match(/^\s*[-+*]\s+\[([ xX])\]\s+/))==null?v... method tokenize (line 8684) | tokenize(t,e,n){const r=s=>{const o=qL(s,{itemPattern:/^(\s*)([-+*])\s+\... method addCommands (line 8684) | addCommands(){return{toggleTaskList:()=>({commands:t})=>t.toggleList(thi... method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-Shift-9":()=>this.editor.commands.tog... method addExtensions (line 8684) | addExtensions(){const t=[];return this.options.bulletList!==!1&&t.push(I... method addOptions (line 8684) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8684) | parseHTML(){return[{tag:"p"}]} method renderHTML (line 8684) | renderHTML({HTMLAttributes:t}){return["p",ni(this.options.HTMLAttributes... method addCommands (line 8684) | addCommands(){return{setParagraph:()=>({commands:t})=>t.setNode(this.nam... method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setPa... method addOptions (line 8684) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8684) | parseHTML(){return[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-dec... method renderHTML (line 8684) | renderHTML({HTMLAttributes:t}){return["s",ni(this.options.HTMLAttributes... method addCommands (line 8684) | addCommands(){return{setStrike:()=>({commands:t})=>t.setMark(this.name),... method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-Shift-s":()=>this.editor.commands.tog... method addInputRules (line 8684) | addInputRules(){return[hy({find:RZe,type:this.type})]} method addPasteRules (line 8684) | addPasteRules(){return[Fg({find:LZe,type:this.type})]} method addOptions (line 8684) | addOptions(){return{HTMLAttributes:{}}} method parseHTML (line 8684) | parseHTML(){return[{tag:"u"},{style:"text-decoration",consuming:!1,getAt... method renderHTML (line 8684) | renderHTML({HTMLAttributes:t}){return["u",ni(this.options.HTMLAttributes... method parseMarkdown (line 8684) | parseMarkdown(t,e){return e.applyMark(this.name||"underline",e.parseInli... method renderMarkdown (line 8684) | renderMarkdown(t,e){return`++${e.renderChildren(t)}++`} method start (line 8684) | start(t){return t.indexOf("++")} method tokenize (line 8684) | tokenize(t,e,n){const i=/^(\+\+)([\s\S]+?)(\+\+)/.exec(t);if(!i)return;c... method addCommands (line 8684) | addCommands(){return{setUnderline:()=>({commands:t})=>t.setMark(this.nam... method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-u":()=>this.editor.commands.toggleUnd... function UZe (line 8684) | function UZe(t={}){return new Ua({view(e){return new BZe(e,t)}})} class BZe (line 8684) | class BZe{constructor(e,n){var r;this.editorView=e,this.cursorPos=null,t... method constructor (line 8684) | constructor(e,n){var r;this.editorView=e,this.cursorPos=null,this.elem... method destroy (line 8684) | destroy(){this.handlers.forEach(({name:e,handler:n})=>this.editorView.... method update (line 8684) | update(e,n){this.cursorPos!=null&&n.doc!=e.state.doc&&(this.cursorPos>... method setCursor (line 8684) | setCursor(e){e!=this.cursorPos&&(this.cursorPos=e,e==null?(this.elemen... method updateOverlay (line 8684) | updateOverlay(){let e=this.editorView.state.doc.resolve(this.cursorPos... method scheduleRemoval (line 8684) | scheduleRemoval(e){clearTimeout(this.timeout),this.timeout=setTimeout(... method dragover (line 8684) | dragover(e){if(!this.editorView.editable)return;let n=this.editorView.... method dragend (line 8684) | dragend(){this.scheduleRemoval(20)} method drop (line 8684) | drop(){this.scheduleRemoval(20)} method dragleave (line 8684) | dragleave(e){this.editorView.dom.contains(e.relatedTarget)||this.setCu... class Ya (line 8684) | class Ya extends rr{constructor(e){super(e,e)}map(e,n){let r=e.resolve(n... method constructor (line 8684) | constructor(e){super(e,e)} method map (line 8684) | map(e,n){let r=e.resolve(n.map(this.head));return Ya.valid(r)?new Ya(r... method content (line 8684) | content(){return an.empty} method eq (line 8684) | eq(e){return e instanceof Ya&&e.head==this.head} method toJSON (line 8684) | toJSON(){return{type:"gapcursor",pos:this.head}} method fromJSON (line 8684) | static fromJSON(e,n){if(typeof n.pos!="number")throw new RangeError("I... method getBookmark (line 8684) | getBookmark(){return new c5(this.anchor)} method valid (line 8684) | static valid(e){let n=e.parent;if(n.isTextblock||!HZe(e)||!qZe(e))retu... method findGapCursorFrom (line 8684) | static findGapCursorFrom(e,n,r=!1){e:for(;;){if(!r&&Ya.valid(e))return... class c5 (line 8684) | class c5{constructor(e){this.pos=e}map(e){return new c5(e.map(this.pos))... method constructor (line 8684) | constructor(e){this.pos=e} method map (line 8684) | map(e){return new c5(e.map(this.pos))} method resolve (line 8684) | resolve(e){let n=e.resolve(this.pos);return Ya.valid(n)?new Ya(n):rr.n... function Xoe (line 8684) | function Xoe(t){return t.isAtom||t.spec.isolating||t.spec.createGapCursor} function HZe (line 8684) | function HZe(t){for(let e=t.depth;e>=0;e--){let n=t.index(e),r=t.node(e)... function qZe (line 8684) | function qZe(t){for(let e=t.depth;e>=0;e--){let n=t.indexAfter(e),r=t.no... function $Ze (line 8684) | function $Ze(){return new Ua({props:{decorations:KZe,createSelectionBetw... function Ak (line 8684) | function Ak(t,e){const n=t=="vert"?e>0?"down":"up":e>0?"right":"left";re... function GZe (line 8684) | function GZe(t,e,n){if(!t||!t.editable)return!1;let r=t.state.doc.resolv... function WZe (line 8684) | function WZe(t,e){if(e.inputType!="insertCompositionText"||!(t.state.sel... function KZe (line 8684) | function KZe(t){if(!(t.selection instanceof Ya))return null;let e=docume... function e (line 8684) | function e(r){t.call(this),this.values=r} function e (line 8684) | function e(n,r){t.call(this),this.left=n,this.right=r,this.length=n.leng... class $c (line 8684) | class $c{constructor(e,n){this.items=e,this.eventCount=n}popEvent(e,n){i... method constructor (line 8684) | constructor(e,n){this.items=e,this.eventCount=n} method popEvent (line 8684) | popEvent(e,n){if(this.eventCount==0)return null;let r=this.items.lengt... method addTransform (line 8684) | addTransform(e,n,r,i){let s=[],o=this.eventCount,l=this.items,c=!i&&l.... method remapping (line 8684) | remapping(e,n){let r=new Lw;return this.items.forEach((i,s)=>{let o=i.... method addMaps (line 8684) | addMaps(e){return this.eventCount==0?this:new $c(this.items.append(e.m... method rebased (line 8684) | rebased(e,n){if(!this.eventCount)return this;let r=[],i=Math.max(0,thi... method emptyItemCount (line 8684) | emptyItemCount(){let e=0;return this.items.forEach(n=>{n.step||e++}),e} method compress (line 8684) | compress(e=this.items.length){let n=this.remapping(0,e),r=n.maps.lengt... function QZe (line 8684) | function QZe(t,e){let n;return t.forEach((r,i)=>{if(r.selection&&e--==0)... class _d (line 8684) | class _d{constructor(e,n,r,i){this.map=e,this.step=n,this.selection=r,th... method constructor (line 8684) | constructor(e,n,r,i){this.map=e,this.step=n,this.selection=r,this.mirr... method merge (line 8684) | merge(e){if(this.step&&e.step&&!e.selection){let n=e.step.merge(this.s... class Dh (line 8684) | class Dh{constructor(e,n,r,i,s){this.done=e,this.undone=n,this.prevRange... method constructor (line 8684) | constructor(e,n,r,i,s){this.done=e,this.undone=n,this.prevRanges=r,thi... function JZe (line 8684) | function JZe(t,e,n,r){let i=n.getMeta(ig),s;if(i)return i.historyState;n... function eJe (line 8684) | function eJe(t,e){if(!e)return!1;if(!t.docChanged)return!0;let n=!1;retu... function XX (line 8684) | function XX(t){let e=[];for(let n=t.length-1;n>=0&&e.length==0;n--)t[n].... function b3 (line 8684) | function b3(t,e){if(!t)return null;let n=[];for(let r=0;r{let i=ig.getState(n);if(!i||(t?i.undone:... method addOptions (line 8684) | addOptions(){return{limit:null,mode:"textSize",textCounter:t=>t.length,w... method addStorage (line 8684) | addStorage(){return{characters:()=>0,words:()=>0}} method onBeforeCreate (line 8684) | onBeforeCreate(){this.storage.characters=t=>{const e=t?.node||this.edito... method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){let t=!1;return[new Ua({key:new zi("characterCou... method addOptions (line 8684) | addOptions(){return{color:"currentColor",width:1,class:void 0}} method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){return[UZe(this.options)]} method addOptions (line 8684) | addOptions(){return{className:"has-focus",mode:"all"}} method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){return[new Ua({key:new zi("focus"),props:{decora... method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){return[$Ze()]} method extendNodeSchema (line 8684) | extendNodeSchema(t){var e;const n={name:t.name,options:t.options,storage... function sJe (line 8684) | function sJe(t){return t.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9-]/g,""... method addOptions (line 8684) | addOptions(){return{emptyEditorClass:"is-editor-empty",emptyNodeClass:"i... method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){const t=this.options.dataAttribute?`data-${sJe(t... method addOptions (line 8684) | addOptions(){return{className:"selection"}} method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){const{editor:t,options:e}=this;return[new Ua({ke... function ZX (line 8684) | function ZX({types:t,node:e}){return e&&Array.isArray(t)&&t.includes(e.t... method addOptions (line 8684) | addOptions(){return{node:void 0,notAfter:[]}} method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){var t;const e=new zi(this.name),n=this.options.n... method addOptions (line 8684) | addOptions(){return{depth:100,newGroupDelay:500}} method addCommands (line 8684) | addCommands(){return{undo:()=>({state:t,dispatch:e})=>Zoe(t,e),redo:()=>... method addProseMirrorPlugins (line 8684) | addProseMirrorPlugins(){return[rJe(this.options)]} method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-z":()=>this.editor.commands.undo(),"S... method addExtensions (line 8684) | addExtensions(){var t,e,n,r;const i=[];return this.options.bold!==!1&&i.... method addOptions (line 8684) | addOptions(){return{types:[],alignments:["left","center","right","justif... method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{textA... method addCommands (line 8684) | addCommands(){return{setTextAlign:t=>({commands:e})=>this.options.alignm... method addKeyboardShortcuts (line 8684) | addKeyboardShortcuts(){return{"Mod-Shift-l":()=>this.editor.commands.set... method addOptions (line 8684) | addOptions(){return{HTMLAttributes:{},mergeNestedSpanStyles:!0}} method parseHTML (line 8684) | parseHTML(){return[{tag:"span",consuming:!1,getAttrs:t=>t.hasAttribute("... method renderHTML (line 8684) | renderHTML({HTMLAttributes:t}){return["span",ni(this.options.HTMLAttribu... method addCommands (line 8684) | addCommands(){return{toggleTextStyle:t=>({commands:e})=>e.toggleMark(thi... method addOptions (line 8684) | addOptions(){return{types:["textStyle"]}} method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{backg... method addCommands (line 8684) | addCommands(){return{setBackgroundColor:t=>({chain:e})=>e().setMark("tex... method addOptions (line 8684) | addOptions(){return{types:["textStyle"]}} method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{color... method addCommands (line 8684) | addCommands(){return{setColor:t=>({chain:e})=>e().setMark("textStyle",{c... method addOptions (line 8684) | addOptions(){return{types:["textStyle"]}} method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{fontF... method addCommands (line 8684) | addCommands(){return{setFontFamily:t=>({chain:e})=>e().setMark("textStyl... method addOptions (line 8684) | addOptions(){return{types:["textStyle"]}} method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{fontS... method addCommands (line 8684) | addCommands(){return{setFontSize:t=>({chain:e})=>e().setMark("textStyle"... method addOptions (line 8684) | addOptions(){return{types:["textStyle"]}} method addGlobalAttributes (line 8684) | addGlobalAttributes(){return[{types:this.options.types,attributes:{lineH... method addCommands (line 8684) | addCommands(){return{setLineHeight:t=>({chain:e})=>e().setMark("textStyl... method addExtensions (line 8684) | addExtensions(){const t=[];return this.options.backgroundColor!==!1&&t.p... method addOptions (line 8684) | addOptions(){return{inline:!1,allowBase64:!1,HTMLAttributes:{},resize:!1}} method inline (line 8684) | inline(){return this.options.inline} method group (line 8684) | group(){return this.options.inline?"inline":"block"} method addAttributes (line 8684) | addAttributes(){return{src:{default:null},alt:{default:null},title:{defa... method parseHTML (line 8684) | parseHTML(){return[{tag:this.options.allowBase64?"img[src]":'img[src]:no... method renderHTML (line 8684) | renderHTML({HTMLAttributes:t}){return["img",ni(this.options.HTMLAttribut... method addNodeView (line 8684) | addNodeView(){if(!this.options.resize||!this.options.resize.enabled||typ... method addCommands (line 8684) | addCommands(){return{setImage:t=>({commands:e})=>e.insertContent({type:t... method addInputRules (line 8684) | addInputRules(){return[voe({find:vJe,type:this.type,getAttributes:t=>{co... function tO (line 8684) | function tO({content:t,onChange:e,placeholder:n}){const{t:r}=Ft(),i=kQe(... function rle (line 8684) | function rle({archiveId:t,archiveName:e,onClose:n}){const r=nn(),[i,s]=w... function kJe (line 8684) | function kJe({archiveId:t,timelapseSrc:e,onClose:n,onSave:r}){const{show... function ale (line 8689) | function ale({src:t,title:e,downloadFilename:n,archiveId:r,onClose:i,onE... function CJe (line 8692) | function CJe({archiveIds:t,onClose:e}){w.useEffect(()=>{const s=o=>{o.ke... function PJe (line 8692) | function PJe({comparison:t}){return a.jsxs("div",{className:"space-y-6",... function TJe (line 8692) | function TJe(t){const e=new Date(t),r=new Date().getTime()-e.getTime(),i... function AJe (line 8692) | function AJe({upload:t,projects:e,onArchive:n,onDiscard:r,isArchiving:i,... function jJe (line 8692) | function jJe(){const t=nn(),{showToast:e}=hn(),[n,r]=w.useState(!1),[i,s... function MJe (line 8692) | function MJe({onClose:t}){const e=nn(),{showToast:n}=hn(),[r,i]=w.useSta... function zh (line 8692) | function zh(t){const e=t.filename;if(e){const n=e.toLowerCase();if(n.end... function ile (line 8692) | function ile(t){if(!t)return;const e=t.toLowerCase();return e.endsWith("... function Uh (line 8692) | async function Uh(t,e,n,r){try{if(n==="source"){const{token:i}=await ue.... function EJe (line 8692) | function EJe({archive:t,printerName:e,isSelected:n,onSelect:r,selectionM... function DJe (line 8694) | function DJe({archive:t,printerName:e,isSelected:n,onSelect:r,selectionM... function RJe (line 8694) | function RJe(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r,... function JX (line 8694) | function JX({pageIndex:t,pageSize:e,totalRows:n,totalPages:r,onPageChang... function LJe (line 8694) | function LJe(){for(var t=arguments.length,e=new Array(t),n=0;n{e.current=t}),w.useCal... function OJe (line 8694) | function OJe(){const t=w.useRef(null),e=w.useCallback((r,i)=>{t.current=... function Vw (line 8694) | function Vw(t,e){e===void 0&&(e=[t]);const n=w.useRef(t);return Xd(()=>{... function HS (line 8694) | function HS(t,e){const n=w.useRef();return w.useMemo(()=>{const r=t(n.cu... function MP (line 8694) | function MP(t){const e=m5(t),n=w.useRef(null),r=w.useCallback(i=>{i!==n.... function nO (line 8694) | function nO(t){const e=w.useRef();return w.useEffect(()=>{e.current=t},[... function qS (line 8694) | function qS(t,e){return w.useMemo(()=>{if(e)return e;const n=y3[t]==null... function ole (line 8694) | function ole(t){return function(e){for(var n=arguments.length,r=new Arra... function IJe (line 8694) | function IJe(t){return"clientX"in t&&"clientY"in t} function h5 (line 8694) | function h5(t){if(!t)return!1;const{KeyboardEvent:e}=Go(t.target);return... function zJe (line 8694) | function zJe(t){if(!t)return!1;const{TouchEvent:e}=Go(t.target);return e... function rO (line 8694) | function rO(t){if(zJe(t)){if(t.touches&&t.touches.length){const{clientX:... method toString (line 8694) | toString(t){if(!t)return;const{x:e,y:n}=t;return"translate3d("+(e?Math.r... method toString (line 8694) | toString(t){if(!t)return;const{scaleX:e,scaleY:n}=t;return"scaleX("+e+")... method toString (line 8694) | toString(t){if(t)return[fy.Translate.toString(t),fy.Scale.toString(t)].j... method toString (line 8694) | toString(t){let{property:e,duration:n,easing:r}=t;return e+" "+n+"ms "+r} function UJe (line 8694) | function UJe(t){return t.matches(eY)?t:t.querySelector(eY)} function HJe (line 8694) | function HJe(t){let{id:e,value:n}=t;return ia.createElement("div",{id:e,... function qJe (line 8694) | function qJe(t){let{id:e,announcement:n,ariaLiveType:r="assertive"}=t;co... function $Je (line 8694) | function $Je(){const[t,e]=w.useState("");return{announce:w.useCallback(r... function VJe (line 8694) | function VJe(t){const e=w.useContext(lle);w.useEffect(()=>{if(!e)throw n... function GJe (line 8694) | function GJe(){const[t]=w.useState(()=>new Set),e=w.useCallback(r=>(t.ad... method onDragStart (line 8698) | onDragStart(t){let{active:e}=t;return"Picked up draggable item "+e.id+"."} method onDragOver (line 8698) | onDragOver(t){let{active:e,over:n}=t;return n?"Draggable item "+e.id+" w... method onDragEnd (line 8698) | onDragEnd(t){let{active:e,over:n}=t;return n?"Draggable item "+e.id+" wa... method onDragCancel (line 8698) | onDragCancel(t){let{active:e}=t;return"Dragging was cancelled. Draggable... function XJe (line 8698) | function XJe(t){let{announcements:e=KJe,container:n,hiddenTextDescribedB... function EP (line 8698) | function EP(){} function DP (line 8698) | function DP(t,e){return w.useMemo(()=>({sensor:t,options:e??{}}),[t,e])} function cle (line 8698) | function cle(){for(var t=arguments.length,e=new Array(t),n=0;n=e||!i)re... function fle (line 8698) | function fle(t){const[e]=gA(t,1);return e??null} function v3 (line 8698) | function v3(t){return!fA||!t?null:Uy(t)?t:d5(t)?u5(t)||t===By(t).scrolli... function gle (line 8698) | function gle(t){return Uy(t)?t.scrollX:t.scrollLeft} function ble (line 8698) | function ble(t){return Uy(t)?t.scrollY:t.scrollTop} function aO (line 8698) | function aO(t){return{x:gle(t),y:ble(t)}} function xle (line 8698) | function xle(t){return!fA||!t?!1:t===document.scrollingElement} function yle (line 8698) | function yle(t){const e={x:0,y:0},n=xle(t)?{height:window.innerHeight,wi... function uet (line 8698) | function uet(t,e,n,r,i){let{top:s,left:o,right:l,bottom:c}=n;r===void 0&... function met (line 8698) | function met(t){if(t===document.scrollingElement){const{innerWidth:s,inn... function vle (line 8698) | function vle(t){return t.reduce((e,n)=>Ux(e,aO(n)),ed)} function het (line 8698) | function het(t){return t.reduce((e,n)=>e+gle(n),0)} function pet (line 8698) | function pet(t){return t.reduce((e,n)=>e+ble(n),0)} function fet (line 8698) | function fet(t,e){if(e===void 0&&(e=Hy),!t)return;const{top:n,left:r,bot... class p5 (line 8698) | class p5{constructor(e,n){this.rect=void 0,this.width=void 0,this.height... method constructor (line 8698) | constructor(e,n){this.rect=void 0,this.width=void 0,this.height=void 0... class X0 (line 8698) | class X0{constructor(e){this.target=void 0,this.listeners=[],this.remove... method constructor (line 8698) | constructor(e){this.target=void 0,this.listeners=[],this.removeAll=()=... method add (line 8698) | add(e,n,r){var i;(i=this.target)==null||i.addEventListener(e,n,r),this... function bet (line 8698) | function bet(t){const{EventTarget:e}=Go(t);return t instanceof e?t:By(t)} function w3 (line 8698) | function w3(t,e){const n=Math.abs(t.x),r=Math.abs(t.y);return typeof e==... function aY (line 8698) | function aY(t){t.preventDefault()} function xet (line 8698) | function xet(t){t.stopPropagation()} class bA (line 8698) | class bA{constructor(e){this.props=void 0,this.autoScrollEnabled=!1,this... method constructor (line 8698) | constructor(e){this.props=void 0,this.autoScrollEnabled=!1,this.refere... method attach (line 8698) | attach(){this.handleStart(),this.windowListeners.add(Wl.Resize,this.ha... method handleStart (line 8698) | handleStart(){const{activeNode:e,onStart:n}=this.props,r=e.node.curren... method handleKeyDown (line 8698) | handleKeyDown(e){if(h5(e)){const{active:n,context:r,options:i}=this.pr... method handleMove (line 8698) | handleMove(e,n){const{onMove:r}=this.props;e.preventDefault(),r(n)} method handleEnd (line 8698) | handleEnd(e){const{onEnd:n}=this.props;e.preventDefault(),this.detach(... method handleCancel (line 8698) | handleCancel(e){const{onCancel:n}=this.props;e.preventDefault(),this.d... method detach (line 8698) | detach(){this.listeners.removeAll(),this.windowListeners.removeAll()} function iY (line 8698) | function iY(t){return!!(t&&"distance"in t)} function sY (line 8698) | function sY(t){return!!(t&&"delay"in t)} class f5 (line 8698) | class f5{constructor(e,n,r){var i;r===void 0&&(r=bet(e.event.target)),th... method constructor (line 8698) | constructor(e,n,r){var i;r===void 0&&(r=bet(e.event.target)),this.prop... method attach (line 8698) | attach(){const{events:e,props:{options:{activationConstraint:n,bypassA... method detach (line 8698) | detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),s... method handlePending (line 8698) | handlePending(e,n){const{active:r,onPending:i}=this.props;i(r,e,this.i... method handleStart (line 8698) | handleStart(){const{initialCoordinates:e}=this,{onStart:n}=this.props;... method handleMove (line 8698) | handleMove(e){var n;const{activated:r,initialCoordinates:i,props:s}=th... method handleEnd (line 8698) | handleEnd(){const{onAbort:e,onEnd:n}=this.props;this.detach(),this.act... method handleCancel (line 8698) | handleCancel(){const{onAbort:e,onCancel:n}=this.props;this.detach(),th... method handleKeydown (line 8698) | handleKeydown(e){e.code===wr.Esc&&this.handleCancel()} method removeTextSelection (line 8698) | removeTextSelection(){var e;(e=this.document.getSelection())==null||e.... class xA (line 8698) | class xA extends f5{constructor(e){const{event:n}=e,r=By(n.target);super... method constructor (line 8698) | constructor(e){const{event:n}=e,r=By(n.target);super(e,vet,r)} class _et (line 8698) | class _et extends f5{constructor(e){super(e,wet,By(e.event.target))}} method constructor (line 8698) | constructor(e){super(e,wet,By(e.event.target))} class ket (line 8698) | class ket extends f5{constructor(e){super(e,S3)}static setup(){return wi... method constructor (line 8698) | constructor(e){super(e,S3)} method setup (line 8698) | static setup(){return window.addEventListener(S3.move.name,e,{capture:... function Net (line 8698) | function Net(t){let{acceleration:e,activator:n=Y0.Pointer,canScroll:r,dr... function Pet (line 8698) | function Pet(t){let{delta:e,disabled:n}=t;const r=nO(e);return HS(i=>{if... function Tet (line 8698) | function Tet(t,e){const n=e!=null?t.get(e):void 0,r=n?n.node.current:nul... function Aet (line 8698) | function Aet(t,e){return w.useMemo(()=>t.reduce((n,r)=>{const{sensor:i}=... function jet (line 8698) | function jet(t,e){let{dragging:n,dependencies:r,config:i}=e;const[s,o]=w... function Sle (line 8698) | function Sle(t,e){return HS(n=>t?n||(typeof e=="function"?e(t):t):null,[... function Met (line 8698) | function Met(t,e){return Sle(t,e)} function Eet (line 8698) | function Eet(t){let{callback:e,disabled:n}=t;const r=m5(e),i=w.useMemo((... function yA (line 8698) | function yA(t){let{callback:e,disabled:n}=t;const r=m5(e),i=w.useMemo(()... function Det (line 8698) | function Det(t){return new p5(Hy(t),t)} function lY (line 8698) | function lY(t,e,n){e===void 0&&(e=Det);const[r,i]=w.useState(null);funct... function Fet (line 8698) | function Fet(t){const e=Sle(t);return ple(t,e)} function Ret (line 8698) | function Ret(t){const e=w.useRef(t),n=HS(r=>t?r&&r!==cY&&t&&e.current&&t... function Let (line 8698) | function Let(t){const[e,n]=w.useState(null),r=w.useRef(t),i=w.useCallbac... function dY (line 8698) | function dY(t,e){e===void 0&&(e=[]);const n=w.useRef(null);return w.useE... function Oet (line 8698) | function Oet(t){w.useEffect(()=>{if(!fA)return;const e=t.map(n=>{let{sen... function Iet (line 8698) | function Iet(t,e){return w.useMemo(()=>t.reduce((n,r)=>{let{eventName:i,... function _le (line 8698) | function _le(t){return w.useMemo(()=>t?set(t):null,[t])} function zet (line 8698) | function zet(t,e){e===void 0&&(e=Hy);const[n]=t,r=_le(n?Go(n):null),[i,s... function Uet (line 8698) | function Uet(t){if(!t)return null;if(t.children.length>1)return t;const ... function Bet (line 8698) | function Bet(t){let{measure:e}=t;const[n,r]=w.useState(null),i=w.useCall... class Q0 (line 8698) | class Q0 extends Map{get(e){var n;return e!=null&&(n=super.get(e))!=null... method get (line 8698) | get(e){var n;return e!=null&&(n=super.get(e))!=null?n:void 0} method toArray (line 8698) | toArray(){return Array.from(this.values())} method getEnabled (line 8698) | getEnabled(){return this.toArray().filter(e=>{let{disabled:n}=e;return... method getNodeFor (line 8698) | getNodeFor(e){var n,r;return(n=(r=this.get(e))==null?void 0:r.node.cur... function Get (line 8698) | function Get(){return{draggable:{active:null,initialCoordinates:{x:0,y:0... function Wet (line 8698) | function Wet(t,e){switch(e.type){case ji.DragStart:return{...t,draggable... function Ket (line 8698) | function Ket(t){let{disabled:e}=t;const{active:n,activatorEvent:r,dragga... function Xet (line 8698) | function Xet(t,e){let{transform:n,...r}=e;return t!=null&&t.length?t.red... function Yet (line 8698) | function Yet(t){return w.useMemo(()=>({draggable:{...lN.draggable,...t?.... function Qet (line 8698) | function Qet(t){let{activeNode:e,measure:n,initialRect:r,config:i=!0}=t;... method onAbort (line 8698) | onAbort(gt){if(!F.get(gt))return;const{onDragAbort:Wt}=fe.current,Zt={id... method onPending (line 8698) | onPending(gt,Ut,Wt,Zt){if(!F.get(gt))return;const{onDragPending:Xt}=fe.c... method onStart (line 8698) | onStart(gt){const Ut=L.current;if(Ut==null)return;const Wt=F.get(Ut);if(... method onMove (line 8698) | onMove(gt){g({type:ji.DragMove,coordinates:gt})} function xt (line 8698) | function xt(gt){return async function(){const{active:Wt,collisions:Zt,ov... function we (line 8698) | function we(){const Ve=te?.autoScrollEnabled===!1,Ae=typeof c=="object"?... function ett (line 8698) | function ett(t){let{id:e,data:n,disabled:r=!1,attributes:i}=t;const s=qS... function ttt (line 8698) | function ttt(){return w.useContext(kle)} function att (line 8698) | function att(t){let{data:e,disabled:n=!1,id:r,resizeObserverConfig:i}=t;... function wA (line 8698) | function wA(t,e,n){const r=t.slice();return r.splice(n<0?r.length+n:n,0,... function itt (line 8698) | function itt(t,e){return t.reduce((n,r,i)=>{const s=e.get(r);return s&&(... function jk (line 8698) | function jk(t){return t!==null&&t>=0} function stt (line 8698) | function stt(t,e){if(t===e)return!0;if(t.length!==e.length)return!1;for(... function ott (line 8698) | function ott(t){return typeof t=="boolean"?{draggable:t,droppable:t}:t} function ctt (line 8698) | function ctt(t,e,n){const r=t[e],i=t[e-1],s=t[e+1];return r?n=1e3?`${(t/1e3).toFixed(1)}kg`:`${Math.round(t)... function vtt (line 8698) | function vtt({activeCount:t,pendingCount:e,totalTime:n,totalWeight:r,his... function wtt (line 8698) | function wtt({item:t,onRequeue:e,onRemove:n,timeFormat:r="system",hasPer... function c0 (line 8698) | function c0(t){const e=new Date(t);return e.setHours(0,0,0,0),e} function Stt (line 8698) | function Stt(t){return t.toLocaleDateString(void 0,{weekday:"short",mont... function _tt (line 8698) | function _tt(t){return t.toLocaleTimeString(void 0,{hour:"2-digit",minut... function ktt (line 8698) | function ktt(t,e){if(t<=0)return e("queue.timeline.time.anyMoment");cons... function Ntt (line 8698) | function Ntt(t){const e=new Date;return e.setHours(t,0,0,0),e.toLocaleTi... function Ctt (line 8698) | function Ctt({event:t,now:e,onItemClick:n,t:r}){const i=t.item,s=i.archi... function Ptt (line 8699) | function Ptt({queueItems:t,printerStatuses:e,onItemClick:n,t:r}){const[i... function Ttt (line 8699) | function Ttt(t,e=!1){return e&&t>=1e3?`${(t/1e3).toFixed(1)}kg`:`${Math.... function Att (line 8699) | function Att({status:t,waitingReason:e,printerState:n,t:r}){if(t==="pend... function jtt (line 8699) | function jtt({selectedCount:t,printers:e,onSave:n,onClose:r,isSaving:i,c... function Iu (line 8699) | function Iu({label:t,value:e,onChange:n,disabled:r,t:i}){return a.jsxs("... function pY (line 8699) | function pY({item:t,position:e,onEdit:n,onCancel:r,onRemove:i,onStop:s,o... function Mtt (line 8707) | function Mtt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r,... function Ett (line 8707) | function Ett({printDates:t,months:e=3}){const n=w.useRef(null),[r,i]=w.u... function LP (line 8707) | function LP({value:t,onChange:e,exclude:n}){const{t:r}=Ft(),i={weight:r(... function Bh (line 8707) | function Bh(t){if(t>=1e6){const e=t/1e6;return`${e%1===0?e.toFixed(0):e.... function Ftt (line 8707) | function Ftt({archives:t,currency:e="$",dateFrom:n,dateTo:r}){const{t:i}... function Rtt (line 8707) | function Rtt({id:t,title:e,component:n,isHidden:r,size:i,columnSpan:s,on... function Ltt (line 8707) | function Ltt({widgets:t,storageKey:e,columns:n=4,stackBelow:r,hideContro... function Ott (line 8707) | function Ott(t){const e=new Date,n=e.getUTCFullYear(),r=e.getUTCMonth(),... function Utt (line 8707) | function Utt({stats:t,currency:e}){const{t:n}=Ft(),r=t?.energy_data_warm... function Btt (line 8707) | function Btt({stats:t,printerMap:e,size:n=1}){const{t:r}=Ft(),i=(t?.succ... function Htt (line 8707) | function Htt({stats:t,printerMap:e,size:n=1}){const{t:r}=Ft(),i=t?.avera... function qtt (line 8707) | function qtt({printDates:t,dateFrom:e,dateTo:n}){const{days:r,hourlyCoun... function $tt (line 8707) | function $tt({printDates:t,size:e=2,dateFrom:n,dateTo:r}){const i=w.useM... function Vtt (line 8707) | function Vtt({stats:t,archives:e,printerMap:n}){const{t:r}=Ft(),[i,s]=w.... function Gtt (line 8707) | function Gtt({archives:t,currency:e,dateFrom:n,dateTo:r}){const{t:i}=Ft(... function Wtt (line 8707) | function Wtt({size:t=1,dateFrom:e,dateTo:n,createdById:r}){const{t:i}=Ft... function Ktt (line 8707) | function Ktt({archives:t,currency:e}){const{t:n}=Ft(),r=w.useMemo(()=>{c... function Xtt (line 8707) | function Xtt(){const{t}=Ft(),{showToast:e}=hn(),{hasPermission:n,authEna... function Ytt (line 8707) | function Ytt({plug:t,onEdit:e}){const{t:n}=Ft(),r=nn(),{showToast:i}=hn(... function Qtt (line 8707) | function Qtt({plug:t,onClose:e}){const{t:n}=Ft(),r=nn(),i=!!t,[s,o]=w.us... function Ln (line 8707) | function Ln({checked:t,onChange:e,disabled:n}){const r=i=>{i.preventDefa... function Ztt (line 8707) | function Ztt({provider:t,onEdit:e}){const{t:n}=Ft(),r=nn(),[i,s]=w.useSt... function ent (line 8707) | function ent({provider:t,onClose:e}){const{t:n}=Ft(),r=nn(),i=!!t,[s,o]=... function tnt (line 8707) | function tnt({template:t,onClose:e}){const{t:n}=Ft(),r=nn(),i=w.useRef(n... function rnt (line 8707) | function rnt({onClose:t}){const{t:e}=Ft(),n=nn(),{showToast:r}=hn(),[i,s... function ant (line 8707) | function ant({log:t,isExpanded:e,onToggle:n,formatDate:r,formatFullDate:... function int (line 8707) | function int({formData:t,setFormData:e,groups:n,onClose:r,onCreate:i,isC... function snt (line 8707) | function snt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),[r,i]=w.useState(... function ont (line 8707) | function ont(){const{t}=Ft(),{showToast:e}=hn(),[n,r]=w.useState([]),[i,... function lnt (line 8707) | function lnt(){const{t}=Ft(),{showToast:e}=hn(),[n,r]=w.useState([]),[i,... function cnt (line 8708) | function cnt({link:t,onClose:e}){const{t:n}=Ft(),r=nn(),i=!!t,s=w.useRef... function dnt (line 8708) | function dnt(){const{t}=Ft(),e=nn(),[n,r]=w.useState(!1),[i,s]=w.useStat... function unt (line 8708) | function unt({printer:t,models:e}){const{t:n}=Ft(),r=nn(),{showToast:i}=... function mnt (line 8708) | function mnt({onClose:t}){const{t:e}=Ft(),n=nn(),{showToast:r}=hn(),[i,s... function hnt (line 8708) | function hnt(){const{t}=Ft(),[e,n]=w.useState(!1),{data:r,isLoading:i}=X... function xY (line 8708) | function xY(t){if(t<60)return`${t}s`;const e=Math.floor(t/60);if(e<60)re... function yY (line 8708) | function yY(t){return t==null?"—":t>=1024?`${(t/1024).toFixed(1)} GB`:`$... function pnt (line 8708) | function pnt({device:t,onUnregister:e,isDeleting:n}){const{t:r}=Ft(),{sh... function fnt (line 8708) | function fnt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),[r,i]=w.useState(... function N3 (line 8708) | function N3(t){if(!t)return"-";const e=Zn(t);return e?e.toLocaleString()... function C3 (line 8708) | function C3({status:t}){if(!t)return null;const e={success:"bg-green-500... function gnt (line 8708) | function gnt(){const t=nn(),{showToast:e}=hn(),{t:n}=Ft(),[r,i]=w.useSta... function bnt (line 8708) | function bnt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),[r,i]=w.useState(... function vnt (line 8708) | function vnt(){const{t}=Ft(),{showToast:e}=hn(),n=nn(),[r,i]=w.useState(... function Snt (line 8708) | function Snt(){const{t}=Ft(),{showToast:e}=hn(),n=nn(),{authEnabled:r}=k... function cN (line 8711) | function cN({value:t,onChange:e,placeholder:n,maxLength:r=6}){return a.j... function Fle (line 8711) | function Fle({codes:t,onDone:e}){const{t:n}=Ft(),[r,i]=w.useState(!1),s=... function _nt (line 8712) | function _nt({onDone:t}){const{t:e}=Ft(),n=nn(),{showToast:r}=hn(),[i,s]... function knt (line 8712) | function knt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{user:r}=kr(),[i,... function vY (line 8712) | function vY({initial:t,isEdit:e=!1,onSave:n,onCancel:r,isPending:i}){con... function Cnt (line 8712) | function Cnt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),[r,i]=w.useState(... function Tnt (line 8712) | function Tnt(t,e){const n=e.replace("#/","").split("/");let r=t;for(cons... function N0 (line 8712) | function N0(t,e,n=0){if(n>5)return"...";if(e.$ref)return N0(t,Tnt(t,e.$r... function Ant (line 8712) | function Ant({path:t,method:e,spec:n,schema:r,apiKey:i}){const[s,o]=w.us... function jnt (line 8712) | function jnt({apiKey:t=""}){const[e,n]=w.useState(null),[r,i]=w.useState... function jn (line 8712) | function jn(t){Rle.set(t.anchor,t)} function Mnt (line 8712) | function Mnt(){return Array.from(Rle.values())} function Fnt (line 8712) | function Fnt(){const t=nn(),e=qo(),[n,r]=BP(),{t:i,i18n:s}=Ft(),{showToa... function P3 (line 8712) | function P3({profile:t,onEdit:e,onCopy:n,selectionMode:r,isSelected:i,on... function T3 (line 8712) | function T3({profile:t,printerId:e,nozzleDiameter:n,existingProfiles:r=[... function Ont (line 8712) | function Ont(){const{t}=Ft(),{showToast:e}=hn(),{hasPermission:n}=kr(),[... function znt (line 8712) | function znt(t){const e=t.toUpperCase();for(const n of Ile)if(new RegExp... function Unt (line 8712) | function Unt(t){const e=t.replace(/@.+$/,"").trim(),n=e.toUpperCase();fo... function A3 (line 8712) | function A3({preset:t,onDelete:e,onExpand:n,isExpanded:r}){const{t:i}=Ft... function Bnt (line 8712) | function Bnt(){const{t}=Ft(),{hasPermission:e}=kr(),n=nn(),{showToast:r}... function b5 (line 8712) | function b5(t,e){const n=`${t} ${e||""}`,r=n.match(/@?\s*(?:BBL\s+)?(?:B... function Kw (line 8712) | function Kw(t){return/^(P[FPM]US|PF\d|PP\d)/.test(t)} function Hnt (line 8712) | function Hnt({onSuccess:t,t:e}){const{showToast:n}=hn(),[r,i]=w.useState... function cx (line 8712) | function cx({label:t,value:e,options:n,onChange:r}){const[i,s]=w.useStat... function qnt (line 8712) | function qnt(){const[t,e]=w.useState(!1);w.useEffect(()=>{const r=()=>{e... function j3 (line 8712) | function j3({setting:t,onClick:e,onDuplicate:n,compareMode:r,isCompareSe... function lO (line 8712) | function lO(t,e=0){const n=" ".repeat(e);if(t===null)return"null";if(t=... function $nt (line 8724) | function $nt({setting:t,onClose:e,onDeleted:n,onDuplicate:r,onEdit:i,has... function zle (line 8724) | function zle(){try{const t=localStorage.getItem("bambusy_preset_template... function Ule (line 8724) | function Ule(t){localStorage.setItem("bambusy_preset_templates",JSON.str... function Vnt (line 8724) | function Vnt({onClose:t,onApply:e,t:n}){const{showToast:r}=hn(),[i,s]=w.... function Ble (line 8724) | function Ble({onClose:t,leftPreset:e,rightPreset:n,leftLabel:r,rightLabe... function Gnt (line 8724) | function Gnt({onClose:t,initialData:e,allPresets:n,t:r}){const{showToast... function Wnt (line 8724) | function Wnt({settings:t,lastSyncTime:e,onRefresh:n,isRefreshing:r,print... function Knt (line 8724) | function Knt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r}... function Xnt (line 8724) | function Xnt(t,e){const n=(e||"").toUpperCase().replace(/[- ]/g,""),r=n.... function Z0 (line 8724) | function Z0(t){return t&&C0[t]||mg} function dx (line 8724) | function dx(t,e,n){if(e==="days"){if(t<1)return n?n("common.today"):"Tod... function M3 (line 8724) | function M3(t,e,n){return e==="days"?t===1?n?n("maintenance.day"):"1 day... function Ynt (line 8724) | function Ynt({item:t,onPerform:e,onToggle:n,hasPermission:r,t:i}){const ... function Qnt (line 8724) | function Qnt({overview:t,onPerform:e,onToggle:n,onSetHours:r,hasPermissi... function Znt (line 8724) | function Znt({overview:t,types:e,onUpdateInterval:n,onAddType:r,onUpdate... function Jnt (line 8724) | function Jnt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r}... function Hle (line 8724) | function Hle({project:t,onClose:e,onSave:n,isLoading:r,currencySymbol:i,... function ert (line 8724) | function ert({project:t,onClick:e,onEdit:n,onDelete:r,hasPermission:i,t:... function trt (line 8724) | function trt(){const{t}=Ft(),e=qo(),n=nn(),{showToast:r}=hn(),{hasPermis... function nrt (line 8724) | function nrt(t){const e=t.toLowerCase();return e.endsWith(".gcode")||e.e... function rrt (line 8724) | function rrt(t){return t>=1e3?`${(t/1e3).toFixed(2)}kg`:`${Math.round(t)... function art (line 8724) | function art({status:t,t:e}){const n={active:"bg-bambu-green/20 text-bam... function kY (line 8724) | function kY({icon:t,label:e,value:n,subValue:r,hint:i,color:s="text-bamb... function irt (line 8724) | function irt({archives:t,t:e}){return t.length===0?a.jsxs("div",{classNa... function srt (line 8724) | function srt({priority:t,t:e}){const n={low:{color:"bg-gray-500/20 text-... function E3 (line 8724) | function E3(t,e){if(!t)return null;const n=Zn(t);if(!n)return null;const... function ort (line 8724) | function ort(){const{id:t}=Yw(),e=qo(),{t:n}=Ft(),r=nn(),{showToast:i}=h... function lrt (line 8724) | function lrt({parentId:t,onClose:e,onSave:n,isLoading:r,t:i}){const[s,o]... function crt (line 8724) | function crt({onClose:t,onSave:e,isLoading:n,t:r}){const[i,s]=w.useState... function drt (line 8724) | function drt({type:t,currentName:e,onClose:n,onSave:r,isLoading:i,t:s}){... function urt (line 8724) | function urt({folders:t,selectedFiles:e,currentFolderId:n,onClose:r,onMo... function mrt (line 8724) | function mrt({folder:t,onClose:e,onLink:n,isLoading:r,t:i}){const[s,o]=w... function qle (line 8724) | function qle({folder:t,selectedFolderId:e,onSelect:n,onDelete:r,onLink:i... function cO (line 8724) | function cO(t){const e=t.toLowerCase();return e.endsWith(".gcode")||e.en... function hrt (line 8724) | function hrt({file:t,isSelected:e,isMobile:n,onSelect:r,onDelete:i,onDow... function prt (line 8724) | function prt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r,... function frt (line 8724) | function frt(t,e){const n=`token=${encodeURIComponent(e)}`;let r=0;retur... function $le (line 8724) | function $le(){const{authEnabled:t,user:e}=kr(),n=nn(),r=w.useRef(!1),{d... function yrt (line 8724) | function yrt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),{hasPermission:r,... function vrt (line 8724) | function vrt(t,e,n){if(!t)return"";if(!e)return t;const r=e.match(/plate... function wrt (line 8724) | function wrt(t){const e=t.get("show")?.split(",")||["progress","layers",... function Srt (line 8724) | function Srt(t,e){if(t.stg_cur_name)return t.stg_cur_name;switch(t.state... function _rt (line 8724) | function _rt(t){switch(t){case"small":return{container:"p-3",text:"text-... function krt (line 8724) | function krt(){const{printerId:t}=Yw(),[e]=BP(),{t:n}=Ft(),r=nn(),i=pars... function Nrt (line 8724) | function Nrt(){const{t}=Ft(),{id:e}=Yw(),{mode:n}=zg(),{data:r,isLoading... function NY (line 8724) | function NY(){const{id:t}=Yw(),e=qo(),n=nn(),{t:r}=Ft(),{showToast:i}=hn... function Vle (line 8724) | function Vle(t,e=!1){const n={};return e?(t.material||(n.material="Mater... function Cp (line 8724) | function Cp(t){let e=t.replace(/@.*$/,"").trim();e=e.replace(/\(Custom\)... function Xle (line 8724) | function Xle(t,e){const n=new Set(Crt);for(const r of t){const{brand:i}=... function jrt (line 8724) | function jrt(t){const e=t.filter(r=>r.preset_type==="filament");if(e.len... function Yle (line 8724) | function Yle(t,e,n){if(t.length>0){const r=[],i=new Map;for(const s of t... function Qle (line 8724) | function Qle(t,e){if(!t)return;let n=e.find(r=>r.code===t);if(n||(n=e.fi... function Zle (line 8724) | function Zle(){try{const t=localStorage.getItem(Kle);if(t)return JSON.pa... function Jle (line 8724) | function Jle(t,e){const n=e.filter(i=>i.hex.toUpperCase()!==t.hex.toUppe... function D3 (line 8724) | function D3(t,e){if(!e.material)return!1;const r=(t.name||"").replace(/^... function ece (line 8724) | function ece({formData:t,updateField:e,cloudAuthenticated:n,loadingCloud... function tce (line 8724) | function tce({formData:t,updateField:e,recentColors:n,onColorUsed:r,cata... function Mrt (line 8724) | function Mrt({catalog:t,value:e,onChange:n,catalogId:r,onCatalogIdChange... function nce (line 8724) | function nce({formData:t,updateField:e,spoolCatalog:n,currencySymbol:r})... function rce (line 8724) | function rce({formData:t,printersWithCalibrations:e,selectedProfiles:n,s... function Ert (line 8724) | function Ert(t){const e=new Date(t);return e.toLocaleDateString("en-GB",... function Frt (line 8724) | function Frt({spoolId:t}){const{t:e}=Ft(),n=nn(),{showToast:r}=hn(),{dat... function Rrt (line 8724) | function Rrt({isOpen:t,onClose:e,spool:n,printersWithCalibrations:r=[],c... function Lrt (line 8724) | function Lrt({isOpen:t,onClose:e,columns:n,defaultColumns:r,onSave:i}){c... function PY (line 8724) | function PY(t){return`${t.material}|${t.subtype||""}|${t.brand||""}|${t.... function Ort (line 8724) | function Ort(){try{const t=localStorage.getItem(ace);if(t){const e=JSON.... function Irt (line 8724) | function Irt(t){try{localStorage.setItem(ace,JSON.stringify(t))}catch{}} function Rd (line 8724) | function Rd(t,e=!1){return e&&t>=1e3?`${(t/1e3).toFixed(1)}kg`:`${Math.r... function F3 (line 8724) | function F3(t,e="system"){if(!t)return"-";const n=Zn(t);return n?mF(n,e)... function Brt (line 8728) | function Brt(){try{const t=localStorage.getItem(mO);if(t)return JSON.par... function Hrt (line 8728) | function Hrt(t){try{t?localStorage.setItem(mO,JSON.stringify(t)):localSt... function qrt (line 8728) | function qrt(){const{data:t}=Xe({queryKey:["spoolman-settings"],queryFn:... function $rt (line 8728) | function $rt(){const{t}=Ft(),e=nn(),{showToast:n}=hn(),[r,i]=w.useState(... function Vrt (line 8728) | function Vrt({pageIndex:t,pageSize:e,totalRows:n,totalPages:r,onPageChan... function TY (line 8728) | function TY({spool:t,remaining:e,pct:n,colorStyle:r,onClick:i,t:s}){retu... function ice (line 8728) | function ice({spool:t,remaining:e,pct:n,onEdit:r,onRestore:i,onArchive:s... function Grt (line 8728) | function Grt({spools:t,representative:e,remaining:n,pct:r,isExpanded:i,o... function AY (line 8728) | function AY({hasFilters:t,onAddSpool:e,t:n}){return a.jsxs("div",{classN... function Krt (line 8728) | function Krt(){const t=nn(),[e,n]=w.useState(!0),[r,i]=w.useState(new Se... function Xrt (line 8730) | function Xrt(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1... function Pa (line 8730) | function Pa({icon:t,label:e,value:n,subValue:r,color:i="text-bambu-green... function MY (line 8730) | function MY({percent:t,color:e="bg-bambu-green"}){return a.jsx("div",{cl... function _h (line 8730) | function _h({title:t,icon:e,children:n}){return a.jsxs(Tt,{className:"p-... function Yrt (line 8730) | function Yrt(){const{t}=Ft(),e=nn(),[n,r]=w.useState(null),[i,s]=w.useSt... function Qrt (line 8730) | function Qrt(){const t=qo(),[e]=BP(),{t:n}=Ft(),{login:r,loginWithToken:... function Zrt (line 8730) | function Zrt(){const t=qo(),{t:e}=Ft(),{showToast:n}=hn(),{mode:r}=zg(),... function Jrt (line 8730) | function Jrt(){const{t}=Ft(),{user:e}=kr(),{showToast:n}=hn(),r=nn(),i=q... function eat (line 8730) | function eat(){const t=w.useRef(null),e=w.useRef(null),n=nn(),[r,i]=w.us... function tat (line 8730) | function tat({children:t}){const{authEnabled:e,user:n,loading:r}=kr(),i=... function nat (line 8730) | function nat({selectedPrinterId:t,onPrinterChange:e,deviceOnline:n}){con... function aat (line 8730) | function aat(){const{t}=Ft();return a.jsx("nav",{className:"h-14 bg-bamb... function iat (line 8730) | function iat({alert:t}){const{t:e}=Ft(),n=t?t.type==="error"?"bg-red-500... function sat (line 8730) | function sat({isOpen:t,onClose:e,deviceId:n,deviceOnline:r}){const{t:i}=... function Lk (line 8730) | function Lk({icon:t,label:e,onClick:n,disabled:r,variant:i="default"}){c... function lat (line 8730) | function lat(t,e){switch(e.type){case"WEIGHT_UPDATE":return{...t,weight:... function cat (line 8730) | function cat(){const[t,e]=w.useReducer(lat,oat),n=w.useCallback(u=>{cons... function uat (line 8730) | function uat(){return EY||(EY=1,(function(t,e){(function(n,r){t.exports=... function O3 (line 8738) | function O3(t,e){(Object.getOwnPropertyDescriptor(HTMLInputElement.proto... function fat (line 8738) | function fat({onVisibilityChange:t}){const[e,n]=w.useState(!1),[r,i]=w.u... function gat (line 8738) | function gat(){nZ();const[t,e]=w.useState(null),[n,r]=w.useState(null),[... function SA (line 8738) | function SA({color:t,isEmpty:e,size:n=32}){return e?a.jsx("div",{classNa... function sce (line 8738) | function sce(){try{const t=localStorage.getItem(bat);if(t){const e=parse... function xat (line 8738) | function xat({spool:t,scaleWeight:e,onClose:n,onSyncWeight:r,onAssignToA... function yat (line 8738) | function yat({tagUid:t,scaleWeight:e,coreWeight:n,onLinkSpool:r,onAddToI... function vat (line 8738) | function vat(t){return t?`#${t.slice(0,6)}`:"#808080"} function oce (line 8738) | function oce(t){return!t.tray_type||t.tray_type===""} function wat (line 8738) | function wat(t){return t<=3?`AMS ${String.fromCharCode(65+t)}`:t>=128&&t... function Sat (line 8738) | function Sat({className:t}){return a.jsx("svg",{className:t,viewBox:"0 0... function _at (line 8738) | function _at({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function kat (line 8738) | function kat({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function Nat (line 8738) | function Nat({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function Cat (line 8738) | function Cat({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function Pat (line 8738) | function Pat({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 ... function lce (line 8738) | function lce({humidity:t,goodThreshold:e=40,fairThreshold:n=60}){let r,i... function cce (line 8738) | function cce({temp:t,goodThreshold:e=28,fairThreshold:n=35}){let r,i;ret... function x5 (line 8738) | function x5({side:t}){return a.jsx("span",{className:"inline-flex items-... function Tat (line 8738) | function Tat({tray:t,slotIndex:e,isActive:n,fillOverride:r,spoolmanFill:... function dce (line 8738) | function dce({unit:t,activeSlot:e,onConfigureSlot:n,isDualNozzle:r,nozzl... function I3 (line 8738) | function I3(t){return t<=3?`AMS ${String.fromCharCode(65+t)}`:t>=128&&t<... function z3 (line 8738) | function z3(t){return!t.tray_type||t.tray_type===""} function Aat (line 8738) | function Aat(t){return t?`#${t.slice(0,6)}`:"#808080"} function jat (line 8738) | function jat(t,e){const n=OP(t),r=OP(e);return!n||!r?"none":n===r?"exact... function Mat (line 8738) | function Mat(t,e){const n=OP(t),r=OP(e);return!n||!r?!1:n===r} function uce (line 8738) | function uce({isOpen:t,onClose:e,spool:n,printerId:r}){const{t:i}=Ft(),s... function Eat (line 8742) | function Eat({isOpen:t,onClose:e,tagId:n,untaggedSpools:r,onLink:i}){con... function DY (line 8742) | function DY(t){return t?t.replace(/[^0-9a-f]/gi,"").toUpperCase():""} function Dat (line 8742) | function Dat(t,e){const n=DY(t),r=DY(e);return!n||!r?!1:n===r?!0:n.endsW... function Fat (line 8742) | function Fat(){const{t}=Ft(),[e,n]=w.useState(0);w.useEffect(()=>{const ... function Rat (line 8742) | function Rat(){const{t}=Ft();return a.jsxs("div",{className:"flex flex-c... function Lat (line 8742) | function Lat(){const{sbState:t,selectedPrinterId:e}=yy(),{t:n}=Ft(),{sho... function RY (line 8742) | function RY(t){return t<=3?`AMS ${String.fromCharCode(65+t)}`:t>=128&&t<... function Oat (line 8742) | function Oat(t){return t?{O1D:"H2D",O1E:"H2D Pro",O2D:"H2D Pro",O1C:"H2C... function wf (line 8742) | function wf(t){return!t.tray_type||t.tray_type===""} function Iat (line 8742) | function Iat(t){return t?`#${t.slice(0,6)}`:"#808080"} function zat (line 8742) | function zat(){const{selectedPrinterId:t,setAlert:e}=yy(),{t:n}=Ft(),r=n... function Uat (line 8742) | function Uat({type:t,deviceId:e,onClose:n}){const{t:r}=Ft(),[i,s]=w.useS... function Bat (line 8743) | function Bat(t){if(t<60)return`${t}s`;if(t<3600)return`${Math.floor(t/60... function Hat (line 8743) | function Hat(t){if(!t)return"-";try{const e=new Date(t);return e.toLocal... function $at (line 8743) | function $at({device:t}){const{t:e}=Ft(),[n,r]=w.useState(null),[i,s]=w.... function Vat (line 8743) | function Vat({device:t,onBrightnessChange:e}){const{t:n}=Ft(),[r,i]=w.us... function Gat (line 8743) | function Gat({step:t,labels:e}){return a.jsxs("div",{className:"flex fle... function Wat (line 8743) | function Wat({device:t,weight:e,weightStable:n,rawAdc:r}){const{t:i}=Ft(... function Kat (line 8743) | function Kat({device:t}){const{t:e}=Ft(),[n,r]=w.useState(null),[i,s]=w.... function LY (line 8743) | function LY({percent:t,color:e}){return a.jsx("div",{className:"w-full h... function Xat (line 8743) | function Xat(t){const e=Math.floor(t/86400),n=Math.floor(t%86400/3600),r... function Yat (line 8743) | function Yat({device:t}){const{t:e}=Ft(),n=t.system_stats;if(!n)return a... function Qat (line 8743) | function Qat(){const{sbState:t,setDisplayBrightness:e}=yy(),{t:n}=Ft(),[... function Zat (line 8743) | function Zat({device:t,weight:e,weightStable:n,rawAdc:r}){const{t:i}=Ft(... function Jat (line 8743) | function Jat(){const{sbState:t}=yy(),{t:e}=Ft(),n=qo(),{data:r=[]}=Xe({q... function tit (line 8743) | function tit(){const{t}=Ft(),{sbState:e}=yy(),[n,r]=w.useState("existing... function OY (line 8743) | function OY(t){return!!(t.tag_uid||t.tray_uuid)} function nit (line 8743) | function nit({spool:t,selected:e,showTag:n,onClick:r}){const i=t.rgba?`#... function rit (line 8743) | function rit({currencySymbol:t,onCreated:e,selectedSpool:n,t:r}){const[i... function ait (line 8743) | function ait({writeStatus:t,writeMessage:e,selectedSpool:n,tagOnReader:r... function d0 (line 8743) | function d0({className:t}){return a.jsxs("svg",{className:t,viewBox:"0 0... function sit (line 8743) | function sit(){try{const t=localStorage.getItem(iit);if(t){const e=parse... function oit (line 8743) | function oit({spool:t,liveScaleWeight:e,persistedGrossWeight:n,onClose:r... function lit (line 8743) | function lit(t){return t.rgba?`#${t.rgba.substring(0,6)}`:"#808080"} function cit (line 8743) | function cit(t){return Math.max(0,t.label_weight-t.weight_used)} function dit (line 8743) | function dit(t){return t.label_weight<=0?0:Math.max(0,Math.min(100,(t.la... function uit (line 8743) | function uit(t){const e=[t.material];return t.subtype&&e.push(t.subtype)... function mce (line 8743) | function mce(t){const e=t.ams_id===254||t.ams_id===255,n=!e&&t.ams_id>=1... function mit (line 8743) | function mit({color:t,size:e=56}){return a.jsxs("svg",{width:e,height:e,... function hit (line 8743) | function hit(){const{sbState:t,selectedPrinterId:e}=yy(),{t:n}=Ft(),[r,i... function U3 (line 8743) | function U3({active:t,onClick:e,label:n,green:r}){return a.jsx("button",... function pit (line 8743) | function pit({spool:t,assignment:e,onClick:n}){const r=lit(t),i=dit(t),s... function fit (line 8743) | function fit({spool:t,assignment:e,sbState:n,onSyncWeight:r,onAssignToAm... class git (line 8743) | class git extends w.Component{state={error:null,errorInfo:null};static g... method getDerivedStateFromError (line 8743) | static getDerivedStateFromError(e){return{error:e}} method componentDidCatch (line 8743) | componentDidCatch(e,n){this.setState({errorInfo:n}),console.error("Rea... method render (line 8743) | render(){return this.state.error?a.jsxs("div",{style:{padding:24,color... function xit (line 8743) | function xit(){return $le(),null} function IY (line 8743) | function IY({children:t}){return eat(),a.jsx(a.Fragment,{children:t})} function zY (line 8743) | function zY({children:t}){const{authEnabled:e,loading:n,user:r}=kr();ret... function B3 (line 8743) | function B3({children:t}){const{authEnabled:e,loading:n,user:r,isAdmin:i... function yit (line 8743) | function yit({children:t}){const{authEnabled:e,loading:n}=kr();return n?... function vit (line 8743) | function vit(){return a.jsx(git,{children:a.jsx(gye,{children:a.jsx(Pye,... FILE: static/sw.js constant CACHE_NAME (line 2) | const CACHE_NAME = 'bambuddy-v25'; constant STATIC_CACHE (line 3) | const STATIC_CACHE = 'bambuddy-static-v25'; constant STATIC_ASSETS (line 6) | const STATIC_ASSETS = [ FILE: tests/e2e_comprehensive_test.py function test_navigation_and_sidebar (line 12) | def test_navigation_and_sidebar(page): function test_printers_page (line 54) | def test_printers_page(page): function test_archives_page (line 81) | def test_archives_page(page): function test_queue_page (line 110) | def test_queue_page(page): function test_statistics_page (line 131) | def test_statistics_page(page): function test_settings_page (line 155) | def test_settings_page(page): function test_keyboard_shortcuts (line 183) | def test_keyboard_shortcuts(page): function test_theme_toggle (line 233) | def test_theme_toggle(page): function test_responsive_design (line 258) | def test_responsive_design(page): function test_external_links_sidebar (line 283) | def test_external_links_sidebar(page): function test_api_health (line 302) | def test_api_health(page): function run_comprehensive_test (line 332) | def run_comprehensive_test(): FILE: tests/e2e_toggle_persistence_test.py function test_smart_plug_auto_off_toggle_persistence (line 16) | def test_smart_plug_auto_off_toggle_persistence(page): function test_notification_event_toggle_persistence (line 106) | def test_notification_event_toggle_persistence(page): function test_ams_alarm_toggle_persistence (line 190) | def test_ams_alarm_toggle_persistence(page): function test_smart_plug_power_off_confirmation (line 254) | def test_smart_plug_power_off_confirmation(page): function run_all_toggle_tests (line 287) | def run_all_toggle_tests():