| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  | // custom_alert_dialog.dart
 | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  | import 'package:qhd_prevention/main.dart'; // 导入全局 navigatorKey
 | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  | /// 对话框模式
 | 
					
						
							|  |  |  | enum DialogMode { text, input } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CustomAlertDialog extends StatefulWidget { | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |   final String title; | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   final String content; | 
					
						
							|  |  |  |   final String hintText; | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |   final String cancelText; | 
					
						
							|  |  |  |   final String confirmText; | 
					
						
							|  |  |  |   final VoidCallback? onCancel; | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   final VoidCallback? onConfirm; | 
					
						
							|  |  |  |   final ValueChanged<String>? onInputConfirm; | 
					
						
							|  |  |  |   final DialogMode mode; | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |   final bool force; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |   const CustomAlertDialog({ | 
					
						
							|  |  |  |     Key? key, | 
					
						
							|  |  |  |     required this.title, | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |     this.content = '', | 
					
						
							|  |  |  |     this.hintText = '', | 
					
						
							|  |  |  |     this.cancelText = '取消', | 
					
						
							|  |  |  |     this.confirmText = '确定', | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |     this.onCancel, | 
					
						
							|  |  |  |     this.onConfirm, | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |     this.onInputConfirm, | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |     this.mode = DialogMode.text, | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |     this.force = false, | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |   }) : super(key: key); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   // ------------------ 静态快捷方法 ------------------
 | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static Future<bool> showConfirm( | 
					
						
							|  |  |  |       BuildContext context, { | 
					
						
							|  |  |  |         required String title, | 
					
						
							|  |  |  |         String content = '', | 
					
						
							|  |  |  |         String cancelText = '取消', | 
					
						
							|  |  |  |         String confirmText = '确定', | 
					
						
							|  |  |  |         bool barrierDismissible = true, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |         VoidCallback? onConfirm, | 
					
						
							|  |  |  |         bool force = false, | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |       }) async { | 
					
						
							|  |  |  |     final result = await showDialog<bool>( | 
					
						
							|  |  |  |       context: context, | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |       barrierDismissible: force ? false : barrierDismissible, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |       builder: (_) => CustomAlertDialog( | 
					
						
							|  |  |  |         title: title, | 
					
						
							|  |  |  |         content: content, | 
					
						
							|  |  |  |         cancelText: cancelText, | 
					
						
							|  |  |  |         confirmText: confirmText, | 
					
						
							|  |  |  |         onConfirm: onConfirm, | 
					
						
							|  |  |  |         force: force, | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |     return result == true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static Future<void> showAlert( | 
					
						
							|  |  |  |       BuildContext context, { | 
					
						
							|  |  |  |         required String title, | 
					
						
							|  |  |  |         String content = '', | 
					
						
							|  |  |  |         String confirmText = '确定', | 
					
						
							|  |  |  |         bool barrierDismissible = true, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |         VoidCallback? onConfirm, | 
					
						
							|  |  |  |         bool force = false, | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |       }) async { | 
					
						
							|  |  |  |     await showDialog<void>( | 
					
						
							|  |  |  |       context: context, | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |       barrierDismissible: force ? false : barrierDismissible, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |       builder: (_) => CustomAlertDialog( | 
					
						
							|  |  |  |         title: title, | 
					
						
							|  |  |  |         content: content, | 
					
						
							|  |  |  |         cancelText: '', | 
					
						
							|  |  |  |         confirmText: confirmText, | 
					
						
							|  |  |  |         onConfirm: onConfirm, | 
					
						
							|  |  |  |         force: force, | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   static Future<String> showInput( | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |       BuildContext context, { | 
					
						
							|  |  |  |         required String title, | 
					
						
							|  |  |  |         String hintText = '', | 
					
						
							|  |  |  |         String cancelText = '取消', | 
					
						
							|  |  |  |         String confirmText = '确定', | 
					
						
							|  |  |  |         bool barrierDismissible = true, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |         bool force = false, | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |       }) async { | 
					
						
							|  |  |  |     final result = await showDialog<String?>( | 
					
						
							|  |  |  |       context: context, | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |       barrierDismissible: force ? false : barrierDismissible, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |       builder: (_) => CustomAlertDialog( | 
					
						
							|  |  |  |         title: title, | 
					
						
							|  |  |  |         hintText: hintText, | 
					
						
							|  |  |  |         cancelText: cancelText, | 
					
						
							|  |  |  |         confirmText: confirmText, | 
					
						
							|  |  |  |         mode: DialogMode.input, | 
					
						
							|  |  |  |         force: force, | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |     return result ?? ''; | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   _CustomAlertDialogState createState() => _CustomAlertDialogState(); | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _CustomAlertDialogState extends State<CustomAlertDialog> { | 
					
						
							|  |  |  |   late TextEditingController _controller; | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   bool _isClosing = false; | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							|  |  |  |     _controller = TextEditingController(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     _controller.dispose(); | 
					
						
							|  |  |  |     super.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |   bool get hasCancel => !widget.force && widget.cancelText.isNotEmpty; | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void _closeDialog([dynamic result]) { | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |     if (_isClosing) return; | 
					
						
							|  |  |  |     _isClosing = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 优先使用当前上下文导航
 | 
					
						
							|  |  |  |     if (mounted) { | 
					
						
							|  |  |  |       Navigator.of(context).pop(result); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // 后备方案:使用全局导航键
 | 
					
						
							|  |  |  |       navigatorKey.currentState?.pop(result); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |     return PopScope( | 
					
						
							|  |  |  |       canPop: !widget.force, | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |       child: Dialog( | 
					
						
							|  |  |  |         backgroundColor: Colors.transparent, | 
					
						
							|  |  |  |         child: Container( | 
					
						
							|  |  |  |           constraints: const BoxConstraints(minWidth: 280), | 
					
						
							|  |  |  |           decoration: BoxDecoration( | 
					
						
							|  |  |  |             color: Colors.white, | 
					
						
							|  |  |  |             borderRadius: BorderRadius.circular(8), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           child: Column( | 
					
						
							|  |  |  |             mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |             children: [ | 
					
						
							|  |  |  |               const SizedBox(height: 20), | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |               Padding( | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |                 padding: const EdgeInsets.symmetric(horizontal: 20), | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                 child: Text( | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |                   widget.title, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |                   style: const TextStyle( | 
					
						
							|  |  |  |                     fontSize: 18, | 
					
						
							|  |  |  |                     fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                   textAlign: TextAlign.center, | 
					
						
							|  |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |               ), | 
					
						
							|  |  |  |               const SizedBox(height: 16), | 
					
						
							|  |  |  |               if (widget.mode == DialogMode.text) | 
					
						
							|  |  |  |                 Padding( | 
					
						
							|  |  |  |                   padding: const EdgeInsets.symmetric(horizontal: 24), | 
					
						
							|  |  |  |                   child: Text( | 
					
						
							|  |  |  |                     widget.content, | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |                     style: const TextStyle( | 
					
						
							|  |  |  |                       fontSize: 16, | 
					
						
							|  |  |  |                       color: Colors.black54, | 
					
						
							|  |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |                     textAlign: TextAlign.center, | 
					
						
							|  |  |  |                   ), | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |               else | 
					
						
							|  |  |  |                 Padding( | 
					
						
							|  |  |  |                   padding: const EdgeInsets.symmetric(horizontal: 20), | 
					
						
							|  |  |  |                   child: TextField( | 
					
						
							|  |  |  |                     controller: _controller, | 
					
						
							|  |  |  |                     autofocus: true, | 
					
						
							|  |  |  |                     decoration: InputDecoration( | 
					
						
							|  |  |  |                       hintText: widget.hintText, | 
					
						
							|  |  |  |                       border: const OutlineInputBorder(), | 
					
						
							|  |  |  |                       focusedBorder: OutlineInputBorder( | 
					
						
							|  |  |  |                         borderSide: BorderSide(color: Colors.blue, width: 1), | 
					
						
							|  |  |  |                         borderRadius: BorderRadius.circular(4), | 
					
						
							|  |  |  |                       ), | 
					
						
							|  |  |  |                       isDense: true, | 
					
						
							|  |  |  |                       contentPadding: const EdgeInsets.symmetric( | 
					
						
							|  |  |  |                         vertical: 10, | 
					
						
							|  |  |  |                         horizontal: 10, | 
					
						
							|  |  |  |                       ), | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                     ), | 
					
						
							|  |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |               const SizedBox(height: 20), | 
					
						
							|  |  |  |               const Divider(height: 1), | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |               hasCancel | 
					
						
							|  |  |  |                   ? _buildDoubleButtons(context) | 
					
						
							|  |  |  |                   : _buildSingleButton(context), | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |             ], | 
					
						
							|  |  |  |           ), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |         ), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Widget _buildDoubleButtons(BuildContext context) { | 
					
						
							|  |  |  |     return Row( | 
					
						
							|  |  |  |       children: [ | 
					
						
							|  |  |  |         Expanded( | 
					
						
							|  |  |  |           child: InkWell( | 
					
						
							|  |  |  |             onTap: () { | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |               widget.onCancel?.call(); | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  |               _closeDialog(widget.mode == DialogMode.text ? false : null); | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |             }, | 
					
						
							|  |  |  |             child: Container( | 
					
						
							|  |  |  |               padding: const EdgeInsets.symmetric(vertical: 12), | 
					
						
							|  |  |  |               alignment: Alignment.center, | 
					
						
							|  |  |  |               child: Text( | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                 widget.cancelText, | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |                 style: const TextStyle( | 
					
						
							|  |  |  |                   fontWeight: FontWeight.w500, | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |                   color: Colors.black87, | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |                   fontSize: 18, | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |               ), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         Container(width: 1, height: 48, color: Colors.grey[300]), | 
					
						
							|  |  |  |         Expanded( | 
					
						
							|  |  |  |           child: InkWell( | 
					
						
							|  |  |  |             onTap: () { | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |               if (widget.mode == DialogMode.text) { | 
					
						
							|  |  |  |                 widget.onConfirm?.call(); | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |                 _closeDialog(true); | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |               } else { | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |                 final value = _controller.text.trim(); | 
					
						
							|  |  |  |                 widget.onInputConfirm?.call(value); | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |                 _closeDialog(value); | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |             }, | 
					
						
							|  |  |  |             child: Container( | 
					
						
							|  |  |  |               padding: const EdgeInsets.symmetric(vertical: 12), | 
					
						
							|  |  |  |               alignment: Alignment.center, | 
					
						
							|  |  |  |               child: Text( | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                 widget.confirmText, | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |                 style: const TextStyle( | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |                   color: Color(0xFF3874F6), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |                   fontWeight: FontWeight.w500, | 
					
						
							|  |  |  |                   fontSize: 18, | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |               ), | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |           ), | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Widget _buildSingleButton(BuildContext context) { | 
					
						
							|  |  |  |     return InkWell( | 
					
						
							|  |  |  |       onTap: () { | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |         if (widget.mode == DialogMode.text) { | 
					
						
							|  |  |  |           widget.onConfirm?.call(); | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |           _closeDialog(true); | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2025-08-16 14:13:23 +08:00
										 |  |  |           final value = _controller.text.trim(); | 
					
						
							|  |  |  |           widget.onInputConfirm?.call(value); | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |           _closeDialog(value); | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |       }, | 
					
						
							|  |  |  |       child: Container( | 
					
						
							|  |  |  |         width: double.infinity, | 
					
						
							|  |  |  |         padding: const EdgeInsets.symmetric(vertical: 14), | 
					
						
							|  |  |  |         alignment: Alignment.center, | 
					
						
							|  |  |  |         child: Text( | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |           widget.confirmText, | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |           style: const TextStyle( | 
					
						
							| 
									
										
										
										
											2025-07-28 14:22:07 +08:00
										 |  |  |             color: Color(0xFF3874F6), | 
					
						
							| 
									
										
										
										
											2025-07-22 13:34:34 +08:00
										 |  |  |             fontWeight: FontWeight.w500, | 
					
						
							|  |  |  |             fontSize: 18, | 
					
						
							|  |  |  |           ), | 
					
						
							| 
									
										
										
										
											2025-07-16 08:37:08 +08:00
										 |  |  |         ), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-08-29 20:33:23 +08:00
										 |  |  | } |