From 93c8ace8e76362861b4c98b71874dc8fe4c4c78a Mon Sep 17 00:00:00 2001 From: lihanqi <13868246742@163.com> Date: Fri, 1 Aug 2025 19:09:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BD=A9=E7=A5=A8=E5=8A=A9=E6=89=8B=E5=90=8E?= =?UTF-8?q?=E7=AB=AF1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 2 + .gitignore | 33 + .mvn/wrapper/maven-wrapper.properties | 19 + Excel导入使用说明.md | 484 +++ VIP兑换记录查询API使用说明.md | 182 + kaifa1.xlsx | Bin 0 -> 981404 bytes mvnw | 259 ++ mvnw.cmd | 149 + nls-sample-16k.wav | Bin 0 -> 106826 bytes pom.xml | 198 ++ sql/ddl.sql | 272 ++ src/main/java/com/xy/xyaicpzs/Main.java | 42 + src/main/java/com/xy/xyaicpzs/Sample.java | 54 + .../com/xy/xyaicpzs/XyAiCpzsApplication.java | 17 + .../com/xy/xyaicpzs/common/DeleteRequest.java | 19 + .../com/xy/xyaicpzs/common/ErrorCode.java | 39 + .../com/xy/xyaicpzs/common/PageRequest.java | 20 + .../com/xy/xyaicpzs/common/ResultUtils.java | 51 + .../common/requset/BallAnalysisRequest.java | 24 + .../requset/BlueBallAnalysisRequest.java | 29 + .../requset/FallowBallAnalysisRequest.java | 26 + .../requset/GenerateVipCodesRequest.java | 20 + .../requset/PredictRecordQueryRequest.java | 23 + .../requset/VipCodeActivateRequest.java | 20 + .../common/requset/VipCodeQueryRequest.java | 74 + .../xyaicpzs/common/response/ApiResponse.java | 29 + .../common/response/PageResponse.java | 67 + .../com/xy/xyaicpzs/config/CorsConfig.java | 27 + .../xy/xyaicpzs/config/MyBatisPlusConfig.java | 31 + .../xyaicpzs/config/ObjectMapperConfig.java | 22 + .../com/xy/xyaicpzs/config/RedisConfig.java | 38 + .../xyaicpzs/config/RestTemplateConfig.java | 22 + .../xy/xyaicpzs/config/ScheduleConfig.java | 12 + .../xy/xyaicpzs/constant/UserConstant.java | 36 + .../controller/BallAnalysisController.java | 1805 ++++++++++ .../xyaicpzs/controller/ChatController.java | 126 + .../controller/DataAnalysisController.java | 138 + .../controller/ExcelImportController.java | 156 + .../xyaicpzs/controller/HealthController.java | 15 + .../xy/xyaicpzs/controller/JwtController.java | 108 + .../OperationHistoryController.java | 96 + .../xy/xyaicpzs/controller/SmsController.java | 48 + .../SpeechRecognitionController.java | 83 + .../xyaicpzs/controller/UserController.java | 578 +++ .../controller/VipCodeController.java | 298 ++ .../VipExchangeRecordController.java | 139 + .../domain/dto/user/ResetPasswordRequest.java | 34 + .../domain/dto/user/UserAddRequest.java | 70 + .../domain/dto/user/UserLoginRequest.java | 18 + .../dto/user/UserPhoneLoginRequest.java | 22 + .../dto/user/UserPhoneRegisterRequest.java | 34 + .../domain/dto/user/UserQueryRequest.java | 57 + .../domain/dto/user/UserRegisterRequest.java | 22 + .../dto/user/UserStatusUpdateRequest.java | 24 + .../domain/dto/user/UserUpdateRequest.java | 75 + .../domain/entity/BlueHistory100.java | 50 + .../domain/entity/BlueHistoryAll.java | 55 + .../domain/entity/BlueHistoryTop.java | 35 + .../domain/entity/BlueHistoryTop100.java | 35 + .../xyaicpzs/domain/entity/ChatMessage.java | 56 + .../xy/xyaicpzs/domain/entity/History100.java | 50 + .../xy/xyaicpzs/domain/entity/HistoryAll.java | 55 + .../xy/xyaicpzs/domain/entity/HistoryTop.java | 35 + .../xyaicpzs/domain/entity/HistoryTop100.java | 35 + .../xyaicpzs/domain/entity/LotteryDraws.java | 60 + .../domain/entity/OperationHistory.java | 56 + .../xyaicpzs/domain/entity/PredictRecord.java | 96 + .../com/xy/xyaicpzs/domain/entity/T11.java | 35 + .../com/xy/xyaicpzs/domain/entity/T3.java | 35 + .../com/xy/xyaicpzs/domain/entity/T4.java | 35 + .../com/xy/xyaicpzs/domain/entity/T5.java | 35 + .../com/xy/xyaicpzs/domain/entity/T6.java | 35 + .../com/xy/xyaicpzs/domain/entity/T7.java | 35 + .../com/xy/xyaicpzs/domain/entity/T8.java | 35 + .../com/xy/xyaicpzs/domain/entity/User.java | 86 + .../xy/xyaicpzs/domain/entity/VipCode.java | 72 + .../domain/entity/VipExchangeRecord.java | 61 + .../domain/vo/BallCombinationAnalysisVO.java | 39 + .../xy/xyaicpzs/domain/vo/BallHitRateVO.java | 27 + .../domain/vo/BallPersistenceAnalysisVO.java | 39 + .../xyaicpzs/domain/vo/PrizeEstimateVO.java | 47 + .../xyaicpzs/domain/vo/RedBallHitRateVO.java | 27 + .../xyaicpzs/domain/vo/UserPredictStatVO.java | 46 + .../com/xy/xyaicpzs/domain/vo/UserVO.java | 78 + .../com/xy/xyaicpzs/domain/vo/VipCodeVO.java | 74 + .../xyaicpzs/exception/BusinessException.java | 33 + .../exception/GlobalExceptionHandler.java | 28 + .../xyaicpzs/mapper/BlueHistory100Mapper.java | 18 + .../xyaicpzs/mapper/BlueHistoryAllMapper.java | 18 + .../mapper/BlueHistoryTop100Mapper.java | 18 + .../xyaicpzs/mapper/BlueHistoryTopMapper.java | 18 + .../xy/xyaicpzs/mapper/ChatMessageMapper.java | 18 + .../xy/xyaicpzs/mapper/History100Mapper.java | 18 + .../xy/xyaicpzs/mapper/HistoryAllMapper.java | 18 + .../xyaicpzs/mapper/HistoryTop100Mapper.java | 18 + .../xy/xyaicpzs/mapper/HistoryTopMapper.java | 18 + .../xyaicpzs/mapper/LotteryDrawsMapper.java | 18 + .../mapper/OperationHistoryMapper.java | 18 + .../xyaicpzs/mapper/PredictRecordMapper.java | 18 + .../com/xy/xyaicpzs/mapper/T11Mapper.java | 18 + .../java/com/xy/xyaicpzs/mapper/T3Mapper.java | 18 + .../java/com/xy/xyaicpzs/mapper/T4Mapper.java | 18 + .../java/com/xy/xyaicpzs/mapper/T5Mapper.java | 18 + .../java/com/xy/xyaicpzs/mapper/T6Mapper.java | 18 + .../java/com/xy/xyaicpzs/mapper/T7Mapper.java | 21 + .../java/com/xy/xyaicpzs/mapper/T8Mapper.java | 18 + .../com/xy/xyaicpzs/mapper/UserMapper.java | 18 + .../com/xy/xyaicpzs/mapper/VipCodeMapper.java | 14 + .../mapper/VipExchangeRecordMapper.java | 18 + .../xyaicpzs/service/BallAnalysisService.java | 3154 +++++++++++++++++ .../service/BlueHistory100Service.java | 13 + .../service/BlueHistoryAllService.java | 13 + .../service/BlueHistoryTop100Service.java | 13 + .../service/BlueHistoryTopService.java | 13 + .../xyaicpzs/service/ChatMessageService.java | 13 + .../xy/xyaicpzs/service/CozeAuthService.java | 84 + .../xyaicpzs/service/DataAnalysisService.java | 38 + .../xyaicpzs/service/ExcelImportService.java | 249 ++ .../xyaicpzs/service/History100Service.java | 13 + .../xyaicpzs/service/HistoryAllService.java | 13 + .../service/HistoryTop100Service.java | 13 + .../xyaicpzs/service/HistoryTopService.java | 13 + .../xyaicpzs/service/LotteryDrawsService.java | 47 + .../service/OperationHistoryService.java | 41 + .../service/PredictRecordService.java | 50 + .../com/xy/xyaicpzs/service/SmsService.java | 25 + .../com/xy/xyaicpzs/service/T11Service.java | 13 + .../com/xy/xyaicpzs/service/T3Service.java | 13 + .../com/xy/xyaicpzs/service/T4Service.java | 13 + .../com/xy/xyaicpzs/service/T5Service.java | 14 + .../com/xy/xyaicpzs/service/T6Service.java | 13 + .../com/xy/xyaicpzs/service/T7Service.java | 13 + .../com/xy/xyaicpzs/service/T8Service.java | 13 + .../com/xy/xyaicpzs/service/UserService.java | 99 + .../xy/xyaicpzs/service/VipCodeService.java | 40 + .../service/VipExchangeRecordService.java | 22 + .../impl/BlueHistory100ServiceImpl.java | 18 + .../impl/BlueHistoryAllServiceImpl.java | 18 + .../impl/BlueHistoryTop100ServiceImpl.java | 18 + .../impl/BlueHistoryTopServiceImpl.java | 18 + .../service/impl/ChatMessageServiceImpl.java | 22 + .../service/impl/DataAnalysisServiceImpl.java | 217 ++ .../service/impl/History100ServiceImpl.java | 18 + .../service/impl/HistoryAllServiceImpl.java | 18 + .../impl/HistoryTop100ServiceImpl.java | 18 + .../service/impl/HistoryTopServiceImpl.java | 18 + .../service/impl/LotteryDrawsServiceImpl.java | 65 + .../impl/OperationHistoryServiceImpl.java | 67 + .../impl/PredictRecordServiceImpl.java | 77 + .../xyaicpzs/service/impl/SmsServiceImpl.java | 153 + .../xyaicpzs/service/impl/T11ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T3ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T4ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T5ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T6ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T7ServiceImpl.java | 18 + .../xyaicpzs/service/impl/T8ServiceImpl.java | 18 + .../service/impl/UserServiceImpl.java | 332 ++ .../service/impl/VipCodeServiceImpl.java | 273 ++ .../impl/VipExchangeRecordServiceImpl.java | 32 + .../xy/xyaicpzs/task/PredictResultTask.java | 44 + .../xy/xyaicpzs/util/ExcelDataImporter.java | 1737 +++++++++ .../com/xy/xyaicpzs/util/ExcelTestRunner.java | 48 + .../java/com/xy/xyaicpzs/util/JwtUtil.java | 140 + .../xyaicpzs/util/SpeechRecognizerDemo.java | 231 ++ src/main/resources/application.yml | 75 + .../generator/mapper/BlueHistory100Mapper.xml | 21 + .../generator/mapper/BlueHistoryAllMapper.xml | 22 + .../mapper/BlueHistoryTop100Mapper.xml | 17 + .../generator/mapper/BlueHistoryTopMapper.xml | 17 + .../generator/mapper/ChatMessageMapper.xml | 22 + .../generator/mapper/History100Mapper.xml | 21 + .../generator/mapper/HistoryAllMapper.xml | 22 + .../generator/mapper/HistoryTop100Mapper.xml | 17 + .../generator/mapper/HistoryTopMapper.xml | 17 + .../generator/mapper/LotteryDrawsMapper.xml | 23 + .../mapper/OperationHistoryMapper.xml | 22 + .../generator/mapper/PredictRecordMapper.xml | 31 + .../resources/generator/mapper/T11Mapper.xml | 17 + .../resources/generator/mapper/T3Mapper.xml | 17 + .../resources/generator/mapper/T4Mapper.xml | 17 + .../resources/generator/mapper/T5Mapper.xml | 17 + .../resources/generator/mapper/T6Mapper.xml | 17 + .../resources/generator/mapper/T7Mapper.xml | 17 + .../resources/generator/mapper/T8Mapper.xml | 17 + .../resources/generator/mapper/UserMapper.xml | 29 + .../generator/mapper/VipCodeMapper.xml | 27 + .../mapper/VipExchangeRecordMapper.xml | 23 + src/main/resources/private_key.pem | 28 + .../xyaicpzs/BallAnalysisFrequencyTest.java | 173 + .../BallAnalysisMultiLevelFilteringTest.java | 232 ++ .../com/xy/xyaicpzs/BlueBallAnalysisTest.java | 204 ++ .../com/xy/xyaicpzs/DecimalPrecisionTest.java | 77 + .../java/com/xy/xyaicpzs/ExcelImportTest.java | 63 + .../xyaicpzs/FallowBallAnalysisApiTest.java | 245 ++ ...owBallAnalysisMultiLevelFilteringTest.java | 250 ++ .../xy/xyaicpzs/FallowBallAnalysisTest.java | 291 ++ .../com/xy/xyaicpzs/GenerateVipCodesTest.java | 126 + .../com/xy/xyaicpzs/UserControllerTest.java | 1 + .../com/xy/xyaicpzs/VipCodeActivateTest.java | 76 + .../xy/xyaicpzs/XyAiCpzsApplicationTests.java | 13 + .../com/xy/xyaicpzs/mapper/T7MapperTest.java | 15 + userController.txt | 164 + 会员码激活API使用说明.md | 355 ++ 204 files changed, 18805 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 Excel导入使用说明.md create mode 100644 VIP兑换记录查询API使用说明.md create mode 100644 kaifa1.xlsx create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 nls-sample-16k.wav create mode 100644 pom.xml create mode 100644 sql/ddl.sql create mode 100644 src/main/java/com/xy/xyaicpzs/Main.java create mode 100644 src/main/java/com/xy/xyaicpzs/Sample.java create mode 100644 src/main/java/com/xy/xyaicpzs/XyAiCpzsApplication.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/DeleteRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/ErrorCode.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/PageRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/ResultUtils.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/BallAnalysisRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/BlueBallAnalysisRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/FallowBallAnalysisRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/GenerateVipCodesRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/PredictRecordQueryRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/VipCodeActivateRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/requset/VipCodeQueryRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/response/ApiResponse.java create mode 100644 src/main/java/com/xy/xyaicpzs/common/response/PageResponse.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/CorsConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/MyBatisPlusConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/ObjectMapperConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/RedisConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/RestTemplateConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/config/ScheduleConfig.java create mode 100644 src/main/java/com/xy/xyaicpzs/constant/UserConstant.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/BallAnalysisController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/ChatController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/DataAnalysisController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/ExcelImportController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/HealthController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/JwtController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/OperationHistoryController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/SmsController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/SpeechRecognitionController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/UserController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/VipCodeController.java create mode 100644 src/main/java/com/xy/xyaicpzs/controller/VipExchangeRecordController.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/ResetPasswordRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserAddRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserLoginRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneLoginRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneRegisterRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserQueryRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserRegisterRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserStatusUpdateRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/dto/user/UserUpdateRequest.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistory100.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryAll.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop100.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/ChatMessage.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/History100.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/HistoryAll.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop100.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/LotteryDraws.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/OperationHistory.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/PredictRecord.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T11.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T3.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T4.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T5.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T6.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T7.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/T8.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/User.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/VipCode.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/entity/VipExchangeRecord.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/BallCombinationAnalysisVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/BallHitRateVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/BallPersistenceAnalysisVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/PrizeEstimateVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/RedBallHitRateVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/UserPredictStatVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/UserVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/domain/vo/VipCodeVO.java create mode 100644 src/main/java/com/xy/xyaicpzs/exception/BusinessException.java create mode 100644 src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/BlueHistory100Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryAllMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTop100Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTopMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/ChatMessageMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/History100Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/HistoryAllMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/HistoryTop100Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/HistoryTopMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/LotteryDrawsMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/OperationHistoryMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/PredictRecordMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T11Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T3Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T4Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T5Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T6Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T7Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/T8Mapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/UserMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/VipCodeMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/mapper/VipExchangeRecordMapper.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/BlueHistory100Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/BlueHistoryAllService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/BlueHistoryTop100Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/BlueHistoryTopService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/ChatMessageService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/CozeAuthService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/DataAnalysisService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/ExcelImportService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/History100Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/HistoryAllService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/HistoryTop100Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/HistoryTopService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/LotteryDrawsService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/OperationHistoryService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/PredictRecordService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/SmsService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T11Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T3Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T4Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T5Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T6Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T7Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/T8Service.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/UserService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/VipCodeService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/VipExchangeRecordService.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/BlueHistory100ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryAllServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTop100ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTopServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/ChatMessageServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/DataAnalysisServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/History100ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/HistoryAllServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/HistoryTop100ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/HistoryTopServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/LotteryDrawsServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/OperationHistoryServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/PredictRecordServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/SmsServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T11ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T3ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T4ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T5ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T6ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T7ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/T8ServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/UserServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/VipCodeServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/service/impl/VipExchangeRecordServiceImpl.java create mode 100644 src/main/java/com/xy/xyaicpzs/task/PredictResultTask.java create mode 100644 src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java create mode 100644 src/main/java/com/xy/xyaicpzs/util/ExcelTestRunner.java create mode 100644 src/main/java/com/xy/xyaicpzs/util/JwtUtil.java create mode 100644 src/main/java/com/xy/xyaicpzs/util/SpeechRecognizerDemo.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/generator/mapper/BlueHistory100Mapper.xml create mode 100644 src/main/resources/generator/mapper/BlueHistoryAllMapper.xml create mode 100644 src/main/resources/generator/mapper/BlueHistoryTop100Mapper.xml create mode 100644 src/main/resources/generator/mapper/BlueHistoryTopMapper.xml create mode 100644 src/main/resources/generator/mapper/ChatMessageMapper.xml create mode 100644 src/main/resources/generator/mapper/History100Mapper.xml create mode 100644 src/main/resources/generator/mapper/HistoryAllMapper.xml create mode 100644 src/main/resources/generator/mapper/HistoryTop100Mapper.xml create mode 100644 src/main/resources/generator/mapper/HistoryTopMapper.xml create mode 100644 src/main/resources/generator/mapper/LotteryDrawsMapper.xml create mode 100644 src/main/resources/generator/mapper/OperationHistoryMapper.xml create mode 100644 src/main/resources/generator/mapper/PredictRecordMapper.xml create mode 100644 src/main/resources/generator/mapper/T11Mapper.xml create mode 100644 src/main/resources/generator/mapper/T3Mapper.xml create mode 100644 src/main/resources/generator/mapper/T4Mapper.xml create mode 100644 src/main/resources/generator/mapper/T5Mapper.xml create mode 100644 src/main/resources/generator/mapper/T6Mapper.xml create mode 100644 src/main/resources/generator/mapper/T7Mapper.xml create mode 100644 src/main/resources/generator/mapper/T8Mapper.xml create mode 100644 src/main/resources/generator/mapper/UserMapper.xml create mode 100644 src/main/resources/generator/mapper/VipCodeMapper.xml create mode 100644 src/main/resources/generator/mapper/VipExchangeRecordMapper.xml create mode 100644 src/main/resources/private_key.pem create mode 100644 src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/ExcelImportTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/UserControllerTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java create mode 100644 src/test/java/com/xy/xyaicpzs/XyAiCpzsApplicationTests.java create mode 100644 src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java create mode 100644 userController.txt create mode 100644 会员码激活API使用说明.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..2f94e61 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip diff --git a/Excel导入使用说明.md b/Excel导入使用说明.md new file mode 100644 index 0000000..d0f52af --- /dev/null +++ b/Excel导入使用说明.md @@ -0,0 +1,484 @@ +# Excel数据导入功能使用说明 + +## 功能概述 + +本系统提供了Excel数据导入功能,可以将包含T1、T2、T3、T4、T5、T6、T7、T8、T10和T11工作表的Excel文件数据导入到十四个数据库表中: + +### 红球数据(T1 Sheet): +- `history_all` - 红球全部历史数据表 +- `history_100` - 红球最近100期数据表 +- `history_top` - 红球历史数据排行表 +- `history_top_100` - 红球100期数据排行表 + +### 蓝球数据(T2 Sheet): +- `blue_history_all` - 蓝球全部历史数据表 +- `blue_history_100` - 蓝球最近100期数据表 +- `blue_history_top` - 蓝球历史数据排行表 +- `blue_history_top_100` - 蓝球100期数据排行表 + +### 红球线系数数据(T3 Sheet): +- `t3` - 红球组红球的线系数表 + +### 蓝球组红球线系数数据(T4 Sheet): +- `t4` - 蓝球组红球的线系数表 + +### 蓝球组蓝球线系数数据(T5 Sheet): +- `t5` - 蓝球组蓝球的线系数表 + +### 红球组蓝球线系数数据(T6 Sheet): +- `t6` - 红球组蓝球的线系数表 + +### 红球组红球面系数数据(T7 Sheet): +- `t7` - 红球组红球的面系数表 + +### 红球组蓝球面系数数据(T8 Sheet): +- `t8` - 红球组蓝球的面系数表 + +### 彩票开奖信息数据(T10 Sheet): +- `lottery_draws` - 彩票开奖信息表 + +### 蓝球组红球面系数数据(T11 Sheet): +- `t11` - 蓝球组红球的面系数表 + +## Excel文件格式要求 + +### 文件要求 +- **文件格式**:必须是`.xlsx`格式 +- **工作表名称**:必须包含名为`T1`、`T2`、`T3`、`T4`、`T5`、`T6`、`T7`、`T8`、`T10`和`T11`的工作表 +- **编码**:支持中文 + +### 数据结构要求 + +**T1工作表(红球数据)**的数据结构如下: + +| 列位置 | 列名 | 对应表 | 字段说明 | +|--------|------|--------|----------| +| A-G | 全部历史数据 | history_all | 球号、出现频次、出现频率%、平均隐现期次、最长隐现期次、最多连出期次、点系数 | +| H-M | 最近100期数据 | history_100 | 出现频次、出现频率%、平均隐现期、当前隐现期、最多连出期次、点系数 | +| N-P | 历史数据排行 | history_top | 排行、球号、点系数 | +| Q-S | 100期数据排行 | history_top_100 | 排行、球号、点系数 | + +**T2工作表(蓝球数据)**的数据结构如下: + +| 列位置 | 列名 | 对应表 | 字段说明 | +|--------|------|--------|----------| +| A-G | 全部历史数据 | blue_history_all | 球号、出现频次、出现频率%、平均隐现期次、最长隐现期次、最多连出期次、点系数 | +| H-M | 最近100期数据 | blue_history_100 | 出现频次、出现频率%、平均隐现期、当前隐现期、最多连出期次、点系数 | +| N-P | 历史数据排行 | blue_history_top | 排行、球号、点系数 | +| Q-S | 100期数据排行 | blue_history_top_100 | 排行、球号、点系数 | + +**T3工作表(红球线系数数据)**的数据结构如下: + +| 列位置 | 数据组织 | 对应表 | 字段说明 | +|--------|----------|--------|----------| +| C | 1号组线系数 | t3 | 主球=1,从球=1-33,线系数=C列 | +| F | 2号组线系数 | t3 | 主球=2,从球=1-33,线系数=F列 | +| I | 3号组线系数 | t3 | 主球=3,从球=1-33,线系数=I列 | +| ... | 依此类推 | t3 | 每三列为一组,组号即主球号 | + +**说明**:T3工作表每三列为一组数据,每组有33行数据,从球号固定为1-33(行号),线系数在C、F、I、L...列。 + +**T4工作表(蓝球组红球线系数数据)**的数据结构如下: + +| 列位置 | 数据组织 | 对应表 | 字段说明 | +|--------|----------|--------|----------| +| C | 蓝球1号线系数 | t4 | 主球=1,从球=1-33,线系数=C列 | +| F | 蓝球2号线系数 | t4 | 主球=2,从球=1-33,线系数=F列 | +| I | 蓝球3号线系数 | t4 | 主球=3,从球=1-33,线系数=I列 | +| ... | 依此类推 | t4 | 每三列为一组,最多16组 | + +**说明**:T4工作表每三列为一组数据,每组有33行数据,蓝球号码1-16(主球),红球号码1-33(从球,行号),线系数在C、F、I、L...列。 + +**T5工作表(蓝球组蓝球线系数数据)**的数据结构如下: + +| 列位置 | 数据组织 | 对应表 | 字段说明 | +|--------|----------|--------|----------| +| C | 蓝球1号线系数 | t5 | 主球=1,从球=1-16,线系数=C列 | +| F | 蓝球2号线系数 | t5 | 主球=2,从球=1-16,线系数=F列 | +| I | 蓝球3号线系数 | t5 | 主球=3,从球=1-16,线系数=I列 | +| ... | 依此类推 | t5 | 每三列为一组,最多16组 | + +**说明**:T5工作表每三列为一组数据,每组有16行数据,蓝球号码1-16(主球和从球),线系数在C、F、I、L...列。 + +**T6工作表(红球组蓝球线系数数据)**的数据结构如下: + +| 列位置 | 数据组织 | 对应表 | 字段说明 | +|--------|----------|--------|----------| +| C | 红球1号线系数 | t6 | 主球=1,从球=1-16,线系数=C列 | +| F | 红球2号线系数 | t6 | 主球=2,从球=1-16,线系数=F列 | +| I | 红球3号线系数 | t6 | 主球=3,从球=1-16,线系数=I列 | +| ... | 依此类推 | t6 | 每三列为一组,最多33组 | + +**说明**:T6工作表每三列为一组数据,每组有16行数据,红球号码1-33(主球),蓝球号码1-16(从球,行号),线系数在C、F、I、L...列。 + +**T7工作表(红球组红球面系数数据)**的数据结构如下: + +| 列位置 | 数据组织 | 对应表 | 字段说明 | +|--------|----------|--------|----------| +| C | 红球1号面系数 | t7 | 主球=1,从球=2-33,面系数=C列 | +| F | 红球2号面系数 | t7 | 主球=2,从球=1,3-33,面系数=F列 | +| I | 红球3号面系数 | t7 | 主球=3,从球=1-2,4-33,面系数=I列 | +| ... | 依此类推 | t7 | 每三列为一组,最多33组 | + +**说明**:T7工作表每三列为一组数据,每组有33行数据,红球号码1-33(主球和从球),面系数在C、F、I、L...列。**特殊处理**:排除自己和自己组合的情况。 + +**Excel数据结构**: +- **第1行**:标题行(1号组、面系数、2号组、面系数...) +- **第2行**:从球1号的数据(对应所有主球的面系数) +- **第3行**:从球2号的数据(对应所有主球的面系数) +- **...** +- **第34行**:从球33号的数据(对应所有主球的面系数) + +**处理逻辑**: +- **1号组(主球1)**: + - 球号列:B列,面系数列:C列 + - 读取所有行,从B列获取从球号,从C列获取面系数 + - 排除对角线(主球1=从球1的情况) +- **2号组(主球2)**: + - 球号列:E列,面系数列:F列 + - 读取所有行,从E列获取从球号,从F列获取面系数 + - 排除对角线(主球2=从球2的情况) +- **依此类推...** + +**关键改进**: +- **动态读取球号**:从Excel的球号列(B、E、H...)读取实际球号,不依赖行号 +- **完整数据覆盖**:读取到Excel的最后一行,确保包含33号球数据 +- **不排除对角线**:读取到什么数据就插入什么数据,包括主球=从球的情况 +- **最终生成**:33×33=1089条记录 + +### 具体列映射 + +#### 红球表映射(T1 Sheet) + +**history_all 表 (列A-G)** +- A列:球号 (ballNumber) +- B列:出现频次 (frequencyCount) +- C列:出现频率% (frequencyPercentage) +- D列:平均隐现期次 (averageInterval) +- E列:最长隐现期次 (maxHiddenInterval) +- F列:最多连出期次 (maxConsecutiveCount) +- G列:点系数 (pointCoefficient) + +**history_100 表 (列H-M,球号使用A列)** +- A列:球号 (ballNumber) +- H列:出现频次 (frequencyCount) +- J列:平均隐现期 (averageInterval) +- K列:当前隐现期 (nowInterval) +- L列:最多连出期次 (maxConsecutiveCount) +- M列:点系数 (pointCoefficient) + +**history_top 表 (列N-P)** +- N列:排行 (no) +- O列:球号 (ballNumber) +- P列:点系数 (pointCoefficient) + +**history_top_100 表 (列Q-S)** +- Q列:排行 (no) +- R列:球号 (ballNumber) +- S列:点系数 (pointCoefficient) + +#### 蓝球表映射(T2 Sheet) + +**blue_history_all 表 (列A-G)** +- A列:球号 (ballNumber) +- B列:出现频次 (frequencyCount) +- C列:出现频率% (frequencyPercentage) +- D列:平均隐现期次 (averageInterval) +- E列:最长隐现期次 (maxHiddenInterval) +- F列:最多连出期次 (maxConsecutiveCount) +- G列:点系数 (pointCoefficient) + +**blue_history_100 表 (列H-M,球号使用A列)** +- A列:球号 (ballNumber) +- H列:出现频次 (frequencyCount) +- J列:平均隐现期 (averageInterval) +- K列:当前隐现期 (nowInterval) +- L列:最多连出期次 (maxConsecutiveCount) +- M列:点系数 (pointCoefficient) + +**blue_history_top 表 (列N-P)** +- N列:排行 (no) +- O列:球号 (ballNumber) +- P列:点系数 (pointCoefficient) + +**blue_history_top_100 表 (列Q-S)** +- Q列:排行 (no) +- R列:球号 (ballNumber) +- S列:点系数 (pointCoefficient) + +#### T3表映射(T3 Sheet) + +**t3 表(红球线系数数据)** +- 数据组织:每三列为一组,每组33行数据 +- 红球号码范围:1-33(主球和从球都是) +- 线系数位置:C、F、I、L...列 + +**数据映射**: +- C列:红球1号线系数(主球=1,从球=1-33,线系数=C列) +- F列:红球2号线系数(主球=2,从球=1-33,线系数=F列) +- I列:红球3号线系数(主球=3,从球=1-33,线系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主红球号码(1-33) +- slaveBallNumber:从红球号码(固定1-33,对应行号) +- lineCoefficient:线系数(每组第三列,保留两位小数) + +#### T4表映射(T4 Sheet) + +**t4 表(蓝球组红球的线系数)** +- 数据组织:每三列为一组,每组33行数据 +- 蓝球号码范围:1-16(主球) +- 红球号码范围:1-33(从球,对应行号) +- 线系数位置:C、F、I、L...列 + +**数据映射**: +- C列:蓝球1号线系数(主球=1,从球=1-33,线系数=C列) +- F列:蓝球2号线系数(主球=2,从球=1-33,线系数=F列) +- I列:蓝球3号线系数(主球=3,从球=1-33,线系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:蓝球号码(1-16) +- slaveBallNumber:红球号码(固定1-33,对应行号) +- lineCoefficient:线系数(每组第三列,保留两位小数) + +#### T5表映射(T5 Sheet) + +**t5 表(蓝球组蓝球的线系数)** +- 数据组织:每三列为一组,每组16行数据 +- 蓝球号码范围:1-16(主球和从球都是) +- 线系数位置:C、F、I、L...列 + +**数据映射**: +- C列:蓝球1号线系数(主球=1,从球=1-16,线系数=C列) +- F列:蓝球2号线系数(主球=2,从球=1-16,线系数=F列) +- I列:蓝球3号线系数(主球=3,从球=1-16,线系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主蓝球号码(1-16) +- slaveBallNumber:从蓝球号码(固定1-16,对应行号) +- lineCoefficient:线系数(每组第三列,保留两位小数) + +#### T6表映射(T6 Sheet) + +**t6 表(红球组蓝球的线系数)** +- 数据组织:每三列为一组,每组16行数据 +- 红球号码范围:1-33(主球) +- 蓝球号码范围:1-16(从球) +- 线系数位置:C、F、I、L...列 + +**数据映射**: +- C列:红球1号线系数(主球=1,从球=1-16,线系数=C列) +- F列:红球2号线系数(主球=2,从球=1-16,线系数=F列) +- I列:红球3号线系数(主球=3,从球=1-16,线系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主红球号码(1-33) +- slaveBallNumber:从蓝球号码(固定1-16,对应行号) +- lineCoefficient:线系数(每组第三列,保留两位小数) + +#### T7表映射(T7 Sheet) + +**t7 表(红球组红球的面系数)** +- 数据组织:每三列为一组,每组33行数据 +- 红球号码范围:1-33(主球和从球都是) +- 面系数位置:C、F、I、L...列 +- 特殊处理:读取到什么数据就插入什么数据,包括对角线 + +**数据映射**: +- C列:红球1号面系数(主球=1,从球=1-33,面系数=C列) +- F列:红球2号面系数(主球=2,从球=1-33,面系数=F列) +- I列:红球3号面系数(主球=3,从球=1-33,面系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主红球号码(1-33) +- slaveBallNumber:从红球号码(1-33,包括与主球相同的号码) +- faceCoefficient:面系数(每组第三列,保留两位小数) + +#### T8表映射(T8 Sheet) + +**t8 表(红球组蓝球的面系数)** +- 数据组织:每三列为一组,每组16行数据 +- 红球号码范围:1-33(主球) +- 蓝球号码范围:1-16(从球) +- 面系数位置:C、F、I、L...列 + +**数据映射**: +- C列:红球1号面系数(主球=1,从球=1-16,面系数=C列) +- F列:红球2号面系数(主球=2,从球=1-16,面系数=F列) +- I列:红球3号面系数(主球=3,从球=1-16,面系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主红球号码(1-33) +- slaveBallNumber:从蓝球号码(固定1-16,对应行号) +- faceCoefficient:面系数(每组第三列,保留两位小数) + +#### T10表映射(T10 Sheet) + +**lottery_draws 表(彩票开奖信息)** +- 数据组织:标准表格结构,每行一条开奖记录 +- 开奖期号:Long类型主键 +- 开奖日期:Date类型,支持多种格式 +- 红球1-6:Integer类型 +- 蓝球:Integer类型 + +**数据映射**: +- A列:开奖期号(drawId) +- B列:开奖日期(drawDate) +- C列:红球1(redBall1) +- D列:红球2(redBall2) +- E列:红球3(redBall3) +- F列:红球4(redBall4) +- G列:红球5(redBall5) +- H列:红球6(redBall6) +- I列:蓝球(blueBall) + +**字段映射**: +- drawId:开奖期号(Long类型,主键) +- drawDate:开奖日期(Date类型,支持yyyy-MM-dd、yyyy/MM/dd等格式) +- redBall1-redBall6:红球1-6(Integer类型) +- blueBall:蓝球(Integer类型) + +**数据特性**: +- 所有字段均为必填项 +- 开奖期号为主键,不能重复 +- 日期格式自动识别和转换 +- 数据完整性验证 + +#### T11表映射(T11 Sheet) + +**t11 表(蓝球组红球的面系数)** +- 数据组织:每三列为一组,每组33行数据 +- 蓝球号码范围:1-16(主球) +- 红球号码范围:1-33(从球) +- 面系数位置:C、F、I、L...列 + +**数据映射**: +- C列:蓝球1号面系数(主球=1,从球=1-33,面系数=C列) +- F列:蓝球2号面系数(主球=2,从球=1-33,面系数=F列) +- I列:蓝球3号面系数(主球=3,从球=1-33,面系数=I列) +- 依此类推... + +**字段映射**: +- masterBallNumber:主蓝球号码(1-16) +- slaveBallNumber:从红球号码(固定1-33,对应行号) +- faceCoefficient:面系数(每组第三列,保留两位小数) + +## 使用方法 + +### 1. API接口方式 + +#### 1.1 文件上传导入 +```http +POST /api/excel/upload +Content-Type: multipart/form-data + +参数: +- file: Excel文件 (.xlsx格式) +``` + +#### 1.2 文件路径导入 +```http +POST /api/excel/import-by-path +Content-Type: application/x-www-form-urlencoded + +参数: +- filePath: Excel文件的完整路径 (例如: D:/data/kaifa1.xlsx) +``` + +#### 1.3 获取导入说明 +```http +GET /api/excel/import-info +``` + +### 2. 程序调用方式 + +```java +@Autowired +private ExcelImportService excelImportService; + +// 方式1:通过文件路径导入 +String result = excelImportService.importExcelFileByPath("D:/data/kaifa1.xlsx"); + +// 方式2:通过MultipartFile导入 +String result = excelImportService.importExcelFile(multipartFile); +``` + +### 3. 测试方式 + +运行测试类: +```java +// 运行 ExcelImportTest 类中的测试方法 +@Test +public void testImportExcelByPath() { + // 修改文件路径为实际路径 + String filePath = "D:/code/xy-ai-cpzs/kaifa1.xlsx"; + String result = excelImportService.importExcelFileByPath(filePath); + System.out.println("导入结果:" + result); +} +``` + +## 注意事项 + +1. **数据清空**:每次导入前会清空现有数据,请谨慎操作 +2. **数据验证**:系统会验证数据的完整性,球号为空的记录会被跳过 +3. **错误处理**:导入过程中如有错误会回滚操作并返回错误信息 +4. **日志记录**:导入过程会记录详细日志,便于问题排查 +5. **文件大小**:建议文件大小不超过10MB +6. **并发限制**:避免同时进行多个导入操作 + +## 常见问题 + +### Q1: 提示"未找到T1/T2/T3/T4/T5/T6/T7/T8/T10/T11工作表" +**A**: 请检查Excel文件是否包含名为"T1"(红球数据)、"T2"(蓝球数据)、"T3"(红球线系数)、"T4"(蓝球组红球线系数)、"T5"(蓝球组蓝球线系数)、"T6"(红球组蓝球线系数)、"T7"(红球组红球面系数)、"T8"(红球组蓝球面系数)、"T10"(彩票开奖信息)和"T11"(蓝球组红球面系数)的工作表,注意区分大小写。如果缺少某个工作表,系统会跳过该部分数据并显示警告。 + +### Q2: 导入后数据不完整 +**A**: 请检查Excel数据格式是否正确,确保数值类型的列包含有效数字。 + +### Q3: 导入失败提示文件格式错误 +**A**: 请确保文件是.xlsx格式,不支持.xls格式。 + +### Q4: 如何查看导入日志 +**A**: 导入过程中的日志会输出到控制台,可以通过查看应用日志了解详细信息。 + +### Q5: 报错"Cannot get a NUMERIC value from a STRING cell" +**A**: 这个错误已经修复。系统现在能够自动处理字符串类型的数值单元格,会尝试将字符串转换为数值。 + +### Q6: Excel中有公式单元格怎么办 +**A**: 系统支持公式单元格,会自动读取公式计算后的结果值。 + +### Q7: 单元格为空怎么处理 +**A**: 空白单元格会被自动跳过,对应的字段值会设为null。 + +## 数据类型支持 + +系统支持以下类型的Excel单元格: +- **数值类型** - 直接读取数值 +- **字符串类型** - 尝试转换为数值(如果包含数字) +- **公式类型** - 读取公式计算结果 +- **空白类型** - 设为null +- **其他类型** - 会记录警告日志并设为null + +## 数据精度处理 + +- **浮点数字段**:自动保留两位小数(使用四舍五入) +- **整数字段**:直接转换为整数(去除小数部分) +- **特殊值处理**:NaN和无穷大值会被设为null + +示例: +- `123.456789` → `123.46` +- `12.1` → `12.10` +- `5` → `5.00` + +## Swagger文档 + +启动应用后,可以通过以下地址访问API文档: +- Swagger UI: http://localhost:8123/api/swagger-ui.html +- Knife4j UI: http://localhost:8123/api/doc.html + +在文档中可以直接测试Excel导入接口。 \ No newline at end of file diff --git a/VIP兑换记录查询API使用说明.md b/VIP兑换记录查询API使用说明.md new file mode 100644 index 0000000..2d03d6c --- /dev/null +++ b/VIP兑换记录查询API使用说明.md @@ -0,0 +1,182 @@ +# VIP兑换记录查询API使用说明 + +## 接口概述 + +本文档描述了VIP兑换记录查询相关的API接口,主要用于查询用户的VIP兑换记录信息。 + +## 接口列表 + +### 1. 获取用户所有兑换记录 + +**接口地址:** `GET /vip-exchange-record/user/{userId}` + +**接口描述:** 根据用户ID获取该用户的所有VIP兑换记录 + +**请求参数:** +- `userId` (必填): 用户ID,路径参数,必须大于0 + +**请求示例:** +```http +GET /vip-exchange-record/user/123 +``` + +**响应示例:** +```json +{ + "code": 0, + "message": "success", + "data": [ + { + "id": 1, + "userId": 123, + "type": "月度会员", + "exchangeMode": 1, + "orderNo": 1234567890123456, + "orderAmount": 0, + "isUse": 1, + "exchangeTime": "2024-01-15T10:30:00", + "updateTime": "2024-01-15T10:30:00" + }, + { + "id": 2, + "userId": 123, + "type": "年度会员", + "exchangeMode": 1, + "orderNo": 1234567890123457, + "orderAmount": 0, + "isUse": 1, + "exchangeTime": "2024-02-15T14:20:00", + "updateTime": "2024-02-15T14:20:00" + } + ] +} +``` + +### 2. 分页获取用户兑换记录 + +**接口地址:** `GET /vip-exchange-record/user/{userId}/page` + +**接口描述:** 根据用户ID分页获取该用户的VIP兑换记录 + +**请求参数:** +- `userId` (必填): 用户ID,路径参数,必须大于0 +- `page` (可选): 页码,从1开始,默认为1 +- `size` (可选): 每页大小,默认为10,最大100 + +**请求示例:** +```http +GET /vip-exchange-record/user/123/page?page=1&size=5 +``` + +**响应示例:** +```json +{ + "code": 0, + "message": "success", + "data": [ + { + "id": 1, + "userId": 123, + "type": "月度会员", + "exchangeMode": 1, + "orderNo": 1234567890123456, + "orderAmount": 0, + "isUse": 1, + "exchangeTime": "2024-01-15T10:30:00", + "updateTime": "2024-01-15T10:30:00" + } + ] +} +``` + +### 3. 获取兑换记录详情 + +**接口地址:** `GET /vip-exchange-record/{recordId}` + +**接口描述:** 根据兑换记录ID获取详细信息 + +**请求参数:** +- `recordId` (必填): 兑换记录ID,路径参数,必须大于0 + +**请求示例:** +```http +GET /vip-exchange-record/1 +``` + +**响应示例:** +```json +{ + "code": 0, + "message": "success", + "data": { + "id": 1, + "userId": 123, + "type": "月度会员", + "exchangeMode": 1, + "orderNo": 1234567890123456, + "orderAmount": 0, + "isUse": 1, + "exchangeTime": "2024-01-15T10:30:00", + "updateTime": "2024-01-15T10:30:00" + } +} +``` + +## 数据字段说明 + +### VipExchangeRecord 字段说明 + +| 字段名 | 类型 | 说明 | +|--------|------|------| +| id | Long | 兑换记录唯一标识符 | +| userId | Long | 用户ID | +| type | String | 会员类型(月度会员/年度会员) | +| exchangeMode | Integer | 兑换方式(1-VIP码兑换) | +| orderNo | Long | 订单编号(16位随机数字) | +| orderAmount | Integer | 订单金额(单位:分) | +| isUse | Integer | 是否已兑换(0-未兑换,1-已兑换) | +| exchangeTime | Date | 兑换时间 | +| updateTime | Date | 更新时间 | + +## 响应状态码 + +| 状态码 | 说明 | +|--------|------| +| 0 | 成功 | +| 40000 | 请求参数错误 | +| 40400 | 请求数据不存在 | +| 50000 | 系统内部异常 | + +## 错误响应示例 + +```json +{ + "code": 40000, + "message": "用户ID不能为空且必须大于0", + "data": null +} +``` + +## 使用说明 + +1. **数据排序**: 所有查询结果都按照兑换时间倒序排列(最新的记录在前) + +2. **分页查询**: + - 页码从1开始 + - 每页大小限制在1-100之间 + - 超出范围会使用默认值 + +3. **参数校验**: + - 用户ID和记录ID必须为正整数 + - 参数错误会返回40000状态码 + +4. **异常处理**: + - 系统异常会返回50000状态码 + - 详细错误信息会在message字段中说明 + +## 注意事项 + +1. 接口支持Swagger文档,可通过 `/swagger-ui/index.html` 查看详细文档 +2. 所有接口都有完整的日志记录,便于问题排查 +3. 建议在生产环境中添加认证和权限控制 +4. 分页查询采用内存分页,大数据量时建议使用数据库分页优化 \ No newline at end of file diff --git a/kaifa1.xlsx b/kaifa1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..aaf171177e30eef2c8f0467392d0279cab85285c GIT binary patch literal 981404 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

B z@TDs}i+r@rAcw>BX!zp=9*scEi##&Bke2Wkf&gUSXYksR@)PeW8}-QMr(WVHf*s#M z?QHfE*E%SJ*NKo}7J=*M44E7aQ3WIP90#L?NPdZxC2r2Y#O`0_Ns+VQBQPFVoole* z^8i>`Annk5E^@#^J^v-`bk+dzT4U@qjE zb}ws#@SCCL5r(QH={pnQUN7rFHICFu#he@0%JshIF=w_bAR~0kmttd7)e)EP8&R%# zc9k3NR7aa`Ue(-?xirrDaft5BX;ATtEo?jqzBzTWV-usY59UAV#q*89I;%f;C))mI z*RVaM_vy8ShXi%=_Y01tfrRCXoH~2B=&i4zk74*j#C}nY{+jEh!siirN*By(wq_#s z`zeQcYb4ELAH>e)la1v`k}E=A*^G6M%Y@>glmUag%y;sJ`JAH}uD1o(>-T?N1N`qx z#*hwrDkUWlsJ$8d|9f+f`_Id+X?o5S($QZRBBn3#xSBYA@}HR7^4Msg1cK1Ceq~U7bI;y+7UASMbF>JoxS2k?AJGwll zHc*IQ;Apx&xsJ&2zgj!@zdKl7x;t5z0Ipr_uI!8X-kcuqXZU#>HfJ<7U7Y*hEZiTT zi;4MP4t=}7I@v_H^R?|8`gFm0HM1p{MXHf zcbB)5Vog3*7iyQ;3x2nLd`Ya$_q!_`&COF`2Q?h;Lk}<4GyE?P$9mVP@3(7|oBa_u zM{8r>sGFzH{BI{Y{C!SG?$+~zx~@0-yT#bF7O18>V)XI4QrPdxeVcEORuYDQxA<;$ zH@b(KeVY-L%@(zne#fjs3w}5KF!3^AO>1KJ+Y$a10r#b=cPj~o{+DOX^!f{#$_oO6 z8UA;kC+pOP5q>v~_HT);>aOm_YL=Rt{H|{hz1Xcm+G{Yd!p>0Ka{&8&R$t+eyk zx08O?5pJ=Qeo^CoOH~VZ*@6>ge_y&2D7yV~{7YN@+wB=J@Y^j{(e0=WFwmRz&vD=H zW9P4N|4b4$?zj8bBs0J72m|*AUpF7lINXm=*sT1%L%CM9U{(rcE&* z{7#Bc?#{(5#+v=_7pk@H%I?PTQ3uk|(m1W^Y3Fh8q7}I=ZY~$n-ic?o8b0ko6Els$ zZt@Vl@O;EWb`vNrdSS!YyVyO1){Gq_74$p6zny{9=hEk3o70Nt0w>7lpvE@3RSO8f z0Rk3)fM!cz20zgYiQh9s0W+K>n$*9_;OHDUZe4f_JZ6Er2kpLv!T!?c$mgJB`RPpX z$VM9HO1t}Gnqva#G|sl-#ISA>TTVZjUZ0zUKv}M)$e=?Bm0z^#!jI`m4HsK49zQuI zC{AmM4&}Hpy1`GlM4wXfknJJ~28R6b>9A$&p|WJu4~UH>

xetkMMtI+1i?_Oz- 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�Z)?_f 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�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 z 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�E(qwL;MwS7F>PhX7H$ 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
wHE$$L|9gy9lAVgcsPfzGgPloM`2_}Ae4Ol z;9eIWp$YTmskx5a-rq?>^hUO+S}iaejMwE&i>TsFV5v^BfJ9hJpstzYG02yt}5q}Udo{FPzG2LE-)WY^#mWdaA5&n#-0is5% z5m$0I$-*r(k_Tv*qN+g{0|9zsMt@#tOz4_;nDz12LBr z%YhCH?gIpDCH83sAAJAbRNqYwSy6!`sgoeU^Nb@E8|ChSC{^-&Jqp(t`_}WP5QeUYhBl60v1qica7rBgKy|^ zZr^Ud6{b7rzRIb|Z-ZBV~IjF6lmR#7DCL=OPJh zUAJBW%-js=O9FSQ*^&4Hw=ueJ$@9uSFclk9W$|%A*5UM`(6b(xJ~$Xb2Z(FbsaIt)Fm1BIkT7|OI6Ky?%i3?R~z@&k%At3*dV7~L1#Su zaIl_b$4b;xoR2)fCEODbx+RHTExxslc<0EA-uag^2>x~~F< z$3-=%+lZEBur(h^|6pD+mx&a*gi@{R_zHHFU~{LUT=Yzb2FbSArX^$NN6@tNS--y(>-ZeSUa$9`bJdo-j+u7*!C13FgYHvGBJW)}7gat7OOg2<&C|)$M9IU6^2LD@HhdmFfB#XcKEmfGGf08f-v5Ko!8aqKGQ~1eU+B z{WV*!CAaQNX{_mdpznBY&%@TLbWmxUGeM;}5DF^Ia}SFB+W|Ur6``_~4aFyvkO3U} zYb<(nwmmi zhwzKtd|b?IwceSKav91PO#I4Gbsu`ygXk3GEx289!Uid3qEW5!w_oTAY-B6}OB$ys)wo={w@)MY1oS}xx`G;lFg;5M zLkN(CVgWKa)>?p}+GgXSe6r9{Fe&-#hoYH24frB9yc2CN;0=qOIOd91t4HRl-Z&Qgemb-Np_xHo+=|&RuYZ*~EaxwziX)r0HGEAGYD@??Yw<_YY&`NuZ){ zqP{`s5TGi|F9NE9)A zX{mV@P5Wfc>1zZox^l;l>3u@2*FMg0ObvX=PMZ?m@rbA; z*D`M2ns*+!J2R7y4c1IOR;gN>7h!`-im1XRs9aXkHYbue8>_-AvCHKj>szFr!OSoi z`F=j++Fcyx`@5+*8TZ_be9>2@fes58-KfexWhr@z#RyIJDP7%)EJmdHBPa6QpXEJS zBLa(pr?e-rnx}jQn~LIGs}rCz_dkLIHUOh$<~^xnDx+r6Ylx^|5HY|d(NE6AD;Hg* z)m_XD!_{#=8VjCv+WNM2?(~M&;IxFK@$`?Oro5jWBwn!&F8yDVrh5yWy;hF-hyQ{i zRVVcTEEp}BUc!=Th&EfCcc~DEuTfT5j-3ul@5 z#u^dY#KInn60WzG@`fB^U?g$n0wj}ZXZkEy1ne(6&XB4Ye1xh zonHw>)ufb8H)*_0PFxw7#);UOet!*0Uw;RMN_7@4V%9udlsB?ql26?#OSanlvSg9d z;$UBB->uyDBiYPEg5)1XZ?B#k6!ktmIWg8>6AA_EU0U|kV(vX{`CRcRCzAm1hyJDZ zsnnyG-j|4~-(7;py6_rV7tHMUi>7r)_biZ#GEf@-931yjpRsO?WU%S7 z^g@9NQy+EO%Rhb%BY{%OGVzNaUfCPIEZ}~wm?EVt7`)DI8!7x`yz@GIKCz9)4XjHo zt^@nN`?lA`1zZ-a!4lwU$&q7Ciq{nj32*ADE!1-zD$aFo=7TM`+70M^qAbRQ2MqW| zJN=2<6^?#C`%*M`1=9)bloYhl;I$S8FNM{}kqpLa!ZTE`2?vRE`VA*5?rNa6$rx%% zZzaWX1NZ1MwrFB#d=G^#aL=;X_DPd17+Z;>6B1opB6(2a_&9or(SA$jACq|o-k2|) zp3#EoU_22xSg@;`y6(P$*;Bb>QMqaix07A#tvNM%%>p^xGyGu!h9Od21zbx(<2TO% zmoW~cuHL2S$})XU=9Z$KUWUKpDVnyY8M69r+j+5%vIcXJ(Q1KFA5wUnamn(EakY`) zj03a61ISDupKIpcSMZ_mAc}!!!3W`Xre|%PZtT90Tl#yw5B=wqi!@ZMBnqqTiN#Bm zCWX~=S@^N2!9laIE*YEUrST-&Eo8Z>(&loBC_?SK>V zGrj~ApiE+AFP3N(E023ffb&^nzRJ{o^+g?5bdf9;{_uVE^ocEy$k%Q;9R!ZuEy`?Q z^JIblcNdu9Wp(X*5FB*WyPyxPQ|Z?B<`@ zJ(r-`Inzdr1vlL`8v{Y&K{Jac{uud&%eq2dUCy%PuiEYGM)#%=HRz?VTe@N2Zs8At=-MqGU<}hEUTy}JAF(~=8ZWt>Fk=lg!pZ*{b zH`>2$x_8QWybg7z{9j%Wu)%gBHkd#MTu`>Lu%)9P5=3k$&jjk7J(?r#@D4=NLtXKQ zmqIw$R$~3tv(QnAMGf|IvC*E4aTigu-fOh2ao`&3iLRM3!(H0c>bVs(COqE}1>Nd3Z)S+}=+cXt^#n=dMk4?oi^(QIaKX zdp`AeclC}RJliNaSh#898n&`&y(kGs%#@CcjoX@+@k4S$CIbpH_W45r3=*qelFzUS^wP&iYaAn zm!d^s>Fl2;ImI985oUAE-l~s~zct?n#lGA8JsTW^Kjm?;&NQ3!G^@K0C-sc&FeIve z>sDJ32|l7|n!xInmU^#w?!OohAVa%S_*X%_~IwbjNUl+Kq z%tz6R&X$|UBXRH3mH3>pJa-u4-NFJjsZ5N)qra!VCKcK{Ql|n2IZA85s{gIA2J!%b zt>rGKfOq!fK(W2mDJax#tT_Ghc*pMIdez>bqk${(&=@&7hVQ(pgk#$68|RDPe(i#W zG{Q!`vF3C(PcptbAhf1qnIiy~5_tPAJ^i$X2RS!Bq>gFy6gzh|xr+Ux5j7}Wzy{c|(PN-cQay&~M5mJas!DJsHakDPbj+Lu{K zsZ%QV%f3mTh`t+>0QupzX1P~fV7F85n1C~`N1(_!ffw|i{q`XNdVZVt<-UqOeOJCb2mM1}rS*$2CBPHquQe?pr&w>5u{??2| z=}FGU`p!zp1QcX-26xiuUnpJB1}p>)f4H7N_a3L@P1)V0sav-y=!N!b$o4CHEGH%cS7y?u6&0%eq0Q2QS!Em-uaeRJ`WL5w_ck z=2#kDx_>(B^CzLY{B3~StqZx`7@?PB%`xDjK-$2yCd2FqzMwdKr#?w?7qbz96;rfS zWrRgAK@}LbTor5^TZNleohBv6&9?+6@)*~KMou`qRa8Luq;AR(d7_Wol z9q@+s$8oVN@i769k*G4pgFPjqklz7TwO_s1845Y6KbZLRvVZh&hqwHsV}wZO5PXUz`L zXSz($A0tUk-#ZR&Yk)g^BxKL8U8gXTICX0%Tn4k<Tmkqy`Vif83ueP<@)tC#8{f0n^(dAzzi z{m2g8deL-6YZ8zvC=1qUor^7=Vydr^EE#&%Ojf-H%zG5uh?8l*xGFpr4dWL+n5q9z zx&H|`PBovRN^3JNVopRdBlN0ZZp7FB8sNb&(!6EeJXh&>n^DB{-d-%0j-aNBfZjPx z_yY3%mqmjKy8$rq(H$H0$y_b81H$&nHYXo(JC0(yy-%W2wKSNaGJu_s|0Xr+{ zQdUpdYqufrEX=;tsa^Z^U{I!fqRWhf7CUz%^7|}yikJ#x z(o*BiZ?zi?VuY1Nh^W)5SM8MVyRh9S*yjFQRyn_&@e&%ngkWCTW&pre2)!h(-KT=* zUfbGdGr;N#;phsyf7G>*#o(OXFoZn_<72E?hoQ3pdEe$4ZKB`sf4uu=2-Z&(XIs3j z3Z;~NuV6F1w(|*;&V{tS>o0NLoz0!cJ3teMu3h2PeCGV+b(d?Foudd09G7jr&ZI8! zj>IBIkAxBDcSB8kSQ{-dHvX&Q0}TJpDA2d6y@0-@d6QBZ;Q(u4P{AMs_5{kD(>h#l z@6Lrf4{t?RME3`S%SGhk@ihafKLQJ@FC|(RsbK){eoP>VQChoRbik}apsGwYRWxSp zdE{nEd>N|eARB0|Sb*9@op14pIbF%Odnt{INvcpW3IE6BwNdwf`(9@7K?YXmuPzA1 z=Whwz4;!&Qi1 z`PvOpiY+W8_(0qDqZQt6*r?91ZcL-T)a<$S%Nf>S5xjrwY`plz28d06x%fvoHm0Nz zK{85Xu-P@Qx0bs)hBupU#a?*v$M7^yb4}9V&E0MXBCd19zup=u)Hzx4K#P3Wzwjt$ zNI-QGx+-HDzJ-!s_P0eD4@W_EY$y3&`>Q-UHAB#;xx|fB zlC$7VtU{%Mdr(!>$t({Joy8z;OZ2p~3pbgTlM+vo{;aBQklHo?vyFi+a~vE zXO&-~XN}+$o=AcE`B*JiJo$s{rmJ<&lVffas)Z$!qF>f&SKFV@>YMFOCPVbIbIx2f z{EXZ|&QyV_B(#}~kjEutn<>@3)I0K@Rgoi9m!MTqHX4d~MqpJmCQLd0<)x#7v7m?w zYfrLdpB`!ckvufIDm$%u0RQ<2G`gY<9(b&`nceP2C@X2d5ursiS1!LZni#w&=_;5j zWl}sMD$EyHbq+70mC^;V96-9w)K8bk#%U>Y*gyk6Q5>x_t7!^he8nq9t?RT&j-)E$Pn4bW2V~`{*e~~VSW7Zsx_@>8Rje>eN5Y9a4XVv!V|5K~<)tvLY`TC*H zSKOwJ zcGQ;?rC!r}9i?j6%hh7>Q}jV{SKNM{%{mWGP?<2W8vQ6*(Eky;-CK=Z=h|O=v7!Bf zQ)5kKGk#1f<=4Or%e|<@5B+l4!zP@sT3*fq5*S5~A~#&R+#l3dwPR0IE4cJ1x*dks zLiS@gI6rW<&6$573hpYMa+KI@k@^(1K31aE#|0JugUUir+HHKV8n>hqes^BJ)d!kR zQjxg7QdS=4WEMXcySl$P={xmn9c15gpkn6d`egajQAakn^p!i^KN}aRWAsXrm&FV4%p7Ygl5AprkqZd99 zwJMvyuJ?HdWstn*+@-J^5EYZJTt*~wgHL}tyGt|}yTtrI&F<_~mjn?8j8D9o!aaAOIYTvSvFURvm&pa-6eb>NhfLpDT7M5q+`PO}kjXWv*CvbkVhBv3%!g7T(dK zE{@8@eTjne=lOp|)7t%7?4@;^yRITQ`2JUh$+1BBV+&U`-+b%K9d7S@pT!w4T$M5S zrHWs7>k@C5WUUsy4(`-}-{!MYR(Vl$i{%p&}N#UmUixW>gh!L6l!lX41LG9AyoYp+%Z^5L=Bjd;YPb+c+yPB37o=hI0js z9ojf3pt!U?Pm_uWiOh0NE&LN&uk7SDtPy)JrxZ$Q|t{>t%SJo`l_s>ysj08toFV^ zbO&rNyn=@yG!8rjg%IE&=!G1z;I{~Aqq9%5zj9sxQf-e2zIAjmxgH7Z5tH!`v@6avez7A`lQG}Uao{E{?Pz$V1>EqDl zGnqsY(BfoG<(z7PZ;dHtl$6K>@3ej8>nHu^cMr9JPB96`31}6(V$)aM1Qw)&@Y0bH z!{dh!{=KjN?~=<7-M$pi?Tg+I-eF+GST-I&rlsePZC?(w6^4#*Rsnp;1Nw);O&X`- z6JN)fQ8alB3h^~Lr&-7*=aW3;S;fnVep6#DWS0|r5bwKp}2vk-tN7wZZF z!tg4VFOL$)XT9wWOg!+if!f0Qk|DM3Gk7RaJWqbPsCr3k<;fz|TNZE0 zGg6Z@jK~kPQN$$8Ai7ScI-$)5of;2j#YT~6Hj6u948UZ0HcNV9ig!1^&@lY)>aFio=P!!)_TIbIzucPK&N zziavcz1bttGeRNH&?w2&GBLzY)&x^A3gq252z{1-(M0_!ys(|Zm=vr%>G>Rc0W{Bk z&lGQcO4;d`KCnYpr)ou}`{TGM(h>ZqDh-5Dq~#ex=$ZJ!pIqxA81g{9_d%;VQ_TMX zC6EE)z?UZN4Q|#YT>VrZzp1%1)zrb>bpxdJFZWqkG+@vBZ|Ud;h{S){4Fa@C`QMa^ zRkCY3fpTgC3rDC{{KWsj;0~6i(1$cdIq^!0*`BuJCA0Ah5Nx}2UESAjyJ`NH8{>KB zKOy*}Zw1L?cmWV!a6e(*;t!%JA_RM6IQd*J)Yl7~V&1qm<*u#T{(m;EUcF0SYL3y% zmFh6X%I-b@cNK5A#N_P$ZDrpZb~5ZaFq|GX>v}|XhXrN<88q3N$_aUA&SJp(ZwYz@jBeQnH3W>4-r}2j0r~Q8T!Sv*6~%9sWKY%K3=; zh&KQ9Kxsgg7-!!}h#LYf#6l4>O{gs|>2~oE)uW(Hb=x(uS)a_0oxG*4GrJYWc+3>W z78_pRbg$Ge z3MKZdFaHd-9tgH>3%0I+svL)xGJt8Tc*pl8^Q`sLQ?q=BZbKa3?5BNKxg(HxQVxF? zQ+jymw&saa0P3aJbH3g|t`QAkaQ|9}sV?UTO*TP9(@%y9) znH7zU*J#?huN#5yHcdJq{s5l_{nWrY8%L||EJw3wD&dd?*T`G**)41JY%`}UAVoPj zwtd_J0+irfCl8RG;Ib&zXAkWn;nxUlJ_YG;1fJ61A9mj}L)~bT%T8ZtD%*RBf!`qyG zz#?)@n^^Xr2dABM*L9nbq~Sy2)oi|FfvUQ^6!Sr4lC}-*W<(WNf=WdahYij<>hmjC z_Mw~TZhyqNS3P{-A^>Qi9B$fnV&RadE_S_Vm&302Amzg;Pl+9BA*-~I;b9&eb5hqj z;!|!#kdlmoAjAt?ivv*)QWzH8-Y)R91{f-&%NCw6Tr2RQ`!$cdA$48XPAeC=PhxKE ztEgwj+U65vc$p&w@-u#Vukt*H=WS6sEOepZVRX7RXoNav)N486o4$6(urRo8YdQD? z@)zGnJZ2ENHQ4C5pF7a;wnYcCR{qC!S~sbtcZ3vnt#%pS76_8h2A-}c>d$5we#fE@ zJv$ViHLf)R>MDM}4H0u6$Zzsy9|cD|OEy&Yk`2|P^$mhY`)MvHct_LlLQkIVOTHW+ zqw#M7E^LS8wOrWo!{ov;d?H}MUh*vHD0f;HBCg_L9rkpKu_*MlCkSYt*Hn}zK>IT%Li#J zCJ7VfstP#zUIRRvXz(e;-iF5;8b9y-`-%;?o zihg_VS<<*~bHu&0PiC%`T06Lo9{6pxL@hxoj%le->APgG1{<7d?}N$&NDs>b&nvYuGyS4mRFMJ3`8g9~^IWyd z{GO#3huS64-|jJ*&iYolHBGRsnx&`cyM?`;*1@mUx*0n#`uE~I>FBm*?)wNIUB(DFn&vRqMu?5T37x| zXY?t!|Ay`D{Ctiuio73gbkvw^uh0%82)17-%(*AJQ=wx}m~($l9_tmwQi5gVZA-1a z7sFj6_4B)S6aWK`Z*^pVe*3K#D@qI>smk@Kg@DO#{CY1?X#qNVE;H-pl&wda?6W9+ zHy-|*nP&K4DD_N!pr6ko6TYt;5YIYiVg*i1=M>J1NTvTNE;MD`m?GSC<`jZiV?FU0 zEr!8M5!;TVMrpfKiJSc`eEJOE-x0i1)h}c_NQl^A@iO&1pj_>tN~==H1Rm;v_b-PF z$WMdqV)lf)3PVz{31Hj3JAnWPjF{NOdQEu3pQ+hWp789Y43#|Kuj-P5Y;pY&@&yar z*!KX{a&7yHt7;#?RKpEZ4RXGGV2NcJIykp0cVwzt2<90qrvq;~_`?Sa&)pDUOG9@Y zoeFPP-m>jQSHPw}%-{tLG()BBZlRK~?FU5W4bU}bbbX#XO{Zm@V)*A+C1_V)mzS@3 zl&X+5fBVjdO@@It1$(lm8pu=Ck%s{V6$#yiTlK?3V6LHXm&HyO40gS01%18S3& z(P#k}i2y^R(X>g_+EXJQ1QX&x&}Z7X?RrJP(`T+Po?{UJvq*l!7&3^p+^OB?W#j;5 zy?l&kP{jIRMA^%;Vp(Lih=m81GQQT@%YnUr$8$isyp5#G&bgGD8;tTQ^>YQR{b6<9 znkoXkJfXq4Br}O4#^mm1@ipx~a_HLz)B0MULWx$@e$G;rs-$IuTceqhM7qs|*`04* zgmSEeLE#!Y=-Z$|hbcNHn`x21H_NK0HGS)h(AwF;ujbF}^M({f)Q(vT;Uby7)!7Se zRSvP<|IqrMht`nSf1pQy+LfEblbge1dm^*MoS4#D$sh7ii3?e_`-3~Rc=k_s>yOV{bNP9;~ETg?z|@Qu3+4wpJ{&A!lQdbh?FMZ zqpmtz@mkql@>Eu5@J#EI?~Iu;pXbbgvX3s(zm3Q6rizzN@a@f;m$?Lef6HsvhpO$( zV81Ayy-Gdha$wwLuYPYk#~VWPF{)#uDfDga>0jK<3ipK)vDkMKtAA60|Au&H!PD;I zoz-bxe1)C$nWcH|6?sn->04u1AakuHb&}D`gi3j+lt)igna_!_Dsg_}fjs>K$4oF#cPn{KG%$P%H$6W=0Ek zW(uz4j$oGFmfG*^!nKAE|Bp))_Tm^ChDkK|q>Hofovi3?^Ry_JuPGlyvfxqw*`bvD zMGZwIxB_H%mA}xm zu&vysD#h|mIQk3Wie=pU10wqb-t#0m?lCeJ``GdP9!s@tiyiNX#Evx6*7-0$KTAT8 zp|SKG+?9HP^u29jJ`ePN5RL`9N}TGAR;3?Mqj=o0#-ruP6n($iThU<3h}H_*J|ICucS(FU0+&qfc`f5(=5XTMUzh^=TZxO+jQTqer})78H* z{}#pX;e3U({XsAfUC|LK#K~;0{p4Z1#-6e6C4zKWK8so`ewZJV=)kC`-lKC(_APA$ z`@^QQfog)?*)7^R9p#y}+Ne<{_fjo;TXGsC3mrW^WHt_>MoQ~LD6L*6atSZ@=i zxJrO>zP`$lZEw-{7zH40uY0Xq+h5!v9p@Qc+lo-Bh zVTe?{EjG>72CP@aJHz)Eb`qUn+dn>ZVoI&f5B}@<^Vq8Y!{^r_cX7G*2pU^9enZ#G zmBKjV^F1FGW_3m>`bwmK3hj^*q+QbpLEebJ^s9 zin+1PmpEV7-ViK$rZuEV8-ed?-0aolgKxzxJp1Tw>%RDZ>8LaAU%B&$bRVjYe7s&~ zBySrerTDOy6F_DsWS5L#CCvWkG(PEd+;(*Vt#pxr9GY*R%Asu3Vzsh$3L6z@|dRVEA zP?sAAb-9nY+pq5048VZaG^e!WZ3<;8&X4GL(TnF^A!iGCoOd(vNgg!t(A*oG_Q6Gb zyUh2xHbYpVkC>}W-Itcs)WA>6FJd@*bF#KaVE$r&9;e}tM%9T%)h0&O-0!c>@Z9iZ zI+M5O@f%L(9RFn9ljjb)R_@MB69=sJ&~24=UY$3%Ar1)ORq@+1!`GhZ;3p0Rf$s2a zo$(VtrYM*_f8LH%0JUblRQvZe)kAgl{Wo03+{U1S*-7wWr&N13=tyg%b|{EfQFxf( z8-oOq<(73&U?CSVwamqpJNjw;S;d^v`P(i}QNlj>#9Bzi`&LSq8Q{hbcuvMSZdwJ? zKxcrn(K#D5_BR?x;vzA=POx8ABR_az)+*FNktD^$=E$c5rP4#wI&b1?`Buk-z*J+O zX<}!?tA8%Xbr{dOFj`gf=oCjpQ(|DX;9N>f=6GXryhd^VZ|`)q?fn#myys(j9le^; z)RJsXPGhs?@34AdZr#7}YAk8Zvk5_~+InH9leBO+lweI81gO5&y8>MF29jqkm(NNw zO5-(4NR8iXe&e+ALL~q<%PIhj&LrD|U7MsKZ;MFsv+Q|q`Z+aa7-g)KWyAGyvtxh; z5Ev92FwiAnb?q`(zm>ae5R;)CkkPb#FNrunV61Vv*RZ_}Zn75XiqLyas zEZ9S&97$zq6v&M{!`E+o#Crt z%~Rk-B40+HYGjtYQW83(^HS1!!uDYJ*4>_kK7_se4pp_QZM!a<jMYW!A=M`^@}f4QB0`B8FAQ8-i{#cI&o8im_)zsO#(5pNb^ z07I3hjHpTb_1WOLh1xAy3j5)RQ$264i>62%XqtQ(+5`0G`6@?2SVrS#YL`?dC5|>1 z_@3N@A?7YuXF$Hzw4x*I#aJ4(0kPcZfG}Nw+TMQM}P&XwE=w&~SIh4LU*SSFg_S)=;&#Ul{-1UtVS0tOr78;JAsMa2AqJEf%LV1Aq@h|F{PwwE6BWh)cIid#o~$|gsEBIvKYuy=^*|-?*7SB5p14W z#gU;e2l|-xvkW>hBx88S07pZIF#r}2^9YU8MIZ!aAIpt4Ip^Cma^^C6^^vM%BjIdG zKaxx{>jG`&<#$K?$^C7%*@xa` z%fB>=UK}eLlU?@<+tQ|yQ#N0hTHCc?btbFl^je7HaS}$~NE=8o*~flFT;Xd&PgpyO zh+5WQ++*9)Oe+&y5-p&+$@R1jYv^21f3J3Bj8Sys?yr2tMW6J?rWs;>zAu_}AC4K+ zB*te~+B@VY1yfoxii1tb889#Fp2@WaVXr9VOb$(dk$zn2;h5gX8w}7p`M>mrasfbK zejfk=!)}~q7FlbEPe92S**MtQGuvy!HTiLu7IrJeuj$IlgraOKh~D zg>mTRhPeIGF7)Jy8~K`Hy;B58G=$og1;@VTxptn;AuS2 zXhWS!?Nfir9@wFP7an>~>55P6%DTL5SYArfT;_tA*%PSCg#hW@DJ!~i&)70GVhj@` zuImU&p0ss$eV}S?h5pcqbX1IVl#F!bk96Fz9M8|sBk7!4pMK+9s=Vb9b7jeW!<7f4 zeIot%sx>cW9Sr}g+2i)Fn_n(vKN+e2%WKWkH5v{@g|4>`?$fGED82vuJ?m$mq9X#@ zd?u+AcXF;ng5t7faZO+QkV3foyR-fO?$8Av1KKFDvlll>$ObFsI6Zt(sHFvQoN4|j z?L-Z==M9~ZeK7X@_&s>Lh3jeEOd`p%7SljVEbb`8c}a1~FqW`9nHbH`*VHd%v^085 zOXmD%=C_+#gOm3Yjs?f@iGJga;*VS!?p+f{WSK0sflKfbU%%N`Sc|#to3N!;c|xGj zn)dWP98CkiP9{u0iLg?IjG=1*@ju7(kP9`zixnYApo!cV*s_SM;K@1adCta&{YfpbR{5=LzNt(&(|W!GWG?0HRd z>grt~mnGde_8{080-y-L1E7Yg2T$L$IRy_?1KR-LWZn_fI17j(wwvl3g1m)zaFI}* zVI7Z%ZbeyS>oYk$Zk839Iad5tQDl-S3WW@70coGv^Byy1R<=%F_cU-gXry3Iu4R15XOQJd&hW6`}eKg)I0yR+r zZm@D#I4qtr4@D=yK43nMQnH#1>%@DDkcwG{_@7@NI2Q|jK-I-Mvf1k&t zj-v%cftP4Y_J>kET3Ct+TLVP(QyFGai#33OE6$$NmwL9-qG(UsgIR2zRAFoG^oHWg z8FYo#F|Y*CBdYoMGSv??D4yY1L(KC1?&2hPpQ!x!cxs%1?}(WLB&Tj)*lkP@|FO-u zPXxHx^s`kGb2fB368kFcABx2y;V5h9D#+16B$<=tQ%A$U$38LCyz>){IbCG%;83t# zQHzv-IsD`qO8L0|$wy+AdfI>E(fO;55r?}-3`+T3EmB)w3w<~Xh30J%Y2EUcd3c#H zVe5?cEBoOwGZ(AE+MUZer-F7F^fA;#9uX-5sbLfd-SrGtHpD~|l~azVX1&f1)5S4I>s$R%G-r*dd zqA2db*G6Qq@Q@URJdR}%?2@fr)9KE$z4lR@5_4~Kw$Djbwo*)(a~vunVwhkAV*!ke zcP>a7I$U#ys{5Vy*CmYfHSB)bGh(T;Pgfqa@yLJZyRPtK+xwHJskH*^jhO;@rT{4& z2(Vf%(S#=FEj1EX#)nP>7f+Mo-ze`5#TPAhq!S10$+(NEt|B>#G>Bh(#N7g{lAhEm|PWq6mOx{2Hidzr$TGE^w)c6X1Qx>B#t6h`5Cr=FbF`K23Xo$tH@)5YktM zhDlL`#9Za6fVt&c<%C;|zhP1H-D~`}lzRbuEqoGe0oXWG9nG1 zn@YTjd@zk_O>18z_eUqkfkQFGr09KX#`LP<%a6ga@8R1`MP%;f_>i??fYA3=!{a|%GzKHsYpFlq>qQK ztj@;&>=5*FT%4C&J!>cI?`2`Ea1NaWl@gjl2%SMlx%_Qv+(^3bDJ}V=uhpX|*K~?L zSl!m=Mk65Rt@;!%jM~dlKw>5;!nKoqOAoF2?81J|KgbIjLI!s$D9k0^?ljSY_?Kql z+`h{9E&M{ohTWS!%XF+6_7zcfNPa zIJg+02)kJojB#f_Fcrgn)DViy;ev*N;>Ye0uw9gwf;lNSuty9(eFKtj$erMeE=;&2 zHI=8iqG8o?y)5ue1uTln+TktO4LZ_sLZSPFIn1}rpc{UveQ~D z^ch$!D7k;MS+z$w%Ta7F=rmQ6kpyhtTEz%Bn;&n%qqMXgY+I@%u82`Xxs;bZ`Xarz zD^Dk_3m?hlWNGNCEm)v) z%JiIvyZ<7Z$U-4;;Oo%ZS7q}Jd8umQ_~vzk^kH~*Cs)ecmf6t>vD2^en5{J%Z|VR# zzQ3M1(4Fpw{mG423T`Q9E;pn=93pe-!M@?pZ*0W;XJx*R*|&6os)-vXZ#p6|pcv~@ zfP(;1i_9L2=vd1!E7gj;C>@oV$*4kX13zGu8u7qdAdGxaTV1zzHBw|POJW5#Qfkx_ z;sk>>A+&U~fsMW{{-$jhK9e;}>H4^a<{2pDo*~@Cv zO6L{Nt0E>m4E_D^zEqK9waF*d!@Vr(iKVr7j?xW}G5r(V* zeR-IbslDyxV7XK%f+VcNmU_VMVb$|h_BGU(koAK`2Y$qP734M4)O2+f+e5Bhn9;3P z$Q`)CSd5nAUTt-OzSTHYsYpdte3(XBFLLtAtKy*n_^_3wjGSdVG1Y(UojJnxypXKo zmhrL5ug1{+s|76y$4EYlPvV4bo&Ms=vFGk9NDk}>(0?o%(L8J~cMO6Em~wo78@~Q?afE&I zz0-$031sMfAm>^8vkf%MLYAN_v>8Kx1o zjc+Xt%@`*=4Sx(VK(I*%ebbihPsYm$$q+T=y%8``e*^2y*USUCaqhT_RGn0pWF(p@%@tCc8mu4@r zQ;j=DH(Kq)SEqQ`K3!fU!7TRs`(WLYD={~NtAP*Y|96Q&!v&#(woEzbtb#E9%eBd< zRoYM2j?lg#r)%}vj(H&+=LnW8*%MjszAk-^&K=KopD(tUW9^mQ&Djg4s?$-tk;dFBCvTy`tCr@1;dGr4VusmD5N6E zqaq1*K1*qE|BVgFd%5k;XOMb2+NG#P{QTKk-K7u{elG7UYf;auyz7N}ck$=!Fl^zu z2Dq`Izc10deTg$lBB~V^&xcyc#^Pf&{s+vUem!YusEpJf;mDB-5r4*cz<7JhoZzK3 z8@lS^c_q~C_;1j{P~pu-eoN-u#4qQpdPZvOPYj*d6*(<7?FtkbP5V;2UkfGz`G^uQ z_%67VZjU&FKjrDk&%O#R$m}a#`ux*Hkk)zlKpnm4B1<25U~pO&Rq_4W6Bb!Y@=^Uq zjujOCkjPAnbP%s-JrptBHd=M#5fZ)pdoNdA9Y5TTWt&6SdP~7g(oRk!o`h-vh;IZL4DhbwF>slvE$4=Y{S#ls zZ24F`25ym?A5eG?!u5u#WA^qPI}nW0tAaomV6Q#!omvYjGB29{E-0)?tO91pJu2gI z^W^Id)7le%OG|(gxe!hG3uNmUA8KXppX>c-fQLCt9RW|fP2h)D#lNjNGUcPd9a|_$}x^)H6~E10Q^eqR^Z+@82$ zEO$iKFc!e8?X&Ve@m)9wWQ~%^p4?#6p0YQoVfcicrgT-aL3SG-gPYyV`xBGjOSII00ubSoIE$V|FFB*||LDt3Wga)td+L^{+B9T!sdca;c&RkLMaZxOm3| zmf)=nrH*b|FU7Oq5<%w|K=&DAFk3#J^4_EjD16k1+zV&ks&^kER%v0S{aJ56-$ z(aVxAT9?^zCZqjq4qPI;#+gLZgff8F8`{>J0tvzZggyH$NJu|ktp38EQ?x!#i5l@_ z?nFy+Ms(L#7=RhjN?-gPR{HhE?ddZ!8yDU!;G=pbYWAKgg+NN!u<%G?sEeG`AVhke z!)$4DSQpmd^ot{f(g*yg%kOW1TZCAn-yf|5e8fl83JUbY4O5zp64>I@r-ApTT``S` z^+%?Zd?w%7k5pWeo>XgeE2pb_rnujj*keo7PH(Mue8OX>yTIjM4eou|S0g_&8b-%!(0=r=Bc(^#SCj-`9S9 z*N3GvPHN63)o3_Wo&9NujYzm<#@@Jt|M(qyv|ibP&A+Q<@IF7Y*`VI=x9;2i^NBt*Zx*qmpwFD50ziGI9 zGF%N_>j3mxlh`Ka(kpa)A@%U6ygmQ7CvxwUHx(m*3kgehf-)+*x%*8a9+K+yGU0!EKK1TH zO!LsdoF2jWJ{+-TkRJq^mN}=_tat8N1I}dueh?6TkWe%z*xSLMOS}6-OpY-sJIn=T z{SE)4>&N;2lE)OK=0=%*sxsMxStPLbJNbk&i++RqAPyg-SWiaE3QvsvV zL!f=UUtAcmQ223qjn0Hn-HH!DljSk!P(>iusbw0G8aJU#W1}?hh~dWpHHz4`b4ehR zblW_#t2MX$7ZOP3ocD{|&kL=X!2F6|hj9dip0v=c@kXX-XG7R>I=Vt@D}zC>Rv0u_jQkax`)^b>Q}0NNv|5N zG2N?qf-II(F?UydYI~%3<}Y^t8z!Y+8?skFdi{M!-dgUb^o2;&m6ym8Jf|#q0`u`6 zB=RWnN}lnW-e36<^6{tk=+9fK=V_RY6H8RTq0Q+kdGccWGr` zT``B*2PFs`X|4}s-`v$>QX*ZC)%fcB*2bnGJ^MaKoEypPY^kQqo2>3Er5pn_P;(!t z+T^t@Gf}i*Z7!8q3~slXi8T2qsJVW*Mwak*<2>j7>c*X}8aWlWU7v8K!WF&_qp{Wn zp08?&xv$*ncTxntz2CdlwrGCmPDS=DP{E`Nz&jVsp+haiK2i^XoAgPvoN4yPkkWeb zAH%}0Pz5gUizi)Q<^O?C;UQznVU}7LZ3@)9xG7+u_BxA2Q4vn%9JUz6e7-{cg@{ERfG(|6Z5fHeLQ>5$>(JT&XJx0>|am*uz$%5 ztq(j!cafiKJ>&BSz$>oX9-3UzP;A<8Bv?>V+cu>YOhtze;EFyK&K`5qwulmn`Fo+C zPW-)W`lpFGNePWKRbjo47O|wync+F->UeB5>I9Vro@u50W6S$5O(7&%-D!_Ksh$$y z)A;$I*|G0{n%ug6gH9vZsC;o|#IyLw3YJdboUHWe{qQpD(tv@Y8|%Qm`(7DjG%gF~nYaOAc1J(v0H#eSp3 z5xIKfQdY~&&eBm4f2mN8i2@scWuqG*HL-_~qoqb=f2j)N(kqgG1~xh^Cusw=P59f| zJl;t8u)~>qBbb)*H5|--Xvz|wW6-&|3hI~PIs3j5c{-8gJ{c>oK6FAv^`!lPK|`L`~7e3s$Sq1}Qs z@ruUR1Dhi{f`NA2CGp-1Z#UFVbR%`%KXz&~$boRXe6pWYz469lBDIW3I@Q19U2Z@! z2-a^7X!b89H2X)X;`N_%q2e_E>~gOK0AVv zt*DsRID}_EB1l*o=&D%o+C7SesQeJDeuGh|Zkx?y{#++3eobLoz%6R!=bAqLuRIDV z9%5sdOWZ3GDuB;g;To9h9B5Uoe96*{z@Nd(-Yt=bk!=8$LS!3I8^KC&?pA{vBsb7` zDM1J(Mi>+|5b|F!w^ko_*jHqJWf8o2lu5G+E^EiQr_<*r%vt#_nW1>X<7? zl1gNCyx#g~`~t;N`u$ZjX2nBTuzBx>`H8WuzSZ-$TGZj2w&s!GiDYR4EaX;sykD(w3TK6{;) zk5Jfu3QdP#f(FAR6Ny(&eXcgtC6XmEFcqLjD zqtqvcH%tk7!>-%<_j{ZT6f^c}zX4@b4-UiTFn(z>Z^b4rPOi;fCsiWy4>onrah0zh z{rF0R^D}KLp_Z7y4pWABoKZBMmsAjV3D zWoDZ8%zjs^ExR~rk;wP(wD2tdwcA>m=fpl?WWtTg&6rTtbfhW7aCOIl{BGG*a5KBC zNTU3uI--ACndL%4c$Fc}4ax8YKT^H9rfmUNV)6IgL8#_%P7&Cv+q~fU{)wS7bFgLg ze*P@rK0aip)m?+$AJ%_-1vF?LJ`G9%h9^$9nOMJGQVh;8UJnZk*bjXsnKK(?_f}bH zS6q$Nb@Pcno1G@L~c_Y7_!2U;` zP>Y;wa99A-fV zuVjZRP5|o*DQ=)BTK9jXx){6?@Hsem+YBsU(`~|%ZT>=~J$qr*BTqDGX#)Jk(3XX1firom zwTZ5leR@O8G!8f-9z29xrmjS7ATR7ep&#M_L2g#ki~PJwkpeG=Gm;VTM!L!dLN&1|#xvA*g}8&mWkxeQ;x<%C)~6kHrV66HH%VYik)(^K zb^q{ryaHVb5bh=%6kdkXNR3z+-Z*m0He5;uU(hSA_CGfgb~jF*LeQsQGzWe9q0b2T zaZ0fQ&k1H3%R)6?G}`@bME>VMX(+-N)5tUo`Numh3Cm78YwgX4bFQ8f%R0+9i=M z|le?y~3!y+?0GBh= zHET&19M9f3DOL%wlB{=f0AS?Y4b~J8a3cFFbMB+sY_R=?&mnMv2VC|4X>lB^-YJ4V z;iuzpT*-2G7o)Vsc4kG@o~%Y*-cOVXy^gme$ zEc!DtqS9$3`{AnT=4dkGGbyyIQ+Rj3!3?jtPdiGrXU{p1OzSJ$>|%WO%rwINKAw^IkC1bj*9FPVO2X}U zYA62o__e74Wmjmzxg(ynguxG@+GV)dX~8-WZ-y3MP@>avDvmOqO7VSC@G&~%2K+p? zwVGMcnZ;ZYlwS0pR}3s1;rPJiy3#Jk_+OKv^QZFw`I1h73Ly0@xT3|KZdy9~hOxwQ zoq1mAuE_C(i%}!>5_=fFjkk35oEhSHlbeEl*|H8-b0NjJbS-B|SYukIv)~Ak#l+Kr z?M_$&0pImNzhZ1%bp>;W%jwuYkzQzG4U>w*t3IO2Y@L3I<>cO*1gMC$qG`YR*3HkT zP!Z6&)c84StizNG_xw)B4>OI0wD<)ft zn}(-t({#7{`tnUVJc#TNk(<4#?VEV{E09_gbs80fh zd;)dIKLm+@Fyv3QsQe}VDSi8oLnDQ9hWo+JR2rH<`MC8Wa-`~`oDHbxZg(@8jM?{2 z#N8Q?;4^-1bRcDW&G@|7mnJ{&2p}qsXGp{3c-tPF|C_qtwL{K-+Ne^Cm-^}1wK^v9 zSOH%{J*CqzZI(B_EF{(_qez;rs{m%M+@z;5 z%cJ9S?Y$*e#`HjFQ~A;cO=@&wBaiuO+j*1RkoEym=Ttyp^FI+(;5|W!px0F6D5U{ljOwaAkjg?yyN&Sp zi)iKL2AaKZ=PvM`fH4@nCq2rlB{41v`}2lR>=M_7t*z%Of#=MDmpE*E9~x*vpFuJ+td?pbTrUCjW=?hN8~#2b@Fm3*1S+!qh@O55Q25~k z6#7Pf6`KU5w4HceLW-`iS`<0Nc;IROY<6a(ws<+1&4DBNgh>+`qZ7JAr0h>+sZBe( zE8=|F?Vjlc%;qzC9+os%JB}D;SbRjPmmK!^e0J{bN$1NXa{2kotRu*L`m^(UU1|;B z*fe{yQ``m!lmhowucmzUV6{|vo#5*2U~2mQ7l^lvmZhj5?cRabSXz%RSIVVPdV5Iotza%hk>Za)zvE6Rqc@p6*KqqlyMP4B*p?qAAyuU!Q zc*e|q?pmm4lX#_DDV5$`(dD%~Yf-cE)G^(@myId~o@$rqzyz0TtE)akw0l2F; z=Rmsy-Z&ftsXXo1OX&8YsA5eP99=GkD;MP#!C!BJ3Q$YP@&+h{Hn2jDWl!)#L;E`g8w8{&p&_TcvQina>Q{hI7f^*te3Q9&Yw_M8I+{rVsi;%(`_ zbf+llp;feMcTi~vHgBg1Fx6XusooE44PqMD`MELc z4R5tjQ@Y3aoLYbltv<9~UvN1Ha`7>qO7?Xx_~0-bedAUnKiJW>1{*XBqdWs&7{F%q z--m3dv#*+d6$*l3MxJ&^Xl5SGx4$MF+aT56mE}LRq0sigvxT2+K9U1}T@xnYYWh!_ zw^H)nM|^YMR2cHwR5M}TLKDS*At34Q?}zmZfWLUR0RZBSnCWn3kvsSth#{ zBi3Hadi)ogn#M^@D zSzS)mnj#m*iG3k|vQYkO!VKTly zs2#&;(v>cXp%$l3SwLnVN&uj>OoXX2+n=u!UYnh?RRr>OeDD2qStPmN)NEc)!}TuD z9^9<;3SK1lm-%1V8t6?s-e@gsc_EO~wEKM$hWhq7Ue{G0B+C_k>w9XMgO>>>G2mJY zOYYpL9p&fMkM|*Y)1+x>XS;H-*E^=TgPbKH3yJCugvfb2)kkrVh4dSoq!&7P6H&iH z*U?q;0x7!a{Y^3`=1_0>=`9suJuUo%Bs}|^Wa;T~!w=sq06E$^H1^k5hjmLDJ<>uf z&1|xar&4{}3qIVuI%a?|Rlqz2JCuVqZ(41pm4ZbXiE>7I9247M`7)VgI39C|u;@K$ z>)mMiGIL{gXDw_kkUcjx_XLzr3O=HAbrzxxXUdn&W`8Dt9Hw$eqTF70g0FCmp&L&yUadW+sCtpF*R;clY0(l@x;n%)>%U$|UYVwEI2P)9rwW{)Z z`9Ah0w%|l+s@9~_kTAc|TP|IfTPWcSBvKG&cq>6)*bT}s+(<@XXaLl-Q&8f7LDP={ zxh41n4uE>?q*}_Ud_G#=*(z(2b3TY@roiQakEu>-FwQDy#yVHQj3j4MMf`YT9J^s zO7@4A{Ul6@!=DEhc5F$Lxbhhzs3r*E@o-bKC^3(k=x&N}2|AsuL2U{~cLo~Y|HzGD zUf_v`?1e_wo=+`Z=^nnfu{>IpF`7z`-b#IUYKlpV966g4rkCM1*(zi?5={DK=S>Hm z1$2n|P{sad$8!%-!)_sCb1O5^7(Y&-jwY5Gq%c^BqDJLZJ90;8gpV)7e%5G;!at`AgZA@BExvpJQEanLA|g6~aGg@2gJg+G(PM zYqRjjlRB{b0GWPIy^f#kf;4#9Q}%lMgwk}2_zw0-H+h*sbh z@hoZbc|Ebco%eY97jz)L?ef`X(Y&4-uKxD&%(rSGJtQPyex;9EJRH|(sSCJTIO7ea zPGY)ZjA7El290nas?IYT0m}h?!&>(GqgV}f!mpfx!!JTOof_hlBvSJl z;H_LMQ1cW^UFMi_hPBbCX9G7ar>_5bHQncWXNGd@wBw6U3YqqF*&W{8^6qrs%lXOD zo?ROU@=~`#Iz8TD62I!Uf8A-b;3&uEdez*x>W_NWiSVD5JvFV@2Q>H-j|tUbPl7To z*Z*X0(c+xepoa1N_Q1Shn^U?ck}?y+>Mrw^Q>r4u`-Wbn6txPrY8)n$w2z(`?PM{! zQ63U{qx?t9h2Jd?f8ImOChv2PvyDF8$F!6^UzCWF^C9}GX^v-{+89Ji7jqJ=FnuKM zZ8uf_V$<9CZKX+4Xi8(8ym~khQr-d3X?>&NWqZ2FD!`6+es=?O_f@@{x(_f>V=<+-2ahX5r&@~(|xV-7)5YUjUN&d9=<|m8#9oE=a=ol z_fO0^I~V5my$E={xykJjwdLOTYzcyJ)NHGqmGO3Tg$fvR=0F0SnlKlQ?W4t5%hywL zA#AF)nfK+N%%xsOL5F(VaDVq{|CAZW2uw%5%?!hc!JhETreC|2k_pQvlC(((@kVbp z+1aP5{NML~e9m!XkUal&I7_=?LY)51CMzh@^6HH8@_zTK$WkTlGRX(R z7pgafiFDLV$)!4rfw`_ywRD2XDU&)2)S|W1i#v!U_~!a56k%Q-az{-G5OCzS^TR=Y z54e_3*)Re$3tsF3z3=`?G53uBqpOrqu7H7Y48>CvEn0N4k}Pa^?IL5-BFTJO zF*Xoy)Izi&b%s0keI}-np#u8ksMn0^`od1gYOqqpckXTKoB6S)wg@*^yTB8*DT0pkF^75XHRvPy21~wsaG5o*^%@ax#+3AYlbL* z=JEC|;q?2|<&UlpJWZEtRTUo5*STM_pgOfkOSkBT-udI~7R|z8sA&}G<@)>@n*p{-Ymu)a9%d{ zQiF~9sW#L&4Pdw-lC5$~h}s1&Tlun@iiFny62A8wRFdM~&A&T7*BJ>cxAQP?55iAw z$j7XQ*DjE1t3yl#a@Ykb(QOsr+AHjCnzjKS5rp0GtI!4x%8$!(P9TzjQDr+it!aOX zL8l;AEGL`f)VEeX#BOwk7H%F(B#>|4g$OK~XGQoRF0zV+Aw!xqUP4>U@*S0$g z))2$=Jf4cy5gwr;RcdQGrw`?Om(J8IL^6H-0BLxvUl1(}f)9x++k^zwY^sj!rR+FR zpR{#lnIidvQe57;O)uX0jji&tYZlIfN>$&-aFjT4488N?>qx?(aMttMJ#XQ>H#4HgmOgL94x~EQW&|-ZPL!F*3cAITWD^%I?=%~l^f7bmyrjt|M#3%6g zj)Y@Xnevai)b^6|Y6VOn%7{BV^3?ox+sqs2F=@_Rt3%$EfsOQA6=3TcLX7CR~izYd`80oFErz#bg^B6jT@Z22QxOz*=~s*mno} zmXEY)fL4RqSg+jKDK3Tq{4EChOLerv#T)4*z(uMF@2d|nFS^8|#?Yixnu9*d0tV8gU~z?gZ|SK#E%=A;8-L)MxW zygS%|gG0>QcBoNWajJw8^}e5-p>%M=xn~ZSKeeQr`egGLevp0ptuN}7cNt^fXQ+he zioq-4-XLna7~5~8+a(B?JOPh|1p_5SMNMm~!&0OJzinE>W4|VNUbI!2NUl$1=qe&t zO>wXA@#bZ0%=zYHzDHI8zlUJpd#nKBXnpP6>%G~FHdUxTJW#hO!Ucq6`zu*C6|n@r zRhCpIJo9qtOLS+@k=PYfcIWF_DO}uESq{*f>)`4l#M%)JgAn^EAeeS&h4{d$AxWYMGoyG*x+8Q%Spk8fdYoi zTe-<=b!H-RCqzI4gj@1kW?rbKN8-jMeWv+Jc`Qs}SLP+@X3L{$WVhuwg}g}DB9~#N zZyOOx`#3J!O+gYD)xU?ZtZb^bkx=El7hk+3NCC3}&QH3#%dyH-7)wLmWqsf|y1Uj@ z;rsjI_Zli-prhdUFE_1s=8b;`S%^IbBG%cMH`3$A{k4ZqVmt|Dv5CKSU!3IaeFtMr zOXHabz&|w;DI%#f9-SIDhU8{4&LmL=Z$(Lm1Jv*Vr^Yn!?!SR??3OZzfNsu*TT_rsE6n)(WM5U#U$;&xE{8m!AN>dB_hot?Nx5vH9h5mi zk^czi(;zH$aw`>#f{sv|HSJxQs(gB-?zXm3Czti}D3dz0CsI#~9Hni^$HKYcpxR00bofo+X#d+XGpV@s{%~mT$Vh7a^ zHDIuG8LflJP(8s*!?!Fzb5-z*pbBXTv!<`Hxl)XEdP)=F(NmtB;#F7&SrLeAiTT5T z2T%NOR%a_Z8uL0Jtel|e@y7Xg*b*qid?12*S20mbUGAv?Owv7Tsdd6d<7GZe6l62|9+si~vPwN?St zwYn8NT)vX*Tl(0J(&;sBpM}NLkgX@|BAwbnu6{xVe@nRjqD*?i(=c9JxfBq-K5x#`o}tSbi$ns+}0LB~=Z8=Mzssin%o?xKlLH=K9` zEI9S*XFT=LSEt~ER2W};5-aTyhX8T5ZW+5)Pdw)JpqiJF9US_e z4{Q+Xx`;d5DJ`LaA>ccj46g!7Q6(YF6s6fZk|}sleF`_~wM!OIWQ{-gd*F$-gAXuiJt^162 z@`1Lbt;NtPLH{qqEUbfD;^|E_U3N>>QfR3NXZ63&!X}>{!JwmVJ0UhoDs}lNgj62_(nI=z z>ts3|sXo{)w6lf2?fiZYIn9tF5+v#{*`~8~@6W%dY6G?tPLl>hH6gbE69?@+-JKmt ztO$1Wg=gw8N@apU!Gc<=#2U)Ltmr4~UY(ADBg zndiK_w?>C*8*hxX;$ztyb&fQLYLE+DZ}JmnBG2)b0}1TA$3}{W_RPP2mDYVx(1S?X zoBFyYZSLaAVDgJZ3Nb`Z;m44Um&@0WP~GuVg+VL zfnUE=AW3a*%rVqhb@L6vU62l)FZE6rnuXaL!KVV4E=?oYW>u|VHpYR&^!Qubn2jSU~ zf+Utwwr;mbFOVv(BPX0LzP^uRE53P~GuTPkLg$vQ(QUkavc87R>*42a>(Y|aIC=|f zwQMNCIdb~U-|}_=*b7O$P>~qP02b-iIYId8Me8%;W5_n=(<9d|N-gS9k9H&9k@25Z zNIgTFUOIKP6HZOBbI0vb0rNC%KcyKnmQ4CgEs&F%f-IGK@4!;oQVrV?-<B9=1^SDDNwSmQ>A7d`H~wj2~p1AxM7QBPPz=7quBj zo!fb9CxY#+A4q+QRhNqVSEUfue*wok)H}lQZV1P_Q+7>`7Wo|izEE?*?334vQ%#FM zjTRd!7P@@o$s6BKUA`>1Z9CDk@JM)`r6-eKcb81d-B1TQCbDlkvM7D(^cx7K+z*8+hvU-l*LFc?G4OQ)c_t z#E?ZFr?jP$2FYm(w|K@91#c0R_oq75r1f4DG$ShSOm%vhmV8l=Kva&4Z+lP4a9Ut+ zGSYH5aFa+$f($PD4gh|!%>exNAEW}m2OvkM<+_6fs2ynL^iV}T$C@)z=C1{IaksvC z?CHfxxV5AuUw(?<-v=H|&+%JEZ;+b>dT;gM$oHtM zhLk6GIUgF!%8s6Ph*CHo2!=M#5(f*t=0Ga70Zz9hs65qkyl**Kzk~GspYgYdJ_);o zB|*k0qq!SO+XuC!HKDmaEt5Bu?U)lQ@4(riv@fkbWnKl-k+XaiY}9<vBT7VsKLhT2 zH?Q;hLXI*MwqxAdXdr;w6)-Fd=Fx|khq3y%sMcBl+68p}-Bz&N^~czhs$8e9f-aG{R9pr3{dmJzL= z9Oa4R4{j;M-6`<6PaGC}w@t5UVvJ?S$0Q99@1Z%^_Z8F>(U_iKV3A% zzGa@?)JVRUIna}?S(vL3vgctk){-@F64qHrPCJAtoPP!9^W_qUPncbIb?Gib9TpXk`6m$%WMhEudhp)8 zh|x=2`If@g5q6GwFO%~6CSs7qQ85ckvDCaMqO!6ouboz`6xn7{t- z;{14a-zHhGG$&Cl&5;mVw7PP zg2)or7fnAi6a&Gi(%a^DrU!hLUmCK%FhMwm5nZwP8bIW_*Q$@oK_~=V_cW=25#2>v z>o~mFpdU$k<2MT-A4Q(`SV>zDigzj_b+JF*OMw5mHqzz;;c%Wd)%&}yg9t4D>{21*@1Gh4tELGpdHtzBwF?Sb`Berrk0ewE zF{k%^Xs+|lySbnQ5T{K4axn^Ks!Q6cMx6;v&rdcu<)~jMe_L7jg$*tyJ$X&$KuE;5 zs|v?9JQdPQ)R(`_9Oy{*Ll_<{b3^nmNx}qAXoI?U-h8%WuOoXCnnF6Vv}{*m?a(~H zqNnue?q*w$Ud??=WrM}N5r0$mhaWe@1Q03QsbOE9vSPM9xsw7UpffIv-N9V*-mL&oY@jc2*M%vBDjivE-8YThC1 zqM}P1erdn}t&nTiT1mt83!f_%iWV1|77s5xGvW?@xOd21?tEpd>3bN;wt&$ZCRN1o zae!}34K)h^$48~ydD7_jU67yC{eJ44uA-kZbfM7id)=iKBlB6a;6xe#sRUDiPie+7 zdQ*tA(fgjP>T&a=p8|#jLf>+VvPG)$_JC}D1LnPq1-Qx1k_Oy6C#N%#_@FdI=G8gj z-8}J|wRHzHJO9Z?qQNt*F@ljdXEy(tit2wSApib;TT<4qb+f|J9~Z5);&bO43q$Sf ziUOaJQ`L4dbYmWFeNB@rf%K#x{9SQYUg0e`_@O(?N4UrYj?Hw;Nq{2xEVE7 zVy|w-B?+b79@7(`#t!_isu_h>T!12n|Hs#N$5Y++|3_44D!OP`p{&Y^hLorzvW}II zy=9e*Br9a)C>#{Y-YcVoijI}NLdqebLH7E+-k(F`y07o=pZmJ*`_bcmoYVPy-tX7z zISoruk;5buIlMaPozCOW4g02%KEY z-7L<$6&R$`NJ}2UXjk@D{u`l5?}LMZF#zxhu&_e5abC@k)&1k!_r66(h2YLz8sRDh z5#`X@{`-KbSwMnj)Tt4v!@G0jiK?5E(5nB1v{E^<60+4g*ba$dGynk8ELoFY9NXBf zIyD>wp5yV6m)vEWTb|s47*J1KMSrum^P#~ryu0opKk~>}a)b%qBXpp$VAQcX+-5_# z&5Y{Y!Q>MvHMq*Wrj*OK*|ZCo>p6EL3G?&CBPZWRrh7vm_(RU!df~x`%uQ06_1an@ zEyn#0vPE^_j!;6_h7IRSM@tkBwx;{%i1dz&pzZnn=4y~sH2=I>_fWJEviBiMuMR=K zmi!-39mrmPxS8OrA#`Cb$|UT#W?VS>GHx5Zw`=IczWUQB9^g5AfR&y9Sy0BT`C|(& zrA7v_5*ULynmvqpaO_Okz`IXZWPc7{IdJfKs%Gn2Q%;=it}Tvq-Ktp>1SWh<4f9af z=Y9^~;@5Tjjs(OC4c`_F8j|Fv?yRY)46*Euu(#vsBmAn!X@DvNAeF#!1pXGflN7kN zeODpC7=1#r`!fUWsPAdT_U=0JK4oV!uz8+p6pduj0JQ=R|ELNS1HU5YF@T2gc>GD0 zUAYWbrPXeb)ilqK@!JuZbQ=RycXW1c%t{kUCd$FM-uhxgPv%hR+4s*Y`WPJ66-;4{ zgtb~fxrMSUxJDpI;8>z<9kLX!f{>mlESFvvvJh&`IW-~B$P0y)*Z6|ijUM~l1s|9W zelvH?>%P~^=gf>xdR5l3JsSp@Z)?vzGj=XIxXrQg049(*SAp?KtIM9&cPayM#V~)| zZ*ImH zwBU+&@%%Hv0h4R|#Sk=`r==|tu9(k`-M?bk0s$I4!x%lo0b$W*<(5~^%dtZ$2u`x% z0Biq_U>n+VV*jN@+OBVCdsm^6HW~o}55nQr=CG#_rDrHIdqnvLM0^r~aZfE+*YT7Snn)n{LkX6m?rrJ^!%8QN=o^x2?RX{$ z#1rW153rMUC%vsflqq2Blj(r5^LqfsUaNzc$JnKBdtN207WrIps+gPav4Wx9UcnuM zH9B$|1iLV)@vrIYmjDc=FD;V(%k;uWgaeV%h3br3-(rw9AOxxtJ3~7C`1~`BFjxaD zwc|Al5%)6y*r<9v{?&R=?O(vgA5Fb_$42}Z7HD5D9V$i7IMj9Uk&E82x(*P55s}X$ zd9C!#3A$M$uYwx2j*l<{Re5n@i!$j4g57<`BhZgv#%fsF#~9z%k7V?Gss+{53Y+=dj}$a5m* z&jCDse~+@haFl}Id95Jz!pLJWxf!FUmPS9B>U=Oh*7@_kNZR~<`22qaz(J}?q^{1b zwGloXm8C)l{#Et@&kAG?y+D~m>!udw>}J3Cf#%Lw_ruh_M*1gP&a2p-? zfmdOkeHQ*J{_W4R9IqgMF^QpYa*O*clb_wi;xdl~OFmF?>zL<%zprEH=5-Zv>=rb; zFH)UefyKxe9THb1Grsq^{4~rH_tz}88kPoHFjuB36Tp!8SP_{DQ@T!HJ%Q(X$97N_>^KDtcvs4TlcA*u`NJbJ(!IYwrZeqc{jtmi=<|&KxhvQOhv+fTZ z#xzS5!A*M-47Q(xCJuNAsWsCBgwAne_{@ zUCbgA=B+XB`M6ID_Q@&QpF8=R^D)aSV0$o~*A9#$B;pD}#{st#qEp5O4PN&O7)mL}OWEKbgj|s7Yg*!j-h_#|Kd{bLX8Wh!a7hqnbP?6n%iD zGCGOJI!c|gZFk9;iCzOWAP#tMBLGqWGB})UPi3n*d>#FkN88!vNGFy9;S)7+^vx(; z3zSLlxB$+Fh-}8=+-fh}rL#?dc1j%=XV=QB0HF*FHoZ$V#vb;Kw2*M~d-b3JE?eun zr(VSQ24J&=%0mm3>ZqKj6~D^a(S`#7Unjh(mN^3cFe)wkpmFx9Es&6+@f1r)d7%7j zc>fE0e~aqyG!POw-p&1zXzvY#nQ?$I;!w2-d|KUoBD(8e=$!p3dkR*b@DuZVYYFQ9 zGOsjIuCzDx8BltzqQ1XZ4v9#?M zRM9H+97DRzzj2xG#gA^%MLzPgf|U;wZQR(Z*=XjCYr)x}n@3)}?3K$|k>$@0s#J*MuR-8{={|7oVt?-w=Oxe7~h zrza^y8L^5>T2ygq{00V0dDae(vsu?=FNOoO2LOCE5=3I3A0(+e8vmRx|HoiJt&oI2 zAY>%X`-&EoW1z@eX#Eni;{gnwV3OVyuQ)qnByVUv(9)ctE&2nuBYnt#&p8~U&0Im- z2EnRG^Yb4Oayhlo9?Vl%Kj9GZr1l%@L}YcI=*y*XECQ1;dnw`l4WFAOUp78Gk}4BE zHpXbf@p7{Z<*4KdiU5!tQS$ZM@b+)W^5n?JG)$$kVtKM+X|iHZy1rkI8gJZGmecx< zw?B)wKbRN&Nw}T2Qya3M;Nzt>JQE~bW96ftpy~vT>*47#Ih^}CnVD}o)O?Quqq@Pz zJ?hHcM`b)jK%fWr6+aDRUIHO&DlrAJ=Awe_k4xod*}j!V{Ck~}6-u;)uqkBk$U)K8 zHJW$lYhU`sfgzIb5!|d|`5*S4N#Gt`O&-Rfg9j9E62XFJ+2964Z!a93+oTIBGC%)@ z4d`Oh`0g_ZgE)9~zy}Nh6-Xkr8}n-mi)kD7X9U*VY$KMOFY0P>QQXx}wMYI@2rdCZ z?a?5isvFiHODj*-$%dsHNmyaBnlK3R9eB|GXF%+~X8bv1^kCcu7uVocbmzKZcdmw- z%2jAYr}b5!vpP0W^X9s9$lh!~v`2>XG>RhA5AhYB{*Utqqw4cN+zk+%l>sTR+w*k4 z!v-38ks9H7`R1VIh}1Ex#{-&eR}aKx8-9BX+>p>EIQN30duX^)$rk7Y$1RLDN?5RJo2E5N3AoU+v6;w{0P8y;IzQ& zXhCK+sBj*Q0fovFP06QM6%;N)0*wWk<|f-bIzSCf`4RM-nl?J!)}+y_6&bwmRfXlc zig^p^Fln_{YA>0fY`VzE<@tJLc}MxzIfamCyGZP6OJxFG%A0nHn8o{tGCS<%@}o44 zzU5~r2nBDMEziHr==3$otL8H}LXCQu7s>*DV@}5{^kJ(-JSm{VGk!9!eh1bI4z0>l zs9*h26!u4=m-~ji4@(BcHhwtI=I)dTW9d{TaCtO}dmeS2S^QdmChFAW-ZM@+5A`{b zmNYX57e8x~Ve$Ok8T2Yr+&e#~DyJYd_yN6)lap%NTDZ!YR`41w*I7dZ( z$BL`0Fm-(RkxpL43-{`sTc;`GdOf%;i297v^(NB2)CPip^j%iEYs6mn7K%1>NE(9X zTIonUY4JyfWx)91)mn;Vxh@5~!&9Er(uh1;p1+;)aZ9t;(!3UT>zJ31Zr6b%&ejyc zR4^$c^MnQft8{_O*)wTQCIK=@WT+Y>P0peb3|J#5hHdA6m|;n5S%@#_q%Dc#9az0~ z;jyQ#S{}45v)x&dUHIs2+UM|ER5w6~nEd+az3+@&+*9q;F2Vzn#8U4RYj^F32%XM5 zSTGS5jk*f6 z0LF$gG&Y1P)44?}H~L~Y&OQQVT&oAS5HXD^9YDQZ6 zE2j2P$ZIrcceUWYN}_gAN&U1=YEQ;zT&`%S;||eR<3z`@zW}z(^T`jmHCg* zq>)-8G0&6baYuVs_j$nc(?OXvh~g`~vLU|maKO#fFB`|Nr$|3cALF9z#e`Y(Mie3D z<za|b0b2M*E_l1Vk{hPOv37}IU|S8QelU?5@|72BD92{VwBlaoNs)wIBFUclbb ziz6+*+*s5B69T8@A_&aW7Uz3%i^R%q*P{JNFcpBy$Mr8ovDC_Y7b@3YII_0J$UsAB zmgK~`s#{$(@hg#oZMqhi%Y+ui%l7l|LZ74zES%a7GRgz(CC~F%6blN=%1&K-)LRy~ z|ALtC1u;mFhIO|((-UP`R$^I}=+X_b-No!?n2LFEhEw)UZcX1|5N=o~RpeRu%v0)_ zXJw(MRH3K-RYc347EA>tu(E*xPMP<kX4o zD$goHFCf0>aqI5Pjey(_sBDI^WqHHKj$s!CzW)EI$kf~2s$K-G(lUyhvILotl=UjY zav0xx;A7s59p0s>sLnP=)y|AEHQoDV}ZIUA3+z#3pMxY5G0(7m#JQ!ID& z+CEb?VQ%n^YM`r%MSGSKkG#}V!e-$gjCn2mGlIv)QmTWlH`0z#{)!~9DxZL)wjkF= z+F8nvSANBHirwK)9u;&p$}&uU(q-JSPOE^UBeWo}?vPeKz{$h&v=-AN$W#Pq{uWWK z`$|`ML1MWtQ4o?LexIj1jy_hg7-CSji=ihvL$a>>J?ac3CPqMKX{IDBVe4eTCT2zZ zu?us$I>JfX^9hz;Ea(`_pJKm#;5rnIpywVVcItule|7)WKup!frSYfRtKt~^V2sED zhXp$}Ni#b-+^X#PY2-0%BxY<>wB>-2cYOrNMAHyL3oipI!opIw$j=j&@?=U$No%bzPW!f^LRj9M@ml6^7Ll*)(jVA-pF_r$v6~VzAuH6UiGgv zX4TsQS~K%rGihE=08b`T6Ccg~$UOcJpT8?xTes?Vtwz6&n_8-Rx8BnV-90kxw83sO zW66g)SLONXaALM=^ez676C8ZgY@f_Lp>08Lp3ojOJ7>?c>|$|2GEwkd@(z2R_0h7Y z6La1r3){;^jy31Wg}Yq25NXJ78mVwTTsiHt43*n99qwXu5-7-NQaB}x}VC2fHN zfILF?8jIh|0b^GO2%u;%bs5>^g0T`^9^8e*6VyX-43Vq(PDn($D6v-*u>C!{7YV{9oKod5GHZly5~6`w9^9soluIC|8*R-ly)hqW=6gm zcNDC_RvD~ZAr+YN-N2NOiB#^@C2<8pSy$~#2vGMp8$`G*%>f@c?!*avlt?6GiopCo z^;4yOb5Gp10?Q;HJ>;cp+zmNS@R{*M4#p;FUILx35tzF34-06rU6ynKR&>{wpV|Dt zcGdxUAygAuU|Yur{v1R0diaNigGyR6?SaAP=fP2D&NAd$&ntTJOtwNNZ1CewJ_CQ{ z-T$ZY;*&Ywx~1JZ&abmxxA)2JhY2*NVHOn9?HOTHw|2JF;70uIOIKL~}&x#WBdz&@*ji)`uwf&W?erPr9mq1M0-Z?3IUdWmoIJlL| z*c}3b##CR#=o)T}2Nn*hgCPX(25UKVSArt|`C(t-z!7rJ0`iVFIS`)h*otR7o~?An zSYP#LkcxGxQ3gEiG+Zgtg%1Jm@68}?+};r5@s(5E-v8RJFZA$3#Ep%W-7WZhOGc}y zEuYC!!@K}*Qq$E|I7@%h-0aSp4h#MVW6J*SQ1UtTFiWGn<5 z^hSXs1S-V!ii~MU`GP6;vdR`i@@ID3OGvvlzJXWo7;^4-a_&~Lyz$lMn~L)j4N+!D zj5ZCod4{)n(&-IR6W7enh2N9Of+(ryCqyQ)l`dtpY&}@Ary3m_S(A0 zUd`VI9*H$191Xa69G$jsymTB3471IgXGDNwpI{g81Fgc+D$G;$v!J6(0cK>%bS^^g8^R+yRkos<4mrJr=ddp_)F;& zX%2gguP8{I7a)R9jTonu2X=4}gj2HW=2eurf8M!uo|0Wh@;#mJ&0Syay!sOfj@PhKB z0Oj+aRN4qdn%f9{O{RfLo1Lsf0YU#Vq@&;eZD^q@^^WV3>RyU>W~!Z4L4YuuNfpVP zkP&q1>!J7|p7(w-`&2=&2rR}c=xVJtVc43=c-$@~bYcVJ;wKQ4zu7Q|mp$zI)(#l9C4!ay>> zCc|TZKkVh;WC`H~NGnF>VmNjv1;PQP5DKtjb-`nKDp09u3RmS(!)|UTQ*7d8XPs)> z^lLnYGPi;c5QVsI$D|{#Hf=54xisnJSDG)Gz|htR8$xdLdlyNB)P#C0Fnd z^qgzEZ=et_nDT>f>J0EfIpiG$6SG4}hW@ z#bE)~3d^Jmx2@q!Gm*!_F7sN=>x*;RsG1W9na^=!FaGIi03xGVR#fM9daoH&HW~pQ z&D0?gBa-H~)oxvQ^jpyL{(I4peMtI2Msq%ZtAY6J+7jEy=g+z<1yqU5#ZnSbNc z+G1r%yv9BTDE%wYGD%q`8}faGLFkMDT*$#$mmI257_Mv~G?Knw;f>uoN8WnXhqL)6 zbx4-4ee~eZk@+o7gP+28kt`jr^Ocn1{#zSnCXR;|5tO{x^Bp`_{{FEHJ4g)M3SJ8i z^&RsyS3GaRKQl=Mf*ur6hHWVi2@TgU`QTq()tVmoAc}F|9QAq4oE^z#69p-R>&=6NNblv#<@4>yi~+ z3szdPo(-~x$-(L8(?``joYFVi@w_Gw4=2+9#)m=yK$@Ge^S-sq|2AT>4XMYIhdxYx_L!hssXsqB4vhlI9Y@xD<`lFJhil)tiIo;*Q)}(7| zQo$7L8K7IDrF{ZO{3|F-%a;E}V9I;@??4xXXBZX!Q#hSa<6%Q_H+PeRQf)b9y|}uP zcz(m9d75a*O~_)>GG{3%bd(4`+emwa!=g1%=cc&h_dDK0HX}4_10o${5_)E+ z*Kg$2c~qyWJO3^{qIAA4>8(+Vg^*b>lSp5HtXLmhgtC#OACX#ZnFGwX7EcH`%${m1 zyVsfp0U`$@T7?D*b%+MLx^b#b-Wz>&(EYtn9dJl!jy{t}H`@`lz6zSdu1jj4c|7oY&vGp$H$4insiod5m>7qXB3bd~B9FrPK4visCIaV}j$vEJ>tR4?rb(V)IZpOc84`Y7%!g7?P!S1M0`o zWlyWWC5xU5>v?kQR~e30iSO!h3u6QJyWQ)jienJ!aRm)5IH-^VLtS!XH$>)vE4ra)hGxb6VNK(-fe$)n{u!umGcUfqG3<{Gx`{aP8 zcx8k}=hwzBgc-s;0A=SoH(KORz}<=MN9LF6<7+bCd;Kd~0#h&=t=5Dh7+)3~NK-ep z8ZvGDUx9@Lbn_Y7)y67Z9|zid+z5aQfYwNu4zkFrC2F+TcSGc_gd#X!ET3JWB(d0N zl@HUF$6@Wd*s+GC<#`NJE>tm4v4un9xf>P8th1gj|Hd^uNxIxyE6m?G)>YV2c3sU{{1t4Qt#3X)M{q!~YUR1UPR>FOD zJT(NMv={nrXle<1Y#Od!H>|m8`JOxphnss2Uw3{4xk-dp;5&&PD%2qa^b9+IDGCQ5i%*N z+0#|zZ#&Jj{Pofa-?*XL%Mdp$ z2(Tm5ETI`-a$uZ7y{x%Y*U$8QIaznd349J}l0cxq!=GSrdc^AF+%`?5v4DCfvi-a3 zQalrq_*m9E4S2ZlLV)L$!q(d`0LKdu7LPRCE&O2b^~*`S$zkq>1KZiAi!bANxwPS_ zBAGvAvMBsWc)2il_`r4$Q0cA&vH6K`Yp;|wQt>5YaVrE_q>csp+4(*c31MT)6PSZ@ zOL1u4x+8zRhIN^(u{2r^Ro8?p5_FySq}RRtVr~xpW!J?uPK7Louko|$IkItU)^8t% z7hrom*{uXO@=9sI+~T6vrEq$-EB5|>`^G7+UPc{4`n%i~1(q2J3O*Vjhk;9+BK&9e z$j_t3MjG9+B5Oz6uBy&cIq`m#(9AY^nBFx_>lkjGnm0bv2Mf9?n1Q9!`iNP({l-$R(_%X5C%B4jsx&@|G-p*fcPn!G z=90?wpM)2%==-SC_^7RSi_nDh;Z2pBTbRdJ#9$9Tl)XsoHslg{koxc>E%>wQ7D3q!jjw~TEwx@fFaXHHtp@c9>C+PuwZD4@ie zwd@{s7K^d&j(ck+$_6qTWPtLGDI2h2&49)i?dqzC=8WskOl$XF?~Y}Y#AJd1{J~kP zX_<7=;7yAAIflAxe`z+znH3b*Or@f^c%WD%&Lu?FttZ3i)a*ZRAun2j%SbyeSL5!N z2*b`mz6)J*uQ#S8bCy|c8J%q(e=Yv4Qsr8Zy3zAnRj%e^TSDsi9r!);8L%Y zB6CWjF2)E#>UNP)Z1kjp=-hKg9-OXWk@T2uu{l@ECXl7ls&GAGGgfDNIDhGe z&g0kf38TbcB%nm(6cAA>LHDjlWP9#IzViT#>yZ_pIXLsZet z@7wlcFk4Q|fn@w5@jxbC<&Nz|vo9A8S#wnqWLJ+~%nNN>bAX~i;l-w`?3a`9EmX7M zTZ9K$LOJ$>nJzc)4L5sa)?dXST&ooiH(6t1CUs8}xzrnXCsKZF^b%4b@>3*061~_z zt646^Hi0waQC1J()Ro@`{f~X`Q$GL`5XVc&_hDn!lOUzUc4(LFYI}nIvx-yT^!)o9 z-F1HBZ>~e)QWB_AB5s53Nk6aNwRHN&>}I~Gw?|@YY!VgG%RULo!#JMo*1X?p6-W2$Jd||o;*;n!ggl!+IXH@v58`bnjCa*{U-N+qi{ z34+N9;U}Xt3wQXSzQp_EQ+LSUGqOFSvUT%&tVgj-i*{vXGA z1Z?HsOq$I{8ZCNa)w2N9NRC~GP4ai+7Pg!x)fwQG$ut>M;X)5KB3(IOOua3HZ_zc0 z0J&@c zd$p&1bZU&Nw`70KC9f74r;M%Z=oTEd_R2Y8HBMN-7uoXtFNLLi*^6cD9#@^2qF%_gtfZ!_0O zLFaPj+I%tB&v=^-yiGM{b)ze9gLY-E(k1zu`x8Cv7XF~U*E-BWF$4#3bIWkh{tM^A zMDp7M6Cl(^iTJ1f;Ii$X0UvkQ zMVmc1yd)(vIV;k}dW&$&Rfi70xTR<$b_}>mo>_-}`{CzrKfuaIU?Wn(Ig2S%z$W+* zn-QVoECs>SapHhgC)1TEY<`Z8SeOvW>L)TbU3pOLViNS8orgUM2yZ3rqdof{*Vbe` z-IMIl9lbbCnf5qHb~JvzyXvVnFXNVbB~#qnvy^{GNQ$b&L7Jec^YQlUXL9PJ&SMnF ztA81g$ZI%7fy8&PPC>>kMZwPUxwWe@Z|xar_nxt{GT>VP$u~M9QKS(3E7q2`OPAvC zfk=)fFQHW8>&oQ9NAJDg!6i-S1@o&_lqs|sr6b2C#`qP$W)uiRWt_O4W4~}5VR&PK z*0s$yA=kug8t2t&V(t#4JS%VGQC~h*Jy-Q?Uq=e_t@Yvx-=i(rx_jK@w;;PW zEZ*M7psy`920k64UXjlPvJUqbJYJGS+Jg>DiOh3Oh92gyo^D7%C6m4&KM)`st81Tv z#QoPfP@B1mTVvgTM~twh%vDEG}af==1->%qn> zQ`cPv!xitF*U|ayPSdkID%6}Nq+FLYYuG|1WaiBz@;V?=U*>J5>uf-zhRj9&c=*F_ zTbGyyrcpPm+n98g#9Cgz5FL!qMDAEbbDT+X2gU=+)kRTt$cDVfgUmDAx4OoOPhA$f z|7740dyj_@*N^?I%+#;q=*nbMv~1?865T)V*cv6;GR)EJC1gs>;>fpB%Y8%;p@H%} z#X71Idr{t-bq6}2wCx!$m*u7?l(3~gQ3o-hIk6|CG8`qmf+1BuTA6G>#ZqxQ2UUt8 z759#OKJmKR$$hbf92MiE350f(n*+9e-4vYo&iZ$a&nC%{h)MW#R|V84ruC{kv2yZBx5J_gmFcC|_<};mU6zyYM$N-nKUFc+{ir6lMxh zh50(3ui@9{6{*{iuJE}(oJR|h z{nOds(Qw$B4Z~pq#mb}(CZK#u2wPU-MG_16*JiKFk+yq%CoQbq{66k5>4@vF;`D`d zsEZ!(eC>e!@sBq}A}m*?2&P}EPn7KMy^kupKn@vHlKVvty+u_u5EGT!E|;DLjUf<- zntoL%--_R-SH2u4eKG4|_mT32Pw(d=XKbLjfhM=R^Z9YXI&;wdR`59o>;6$qg@w40 zz1k?mEo5Y9O*gL||I05IE`j6}OvX?Gf9;W`BvAYimV+r=-saF9&H(@#?#Z)0Af+~w z+N7ISY_smnY|VBm@RzT~o;dWsH+6bd0Ry}|ZJhuiJrau46B)o}S-8pJz&l|69iwua zzg-OP@yKn4*hrRUtFdn{{4Z#gg95S)zE2H`qFd0+2f~*8$o%hZ_;vuoXgTx7k7Dth zAfg%qwb2-2ctU~U85iNveEr1`jo`pb(J7Yx6R6!VHMj?++y&`eEIs1 zV}^tYPB#$o7wzXWXDP2|`mPq@q$`wXwdHc4BbocxY*XBazbs(`eR-7d3n*WK9x5VF zViOU=8|1F=MiFEaPbFrM8bA5CKqN5nfL=jR;=FR4&T_R9ShkcF<{|?2EaR%}mF^X~qAV%xLd+ic)bC2R?JL=SzFX`zX4 zloYv|sUGrJH3X?X2wVd>m=Ws7vdzz$T(jtjrH}SI@{*aSXo@vc|8m@{NjTJPfUbN{ zCFftpgaj;?u?Y+fWr3=z{Y~w=Cce^|O7sYxsw^p4oVoL757#4VaLN^6Ammm; zvNtID0h#`Y?+*mT^Jfq_lzdemDe6**uAw@BTA=dNTc)S)r0DZ}t{+KBT}N`f+cT%7iBQ^XthcJVbp5p}z{7 z$h~t={MQAyd;5pE?FJEydc7$(`}*m|Z-*a|GTC`A>+5M|{E7be&@Fj7jL!EOT4{Z; zU`d!!YSn?jwVE)sd+V|Q)h%ZLa&*)dD>DQ2D=sxRr-%_*RixQ!==X zv2ghDH_5NA@z_bcpqzI|ivcdz{BHX4;ekxUKzAIrk%LavjQUJ69n%HF*e5XYdecMx zE}0TUEP>mJwFo5mQyt&#B}4>yPuz3ri)L`6B<;Q+-(O9 zpP{-=22G|d@)v5JM_t#wcm}6YTK(V4(6D>A|o6+ z=5YjtZx*K7)$Z%?%3Zd7Dpc3&ceTq!(UDiaN~kkbBBuvDI}t{mQb2Y5Dq`g9+Dmc> zzHpSK-c!SotF;sd;s%S~m5f+Tkm(@AGjP6~Vk!iYSPO{6^1rq%|1;ihJHq`E*E%0` zn(I|^68s$7N}Oy;yMuh6q1G~x16$_0tMVM(DJ!gBm_h%%UtA%H^M766O)__TV4s88Ku9yxOkRr=ETBa zKrR1B-GCrZNmrTof&*VS5)4>oHoPRp)4+`=b9wIpx9c#iaBCT82%m=jOAK_^-I>!6 zcNA4pt(7K=ghdx_3ZiYino+xdH6sS0?q^`UfuUc3z@jch(M|o03I<20Xl%a?=?QE3 zhV@&HhmW7He^)$aBpqT4tf$!e!z}#w3;gQNR;S?&94HIST-UJ`u8Tf9yV-+fyfz9n z&juP_Pv3M(U$Eu* zHOQ+(G&@?*`ktcLW+Jsob%DlLqH(t~C3}O{vxW5IlKqWZmj>DQ1IXhGG3Xm0rAL5p zC)r8*7JS8r`TewGb9Uk9AhCUjt%GM~&m z(luEg+G63n7$-Qs+81)}a)%Nmd?i+S)?W2tA@YXSgvhrh`WpTV%p5F!W)USmOk&b1B&+}927K-P^ zs>F0a>&*}q1g<;?Ng^?*E76ejFUw#JZQ@X~ylVdCMdn`%Tb^hF5o*oM-kDx2N^Af^ zs&BAeeE?iBQ?lv}nd26xAZIp2XF{^~uAm2c85pk5hoJhBFtlc!>GayI%+!wxWv9-& zVP$g#{ZWvX#2*>2DJfTyHGez=zJUH4tZWXBtyNWGSdrAaeYsY4@=s<**cb@gBW4|< zwCAcFhT~fj4BE!@zCMe()#KNlf%Svou3{s~X(TTpsbJqk=hrvE6NnfCWx;IUr71J% zLLFWuP*{2djlcPH8ddARBc(c>#Y5+O z$<$v|j$nJN#i#zJfUbzqu+97W_4&iG*fC7DGoyytowoL*^J}YsDTJS~za175d0qqm zj9*3w$NnAZ$5}qX%W>8NveQQ^X2tRCQ5(=4346(4+-Gdl^3-?8V6ZL$i8?k3knF zPSw?4F>|sWhj37Riq;Nyo?*&jql0GhfHk^*BnC>VQSYcqD|bR9i9 zbaX8oV98d%K|i1XBk|R`&XrVYy&@90;Wix&8gdou=l(HG`T?Cy$$xMNJFv74WCkU3 z2%$RjaRuA6vMbQ`ZkQFLV<@Z#$dE$t&T%%8?SMHZd7JKRN|KwbhAvj&)440<(P&YG z&f@;|?OCWh{{Kg!qme8OoK1dMDkEGZVTp2wjNJ^6jq?ucw~EWWaI`REi7+bIVQuUN z;awmFA5c?zOS+@#2-`=_`d=?RASpELoy5CbRLwPBi z++tY$FQUc+h(;mX3;CJsl;%(W1AM?P-OXUKjSr1`C&HM^|!??~*U*F3~C<J0rEnaQAF{d>^&*-fYCN{efge+)kcjbs1rwcn02wSS%Zw2_Pld1#-THdK#?^S7A0 zmXaM+@c3SZYRRjRx8^@M1M)cm0x>MCh>=a&+ethBHnF2cd1MkK_ z@AOJk&#~l$k1Sc(Bx30e0K7-tp&A&yP@YOI*itlE!fnB}`j;{sm>gczk7U4Xe^k@r z;kTCnri4#(!FCS;gJ$~$Jr9)mE+=LSA|RWT3o`e6M>J75FGUEj`O=38YhZ-z@4)&p z$kIj!w)IN#H0V`l1*A)cA0a9xf#CAM#`$}ur=bQc_bLIjju(9n!Fxi5gpFw9Epsa< zrB1v>$yZD^dUQpKqW7b{ep@ZzDdcbQ7W)?N@YMXzw>S(stQapSc3>J%p%uqtbi-+w z4-#)ReNxcBi?;R=UH+GDyc4o{aO#3iUloB4vS@y1$M6R-+n?9JOO--#STt5cS&#{- z=B{ojw<>2cLBGZ-wz|_csjf`o2^`1jQw2QMUR$kpe%9QkTG%@5mqaTT|E0-Eoilyt zW2V-%qfy!TJQ0gG&{Y^%*HN6mTVZjwf0o%owPizhUg^3L`(Gb4k zXg-_{nJbEJ_dXJ$7b88Kj9ShJnK`BppDt=$Jk*>Pk!;j*S;#Dh3A!a$7~Kd(p_-&* z!~?X0dh=9#yNy79b&e-T z4LxwlV!JPh?YJPe@z|yN_w-aN*jjIEx=BDxSD36A2n{{y3FpHa?j^9s?ozc87)E3} z_{imK+~UNUj!_p&aMWyWN%%)2Jebe?b9IjQQg74Q6g%$$wPvXi`q|bN;?u*!k;ym< zL(UPaA)yULga^vAf2x7(J#ltcD4Hd@bp0&o|G>27Ft_+~<7~G&Y3|xObC| z2=Y=|-Ri21Ed?)rY$!6X;TU-Qjl)2SGcxFM1Xj2Jsft)Vg4GKR_y`K~1Hb8^EC!A*<>fTNmRrwRJngKylLU7KPW5h<`4g$~x*OrIM3a||1m~R;pB;KGa zP^gSLj|I_TP7>L_HkWavasrV1@d&ah=$$B&mA~2xBoG5+%+hNj0UWuH5#bAz>;Stn zMjq%8c(?UUf_svE$x#Xqa<_rDSkRN>rysW<9RwKti=lj(i~X4c3|vVdokNH{4q$=E z`!KA4wS0u!T(c*Vg-@` zKlYPPz^Y)4jxmivl}K{jeypzkEV?1h4S=Aot|(O%p${-u+#7mpdaR14VpR0#3Sk0E zB&;dtBI1M18>T*<+;+V%R=)x=bwO|@lJU3TjBbefAh#bJT!alMfrf54#W@GA6khx8 z?==Z9->3UN`|RgSC&qy&(qRV)4M@Cf56DRa;^BUF8eSg^&7hdW-s6={HIe-+noPk9 zkLq6}{hsT|5VwZ>-OSQUkY0Z`Q@a~ffTUa`o6DY@;kiQ%rF;>=G;)tJr2rr+!DBRrxRr2sk^v z>{}NOHy(JGAc>}yS~$0(p}NA@2u8@rDy5%Dx~SQ11xJ532c01Qy9Y$u+mV}qtkUJ&Joi8x(@}WXb)Il02Xw2ZafAtD4d8!Z8_8>_-ArCGB zi8-m@iQG2@&M=2uaE1+#yQICE+b`1q2eg(Zm(CQpxhB}LP-g~-GSr+R1T`rGZBn+- z{Z;AGl{FmyQlKGeGu(!VvYuJj;WeQzAQg4UKVw5KopGu_t<~$ zrz~Afs5WPPglZz_$bUnRRO(Z_K{EX9neRUgau|r-S9w9F@prrt@+|-_$2i6@pnhoq z!YxuhW!K)gIaQ->gi}kp4~!hB0STz%I_ExD9^4(fA3Nwx&|K}zeO`OX7uX+rKP!rC ze%2hzr0f7x))%>50~5t+S39}!rhJ61oBACj5T+;xU@^h~1WFdo$Mp)lOLz&ks?M=5 zyJ-{|ZR%f#7R1$YSEpI3M%iVf$bJdG=*sAW-_?-gzlLrBsR&X6Y zaf!uXyo#<+j;?O0{B}3h3!*d~oZ(G#Gn>;!b7#S5wD`yBo_?Y&Kg16TcsC^A9Ja zOx}^DPF(KCRXoO3=;12Z+HT*{IFcn8zdJDb!>Bz~>+KOG;pHSBT6x~nsgKjIc;b}j zH;7gi9Ov1pd$9y}1iWKo&xEWrmqI_cbj4OYG?uw29B&k<2xMuI(Vt}LS+n8yPn|d^ zZcsndRs#JL zyvU7s(aOHwhjwWn7W z7YA1YC`+D9JWiejIth`_J5sM4h#-wUS*e}lET3X>2nxQn_kuq7POh9B2?{n8 zj_Xdj$-=fBwXnB)U5<6}Y?=DRV+(pN2u=aqc;)Ln_U6}w@JEwC&^~P`BkXa5WrZD` z1o$n1aPV#&D>w>bot21xFk=1qa(eSO=ffUUCE9gRnEC`Zf1jhxh_55uf#tq~aJ@%! zbD|b?+inE}8nQ{KlLNxPt2kf_b-0CRk%#|C7 zWv^oHZ=fmIN$>1|e;$vPF!Z~?=u&iQ-K!+JqRobv@9Q>9865>^^_tW}?Q@BwqP0Dk zG+VUgr3}bd9HSZ&g)1bh?m+#dfF<*sm0aENlkYeu~--fq8lTor5uqG5G{~J&;u4;n6kH8WO zD}8DlFB-je+D`QmTczQWnXAfhul}RDa~IG3?~t0|5Y<395Xe>uX_8W z%-OmS+%ev`sdqO;q`(c=wt-(hLrXflp}s2NI98J;oJiGibZ_E#O)?c$k;0oeP9&GR z$dWlz<~+ODGSB12eG;bwr8B_glj%80#XGSVG{JbP5*yk*sry?@j{dOXZnv7(-`|AR z706zLz>Hs{ypXrH*h#PPm|dN5yqD>G0bzxG_g2x|x$AWGUKM0)Qh*SvJbQs>0R2qw zyDvSU?4hK$Xe1m$s5hje6C4crp-cUEgkV$*LX0|Vr=gKIdvN#@+A1N}F~! z@Y&LKO1vNB(owf0(AV5E&j}w~{Fia|h#L}lNE4oix8MTUh}^dWA!tQ%5J^APaq#8> zYpv~0+qz@-f3qsk=J}67c>BsPgW{K?5&v*IeZ6|)I`CY9zy#z0|EOPCA7XfYKHDGe zJgt@JGs@A^o1feWyn20Jd@FK~{8RpydqhRj1spxKh_^e$%X(E?togA^yQh8$yc$=* zV%Oc;d0>{oW>5_*_&}vN?$z6NZLnQSQKDUZEew?JP@#6^*(_A1=MRz^8@T-xq01v9u*R=K!1N9O~Bfw|*q|NJcp6#bo@QV0i zv=I8=Vby?rOV1zGd5Ffw+TArq%HD@R$fP`-@v2RsXJZ~BA9YBnI7*+RT!NKx3g6NcLr`Pgm?cok6tC?Jtpq+$KUjY4Y9UTsJt_U zFbux-#MVOs{aXe4zmG{qFQG`dmq=%~X8XYR;<7>9YjFv{=OK`P(tnNlO_NRfT?v|j zIrGLR9Hlh^Zgq8DwY95BdTZD+DtMGKZMc0QM{|2^5|dHO4k5EEOd{Coxg zN7A_R=I*%i>B!K5lCIY?x0q@!pOi1(&*T4NB=a%cA~zFtX}0n4tUNJjHij2{6+L<| z0d#z}H?ENZhn0jwyaq@mRK}S~z}j8_lb6cz5}T*z-R6_v%CB)uHQpQ^yrE<)U4Y%9y}&LD@CG~2vDZaQJ2ZN& zKvKlB4c&aE!o%9rp}wspb$ zQ(jmR^i%3Hf4kqn6nj3sn_%9wz+iA7sbS-j&asa!YwYO5!+@}(h2A!Et=EJ5_{=#w z&!LNCV?j{W*+*e37l~5c0h)rqrsOBgVe$Wuz4w5MD%tjj&4>VuqXvIr8CAd(y; zNmP^^8p%OGKtN&}P$WqX5@eJlp+S(G8j&bTVv}2PXmW0v?*7+lX6~K2Z{}TR?tAN- zx4v1c*XgqC!>O}t*RH*PI}~qmIWtX5eACaxAAa&Tf&lFc9Ru`O_-PDD{IUb_YXM{y zRDS(?Bv{=P1oQfNI9`;v<3QYB4lQ>_=+KAn<4LA);Ad5`Tmb1weis0OiRJ}BfYin9 ztj>KIBHhwb&wrW82%VYN^&D1}r~OgPoQAh-C+2vYyLMz-O4$Q>_xxSc{U zIbXKGC3j{R`M?HPyBo>y%P$c zSBe|{R7$T?NRf-oz6w%;%^QY8a znt7RfHm_Ne7B;rpm*-9?}Gj@W>6yASY! zY=%3o*i+F)YEY3u;qyrjiM2`>9ONHOjw3#Yjbqms1 z>^@%NA6&+`1N&={{R&WAR+4{ll8fDTJVVDz6zx_T#yCMFnT8+^k>WGAW8ATGspeZeCMj51ADKf zfdC2+Ao9spTXQJD*=tSrl6BUAS9A-AyUl4s-PPr3s31kINpA0p{K;GQkC=KHo{%6= z7e1zf48*P-5sLyPi$ibU5SocBXt||x%=KkH$TImt3M7QGObTehiMvu(*$_@qn{im- z(OGQ}$R<|mWZwuN3VBjQ$P3+n)Nj`TF-9kOFC!?CYMCIA_^u#u70f(5v3K$Ugohng&arz(#tTi(KT0uQ0p+$tyw<>RLnojN-nCf)Yn~3Tt1Sas z$=C-EZILb6#c#b#1!Hav1tizC7;XO_h00vTxxM+ zA!YxCxBTO%BiVkb5&Hw1DCzu@NpJHb3kifp0SD~`Ps1=1_E$yBT+g47D}WTFwz@;u z_fCA9_U-Iln;&r0uqO}nUcZ0tKH$SZxk7V%iDvKU%$LwS8-{L1Rz8!1y@z3^#6^lsL$%NuIXP~sl@>6l=F=Y>J>8JzI&_Zls(oNQXkXv@ za1)z$>ne6TQe6!s`Diu}){~NrJin~Nz*gB7RyZrHRpOK2g?Hh9 zy3wSKl|S-HD@yD!*jDCbvUwuz&+82;dywQTsFho`9GFlBoGt;{z}JespaEhzpAT!1 z(z5iHF>W9b=@V0zYZksw_X)!+SV8-sd=64!55p@FZ-)}@JJ45@p1j}kMJ-h=fEVZl zrmsQeRAD<1#U_|-8VdKFYG4>dL7X|nM_FnR3*hdObf-r322q*~>PZ{kBgBL(Az z!}@cxSM@R`?(m64fozV5+q0x>4&>%a5lA3d@oCGg>_e?(r5x9)t1(~YIj06?HuV)2 z#eghj`PO-0yu3Bhz4mqw5qo3>QU@SsS%TjC761%~*8dcsGch2vGz)wy$1R|D1hwP` zmRr*vncWuRiU;0_vaR*hx3ZTUYVJ55ceUtUz;-s|Dw{`5e}P-!I6maVz$ppo4a2{Y zA4{W$2|6-)`5moh|5R&A{B7)1Iu|$u3%`bonEa z4Q7^vR+>m2xNwSSvC4ZMMTc>HJd$RtckS29r|69o7aho+AD&7uTqBdaa0TVnRytx~ z7!874Uh127_6m=Lf*QiD-%Y9N+~#SjulM{e|K9Gwh?rjod~-&fefr9*`_3gBzSF|5 zfVydGe;Xx95Gc$}EH&@m3ksVcV040@@Z12yq(@N#EFjLUppN+_krjF7n`bekWrV3{qoRO?DdWo$fQGDK?Q1KaiHSy zMCRGcFWgtqg4Ib6k}S&D^7bL$(6pwr{T!bVZoYMHi9F2wMr!QVxqm5>@4BCGv`{(} z=D9z6TKlx>1S&J1{3-~rDmd^~`kNi(cTl3+V+pq+%aGCp=m}0T*@~ zpwzi8K$tBJb#doi)m)$VA|@GJkf|R+DnTXOX||iM#iFd#0J<~_6{6%QTok-NKgr`p z2+}{i6-oYna9+cDvOJVji2hgV0qum&@Q(X|qL^xcn`55b{b%atNLnL6WDS(S(Y22Z z71hn}L;$NA)M3zn4+5*{C|=wJVSPL5k!+wkiFh3-Kwo6sluL;QGfb*hX>+(Xn?fvX z2NwxNzIE3Z8!m&Lbrs|4l0*KJEuHfUriP^#7X>>COF?PE40r zfEhXrj)8%~^b7K%zv!)7<}SNElRWqNGIPwYc2#gZppwn-_+%Nqp^u`Z1LszPk`w@; zhU@TO!2uwv;H|9iU{0n%joeKW9jfd4l?759|?DSo*qJwayZjlm*!6+fvT2$^aBVF4HYO4U2G0!Yz1;n zvecC&IL-i6Wq4O#Vd+WlSblAsf$ZShuK?9&K5|61`q9tlPWn>3*sJtw_pS@n`faHL zao0a!^P{%G8oS!Etu){vG7d_4Rf1Ap0E~sI{c1zbF)FB>1p6we0c@N467~6PdU!*| zyyFD`Eiy`0%3`tGlFc!G2no*!{C6j!-OQI-Qx(?9!3yu ze}`Pbg5!)5$C+0geU{NhNqGX7ct! z@D^M1=-U~S&_Qtqq)MmE(=hm8mN8TyF6`$5S)}k55G8S7tm~Oqw7CwgF>v&qIHW^5 zVTIAA+XT44%UZ=kEhb}*wS|4{2Kf?7d#CzBp{@#@z94i@ye|9Ei^4Z*%(;9i#HkxA zbQSwg;xG4n?mVqm?7H~ID^sOB&K0W9VDB*fKv%Y7{ma$*8h=Avgtl?|+e3W=A3~IW z;UR<0NBUHu6(AP1x5!0i3bH2-WL3wFhgpuq%Q|1^0!Jk&8$dum8HQZTs6X5|D-&p% zhsr}E_#~-8#h6=^q}(S7aPT_7qDY4c58S+d3c)uoCGlNg&i8u(4FE8kJQ-*Ws>Ylr z83b)PaYCNQ;$m=fqw^G_pitaNFN($o^PBLv%V#OBkRW~tF*_tKPRjPumbfz4nD*Ai z;B)@f!}_?Nlg{_H6J)|a3fBWSAEZEYXSn2kT1Nz}FtdZKv7|8H)e$pjrEIKDAJSJ& zAWo2LjhOxj0sXElmKw6vg_fRTw`#!lIPFh@?&Ay_7n>y$z#5sx2-r!NH&hJHT&o?t zX?hwuI7z6XjAEM0D2MOB2=Kk^{_+UunN6a@yiv@>=Eb=IWPl8nG5MkTE55AZHK*>4 z>tmnbRsGoBj~mM#P5incIS^~QFoHr-=B?Moz+RT}SX#ta_U6Rt(r65R9J-W8{)*qQ z&5L}?OE=eU0lRaxe4GL4UD4rzwKYf{V6LyK8o+2jRDUIG*oyUN+Z=E3(xttXq$-DK zdMA9gkTa#XyDQF1uS?zbfL__bv&8TG;YVCc+b6nV7bOch-}TbDB;{_bE=*&uI?QZ( z1;d5qP1-XAVXzX4F6o*rxrq&z4jy(9r{ojgNX(Llyyrv^`7={2)+b$KUHBRcf`@u|&OrA7^J!z%cvhT|XfU}Q${ zj!L~=TMf@bujtgBPCPx6TeIc1XU-WM4*=pFT z+9LcBQHR&sdHpx~g?i%}^=|9(WNmC{4=x0^bKnm4q5N~v!M?q)i>br(_bSJC+&{Jj zzOOVM$DMZaR0}?gs~L`>pI>Nb2)<+ilO~j@zooroArlT=SZO=^=ois`&C*|_$yUv7 z$A|V+Rdr+JtyC3lWR!3<_{*n}JF;6YUpF?a)fAm%0-&21#AEe21zAkfnokRiG6`S` z-$@!vH9zv6J-#4f4C69F%HT|6HW<1Hmd5S@yQZ9pwS%GgiJ3A-K#j`C*Fis8@j#(!e zFe|o~rDDExqaLGj58fc>R#Lnv<3ST15gJ!@UwU`E{9w&hve(j1QpBww>v??jHY2s^ z=0?oJ;d7>(L#7tq&6thDo3YsW!c07QizT{jY$TU>vJ;h>zoJkIbGrklE4|8t_@b0m z(5Zwd(Bnb$DP_IyRLU-3;6XGhW#vzQYF!9%g88UsmhRY`(6gS?ga2rS9|<9Tk73TC zH<9M=bGI#$ejE%Rxdzy8giTDRlh3_TrO5u9@91;XzF=JEGM?Bj${ay&6;%4-28`|dEs=6V_bA=}hIV-g| z=P`V)q2u}?4*t2h%HD{kTw#3SrMocrr1qs<)H2Ki_emCBGO~-8xI4Y^_4WG|?!=+j zw@qt&4{bgZkJ}2d&F)8qAnl)a`eygjuSV4;t3xcfqx4;TXrr$XCwt!0rB9sf0)}cZ znN=E%n9vg6b$0f2{-M(^(E^{Lg;dAF%VK!8 z&VbI9~cQ(N@6P|ae+q4=fs8QM9J;=w0S2SkxhGYlQ>O@iu5*2O2$y4;;VW#%06ze)-BBI-+)=> z;gd8_M#l6*wxMLe#h*_wr7KRl ziklo%(ZRLTW2kTM=~AIRr6@#E?~6-Ive3fOdFKY`%rb=3s<`nCgF+9)*bL3oNU z9fujRDipTfA!_Z7-{x_US8lZO9-S->sU7hd0$>5=8k4b!xb|V|1-x=FOe!A-mXGf3 z#LyXEUrrz$Uy*01D4IdiyPQpsB|f#epLcYG7fA2Q+ftr(HcQ?Jj z+?D4y;`2t{K1{^7qNRKi-=!*9;B`22v^Fu=)5V+_y+S>4q0vt5;|^#H(&8abIVF=| z(v&G|Sjd^(8`%?Apx32kJ65)Y@=(}b^O5AI$t7m?Vca50n6im9%y24+*mhhBhgptq zEqe-(YvldsSyql(D=1ziTQk#m8G8SL*zi$nImHVyO4Kv~p=!QntSK}sVP{(GI$wnD z@0|QD^gdN+A;XR1o{zjX^_rN@B~`lSOP|NyQ+mZ5`T7GsB_*o2wlhvoFGAVY!&+4U z!JQ`DRFL+nSGFt8MlV9uw#-`f3W9sOiVtJh(~eoK_;R&(@?#z!Sp@CyQC)hL9_Z2v zUFwdK%PaDet@VWkhUz^K%lq9?xpYis2j0&OjB?3aEk1`S46o#q@?0>>4Qx+~EahwO z_tEH7vNf?*y@+T^6|OAcjP0fCiZj#eQn7t&ttyOYN)sL~;7sU^bcV%jM9)vVxErOO z#jJkSiFvw&VKp=Ky~74BLePbdjr|l$<(U>!1wI*@j>%fqloKo&N4ez`&&yn;4)+gL z@|ATGD89ia(<=v3UTZ4(w0i44m+9!zV}v8{lo9Pl*Za`|l9tnDXU?M8b!nBQH8WC$ zOAFFsK!Myi6TJu(+c;}gAw))+aDPEse6Md;oYNvEeb})sS1@pF9 zmwwcUo(E%MZkU}NxDnT6M4wdoJRdbFCXSk%(V@3BnN7b?Sil+6yWSaRtan?*Hr!hE zGQvMixTk1C`gOzHS3DA*P~Ul{al*c>=CiL zRwj|F|I)?%es=T6Ef?zWV2Cu(1&pUxPEkO{LoBx8rGanv+h%_`MIIRqYK?%^1B{75$0=0VPakc8`krQrwLXMFP*ybkl!!KOeNTX6s)<4BDed$1J^qg7 zCI(TbwAuMv>~iFTYz>WK2f<%3Gvq7loqTJ%_k~i?iD~Y)J)hkyCf+-lx`c7+sO?nO zw6Rv@L(HZMe=JCg?Pc$Zv(Teewav6v6+z6V36B<}CE&`kw+K=`uGqxs$?84A#WKyx zD~iZuLUU>HA22*hXQ4Vq72i9o?BP#KRT;qamnFDR zFYa*{`)*zaAQUI=Lm+ZdI1=B#w-&eOzn$|fR{-bpivS*TkmuB>`CU$PR`>(U5v90U zwmmN#0m)KI^W0`<*PP~#JU$@Xzik%XPDs0)xXFIIEcFN`asHnd65wkh7&nGvs1u14FfZQ&>~zSl%3+ zl~v@Fxj;?R^l^wY7;I05ZDmKdAkhw_DLx{LB)D?#{~1aZ(?XOw1}H_=0If=TmVRja z>wqpKN|CtAeZEmn@nTtmj&A`g`w5oRqvUdmTr!uaHT**rk57qM%QlwHIQ7bvp!PN# zFse$6d{muf?wffR_qH|{v8%mxaXLF0O5d^zx{g7+;N3I-*aiP5s08*LlnRNdA}hhJ zT*{}=P^Ra$aIuCi-12{3 zp}~o>L24iJvIj{pR9(*JjP}XYP_}ilR^>;KrwP{;aK7pl>WZ_{yRB-QZ>=hdAWs*b z9735_CT_bMzScg~P$mJ!1+<8xP0(Qcp$kb|{dxWP&u%n-i_dQ{A^sMh-(W)gLOb{? zm=GuzY?H%U4xit8&LS{q+(!q?PHBtO7xLAg2zCUD``+iUsX=9hK*;dtx)K}ryY|j? zCI*O8+863I16FX1Ici=`|DCpuHgrKWPtFU|_D(u&G91G=wE@*=7FT8<^xGE2l5>NL zLq=NruZ%(QKxXOk-3j-+75s;0V9I+?M%V)rHH87_FeF(8B*Vv}vy;Y5;=k66YnB`o zxvt*$ZM_QPrd_F3Gx#7T_x^%!@hqR^?au}=)0VyJN_y6+yomp5IO7Qz)SG`bRK)|K zO*#*3((acph4~cQ&l?l$6-0q0rV$Lx)n8flXa5Cg@PS{y+HvD|R4ioq90W8Fj-k|m zP6N;nV2myNt~KF9+`tU}EB^5d0l(5u5~hGq{~rJNH^aIB8PF=5Zt{@c4!2x~OvHjJ zPemU5F8gm8I$&r#{r}C-PSl0?Y<3}cKIRf;{LlzS@qaaB6$SUK{UPdKE6t-@qA9eA zzhhf(lxO7w%i>!t*(Ib8hyMS}UbKy;oR#JJ9b5#zn3)Ys>u)qLHgLJHrvGB~|4Nnk zS7L#E^0!f~Z<|%fB>T78Ggt`P`Tx2Q{-m~wMu)0B2>%`9bt&ibAFvUT#GR;n|BAQ$ zIZNaJkF14q(M8TAp`Km$(B1-ySH-fOVGs}FxE}p@Kz&JX-A|tz~!f;n12JSWC4)Ro8x=BNen(2i%;masw_g|LYMX0>K$N{^lmpfiPh^nm#RdSjXU z>OCKTNp9-IIJ@Fux$t7_#fuEvBpKXw1qHNf>2eZu=}l~#**()s+}IG~$}33w76kJjIF9>$FW28iasCh< z{#$rqfh#*=eJw&q@AiML@c$W%{(;KPHJAAk+UQ+_y-t zznVE|7=tF-jr2^0j`Tl(`p9w3_KP9CD`zy=`09smp|Ufx@mzpeHB7Z2kve0e1Nq$0~x%yYrl z&4qtY|DXQyyZZlcIL>q-&@eD~4>bIJdH)AJXDB5I#VmxNand$qiMw%w2jQP8{4Jid ze;On|d(K=SQ^bY3GYDKXf9U>NT4woa1>;j@#6gXb9$L1o6;~&()S(63kHw;t7Y`vuyQ+e2~z0 z5zObKH{8?Zp)Xs`YzW(->zzyh@eG|?E~QrA>fhgkbk_ccKY`PO zod)3abpWTIZf%5ouxoDOzjh#`oZ7>h7GHe3qkn^eoM<@wA9`VbAw&N+wfDa@<==^~ z`P+Z+-#e-Qyu^Y+kpA``{5$_aPBZiF{|)!+)BhE*{8F_PLsK;!=Db0WxbW3@)Ym4|*j zbMjef>xn?eLKB0GQ`+41CjuN@OblL~(&nf?(FAn(Eb4JRfYOM7zn~ivnB!79qqq0< z&F)v({}Mx;SQnCHNT>sWb~wuzfGDgpa1Mi*3`JoOW=cX7{$wofh90>?mtmWcI0iv2++z^}vqu;pieJ+Pmljz1Rv=S$341U5|szP}E(#qgOhzZU}Q<@%?+?U zywd-TF|UR((!2jRP@&SahF9rP+W%I{S_FsvLzXr&OEUPT@Dn?BH&ar~$?ayRf_2pbY|N;7&cZoVJGc@Iu@3AS22W*bB<&-pRB- z;6mM*U-gvsF}ml4n_sQ@15uR!CbGc;VOFW?CJquJp|8JC+)Orn(MkNj#Lb*d`sM_? z(S=$h5sOARc==4j2!s&$Ljvw1x_4=FZDeex-F`xP&glmmceSZ=2$keW>-i?33$NjwhC$I?2gh3ZWi1_kZZ z{X!?dAJOP5e-lxBYSU(B;-X*W>8tJ(V}pnn4#n(M!*ScLf#4qj4#m7x!)4p96yt-4 zActb1s^J0fKj0rP9f~EYf~9=cvtWercAqi=6+u}IBO0gu-4g9eh1V5M8AW=kD)m~S z%-DKam1KWw71Dsd@0z*GAf}T1+`3jE_+(mGjgV5T{L!u%V}{cz$xp0h1%i*Hg;fi2 znlR9UQTm4ZL!+c6jZzjGr6e^NrHQ()+DJI5`}`)<9Z2dng}OUQ-B(E6A(GTCPHKmi z$Va%w+@Ic8@eSo;@=AJPeMd0ZKUSW$EB1vo9jQqLHM<3%UJ9rgNotZo%{!##L8uAd zfYW5)^-&gDmWtH(Tryk^g7f}gn)Hu*vOZWnS^N5EVg*MY)P0N8eUj8&4|S)Kx*bW~ zOrETB6A4F+Hp|s(*BHLW9%V6<*p{O1dI!C7FlU+|b=P@PlL=~q=>xqdNxh`zaZ;}_ z)O!SKlEzgaNiD-E^HBLNL;({L1CP zR$mq0<>(rS0(B&MiIFJqJw%vj620U|gwZ8+pCWaW=v7DRcAxiu7vaqMaA8r3x}Cz^ zl-2ja%2ym)&8wv56R61mHTTA~DSPzQ(b0>~APNMM z=;cJBz&R3O{7Ky;dgYV41xVe&q;3+uR{LmgaZSrEFAjOLzAm1tmpwW=_Hhd^&IxEL zgh=c}nw51D<4{7q1*9f9)O#(U)xO1>KaS?k7-p)H$g8EUEi2srwPsP5K1+3*`6%YUvAPrrQ)kT(nznJd7(EPRef4x|Ula*M?4fg-Ov(Bq4m@4M4Ar&-TfK>3#f~3Mb(GQ!% zT}~i{)FiR|AT5g-t8XzKX>mP=7FRQA zDLx^sId)Qa0I8d_6l+M`LZt4Oq;6An*+g){tG?!z|HF}D23nSsK#$89+rNmw%9;ZL z3#SDMtXmEi-m3qy2}1j!A0(D+ND}H9)KnrhpF+(Gq~>F&3FPVj+&1W-ISjTzv<e+`uFEA(Od|={cAp)%&q@{&Tjz${9z^2(n0I^li9{rBW9Q(H zn08uVUUZze!4Jn`P((}ot&Qmh!h`W0B4LIZj?E%Epue^g_-`s7 zJVdu|-@c>!{M5#-B`62*-ETjz@AxC?eWyY1!+ZR04os04^CVN0sd8zhghGulnrTO41%ZYmHneeaU43SC4~QwwVr0e`RSgPhzZ zjb_YidZQ{AS$^fB7juFiUTl{WH{iP~F!&lXlDGyVET_Y9ICRx+YdV@RwMEC$jIe`(6Zzq|VmP(|j>R*>w_=dkE+mnFmL*`-;e_!eLMCymow(sZ zTwQ__@Jj@1#&u9}d9Xc6%9}VSO<1HNZVq0pfn(Q*QKq}INkl9aaT|w{#*f2^<4eSa zT$fO3A^`^9(l#W5r&AFLF|Gx~6?J0F%PsKthv9QZgB#z)Z0ngxk2IrZcL>{l@ZGf} z!fHC4fI;t$ClR)bU98s(2|I%@$0Yb}!|XM(e8P6QG_jaSSRw`<-(4yzC9Y8scl?lq z_666$!+1h2{t6KbMj}eYF2S+!@Lf?@-MN{`1~h??ivj~c5@thkkvPnf4~`06+*(as znFjoc#HC9&jycc4*QU|LHHd(oSpFqgRmJWu;)~Wgk??7WxW@m9h>r*NqlsJKN3dKZ z5e3)8#!7Cy~T1@CUlq=)nJ@iQ~>{K5OFmT;jGj^Rlx04zagi zXg5af9T6)rie9ulLtJv*9E?sTj<+MR>EO>U5pYPt2AD@Yad$L{u)_~0>Yx2WTp+Hb z6TNl`RKyJ!A@dw~Gl%x41VAB8g)hY2R%YUI%NAgS1~fio0Zz0G_Q7t7qNU-U7Q1jl z));=g7>R9AjiMrqJ?&m@XUZWij3!CriGl_>MISH$lDpi=iQ5@J^10EjBxJ!M0?$gr zlh0tvlH4}1DD*wl&Jxm-uOx=Js+>k#X(EcAm_b@0GUxbra)~QcXleW~n$WNo%2#^F zzpYQ%D1SnagMZ+lN9%O9yNjy7`)i!t4uA11awwg+x(vrwkoz!A4-@5Xe`zO}OXJW= zb&J<&-($DabP266i?d_uKfpw22dt{Rc6>c6OC~T6i*j-OB3arfufgMM2j1kSp##UZ z9d6uRi7r4-x{i2$X-BVRGTnf4dW+(lvW~%(#{3Aivs7;P9dB&oqESvRs@SJP+MhbN zcoeD*d+o10j1O`z<*KWY2(MWv&sf;-JnmUGO|{_P#bmKP7XIGPwzRB%R{4kA=jKZa zHN}rw7B0?M8uUwYcWxZrNyYU$;p}ZZ@jf-LwdVacU-K~7(sz`W$fje&51%nGbWV`` zl#j}FE)OhzbY=eHxt@^-nFY2POWtU=u5gs!^YSGMx3LF)T?Pg;ivrEss59l4C0yy3 z4^LNdJR9)*!mra4lA_bIl*Y`Zt{zPl!KLQeSYO9+m#Vz0N4Npg`+j~yH)rCoS&97* z(x0j&xpQz~bW>>6W+P^Xj;``Lztz{?2cj>kIXgC;Um{Dx&c&I!Kj)wtKp#*G3HmXj zA|*Cjp>r`^L=ud}L2P0cfw}J9zICnfQ(Q#}`vl8DZB(QLZ+{fnLb!@!>sa7=aPBXePxNt z{C(p!O#Y?9RiXwAI7GU9r4c;4V+s99`Ev1(&4IQuY|+hyC(h=M$}6)iu3wxr>qyVd zZNrn^%@Rw$5SfY%n8~vJbYYD|{yH2tFjvBMRIu`fk1*Wv4r#y+2r~J#g2;c20sYE`8=rZDoIw{BAOCBE`Ib&#KK+Ed*0i|_^HBSV_ zC}|Y$P<_);Swb@Dao#ese|k~M=rhI2M{wRwhZ$4WJYIhO9P+S|ep{XkVI{9n^6FYe z>Nn{WswQ<*IwZL{q-o$E(^f|A>q;mm8`Vlj&xmf^V%3_TtP^IT7In6h;~Gq+8WkEd z8W}JiCp4~iU6ucEyL@_PcI{QIGlTd2^gMMqpKWCXcpCpgvSM~0L_l`?&4B%VwxYK$Tg*ns>JObg)wRBFF|)|p!=XfFGhRK+LmIpm?5jdpNpqkSO%jukbbndF zTN?kHND)1z(bvru5p}?sFE8)P>RU+I`~hcmalBj3kohSR-WA*e};GOX_KJXuBi7m&{KUeufIAq zHW2XAtx-N?Eq48|U)6royCaVUZ-mss1a>M%SNj|!qc^5C#n*Tr$+v9*R+2Yp1Jfiw z|6OkI)%$(4BQ%$9i5kBsJ2*ZRQrq=34cvjg(>b1*gq7I3?B!fi5Vzc?K67Q~+GH3r zTSbwn4tr6%sBw0szKKWG!B1;!f=L=nl%98&n2XXIHLtI^+gnMQ8XAI;`368Ub*0ue zd6GKJUHP*gp7K;f)j`we%>L67de^MyFUK;tV3?&WrLrDj7?d|VZDiOu@dE(~4c=PC z1yv#*MLFIlo|WbeISHj>j|cI1vcGXP-(uGTp0zwZl&6{}j}NKdqu*3)Q5PHmoc=)~XXjPBv-GF7Iq)1)_z&+DnBPg% ztlEnEs{T;NC?J8RS=(8xF3AVaGQ`zf%wIZoTCoxVKck3j3wd1oxzx+G_53RRh#^?K z?4eS%juU|WOwHzw1Yyd#EGC$$W5>6iU(8oG3Fsc&ZD7ThNe9$s@Ff}2vgYmPAl}Jt zx^F~qmL2mE+Uh-`&n^$1_QM0R`blY;cJ+HOJ^%R#IwoW`L!9OQq&^*n7%f^RoR$Vp zIaq{WQ1Z%mkbQRZ`kk}!v$b6{N9uc|Y1A1QU72uKl|!;#PBjm8EWdHJ79ORJA1XYN z_;B6&Gu!HBZ~fJmSJnX`2(M$4OeG!(`Ylny&oqFEHMh4aIRVpCwW@73&=1>E$lgIc zw>u`f79C5mbtLFL`f+IvZTsVb17uF{jaG>qhB$ub>z^(|j4;obk1C|P!}#Y(JS9H(7W>JCNocX(G1R~1 z@0$TAXNJ`A+S) zBA8Yf-0U>K1vjgu zY&i2X+u}xH2W<%RhIsLrX8xMR>MLNqPtR12$}wr5ZAFzPV*^fjS_{uoqde_2C#kKy z?FuAJj*o<|qTGOpzlC|@s?t@zWDW90cHD5iD1FM1B(#89wionpSqo5G$nm$0A zgSJ^$$y3@*>95r3GaAH-dLFEo7^1!GMD_Kx7{47XPIdECYLliq7@c+1m<-@O)y>jD zzL|l{&+KwYk$X`OFFsUmnXaQe1#Mj7SV^0sQ7*~h=`zQt7r7d7Dz;^|6lY^z%BT18W4J8d+e{Wh~gVG;Eq zv-B_4HCz~W{;slBG`po)6qTaHn+J&A z&nZ1`H_*2lqz~v|iP@@c89I1M%pKwfn(48llX|+i_KwTJ z`olncEs_cF?N*Ln>d)ns%P9j-aa%($H?soKUm9jO7*?S?W^cqOHOS%pvc_w3#7PLL zT*>vC`HJJRSVVoGO3nbd!*h-DBp-rP)1(WGOT*tEZr9Bz2o$e3OS%tJm{%=xZ*^ zjaVQ(^u4Z{_0k3!ZS$PQ(g&`WIC-l42~fhM{8C;3l;$T zOF->vImB(PxxvwjWQemwRg7n6&6>vCE}6yUfZyBt27HcGF?l7dzW<= z1GiJS5OSs7Hks>j&}*`2AVVE151JkU%E@$)x?Kp4>(J>2&D(3<_BK`HGJwkCFX91H zcfNQJWIY2mYgyDdsA~WCiLKYMX-w5Rc1x7}2TE;hs@hds-G&-cds1%jBEgGClnkNd zo7wMFaMYa{4tFA}IB3c(LDSBd0yZwi${cvb4?EsI+a+V-i>s@{!lPkpK7huIDIue> zV?V6-9$_5UbvszkK1}P}?9TpLFYdWrK0Gba))UB%B>lK0#aie=jU`2ym;5WLL~Jyx z9sK+8!;b`ewral{K6q+v84%bO*N~YG=Kf9aU`0WkkpGZ@zUHgiR-j;o-!Pu%6E!yY zDk+G3>a~yUJa`F}oSiskXV@p?t7T|irGW+cnVkj)X0MhPyo8jS^3@ID>hCx9)$>+} z8ZhC$>I_J0*|mPy_jq^zVK9LVkV5ZLQNSokk;4D!RGh=9;M?fOD+4Qv5|s)f6-OsB z^RR-VBGUJn!H+o|D^XgSoYW|==bngO)bD&9upqe^9SM)AK6}dFlYQy~*lV6C4CDMl z7ML#>vyOfRV`4J^FW_ElP$A-Rrc~5eb}>2@(R}t4im2GK6}$x~6w+3R*xC$H-Kq0= zxPRv{u4MPVYFzF3#6YH+%FZcEPFgn2V%K?wRwT_=l3F=+8((=hUSiSCCmUjSHh(#= zr*YFzEDvNVvBN#K2HvZVS)dgtjSX#@mO(_dS)Wh5slSrV`@Rp(yK#Wqi}~3+0ENPw{~7LwYT>%t^v=I8N|d;Lz~gb*fwu6`3WY#z`^bKl>tJjjs5GxL!6Er5T(O1ZL?Mfj`-O1 zUC29u@QA1vu`n8c*`#bE_E}I zu>{@v+@U)5xwt@YH`_{N)APh8A8Tu;9`tSkj*+nOj5MdkD6L7AG54-_s+``+pW8n= z_@~!V2Ho&te=Rp~&40dJ!^6NuRC;=GiYs~&@UKEGSn@C3n&c}BaFbWT+W`Ied53_D zy2@=T<9kbBy9|?Lw$^YXj_PC8Pu#aN?ExA}T&)(QI{2@q2fVS0z^k|&G;Q_HU(8ue8* zToo1lvL!OW+0L2~LkMA;%`pyQ@2v+_H?)SQ)iS{Qz}fsr`QTm(;8<~q4hC)|!CcPG-f8EwboZL>Tw;25f|m4W5y znkxd!Vf7f`09ow_Tqttw|HM7U&(UG6qR^)y-kE!AYRIscd5UXKa&Cg5vqbim>N`D#HQ{ z5f91gqa+`B&J;N#MR!*?OXu$Sp;@m_n$6a6t=voi_plVtL2 z`+><-QP3mkRdJ&%wT}_p^NJ4%pb~5#n50$CQn>F}>RAMZY-M5I<_iVFMM1YOo+g}& z`-3U~5X9ssP5Ij2pil(aH=xL#4-7nRn!%w$&BPZ$BZn;?+M2e@)_)xhc8^c-e3>>4 zXr2feplGcZ-RSh<7ZX~K$wblC8|sc_`;}t)X4gX;%d*Wj7t%CJ$5-og4wxFwB#p0s zv}0^4i?|+3_@V7gNK-em(b_&4A4ZX!b$oiVYiMjaMmTcLpX@LMrw8=M;^4;Ako zk;pExlS%1T$Q|uULUT4mDq06kQ&dF8#dP{O3zW^d8cDS-98Wq9-FS@a(p>)K)@?2l zU^wbBZB!CVo!UK~D03yOYeJ{Qi6NnFQb;UEU9Gipx!hSX>N!=?B7f4Ij|e(9o(w*v zj6NQY9&?UDSl5(+T5!7wLu`3SBxi#bZ|X-ZA4h7F}r13kSkMW698V$kQ$~+ z8mNP)-DG)o5bNBrj1^tQgX3Q>F+AL%{rr`zS*m_bPE)?M*(&L#?1P>&m0oe>Y(6q< zZ}^nn^nIqg6%+NvN7b%}G3KV!fvAp&*zdVjUyk#nd`xE|_u5%#Zd0~Kik~+uyuqI| zCFRefq!hxyL7?8p?V`)QAb#t%je*i#S^0yeNfBSFU%dA^V&PjDe8kfC#I3c}{`TWZ zS@yGF>i8N~zv=w{M|8D{%+$Bujnn&nIgbofK*?Rg3KWYGAEo zz3k3qw>zG=E|&;y@&q@TDP{y}aKFB&l+oN4UFpbOS9V9~pt>|Sd(!Q=@w*1{Pnk~% z^Cu7Qm$^Vjk(~KeKHy>FyTDE>__?CcviX*GdDjPW-5L2(KbGPECkh&|sJ57z-eV03e1?zKrwWOw@uz;AcI%uV zW7*i&xGFS$KU2$Ow7a!_h7KEkn?CjS#5FZT*P`X%X71=Gz23%W4CD`9uDuj@roM0< zdaL3NLe>6cn9yL15$6~RndCDm=-bJ8WRyHzkBTsi+nMgHm9VMV2gEzc1( z{`96iyGHBfr=f8%T~g*5>sU;2NR$-Ma>;ag-DK*CRE?o77k=?3D{&?6y57~I5WXPt z(*0|+iQ?P4(Mgs`xU_nDnI2nS-!jJ2mp(_37(<5h4Ij^&>RfR?(}#o`?-ayqK6HEy zdLP8uaLgl=t!7CaHlLi-a{&U`K0{3y{435q*UI$$u4tCa$&xtH9m$| zG|PpzAFY9m8s7#F3ORNf5T9?qQqOrX#Hdqj0rNL90v~ja2;pnxlmQ<`GQ?<@-K3^$ z;R*z@rax8aO4JQ&r}-O@sF4)7nJI7lrW;Z7u7DYV@SsoCPz=+EN#qvhOAUIH!0C5c zOch8M>-%l~2}jbM#e`wJUM>eHQWsCirdfc+f<=H@Rv19vfwgWeA|0 z+-Ix%_TK^SC=G*zsP+Y!OfBQP-K{lNbY1+(e8-ZJ%ahL`ChYW&j1x~S;Q|bp&}4nz zN17|W$&t}1?u>uv?KP(Xb*glm!za~-d4tp(FNwL_x>~27lu*{9Hfo^Os-DQ{M=M6@ z^HoS}N<}SVTx7DlB4JZAS`Ep|m~MHP3A-CF!N-p{pJ?KTTr{67XkRPhKrZ$veMC1p zHjCcpTM!pZ+x_9?IC5zy-kO;zeU3}2ZI<5c%yqSN__H;@OI=c7@j_x7d7rsWIMX|Z zmM>F^sUDvOGCs+@(R#It***pg)-rv{)nk)sL+8)O=i^D& z@o=)4PcX3!?V5Aqt6D1O-h24~JLDw_bc_RUPaJO+nLh8jEXbQ$& zr+}MG{vT6U9#3`ty=SILt5%hzh!$?j79n9$wu_5vtArwAPo=31zMxa!0JSy!Wp)-SSi;`Nlcfgek|yFZAR~C#zc2rk<(lC0EcLTU)XdbduAf zRh@OUBJAGLom>hk^qk!G-$cxO;?y^Z_Dil{yk53BHqVJaPE6gc_x4HL0+Z-SlctDR z!A9C)2997;hy2*ncG~GvwJZIG#@o9+eN_7O@G(Ao>^OhivvcIt*ebG2qT@R2b7DWN zXA1H!-6nVj&Zuy7(~k+^`5rP{k$hU9pI__s;>{s>cKo3u3CCAS zCP>i}-b&)$g-PVFuCoU?WfOUgQo9%t)r^3QM_21QatxFezQ65xV?X-k?vvr0XZOA! z*~Dar&3*5^%Eem>2gVM)%Z_-fG%$9qZCKJYj2-${``F;brwYfyT>T!4hqFYuU-s@y zxDZWlxb0{(ifE0Wf#r)sIFf^3gk+reXxPcO?j7v#`l9-z+rBl-M&tbPIa;q5;vud0 z|55!uy+pvnSg<&cWgLCFxm!yTsH8%8_4(+!)r%e6uKP65BSe(Gjuk(!Q2g7d*YBWd z@FZ1g26X9Go-3K{8CQ622JvW}>)a}HR-A(y`0!}W4e6DSsWfs)cvOrnMQ6ViM;hr| zo_&`T+qe5NdvRiXH62QiSv>4k_LEO?VjSVZeIrQX3?y-Z;@`_jB6;lo?WKC4GzsS% z2W15*Zq5c8@5>X4I4luW=JnMksrb0fXCY~hZ`~8ERP%$l=g%GaqzDM%V*n~S2&K3R zbZW=p@6r&&F{fw-YLdKaX9w#`q*oT4@eg92T98nyw$o31isaU#Q6#rEJo|aUEAWstvyju(zDlJTS@br2y6A! z-nOcP)fZ2hxEx!<#6MzKH0SiGtTi^uU%k3BwSW8Xo+9=gB1rLW%8bps8~fqr3KKh( z{>ImyE0Nak80kl>>v9vEJkT$G9;scLJM}rS-Q1mRNF&Jr6f-6PmP9@%0uIzyu z_fjIM#5~xNsUNWQ9O8xmlq7w6MEkeIdLY80T`AZ93SwsSCNS>`&^!PK^%HToY3j{K zaS|Jt{U3$8~Fq|@TdT)hA`7V0IB+cw{E*fZC|LUz99*!p@+QI_acqv%MZd?ks5 z68nYX;jf;|IgwQ6eJ*Q-Si;lsu1yI~7ke^?<<5N5{#=kEj<9)yuo)v^bF!Dc@7*<~ zNO6U55%7K#hbb7lbrZKtmV@7RDh16(o!__pBdyU>bs4`I`b@9c5KT_qwerp5mleV% zbkkI_O+wDj>bB5RbPFjA7%obhqwF?afP$yENXbm^ldFE=qaJ?S@-f{vd zEuw7VpU7I%?RI>he8A#SpX=oIGDqXcKxJmDFf%pmKwG_P(Z75%fua*W6JyaPJ8B*d zs5X?lE@fWNm)2KjU#&J!Q^Fbe`bhSdo@eUrkuaOBSf{qL@iiTo*Gav{9JNT2BXd7S zFnVi9RPB?Zb=a7L%k<2Q9x$xvxNi)AmR@-;(~!nW6~Wsql}X~0!`s~MGIW1p9Atrr)J~t z*P-z6Q=MY;67$EnvBtQu#?Q62tXNt#llYpdZA`lpiEmdRnHb%^vaytY6?J?8jkoF# zos`qG{^)4>+0EVruZ&J!q7%Fl`JwY`9xi%fzXXR5n@B~hVw$@`^IIP%*6x^WY6~zF zJ)R%3$d`weYK63--eg45igG;_U?$97yEs~C3rG5{!9^BNS03{1+)r_P%+>6Dd+|UbhWHJ57&<=1>vHdkH%vn>2f{TKGvh5DjeVPHq-tm z&r*Z{Z9a(4+)>M_j(Yn})>*@rk5!MajjYX#J(JJbbvN+0qyS^#@X|Ah|qucKq8kKRiey4R( z^6(Z%7ueBVw+VQJGa4+p(mLTGRP!scDWc|y=|+GBcS{UNrj?>$$=w!rCjG+>S-L3Hl7gJqe$y{Bv(MT3LXDo5wT*Hb_ zW4!z8hI;!Ad>`r68|@sH2t=V-mZtHleNWjjRItLiTJ1PTcKZFAa-UAqDZD}zyutx3 za-q3hDUr&FIW*m`2RE-!X4Su+Gx)76ylUZ&juFP6ZpCsoZ1in=8CN45w|* z&Ck5e3SMtL`XC~*HOwu4Z$W?2rD}%zj)?@7lC2jOyB$*iT6H+SL^tzSL2Gs+Au2nzjVZZH&HDH4h=il z|Gjs4X8&%g%kf4fjw>bzCNqSmDP3VD>m~PTj*3?-UU>*c%`4)u@X{c+QdtbZ%V{HZWWF#fA%b8Q_euR z2!-iyAU^KKq9462#VO(NHU1UCb5mV<_W7j(p`V(LM9$z|=>*^KC&}A!k4G0GG~^H( zRqq~g({wI|_FNu~TkG zj**4{)vQxqsgW^TK{>X*e^Wqx_M!e^G7KVh@T?Im%VN6>^VHHmdf$ z&nFhZ)3O=x^!?h^Z3QTV+*+H8>7Kpe)jm@~=@Ul>HnxAR4W_cOXEPG2bB{+UhflAK zm%r}JtS;@QQ$yq7tpo8@Y7370q+gq6?izB{VXyeX3pm;cRQ^nh&C6M3jt4eH)OPTL z7s%bRk4W?KE$Eorw+_mWkMH7Yj4W(pzT`Y(R!WUAdw(r}28|P}A z)EhSLBKdCVZUX8w7e$)1M@+F+pP0=QZ0B0gKJRr3VdqWy`q27|;!Um42v499{wz*< z+8hTG|C;5A^>68)+CrFuK4-$kN_!$}`K$Rhamtp)j>bjT7Fhl0gd0(tD7sF#(X&@B z%_m>GUz^6^-;y9~#V=r?HOug9%hFhZs8{^e(nr?UH+lE?eOi*5WGh;Kyfnu6WkFz` zPIn(~{ixa{1N6cYa<@VRRT97gHPO)IuzSiK-TFFkCX&YV%2jkU!7Mbvksl6I7xm-5 ziWYkZ0T3oR>(F*5nQ6e__E{i?y|CP2DByT~zR$>|UAxhZ`k)*274!bwbNkChdm39x zW!TB5Ypcxtoocg8Vgh;CYVx9`KD1lHg>QGi-U5b-%^zetvVq{#vj=Q6tjskg)@Nsn zw=WBh+xIK)js?6gt<5w7+_jA~BJ8xU7`dm7Nv&RLwiRTPCy2g2is+M~Q!vogag~Bp zg3`qh9>1rVfVH`0bf?ev58W_A3H|%uO7OYgnqZHY!SpgS)*(m1it zqtu?Sq~%YCgnqFjO6-nPAr7P8e_^Xtw&w0?u<5^L>ieWr)Yp|O6UefVBqy-v4HKL? zr=&AbeMv-Jhw4Vla_5ei<;tO-hM&#R7Hb*(B*{I(heS-D{MN5N*?e{~V0%;AH!gbS z^nT}#%;1~ft6b0ee)F$1VpxqlShJvfg-Lt0(BVQ!5JO(dyj6EtbshX^=qMJf<#w$| zYqQ+aVH$^W;(bw-+p6aKOp3;pDvz~&1a88N;mW71a6i`8;Y#fjo%j%*!zLR*hj;VpD&1LS|(M*x%8?-7ZPFcJ@ zJ)rtBZXx~ke4PJY@UR>1T*=c}rLftj;}5!(IeI!#g^|O-7fsNq^1dJ~DSJ zISX3R1;vUc9hrmQEfd1<{My+;709ZnFE!2 zj-^8>&Ij7+rk?$~yvGQbM$Od_O!?=F3FucGD%6IaJ}_)qmuZkEc765o+ZTA$_l$If zITrdzn5iR2hk+uvgWMOyoIdSKu2S)XDAc+OJOiidTWYYh zc{po9f-}EX!dp>$lA$lV3wZ1mC^kM+|5k_=>-1W@)N9Mcd;N6M3^Y~d#`37^q>PJk zsz+a3j#HBy%P+m2>*K81!zY_RVBezCHtEqF6&%{m8+)TIban0E`(u}dJFZL@Ag#P% z>wVAI9voyky4udjHT!BWfX$_=rqOYmr_S~BF*@ptE{P}^gndGpJSEC~+Fjh56E{*S z9-F#ukJ7!HJEilS*#*AW3)f8b-9Fi1n0HT#$}CNhq_I8zW!rv6#AxiX{Xn2VdqX{^ zu5@@gN&x(Ey%*2p9GSP0-Yg$Ncijq;KWbOHDC#-74lxdT%?uqUx4XYV>ZsFmaw*v_ z%UfmmYhu06LpFs~{$_tJ(xG6(jtU%F6b>y&j>a1jP~muBy4IKw`?yO(L{pIoH01@) zW_eCFF~?%w3`$|YeYu_>#XX`5Qt^ATmSOY}4aYx!hVXQ&_{&{i{V0l1bQ6KkegK>V z<5+!yV%v6;3q0Nv$GYy_Tm%lb`w<5{(Q`1e_mAR7TC4=JNd$-Z3>;#OQ}yJ?{woCa zDWQ#vGNuQxJ=PI-Y%7CwctHIx|D0iu>TDx3+?_3i(|9u_C!5 zwsy)tca5f2XoWYJl}jodU9|RSRa$7hUW)F)fj`vNFVYw{W=9&; z7FE#6XPozH%^FrLVivqMU5z&=VhKAi>!>L;7imsl$PtU7ny{PCmXKBUvp~*Rv zxrP%mqSqoenRQu>&u>;&(Ig|RNc~0n?v_*58WTRdlFtNPUiYoI`8mJwv4hKcZ}Wj3 zLema`%K8g$bo#i;GMAUptZzfYmvL-vO+hT4ZWh&7rToQw2%_3~B@f5v>lH#~>^K9C zph{xwV^#m}RguigiiAC`sz5rq0H(Y26Gb1lxuja7A#Q&5FP~-N43X=sO!&&aMBeBJ z?~=7wbq(&u(UJF|=7T>tGa;n?JGA{*&egw-Qs*Dz>|ahn#T!H+s4Y0zP_F1XpF2{( ztH`$S3+Yz56U)O^KlfW{l_*!(hA|-)!1N$J?Wz*iheOO>vAB#=jKZPak<94RokiEo z3v%N`JNJ#3rOQPkk4UO3yCqXCaeb3=zx(_YBornR3Uh+*_`C?yRUFgbjhR;FOxH@c zBl{W1ShI%34*^D~Z#32q7~X&*Ic48yKu^hy967Wz1uZcXEiv;2^>zsDugvwSI|1Ig zli6FtkYyt4g=^3ZS|X2?C!*WsAqacw^8rNnGemcdgr}~6M~&l`1>f%$5GtRLvgwhc z1ia{J(gQ>`PjahSEPe3N+FT>P!=rQqpLdCnOzU=M!u;+njMz0k z%g4OIxt2b0e-`J+T(zoyEwUHdX}M-oC&3~l0WCx?1>`mh7pH`X1!KrBk_L=`;m2Qn zyFDAy7BgNi0ZDDoAN%>38*(#J%WO>uUJnL@q_`KZvCe!s7>w#}Gv|=Jl8ID8SvsFR zp{ef#7@>uXM++JMRur|GmdVbX=ke}co}#DD#IuHTAO|+@M@OiB<4O9tMEMet%|64- zhOLW!2FnhJCusO@MuIP9V&R)&7SjbOs978DPXalN!i^N;sddY=86x9EkSu4)(bA9b zCfzM6zT@@X=^UaM?4gJ1(f)}G;pr-^Ktj0@_K&X{e*{GlDcA&>Rz7)_+!$0NA!R<3 zRzyAC?bQig!{kT5uapmfsqV*9>O~9vv_F`6#2OOA+CDH-L|5>!z+Y-#I5OEB2TyWFISH^r>I(9NxgYM^tDxy#EJ?g(~8A(HMxrL=&ygv z_;i>C&2Kiep#t$TCjfrjgG*FBO{_an!PC3MZXsL3cZo^VmQQYLDb5OQr^5tIX<#o}>ibNT zZS^RC42pEJOEfhAFl{`yllEP64#hPt#0zg>jJH`AIp9V{>ZB~TX&<)=M(SAynbNKt zYKd(BMSl~I*&r8$w773KcGhe50CoEfWIxD=!9OP-oZ;9bKKSUJCjgDw_grxo{oL5D zv71HxV?-4)jHEx)NZIuFHNWED3AaWY*emOC&2GNKzHePzJ@v7jh~LR_r_ZNVc&k=d zq~y9ctP6-umEEJ`@lmEL)39b+z*QuYOhw~KJ(=~e8>~VZgjM@w z$;Np9^c9i`{@vn!?VTAmLMKycd;UGyDAOA_x96mB?{ft`F4Y^?&af2p!+%bywn|p=2F7F`COL8DX0Cc~-1MPKgd>~KBhH{4k`sYvbbdA2QbsD%ZlHsts zP?{)#?5{c3Ny$+YMahXY{C&!!RQygsT%yeVwsSR2d;=Xy6SHE^Du0=%f|{cU=fIHb zABB%B_-6&b-b6eR7h(eQ`qtm#W&bY!X>N zp5Gf92B)^*_1IpR4V(&-c#poGkbs>94dnUDn{JT4AMnfcKGLbdCQjESduieyc%t@= zcO2v-$5_c&2ROmCOzub@%f4GW!GAI6jJ(L2_k9QR{OoEJ9f`6__Zw(7HV9opd?ZC+)Kh?B3IBFCA&=0m0JTzQP!Na7r zV9r@*`RMeBUAcI+9<)p9E3edcG{4Kbr;~yfVat=0?NBjB=O>uFrH~2XqxxQ^q`&b! zp_krzrx@Y8fO}{W zb?^5#AcuoW8Jpyov@hWH64go?I&lWc-@)CN@jaW9KqoC1$LrXJFVd3(OOM>``V}S6 z!q3q4{-j7n6-tb_+DHls5c<+0loV zHz;nDFavEuKbvFEZxXy=#w7wN2=$B^d=~=q0ukBM>q=QoFJwQt_0~1gN<{Xv-9T$Ybf9PxiD>5KEVq|2EFP{K&0vu|N^fa2nts*OZ@!CC5n}yq&3HJ8kUlLr zieLc4&bceSxp4P}n}r3iv)IcoQXfrtFCT)1Zx6qyz%GJ)c&YGUIV8#H@(lij zBevOq_n@Bw5`{=Xwo-)lvJs|my+^go_F`f5ZFKHiQY}0I@=V-Sic3VfWo`P50Fh%! zWv+fWb`P|CE&3B*cc$(;ha$5gq24cZrRl05(`i9XCfq3_aHp6Duy_u?Ld|Kz^SwZebn)W4-^1}DNvK*Wk)*Taf+8tDhBW92H^ zRBj)LSf4Jt-$-k`J&5(ux{Fg-c>b8IS2O9|TK?>2WnCI#9Vj2*SLe!?R-Zk4u-&}j zGFx^kCF*^9jGAOJUt=OU?U4xQDu7T9-@#~RyW3w8I!*@$A{E_^tp*>`eahEm|I~z9 z3*Gy`Euz$eK{?ntEaFbVvnCc{**X=Wa_pn4ev^3)sY7G}@Z#>rIb#kk0$<1E8qyYN z0K^0W#01$cziPCK^Qz!%Hjr81$k8JeEn}}hGIXU)0?aRxPAEG_Y&DPJ0*kB3xNP7z zQ*rvvetCX^Xfi2$tM1{Gtly5lgW=3M5;tw)FCbSo$`r zxAq;BlEW^rO#@txtn)M2k^~B@9PNj&wVWXTvlX>ZCM}fK%PWcR7FEc8HB~mB4fv`C z_^KxRh$2NSqYR_t?CW!Uo?Yegd#fttm>r4rL&FL4tAL6*>6# z8Vnn@0ky`v@2-5@m%apHwb7grQFIM?Bm_XOV9|>dH2Kww|HH|y53ly#zEaLklt_}2 zOqsgg@IX=RlGFR~fMm}vf>qp0;4K4)03yZdGH>9nroUcc=et&( z*)E`xq;!ddGWb9kJK(wMmPjgllySVg6N;zz-?cqy_Jd#UzF#h~O^U=!@ujC8($LSl z-mGb)C3S?ZR(Zwi)52&p+g{pS*45|#=_HzCmHsz#xJM-5LXpm1ZO4FHim-f%gr<%a ze52Y9w?qt(_&A@53#iU6uiv%F?Gss)FvG4c)EZAyCU!DP(J|MW*zCRaIKuh`r@pAt z)eEfPKsO^SPLpmoxszULA!+l2rK25tf$wo*zc9E?X!vL7I$V_l(A>TRe+x4cauH5Z zN&U7t`8u1wbW&Dt4oUsZyT|Z{n3e(iWgHAEA!55>G4$&Qu+usOlblUB2sDdB#5%I< zXF$s)`u>&mWyYVh!#9AB2CQrj>29ejjd$U?a>w`MyOz7W%nrdhgj{cQJoQTgdUh@J z>{_zl$%zN|TS2UX-$AZn*WU&=ph}!9!-ra{e=P;#2vL6lmG|`>5vaVSGV?XhtOp|J zd$XDNyN2%h*5?G;X5tPQZonNlY;{LXDYOi(k!177<44Gch$OkGI2i6akS1c9e z1mzR&?ofI}Z`!f_{LP!jat5{UIMi7~s7m-~?U^4jkP|XeS?I|;@UoXThHcXPl{58_-rY#{$i~q{$!>^*RuP@yc|Ms%YsXqJ58TtMu7tsYP+!TOD z@Z$X}pKts}x<#ZXq}lZgQ9G>A)`+-K_4j24dB((&(h5J3B^N1Gyi*ER?Uc9>6smbo)&swUXUI)a@5(|$?Z9kc^$c)<10uz3m9)$P%-gYcSaqP z<>pu_&j@~lF^+`SDK1${c=WBeV|co3G(@2$p^jfj2hw2Cl5j<(Mf7aIwWL^{Gj>wn z=ly{+mUE~=d@-Ea&J4DM44q>qzzeljxyw>3z|baaz$ZN#@-r16#g8|^7!;r5FwbM} zyxCDkc4^*yQdG);z^KA^Z-R&)Wv-A(A=ECrVhoOq1CETdC!9%ut4#v2oJ2kT1lB`j z^F)WtMo_DD<&Km)v8I4=5FOjI15=cC`vKp61?P z0fCE-^4$rN`y1bp?iSsNuiUz5DuK)rv2Y)+4X&k`50C^h`L*(6)s}}gnVhV;7(4qG znVYR&o1c#FK6}OP&e_&nj_`Mx4;7cT2VZvocK4P^QwXJMUdK6j2Cpqo$&EWWDWtq@ zEy&n8;K_;~RbHEM^+|J^e{)NXI@nfkplLH9J(;~4*}MlghnRlwzR{+KMAbZ*3fm^S z3?|~qYpa)w#mi3rk$iey|1fVn@{b189gTE7n97*2mlBVb#>GI8=sETPk)QCx{5}NO zX>gDhv?9^pPpAnq><_k?uE-s-QTv*3{MT^8T2bbMAQ*9MwSMrSi!}seMUrM-X<7)* zji1;CG93yiVc451;?+grSLQ7|qcM5Ly4HExVGhZ{4B49}7E<4vR(og9+ecnrAgr5$cp9P*j(snrvG)NP2=mLtXk2S{#wFw;QBw_My-;oyk<~EnhS?{>Y6d7BsQwAtmYG{;1git01`of`6cUemhoyUEjy(`wZ{>5_sSeY zz+JW5XG;IZ4{lio+_FqL+mk2^j_N6F!+YR9RS9gL|C4Yh+uXEG*}p~0V}b+{Ar5^&4FM=v(_ebEl6JO*)O2)-;I@XAZ)`Gv6QFX+G3<%?ggv63|i^VQZ0$e6lX(~&`Zt!cvl(V;&YBRxHYNLI8U`~GA{j0|e- z2%R3_Zm;L``R23Z8D=`93d}Ns=_Vego8(MGBkvu#60FbSG-R!eN=WS=*6$l3GC+5A zyqnUgHS)#44o#mmk@j*Ksy0*`~X^T zNAmv3GYq@IG9E6rPIZRsa_YHb=Ac;P)vM_DY6|4CV3F7>pgGsRe(YHDoGuYrlONXf z{z8xgbQVd&!WS08^ZF4;by#>j*T;$QeD!q8ce*;5LNNNA#qRL3%<(sQH{&2u-*P%UkXdK5;G@Sd4HOY^vl(mcLfXo^tUMj@W^Zm9d&$-y(y!5K(J3r& zI^cO@-)Na^Jn#>J#I1i5@6kl3UGtrvzJWifT)JutX?~T0N#QK;*pvkP2hQ$`o1oA1 zU3q2pD!1NGo@YJ_O{Iafpo6rar)yJ0UsM>nJWv4~KJjpDg#}k3YpoSf-P-PNmmhLw zauWw{fsVI8Pfx=4#Iqj7QO57SP%?7nD;ubB<&`Y5%>CT@EZvScbA2a@$}M)0 zjCk;5a0W3BIJG)A441(XZ)4)U1%BSSxp0c({!WFnhhxO&pQYW~wUzHw|VDCe)B!tNmp%n&1g4~#EXrku^&b`jNb zb`-Nc&mqx>KC37PXn*_FS5GE2qXRdVwt<8U^jyfs8&ty^R7>Ak&b?GC?zw6F!tOgI zEVRk|&mkg7-0M?`@aDiWvtKJ*R)BY5Td?DS`%C8W`YnNfyCCp-nkSLF5}a2;!4(5V zcaXK}p8ep1jJW!@6~Y34p(mk3ahtSPWbme~O3;i|W)6_l&aikBwp9tmNy$3mm))wnLG5N)Use}5StR3g19E$a@lew2v_ zhxJvj1=D)7h984~-f=&*r12xWcj7gbX#6 zgd7?|OMIGp`~^a5Sr9d}5by&t`b~|9Ob@6}w+(X*TdfNKa1|vJ%)U$}+<$!P!&VC| z%Gf}hq-@0RhL5ojq7H)h1_VFiw~ z-2jn05l#k^YbbbL#7agqy@4ytpRG;KUSws7&MqmEz+(6*hJ6L5lwxb13~gZhpI0Bw z-69W>Zs@L}G`ncqqWIpG!2X6I8m?)}h&tQ6lQ>me`Q}0AzHlLs=kWLY7kIj*ASJpI zUy@Dik=Hli+j&;|?`8Y;FLy6EJl@89-u@Z07RHCDOhMRr>#x3h#}BqvF=J_Y2X_c1 zs3Oz3BI{Zo~MiCOLuM#uhoTT>?!P zt<*AmTFG|`{w{KRwkGz?b-s2gJ`)~gE)3sMmiX>ldvqG$ANWrJBww9_A)HEl* znKaAAPbUc5RFQHgwqqJ@g z(fSliDf%xT$bl)Ie^(QaI!;SPphWDV+IAl9R=nu2v@6#ed)}3ftJg0AwQ!I>?gLRw zUCLYINz3BI?%wj8$j|B3bf@cmUgaBEW=@;e*X0x>zlTyMFz6d4Ud4Y82v+udb;^0wg7#7N;;B313{?P}_`2eNN zV3jko&iySUllEy*RiWm`Um0*KO2<$2t~I^)tW;pC=dkTdiP{ZB&6!FBE_@JS*6K2^ zU*N5lo@1uMaN5nMD71Dv3frNW4o{f0TaQ@%#!6idN+=DK5an>E{c{iRg*m^yJQ;JH zjx^pKssqc1Yt|*m#tHz<=4_|(_H3T`-rsQ}Byl6QQa8fk61lJmB`w;ndN?zTOQP2# zy^A3dkZNF~SU3}$%itpVhJ*2@E1I;^&x0Og((Yrh$DAI&n;6UBWAk4eK6(E)3T*A|Y?+To|0nXhTauw#I)?oH1Zi_d#wNt4hj`Kstue^E^>oLzD%-d);(95zT@cW*a zYqk!;2WUj zILytP(Huay)}whI43d`#q$T=~Km9Y1r+eF7h!Z^<>L=Tee|hu3{*3v1<7)K+Pf#aJ ziKwrjPU3aGeGJo+INZmQgCP{I5d+TrX7S6ss)(@w_{e_bn&hQPHsCMAx%bI zfH8?{f|OfophnZPCk0!I!aaBzC*ULK~b7}5+9V!z_&ybOMoKAfGO{^;k?*X zp*>0-g)-YUf1#dHC6Kge8W*!n+Uq!M@a&i!c9x}v&c0VJ>Hn7hWr7uCGBp*lfNP04 zQ5zS<=*JRq8V#5nZeg6-&zPufVCDZhJkN8ML-uKLF4HacyKlE7ah8PiyfJhZD2WmK zg-Nhnw`+tLDU@?35L-0oy-;S9ika6}ucD#eP0mr`?xw3w7gc`wD6X&?;7nI5A&38G zWWD?JtQB^dc8qcrkBeSKnuU6*9CaODjFtq?0oF*nUE3X)-Y9XbZVxpFRO1G3B^aTG zwA_2(7xtpHij+i}6!;SdAe3VZxIZ<%;OE#y&OX9o6gNZ=m^HoKTCcT<=_)uIeqEg- zZu*a5zu0BPjIfK>NjlsT4MWZz3ABzVpr~OYcl3Z?&dBMET5$g^k>Lo2<`Qws-rB2DDE>5Pnm|Djqqe`n7iof1jM)jFCQ$ir>q$uC^@}?_+=I$3q*dMnYYL2m*;~ap)6*s zCS5gO$&O@$-LPw2@%EVPg@4>*dG3INW%8?Vx>qyPl)P6%F>;?pLK6>=j;3XNw+N z7i8V$YjAM2jK)|fMAwF)k70&^SrL3m;X>zzPaQhtqBXQLY}~IkH@jANm4w+Nl(uug zB_lEvtkeX>R+Uv-^7y{&^l_0BVb>x}MOteo3{JRjOaXe2YmQ=5_sv+*|=}S zsVf^*_ufYop_8Krz}!z>CZkzyp>pS-I}-ACrxQ2*J|vOC!9Wopz?z6@!x5VhUJiLk zD%&yaZ^pm`Oe`i~;%q-g6E)!2(jVC__#wRC6r#s+m9eJqjaWqRbqs(1$27VvPbaBN ziW|66!+!I-_f2+{3MD0OJbzNxphYo%B!nLJSa&C{-`dwr%+c;&M@+u{4quj_7B@$L zijg2*V}_ME!?l9U5O#A!V$^>@AMTSX3Dd!H1avev25~Grm*30;l|Bo&HG&GsZF5OT z7HvGB317H26ufMS0_^K2{j_4fHFHEL^pRb<3saT4N$En1|9eU(yhked#-^vj_ z&e`+3;=*or*wtEoLvmmi-wP1PcC!<%)sL9bBd(v%UoQp?o51AE39}gW_`Mx!QtA%Iy&357SN8$B%|3&pSPRBlC z@PY_wt}BrZ2Ax#$aR#DT%`#{4ZP3Z%i)xm+@#>ylZTGuYy(XA*o1=o(h?^QT5q23sK9sZ=DVZw=1C`%AAO&a|bl zb)H=|J8XweN~ubMs`;K#+%U@CFYE6{97wAr(DHGgH0Xv_Yk()#avxhjmJzYl<#pA* z&(HhBY*>>Bk1GsF{-slkH|JKofh&4Kemm#hORew^Z>D58to{xm<*>8sv|kQ(&vt%v};)RYfA4bwXhzGQ+#&%>Hn^Otw~#<=z(dkBkX_S%-0%zCav5luYB_bDvY}r zw=CR_m<%OSUEwdlmJ4z^}XNH;qyzI{IWHd$e$oKx!sz(jbH`4B~6iO9ep zrkRUk|MEr#8s72x{AA8*`UQevywQ+Vo_DsYZJSmj|Z7Xhn64J3OuElwrmVDcB=NV97nl%yB0sqdVE5BaicLNo@mAU$i|Rm*lzOoP{g`U+$0)t zMD@RkW)yC*OvbeEH+5Hq=rn9M8HqTfcpN(Wn1?!DIc}tO8)mjE6c@51yS)6IzrXit z>X^XBCUw=2RC{U*fhkD)N{T}tIS;p+R=9^i==5yy)3bzEwrsPJ6D)G-V_>H2pIWNt!G)P6FCuKk-VhzQKn9XyHEJoo02@}`OT6THfabXyP@ zvio3xd29rXu%kc1jt+3XZ4qUG?>+cGJGBO_8%kW<#^uwK<_| zsSp;n=sa?j_@ONz$HFi;pOf!MiClKlKKikEDpC@eQYdomxU-daDZXRykDtu(PtUyV zP2v?iIlUTJIcTf$SFhoMFIg1`lnmUSqmgy*hs9ros&G~J(!NeS@IVWE?fV_Wa84E` zY;IWy^XmQdt&T7@2(53x~^mHIZTNk-;~r9)v!v`_CMFR$!2PJ(n;52uP&IN6xiyv z=sLa6EuI6X2Ul5G5tX%jj%oXyNNFPf0gsqb^L{Q=|;sh>R zPNw>%TmRe7V@~pyYc;MoIqD>=s?kGCth@-D=6w7?3SL2&s;mG&CjdY<0+X>A>6x%I zI>NM ze_x~~J+))HFVj_}d7@CiXE7FBk|j4B)nV&#>O)vIfT@M(TE~N9^IC+I{|RPwjX5bA zRH+{uc`}w8bOhT^zTaB@bN!En+R8|hj)QMtkI8Ap=I+xs1TdY)Z~Fme53D5P=^EC< z!ZUB|weaD~9|R}UwgjFO(Rzbo2|h(?JKY|yWixuqJTjW}>dF4s%fNzeiGR8{@Ot#C zg5TDf&R?lv_SCHP@;~N};Y5+cYA+SNWU?wq0+PDn?I+m5X1Bvz67hS-0Dlt;8}~`!Vp->!dr3RaWa;5Q0|gDJXFEKWV2nG zj|8~V3out{zXVEtDrq_t5P8Cy;eG!WmJeuP`2bc-Q6W6BBdd~VnlP7_K;-+D)rMH4 zpsVnBne2vOV4LN|WQ0LQZ##An+yr{<8h(^R;0a@5cY~9p$~%1_HTUbWRn8M;^<(38 zsv)JZYD#`?4JFc^b?hTbFfeBP#h6%l`~kp!51-0&@G5)1^^>uO{Qjc;g%y7=61+bw z?^;x46IKC06pa~#Oi6A1*Rtr-x%|;;D?=&a zG;<0@6Zb@KQ)A`# zzX^|J^}xWw6#?E)b)u5k$jRc*K9nRs}^J!m@_wB9=9u z^O43mi(G&h{qcn_M}OHe-jSm;E-%ftQuIk(x@YX<9hq-^+DFx__|(P?1zvC~%Eb?B zs)bgFGsM{bxq}#-e|bJ+<9S!WHAP7Q1)KF4<9(K_0;gJ%peQ|8vfq_(25 zL`X^fW4`~eldpK`SJfBkMlGkNU5(DB7>_9>SI^&Gylo?KeCKQ=8cZ#jJ3B1bTT?0v zoRp&@fSIZOh-$+L4BD|>5>0)d;rTAQ_Ouu4koTA_Z%>x7JX-;m-?#ISR?U)QeyVJL9LdXZ;wfdCAK+8_v~XvIstG` zZY;Hi*-y5eNw}%boiiKODujn;rkcH|iv}x3dZY%Kba;*}5e4hf6(#P0M;2R&AWW&q z#-<9OF@GfUob@ZrmOY7&UB8{XglrdS@_aX1-%Oj~EIC}xo%&?hfv4LF97{+v*>flR z-{yg!g_JEKjD)c_EGE{1{Gv>qSt5ZL7rhb)a$M<}bQalzLk*qzo|#PgUI9DkC}ncZ z*#NW0$>up+Ioy$UNh~muyYACM4XrQ1-Ll8f`XN9+4cd3wENUj$oJPzBTA95Np_hA| zJ#%bWDnVIz`TZ+A4(o22ov_w=H0$nvqronsluWSt5XPT$KINv9&3#k18?is~Q84t= z=`+8Rag36!#coGHUp^FMeqE&~mFSEWCTDm4Cgp8R$AC~G6r1*#fwzqC1jV7Ap50+} zt!1(fi-%}j*wR$@8m0PuD2nx)=m@iWNn6R8!GAzKRW!HBJWK?szWK#yR$gZ%sD6amw(&v#yOAuTr1p-1B2`;M|6Bm#FyrL7d$+K zx|zB0CVkfoicR6w!0Qyy)X5wQ)!SRxaaexn%bI!TL=MT947+bevDrb4$<6Q>6aV5N zR^bbHBS5g8{R z%b$Ju$INg=|H7T<(M%R-k}Zhs0=v;j{rdvmi2jdr=|4B6e3+UcBDEbmRAZTRv&2gJ>c11Q=R#|Mx!sJ0AS*q6d7&N@w zy20#Y*gx=bs7_i>_NJ&GR<-s=&q?UzS6kF`$vYTx)_X`>su_&PwC98B^)ZUHCOdpI za|Iyi$@_^9e)JT=+Jd~vxagXjn|`_&|OAMB+kDWT#QMF?^H91m!UQ`Ug1BBK+a# z?mI0$2WPZkUq0~&qS+i=b$s8(alOHq2QFx^ zjkVi|az+i199ySATugl#7|2+#TVqz?pL&ii1^ac0k2jl#4dqe|%B9*wpFCL?IQNtdu_finRQXLC7`j7rlKuuAW*wMqCQI=+a$bS=ev4p38=E=h6qWAaI56Sa-D z62vb?d~rUWXxZbqb=4IGJ$v!bcZ#spcK*|8iD}QbqGUDWY(FxB^ZfCzb~f1adRe~d zsS|d3J|6My-qs+!SnKsspV->!0j&{Mxx{{AWp`wkY?+yas$@_T>$;deW~+%KV}^d3 zJh_idt#imiDZ?`dO&{a1AE79kQdU=X$zkMV@*xcgSkCV8tp+_+GVD*Lfk6W1hK~I4 zU(3eKxr&!w>sOmZkk;}9GU(g{hgBEl*(=g>8XAXb^-E)%Z+_%W)i^ahGVqxb@hp-8 zKAlIJAHgfA4(}5)m<$P#WxK=oa0rI#uV;5>=!t&y66(M7i|7v}eIeFLLH&&wsp=88 z-AE!tDHx_p<0QU2a*;ZQt2%rX8<;vVFB&(p`w2mzCYb*I;l=rM6&jr+*F}to zOYVR7lMSpOb>T}_<|V1tXJAMO`=zE_{#zF}gY69YiE;o5fID^dM(vY~nkU223H=>6 zW%tL1lz0t1q^FD@k^YakyMwG3WIV0HLrQQk*0_{7z&W44Yr}ar^vh%`Z6MW}i-?H+ zXA?ZmASijlx$fo|gf_4Bda&RW(_iH+_PHgm3_i_8?JPp;Fg~Z(bFD_Y;vdjybJSYr zO1JIj#m>1=Qd{Tm^EP+~orpp^Jtt~Vp5Jqqz(Xo{_GUczwcj-PHFLnUC7X%pE^ zL6YPG1T9Ar;qVE8H?kDi$iM)gJ?iPe&{Nk{gdg$Yke!DDJ7*jM`$t?h5Slh;BT-)- zKz$(-4m%vMe2FKrh-`57@zhPeJQ$j(^5+jbQppvKNUF1WTqoVAvp7iF#HZL*)OE=t%^6L`)bnJ%`=C-%_>{58AnrI|LT1{Xk(|XZ-zWh!F0$5& z7-c;?Z!#1RN1)H8xim8sB4->loo~T}G&-L$G@~u&=v+gxx4Oko zXrxx|62??EgdwWOu#(?CRdx0mmQ0&7CU%@qu4ylO%a~Be2D7J%S+41S$<(tHG`&fC z>-IabAS9LG>{7D-jp{L&9k`l$t#29K7E^={$*1GHer(rTz_p3)#~#LNp8_qLf`@28 zi@nL9xOIdzwBGnWUVhr6Uo(my1!Ux&`LkN9QMJLb@Z0`z8|=j=0TD{x9kJ3l>mlcZ z_2eU?vTym}2N1rBDZFZF>|nH)S5^rc_010*QTRRK2%$rmAs>ZP55ajlvjUZT#t2P9 zck3U2+2ylJywqyR*oQ8`*Q$$U;BY$#hnpkc%tz8_)D2;g#gu#%gkUw?O1x%w@jY;H zP@q7rL2<(mH^A#%KOQm54Df~Ad_Q-LFv_lD3dS~vgP)iS+JW#BWLoT}!C17o4Cjj_ z0y})a2l5lHn&Ty8q!U`bt@g>V14lV_t5|~U&9fa0_+!Io{IR=m!cjj@IG7)L72T=z z(xiEV3$33vq~~PY1Z^qc&A$P#`?Qd;y~}b(oD)=+%q5#lslABFGp>b92!O|$g`$_o z?k0O|GH7Fy^y}^F?Y)WeCDkI=a68|2VLcCm~jyfPsF=1l8F6)TmhbJtKs=H`3W#^UO#rq=Z_P51|SRNLycc zd_VqwWW9MfmTTKKzSdGHC96`#5+!bmRKgNUC2sRgqp3)u%o)m5NlJteg{_x8a!QilURdcmj=v9p z*!~L$t6(yJ)M(VF(>B4FBzG-*oXUiEUa%Y^)i?=PzX zDXQ6xfe==T@CvRffgK=dACDtr_&g6!PU0wecz3*`%HmK}vg@7+`~vAKZi775S!;Dx$7#2n9L6O-V1WO``;GTGn|NF9 zLd)7ca+LSBcaIp+Id8Jb}lMXhxYiMB%A!f|>%c}gmXp!I^^2<|Jr<>c5*CZTv$WbFtLy?RG+$f-umq6z1zm*iDD~ndb`rx5)<|Q{ zBwT1t$^={FSO6&y<{%8`wThr~E6_BAjF+NKVJf+ma~&3MWFqH{{Z$=n58Bg#=cEJo zOkPiuRcQuOBO?*2n>9#;(J3W4!>vUem@T=5&omEOtAj=$M3QN|*OZj8Cq%C1>?@=sF z&?vOf`r>wK#4j@RuLY2M=(R6xkbd3=_vKsKP<-HbeuQpD=qM?C;}`W^pv3Cu0egnk z=WF3lLL&yv?=lHs?2dlKyA^fCnAF$!oMO0$dds7OaDYma{VqXk5uZWxLnw%3nVcF%WGnPT%J^>GeWk*7pv?iG&l+`1^#UH3*E7R zQ>zUwpZpZ5vG-e&>5;aY=2w}Y9UoB2=^#*NPgjk)WtC^B^2aW$O9@;Tw-YwF-(5Xt zEbAZnU?>k6fgB5~5(WtKj3b)FXeE`0e!on|wfbVEYEPA4_x^i=%D>uTI)){=<-;|T zD$VE<q?raxtA52?c_a z#S2c>F>X+wsoUfG+=bvMb_I&`92)D=5r!>-!`5i@nL6NORNCvcnl!8sM3zduIqMK_Ze~^1GHVfx#mHEvjTkEU&qFTObCO+r!Qc?5-<}-FGd*fJ#$^}s}HXV>< z!HJ^D0|vI`>}qELKbp;3yG3D>FaQ~{Qp>eq{uf6EnsfeBZc)^Y!cBkZQGfYA*YKqQ zmvZ{z7p^gvJDj_)si0eFOJzmIgHf+Z)q9672QT|sQ(hdU7e&DVm< z3*!x5Q>3e2*9L61b;fV5N$R>DP$Le!$dhbaj{ddS`WjksZw(+MIU45-a6l>JU>1j@ zb5z`ktkI3Gk%=v5pBfuQUAW~9FdfCm*V!tB7|Oyn8$b@cZ{{&4#U7*k0_!s<{W~z^ z?>L^SBFuB$J}rn+9cL}yJsl$$!+tP$CADYIG*>1$DM@LS@e%2p9!+|6o+K+@TG6qI zdE0(zG`YgTpnT}+py9~s67AdpJduc-!c)wvGin@GW4UmGsBr{$t9gZoxy14EWgpp+ zcR2Jv`G3TAff3&FNwy!+3;z1}>*D))i!HhKQgBlaWh0pwc@KV8Tm>t@eu`gMsYsJY zNeJxbT9tsN{19xG`%a&o`AM~SJyC)cqT|Ids(xdW%}L8BIlQ<+N%S-d_t4_#ND^iB zp%Gv}W~*knB)yKC$?VXuUkwcAuAnqC!$u95O#xI?03Gey_;QKyf_-qxVD}ctbGUyI zWd03>yar9!)2r9jW+&QbS{0G??H+xtpp-P}l=Pu6i(`1}S06>e->ON|`|*&HH|T&f zeZ$PK{RKc3m61ZEIKzXme&@P1ir2njvg5;*XWzGvGDZ{-A&K)VPtBb!{M5L*ZFUmD?64Jd#!yE zAIzYqXUk~~C6}3(^_iQ34d5k)Yeb<)6rOAmpURZ+e)o}Vn!PrC?39qjWi_*_!a7g6 zgR>c*aF)_$dzS23>rdZ3If^hS6jDtO9RH^Du;F>xT% znxGWkM3nG^xn-l!5lq)M>S&xWUCW4)-5O#0i=yGGA#8t2ewKh^@gnw9do=>4dh20` z=a>2z3#EP6kbPu)6R}nUqH$fFPrqK&!6zLHY&JHNmsn@@irFgSKtZT+Tl&kQZBxcv zF>y^Au%MiO0zk!mdrR10wQXj$&L6bR3*gtabaQGd@)eAv zm}I(fG%x)O_#DM8Hw4w6ND|CX5ld;I_awa_xmV6X8H>gY4vSqxvP4X#TkC;~#$HQj`Y8*#b zY_FyijLDcDEFE7cuqqr^fjF*$St*J6y&wYk&_YPL@Y;tsx3AE97Ou1(1`W;85&Nr$ zf09%u?;ro`O!l*kqSs->+^2?6EV6Z6kEb#%3Ti~%WXGh$K{&eayFK)|NzxJrW?`NqT-ML)%MzmnwDbgQq2 z9p5mY`v_muh6`9b9vH?poalHwrVTzvS~emj>FKSwUB);b+ztEv{L-H+yUiJ?mwY~B zYOSBb139OdDIFMx?jK!U5|}g4lzlvSVfcN6G5L72CQaCju@qHOKhcdajEBEo?MpTr zcCB>cw=JJMy+Hn>IjB7g==k;_@8n-rpRC+y$Cj5`_(sH+TT(;*6_Gu_9i&7S$)DE_#ViF|eh^BLJ;&rq5cfnAR+vr9;N zl5%c6m#Czoo$YClmT44~gP2Y@rGE<>maroTypOx9SjoPr)&4`o$bHo%<59DBQl5eU zTq9<;Aix(f3t!Y#z3Kk*MEXd4qj}wlfe}=ub0DM{od}pqY-`%PQ?5HC2 zdpRB{J~Zm`-(}x1_2n^5U){@HvT!f1j|+s+Cr)73eR}sz0d+V3hPp@B6Jh5lgq>v! zHMW|}Kp>~EB+)&%5Dz523%)#qGXY61TolR;msk^YXT4ekb0QwzD#;+tdY;Fx(Ym3^ z4@Yc)jOwtAYNGR3!_X~EzRu8x*7h;po-bwLw_GaDxZ`5q>!Okq!GeXo?}(r;=0Stv z?Puee8iCK63M61H3W`ht{m(jIZoC@;rZierqO7bmKy7?z8teg24V49t`)8fYKAj{T z^(-0>)*AGtxbh{hgD12RXgZw0%B))=|3$`&Dl%SJF?8JYdUH(z?&jUKP25Y)eg6S) zAyXIt{kd)74cReuuKAWu!T3UMtR@0S4ipfrG9p`i^>0zO)sDJUt=TU~VDG=-YcBHu zI8aaocr{j90l18D^ZYkm8m5}Jff#h&8rfFg=^;tKJs&P z<1F8JpS{>%Y@$NNbhxEf!ZYSStGRwJ!!Kls`-z-iik>>)53(#?ecnF5#?1UL<$*hW zy)I*H@wxvv8|MVxln#WDlNUnHho@Pl+7nsd7J|ieuwBfx`AiEFPK{@Pw#^FDv|!A9tg;SUbGQ zeqsyM1$!m8NIJ{Ib=8;|!aSa`+L0@{{gz@2^Hz2qZ4*B(nc z-3lFkoizS3slg9$0QW2$@CvjL*C)LK%33!9&!hz%F}DO{#K5zEfYiaLCB&4_OCGxl z3xG$jkIy7%>L-Ar1pRGk{nb0z`)-;(YzPfj{2BZh@hFcmBRq0>+5XrxNq>Wb2jut8 zbz>N(;4>wr(;5)##VUX=>Yfx*o!^^`Tbx1Cfdkg!LLMP}(TNq|fY!tTtrb%nI>cwi zj1@$Y8BwG+ASu-%fR~she*(7%2?VU2S%E3|T7=!(051wTcz&PkrLF}ryaGl*xz229 ztLJad9}l{Q)$PbHy!Y-pQ=8lmnz%~>q4SdAK$!0c-!JgyvI7Pc!I_rjx zW8%*`CKWhg5P3*3-T#6;ps&Bdkat-lK3b=@AWw9s3xiOfW@gI&KM?kQ*(h`rgZVi) zBf_?OXz}i+;Bypv|CL?gp_z_SZp=vR3LQKbmj3-H)n4o;yKv&t zvp`J}pQ@S4I;+i+Xe4P+6Af!xw?p-7yoCNv3R{cYA0nnFxBPmxQN@_-w%fbCBq1Wr zX7J~fC2w)?`Dn+E%#un(wiautLOO8CU>D*bxR!gCqEnMFUlXAlrMHX3!Y-G%BPAI( zb#v>QA#2YSXkG=Z7sm;Wv_{$T1+`OA!(J~Bqgem}&QInx;csD$)A)U^FjXSwN8&PT z7){d7T!A-vgzM^++B=nl@OXyhyKVP=HPB-{lK-8R<~hhS19@2@I;s+t+No!!*&S(eM)N4=^N}(lrqE;R`K0C~da<{hr;Nj) z*6T}qlwvz3Fdkmxx?J{FPSwixZm!!KS2>U521_Td+=>1P1||sP;59fIMn0ebL8=$J zN&+OREr^NKm_YI7V`QWi`L((P2zrU)U6OLhLQD#1KJ^sN@0DjQ0|3O&iG1k?7Q!fD zT$bZS$#KPOY=&K*GB9zncK-ike!UJRXVbh>g0v`O#inCaEVmIvDe&@`XB7ZCNer3a z*k*zVdYO~iDdeI}dla|=^#Hbd;T718NfXwl&XKiwJk3yJzlXrN*62{2>mb{yHeIi>{lptCu0JYaRDq zSngii;k&rl4~yYt!&In=0wqlUU%2HaL8PhF;RwbnbuO`XaPXD&s3f}9NyA;ZELFtp zJyXMGB}hd@U@*QE&(jD6W6Q7h!$KY|cJ!^fZ?2p7F$-=Wuzu$fNLukyXig7M$V?kB&V5t|9mCW|XC(7nRazczSc zpQ}h(+p^o2Q}yg7WNSY^cPwplZV&godc6J0rD+B(kzFK4Yc54Gb(hTS$9~Ey91g#@ zdKOj+SZB|7K00=FaB}WjHc!}3AcrsaJlwdcjrGOdm8_rp@C5?{;gapEZqb{}WQQn? zsr;e@xz}X(HvV;@gIps_DlBXvZV@Bc4Ej>Wv?Qk!*S{Y^-j??A(_vr)j={WcB9b{N zh-UPp-GJig%Yh7bmNb05XRb&Y@zIewL?)v8vl{oGGuyD4m1k<$fc>pOq^36C#`lB- zNng+XNzJboIvzb4yK#D}Wq*A9B9OkBLh#^?2Ui&=qR4vC!8;C?f5hj-`(J{{TSDMH z>#91bNf4y|gLIRwD0B8ua9&G!ODQ}54hP8k9lZ#rUQu?mVc^YqL+H1Xpx;XJ5(99j zPcOPCmIV1-(x5d=!ue3w5d6PXF6VxbO`%MInH>4wcB?PS@_lNbjqde zSU4^NKSY%h0NEjz_GTtQ-~?o5w~GHCZAa=>CPY{hPjOG|CW;(_Is5WVcPLpk+Tb^; zUv;vX9&D&Hd!HGSwfEce;Orb2u|6C4)VSMhbdzSeiv2_u_ES4PT+BP?Z2R$bTZhh7 zh0|ws6`Ju+wB$YUt0ZynvS)k$qdip93BGx6AVdVV2+lu`EPDnI?^jxM3wg6KJV-mh zy41jSi&uQF#b8^*ufaDdC67nOx8qe?YB|iL z1OetgD@gjsAG6+yc*uCp^!^&_0DMYwB0CE1GC(m9QgLqk@e^|_E}VWrj2k^a+;SVV zDG!nZqwyR1uG!cn@k&FyTyu>-Mll@9ADggRL@lRy4PR?;+X`cyc?%QmRzj$E z-1bX0$zSY5vDXB7U!)ie#b_pQ^@`QE!5msZP9$L|@~VQIdI98AzfY#iadG_TU0t3{ zVRybTINBVrh&cK_z(qXBB$lseyaXg@V1f?_aK*rFKpt)b|DeOhN?m@cs-^iRmQppR z!9+2L*@d)}0e8@}5Pw-vvM3S&5e0aYLqszB!avk6#{n(Rf4nMFNlmfR*K=-C ziUtccnQY2~(LUDu@HJ7qZq=Yz{cWB{@wPN!n`Wd3s>TpDO5Yb=jy19-gc(q7NpvOv znH7IixA;qHm49*}xInCoy>4KH4~Y#D@e41hyDw)3pmrWyc%%bWZ^J<;T-8x~DVY<4 z7^*?KJ4rqbutYlqb&+2suflf?O6^&Y?;bay{Btl>QXOy|>5k%Z3hyow^PH6^tz1>^NCzJhhX5S&FU{gbiG zi=m=DDcS!V_-z2sV#421Wp2p^P3x=Fsqe=HGQ3}sfy>JK=fRZ_zIj|c@@05`1=X=U zgKo}QYt-6xqV{owND-+O#6K)915wg-*oTBV5lWg@@ne!Y5RTM=nVdVsmqc%-M2k>d zEC5>lVFfygU$3JPw<}ODrGxchWnytoZ#El?lyIWyrb`n30y!M-`s3{^nANr%vjZMd=(*8wkl$hVN>jC4^lEC{Vy zXokG3d)Z)d>tH_#TR4QvB3^<4v7#dLDG3lIGM8~wGV+>-kN|+JEC*y|A@Lr<0>2tF zuMF#8F{nB&Aay5&yOB7-#|4rbV?QFb`4|YfP6>bo<=xr9F^|u36kZg-D{&W3f5~RT zVKTnyM75?JQKxY*;HlEePMmOrZfX81d*TC!y&EmT#}c9N{q(2vR8?tjxb$64#k;)I z>0B8@8X#JDTb2$+RkM%17-}5U{POL_`k4Eoz~9Z9wh;W?*gFl7=QFWH<$Vf%Pr(w~ z4Bt28Ij1_=w@$8`UJUr3za&oOstshHKX#D%$&lmpWlWc%L?al-hN5Io-AsQB!mUE# zG{A>cL-@dbXBUEFHNbmnx=@n(pF&SkhobX{fX;*Xqmir%TWnt1TY>xdaH}uDLZo1i zgW4FG&J+JsWgZqbT>e2l&*C{9048w}9!=?8e_NTpVD}tycNi^mSWA?8Du2Lw3f`AD zJ*r0e{ASoW#epNQGOWT7P5)7G>g8@&`$;n4F%?z~Nc5HZF3&i^RMe-EE*EjH9FAruY`yqOkS`Q81MzRNL$Sw~QFc0gDvRn@KaJ8F`n!hWmm>zO6WMC(r-;eK4G)-1 zD2#D>PQP8tRawzfFc@`>AgQ=_letdp8+@7?unJ7XOa;2MWIkDUpM-~>YA*M*e zj0d#JXouU##yMjh8JlAm!8J0wH=jH| zfTc4j78^@bbO>IQy7Ft)QDR44d`kpzeU1yXKL(|V88~TO5}C12JA;60Hw0Wa1(AQ< zr&#JyF}#>nC4+5;Ks2Gg94+e zT0o(=CBOc}#{w&6pH$D}aAA^T$tjK z%?d6o7gh}fj(pvzK5G<)oFC%&(nMudn;U_JOfC4=bOgXDNe5L|MS#fLBXxozYYbTU zYVt%Ji%-x;0Fls$*7hBb%_%{Wd@I`1vUg&?bIf>6EUQj5Va?4O5_`V^WBdgWbUES z0xmK`d&OV;ec5F4g8~bnIUIvNX$RWa?{2aMd2`c-Ny?#~BpzWcoJx;xi43ZFdS2I~ zH#AZRWYiJsCUXQu>jYw9UgiB}v9-Bzp{LMfw_s;1n=g-8+yU%GP~446jz1aQ1l!=?ZxezZ2I@MRB|y{3-d+v zaSymf0i3R(4Dpv7!B*cYlPT9azBxxwIdA*9HQ0G1LfQgrhVKa(zaHwq&^qVU@wCcd zA??b-Z5bE0fEHx*gE+UO8q9CU=eX=H*3``)jB2~Z)kgC>g{M7zo{Jc>r{x9+id5nnD0&-;#D-LosC;_9|FU0tWpszHo zKPa~P*7*?!`qk4B`1}czylyUygf$SnEB8XmOe~*1?I^_?A-;`-bq?VUR%(ep@>h_4 z*8W`jHRNPiM!*{U>nzBL>u@dg-X>slLBSFv(~Q&e+bNEU%AMT!n{rvj3$IRcIjKhE z6bG44TM~|<2f7v#x=0xD01I=DFYX>bgp%ndigl2GWZ=z5s_;9#4ZqWSa0Tx>H-O<~ z^e=R9*!RImTr%NYsElpGxg|0<`cm6b_EwOxSGnn@1>wVwrInPE7J@s#zXUs(H^&v} z3yL-nW@2Tz*J7dE^rmA|6@wqLR<#-*!Nge|=2k6aGY==^>G_$cmWITtfdqVn)o;Ff z^C}j?l|a|x>fg9;_}@VDEu_;r)%MgRFXoJ=LZ87cMYszPMjg-3Cq8WhH#({G33PNw zuK&sad5jlUW)n)bkgOMU`!AC(mV~UnP7Fb4Dc}7Y2!jv%_1;h?vgKtN!c|L=?Jzk1 z)WEvLq6p(W$%AK7^VyoaB&;*Q_@{K-V@=9=n?*KB-K>s#Bo-tEp)rLRl!oF;vrnRN zdBWD%a=pl(*>YK^x2ZyIb)r9|hDRPK)alL5a$~k_m_K(0oHhVE>m}aZd~(iA!Cr{- z;i?*={L3llZjTN*R(1CvTN;AOy^MkikaA{K4gasz(>mfm3NHSrF}iIvp>e1J-&FPZ z6iq0fz2VdxLlS@!k$5gh+})H+QECCfP-TqiwP3bB$1`5-;Ujm6*$WIb!%z0qb|Rao z4c2-UDSALs8sU;bwYrcL!#!hJ2((?o@05_ixL=Y`@ZF_DNN&AWPz-+~&6Oy~@B|(D zNfs1I=H(*w#q_6hy%J7KKI^m?Ht>|B?oP~E1nP;z$1oM6C$cgcbTsqYoaTwzPkervIgjs0fvw;bh$)9x ze%*1k>BT^k+C(6HM9<@ET~zqeN|Lg5CM-iB4$?MPZkXG6uip)eJxe5#zr6>*AweBD z*6kK|4JGa0U|{bx>Yy+YIQG;4-f881+&e;RS{L0!`5eb~F7^#k6-PVIeFrZhm$Naf z0N|ne=fo_}8uqH%7`upF7?iEVM|l(Q&`WsTRwQ+-0)(rDOdCE7)`o#HERBuTKwPfK z#Q*}PAcl0NP)+So3tMw^6KlI>ZA_V5ZM$Hogke5A0BUtgY<(b;s#A!CCvJI@DG{h? zZI+ONQ_BxzWMHXqa~>VeY2k2Ai}*w>9MdW-j7HHDtA}DO*X#?TWvU_O&|Zw9)g9^= zVs1*m&tdiZ@r>jHRJk$Bc|Z_E)ytG~Q7SCB+~q|}0s$BtA%d;#(EmsbrgLj zSCxltW*iJ)u4bNd26_!zmyffGyXrGN_%%qV?qf+z!T4dkq)ssq~C zD(wfkfX_O@At32)ETWqX^R+(-8t4nEk$bfZ5A#c@oQlc#n+a`O1NgkiFt1^(JdBg9 z4rXOh>3&5Fp%*cP&LQWJb{_5tPiv+^>k-#QD+(09d+s?8HgH-muolxK0sxAL@4tue zNvXOavT76YrzOUJv3F}Hw*X73#J3DH)q>|~onQ}`5iZlpLb4>JF4Xk|G?(ve$&w`6 z(AQb3#tD(S5~vACdolJ>Kn<1lDk?;r*Ok7j zNP>sW+kQ;cX`TDc|==YpQfoHBXphZ{vS@yGO*5^ z>Rt?);mpBZ^!1jeDu!F(qGNXvJ)?!aI^!s4q!vj{`6~EIWNzVFd*e8b>8NIU`#FZo zOr+t5HPqX!w9q6Uu+%tI9Z3u>IU>47?2P;|7Q3Ui4 z%5d~5?TUzlW&vCHi2Znm9wh- zh{#XTd2GVHT~3U#+fTGbdu;Bj^N#{$RUVYpe_(GBakb?v-MslBVgBMl0(HV_VJFYROySNNHHQ;uW z%&_T?8NqCD<|24(%i|4L&t-O64mhEyGYD>bw0&1h2rpZ0cI zNdlpH0|)2$s7Q>9DHE4l*49B9Ty)vna3g!$pF(K0)M@*=xu!yZaX)us!^YCvD|JMMdQ$7MbgT040PX(BOloqbDWG(B`N$b=j zpNyI&HiGB4uF^uQ1zRHR8Z~_@xhA)IGiPEUW$tEz5*R9Ve^gh+p^AYWeyN#ZDT06l z2Cu=4BNbn@LU?U!4f_Pz;`g~F2vO+1L|j-6u%|QV4Wr7R2Zf?uFd@S#14L3T{Of+^ zEGTx)cvl)ch;TN~o9fmd=dfMRZv5Cl@^w_4L@BVI69Uqly_mI#%h3HT&E(R~AT!9f>>IT}s}Dp**S zfHI7ZeO{c$WHAr@-A0sT=I`jp7b_?bD4og^Jm9{GKS~%;O_cz<9RXY)F^2CU(!@(% zMiP7P!)-o=E2!26wx83h(cQf4-s6FA5?)wLNCo<89zU#hU~2) z*%|?kpogAHIfIB&rJa17f#YDq3Gr%QeTw>W^ZT9W!Dq>3}m?}$Pky09fP=F{2$>%;4{0Q-IK z*2qU6WwFhG@@TpBKK^LRa`>L2e67WgpVf4#fvbgk-@`;f-*G;L?K z0%2oSi)})7Aam|*v0tqAP6D;|24*ytQz8l5Dup+Gh+50b;JXlf6U7?GZm=J~jrw+4 z%+@ot|2JN6o|GBxg8===SfCn!f)-Vbz4@?Pe5-tJV3#}ZeppCXE3cxlOf@BUqp;v7 zcqmTb{8YGYrx1rB+t*|;0HZa#Q6~>u6-i#7HO9O(U9}$jHF(@CfDdic6-&e% zNB-tI!UC!4p5dcMMq)Cb7hPh2^b0b~bB@uzhreS9FRKyg??K+XfS6f14&{ zaK=Kb;FXP=t^WWx4-3>uYr6ENAeWpU{;9iE!KP91;$Y#X?jN5H=i(jHxb+FGOwpQ5 zx-0WA>5eKktXe5|*t9)XP_hHY&7R0OoA|sRl1(v8Ew?jy7r^mhcZeu(u8HG?mW%$p zt{1HQeFKc*|_vQBb=tn_V@KbPL$2OqogSD774R*@g_TMCpMqSs9q6%qY1 z?7KjaCy7uG_2WFfg>7*Yq~-tS(NJLt0BTOzx0FKBgZ6{Y*LgpJ5mzMWPtxA@Lkl-7 zrq`OO>_^0YE!_VaE?q&VOz_g5vjjv`NC2Ut@q*wk4>3enusg^fK5LkJg<@8oC*FBS z_Mg)SBQV}>d2xvOPfHjBeEBFl_4C4dkW`U6M0sU_w1p-5!xLm%L1xE1%BM03X00UQ zh{Km*noJl%B4wl^HH_Zb&_l2ZVOG9PZ|_>_(L?GsCL4_Cn83e<{8rnvkuttEtPJ;15@ZZ4oXUF?9B3{*|HRd3*N9$bKj ziqM()`1AVR(#G*zw>^ik?uP+!%iSQ%7XM*u@rz_ zYMI9I!)w)5*|-q0$S(?BEQDO!qTZ^k_-R|e5%vHH-9^UUu=fsFZ3ah?+kN7q+)qc+ zVH70m#nvt5&Yqacu26wJ-N2ox{!Q^Mwd|fTRiHAPKc~ktN z-RW&$I@&6qm(b;&{1+64dF^s`NnV_)_YYl0u(d$@%MzA?VwKdjo=uv4JkK;j4V}f7 zIEy8{Nqolj(M|EuR7cDfjiC0;Z|ERzxN?R7>=Ay~_fmYh+Zr;xBjpeg$MbIzFCMbn z*7aE<2wTCsfHVfiPftG2wg*F_u#n2aI)6fFSek6YP;OWmi`VZGohHfC9NzEV8l{^u z$y?dCkK9|530;e=Tb}=(VG`VZP~|}wa{ja#C~;SWN@8u3q)>&ZtU|&UzU7|Ni@8u4 zYXyTF!wsD^``U%~au%xIHwxGxG0LYww7oI7$wikRAnVfJVnDspLTF!h80diE}a9&ry_vU6ZP~P|{KqDvlP4E&vN9(8Q=p1>N5&T^ObjSa0cB#t+i{^Q%!K zns~&^%VazrajAjhF+Ekn5-X~<&GN3CD5k?gc3KsGpAh>o798YlHlhnVyl;7}=F%!g z#E}ZBUJdm|eL=<|pGIt2$FYZ5EFE0wU+3HI!I8n|gDXYgi<`?LN(IhzucnU66Z~;t zd3TWYeT4{fm1zt%DKLT-E6H8Wl<}S(w*U*s%=F>JKo2V{@arlbKs8 z$UzKNT-$vjkr?rWqvblMr(Vt@yjL-GW6wp4Edfe;GY(b@_fYGHhm@X?cuIN3!26IS zDLN?sgY5|AeZ_NiMr+l}@{i{bL%H8n+Jy+}oc@X3_M1UMk+C4wY8WeFu@*x^S~UFl zn=xBY_{lI20COS0s*dNLP%;{dhr-TxH&|;5>C36df4AWIa&+0ryJ@m!uVz}39bYEv z`aIpxd9rxM^aQ|VpROJSgY7BGhVcjdRaexBHI*LR4~~Q$>732sEBbnuLD(7_F|)lG z8tp2yXL3d|v@V68Id$aW3Bb3627!jH)%j~JgsX-BS5z-q{RBGQw1gxN0ePEkdR@3g z$+#PVp8#Y`^wHI=FFaE`oDocC=G%Q@eNJv`7hx^`b?cvi7d$1!X=7LOv3)I|3mNJCcSBcP_2Y?Pqj@Xh*aK^lV zaylQp1dgI|bs`c8hl8XbLr@JslX%<*4&t?h@43AU?6CECUlpAs60U9jEJ{|B8+6hm zfpYLDbE34(*9oX?DG3ezKx{rVZaDfzw6PdQup9gmcd~3oJZADjCp4x`*;rbA{fJ;r z2!Ax%(T5v`D|NjiSCTfE= zvBjQNeGHi+H`Wb|rUhYOcv{_h^7ykGgs+6`BEMf0ocit6ulE_DeaED5he+%uXG6{) z`7LohkI6eXY&orVwH?$DEuWC~pNRO;@prrW_KWV1MMB+ZOOg(py4C~7XL-&0Wps(h z>+@w{e^fL za^X}cj87(cw+q?dRYB-NV3svHTn%a+`vjCD$@qL+i)xNbS-G0)FwM7*5kL6T;_w$) zKI<>iWk%XZ@}5Y%D`jlf$_7S~1->ro!@`;#n~oFn70G3RUeDgJs+C`QO1L~c8RVsq(&WE(T$HJ1j5GRoN~fJcWKbfYkoFvBGg3*5(@h*pR4 zj7QQAi>FArN5-xC-{c>JJVTh@9XShjX)Oqe;IR=_5q>a=7}PUQ3VdLTQP`)W^zlSq z#@mqJuGjmiN)3Z&;(A>xPNL4ac=6z0oXGZp6VG>xZ5BXa;g3$%eS8UU0+`oBTxdpf z!^Rf8gIAGM&(Eh33W*bSa*g_MfuPI$=&K72LoMs2^p8N<@A#XA#nF zpbjH|2*78&fX{e4^F&Dwe0(Nr=ZC;t#A!9>ZJ5Z9+Kc6wjw*V=`J5F&`!F|rcJN&9 z0mV1v#>p~7&9vqNZG!H|B(j=Zg~H7iihPKS_Wx47j034e)y3jT4&$U?G6^u#-X$f~v$#&P6=rCVd1 z*}4+ga?3&dUc`iTnU0F-{HT+aih=EF)348a8v93{kXk{Y5rb`>rfw$_J$*$6B<-^U z1Qfb@7gq$e?*L1cM06hAt>fdxQ2cg8hZq8ID!A+?h5#AFt$XF8$(4h;zTpoHeB>AssY#{Ae_hAa^$eg6f!!^G67dCzcBi^c$EL=rBvs-7tC(>PESO*|CHd0sr;%q_9C=vFj1vHlZe%2> z50*0-M{%rTX+a<73WK8HtX_}``c<*PI2*K?jbk7-@L;J+88^905%W!PQY{o4=>nts z0z#1A5p7XyN3O`AK^SMn$auF9wS>`5EnsH}z|NQ=e^RAv3suVQcDafi7==0#>&^5VRFRI{^fns%tPk*9hC*NAA^hyxac*Ez zbY=dm$Lh`iF@G2&cK7Dga2bt_PY)Xh&es7GnZhP^xE&M z2T1C+9nZYmlXbg92?VBbT`w|1PaFu?(g13%-?Q!w*9xydl@IC|CS%^_gx->vbx91^ zK>1n@j;lM#YETXBAuTHn_p2bXEamo4zj!-223iM==EjH8rF6NIvADHowSm} ze}3K<0O`8JUE-SE)8a;)H_Y!JLyhSx&K!~{pqln*0)Zt@UhJD=6>7jG7q_*h1FUnI zTaVNU@B<~A;>8&?;cug-;m;Y9`+!P?*G-9EJ(AaDn;HId{k{M`1H5(WPXuuw2@yo_ znWGeU`;|e$C*BkW*veM8QX&Ds8niG7h0X$JdJCuXxE4(T1i&9WH>+YO=AMYbzOJs; zC^7Ce+~#^uZpLeqM_|#d>F?rW=g^IGM`A%c4kLw44KjfcKfvz!zo6W2Ld&RR)uZr> zC&8Q$b&ZT?`ix%)Gx2_gX-gbBh=ByJTN!@iSQ}rWVG8E*Z^L6h71GJ=T=}6Ws#Yuy8h?eoGyb$ z!rxbuS+tA13u5L;9Fh6;fuvmqM~4^U=BK0r1I+C_e8h0M@dzujad$X15mq`i(&4;O z_Y6@}n?)eZl-xu36l4ORQ%;R;XT)c|@kP|QfP|~}UwDY{WgmTFiyXO{m%)e3(E*)> z+gdQ_+;mzm1zkAvLay4&;Qa49MJt%Rgikj?qC?uIayfu^b^MN(>hr!Sbw^zNk1lFQdusr3LsU(dEiW$PA zCN8i!6yng2QOKjS9US+u0ydS?l~pU8@ht^u=!CghH@Yjxy6JeVW%Sfpj>0rzS=@sj zl#U$|$;P8u*8-lOZg$l03zIwS-RQQaq<*0F^a{CUY;- zNWo=E3~ryS{-cVvnK2?_PCZo>GFOqA<49V0qVQ`{>>%xY&CZ!a5?{UQr>#CnS^siZ z^3q&PXhlkr5Y24uOMElVW`&~TSxk^}Gbm@u_v)0#)_8mTe_QkOh6ln7>tZ!zmCF!C zBWkRJyT3HEYuRwGFu zLH_7?cdAj5kEvNHDHL2DsBvR(jU;l9SyLG`46e1V}Yj<23xT6Ifb>O3O>r*c1i$r@69rj|U8-A!j3HEMVq zKJVBiv_YdVXk!VvJbd+k%tav=ghk8k5O7b2?jEgmvE*K81QW){3hcA-44scrqYe_s zV4(H0>*|->ORa`pNW)R|ud?=OdKR8FUnlgKf{O{Vw%;Hm?$ee4u!&S40@KQgSr;b< zmBgX6@8x}Im8a=b>AiR0R@5_WGDaPi{+_J52t##`=0OBSSkboqI?E;KpV$6v()h=p z%8#a8Jr(=nEc2m83ikb3o>Itb`1WxOex2ifr=BdQfFjAnVo^?yLV=Cur`YZ~(SqVD zr4w7_r{LmBCu|HaJWxe{*bb4ik|urCHaLV)7h6R7NfJ#XrAlXW-i%rO!)av8P3|B> zL!=Fe?=`~ESd2C20uViSSgV{c=*eOr_q31>iccr|S{%!EprFSLVXr>~*VA>{#1Tei z8;ehr8EsyL^?NHf4>Kz3Va%sn9bhPaT8}HNU$X!rpP)f@O_j09TKo3cny|!aIhG8m zILf>V|H@O^JK2Anm&cp0*a|0^a=?*1d(z?+J1ISv@-f0xbfgrdg=?5dOrZo=Mbz()oA*6nh0p#|R0MWQEBCqU26Yhz z^7>>O4zS{!f1b_1D3`H&00b4|a9Sis-SilY+jcuwniYp;77|zXXx|*>rD2yxNUpyD z#RG%ahpo%|G**0yV@;~hvhUSY`pmmO$Y_weZam)dZZBo;9P!DViO-0`iqZ3red5G6 zk50K>5BhrMDwC*|jdbKG7~?k{QF-n7V?fc3t{XcOlKXJdJ5Bo{Ib=($6kM8b7_?uz zSmne&mT&#-`G)dAb{&h!9h9e)HV#)Kd^J8Ep}tn~&ge8(#S~AA?!N_y(X2DtSe-}U z2-w2(e*CO~PC1VbMPW7m83JD1d4pHL`Sw$;XJsT}m`&)_7I~w!s5@0!LK+P#8q9`A3tW_In*MwCA8=yP72)I-jcLLdWx(1Y+R ztC#Ov`_4slIb-d+%!HShV_<_aNr8PaaiXwn425}RM$J=cZSVEjBw1p@OvX3TECsLX z^H#kLXjX$_MTHop{PE!HxuA>Rp4PJ(bkvDkek$NB^@YMZ z7H9FWf~>MLzk7xC;%>-@i`{cifKNIu{4O(gM7^Wo*X;^C|D3|ik-?83z*}?c zf)#XMMpXsvp{hbqTaz?i^}bM&YkIBa0*+s-fhBEe@*XnR94|i-|^`Vs)4C4q2(B5B8l~ zHs-A*_Mc~FboOpZ|6;hxeYzv*3~GlP7c?Ky@jzL`i$GBS3WJz?#FAK~6JqLN(fD&% zzlRlq&f4wDikuZhA9^TIEmVrnWl7+tJC?OBh-Ml)DaYygIC@6+~XqtPBtg4TkSgx^qjY;2u9S(D+}n7{oWo~yQHa+ z)q7EF?koDIkHj&SY}asEk{}|1svp*u)^@GIx3zDJOnA$PZ{2ZkWf7+GX-DOA30qF@ z?|RlUMo((MUnhsZE=HU5T^~XdYF$hx^dA0uvytPj&JF}2Ke;LR-cnZKywrn&Ze3jg z=?7Cop$66m)c4Ni@lk2m>UXV2M7>BGmvO~b!*-|Al?Gr~*pbUe8s7XziBE8YKJ;gC zo8(d198lR7N&F=aF`k0|s-6=nU%O0kpwmZiA7dqT4wNmnotKF3<=LgA&eb+)=5=$Z zAqzYZS>QpRjvcMty)odyHT}9+w6B}_d24Vy#>0d_EQmN+vjGDqGR?4Q^DMlVMZjK8 z$XWsev*xP}s!GK_RBYBN*F{H=xmZJcG3^?3wM!xd1+FCAeB^XL_wbQ-v4zJ$Qhp#s ze=w=OeV@txeG`WE8db|maU0y&=Y4pdK5n>gsK0Kv|DA`hU=r14g+J*dAy1Z)^71Iv zsplUtSsxBj0=im-*5tE;FcAb*ozJS+$=1Hw5}3oYy)F86qJB4K;s3hDc*qSxA6$2; z8TYr-SQY?mUWC)cwyG%?rI~aNz8}hW_kJ)$LU^U&;kgyX#msK~#qc3XWSlHPn8!8r z6f82+w7#z5&(tRqzk(lc)(8=-i)f9=$~w_BJ>L9FRY*#n?UZJZBd2D-rsu1LMI^sE zpQ_8-c4w$N@8kG`k94uW^$uAS?oMLAVnVClPv_i0+iF5Df5upEKyw+_whqtxI5ysH zXi9JIRw&y~kDvbGac{5NX0M6K4qZ-8p2Ss>u8Eh-6lCWlW{!d|7I`eIv_gNRA!~T5 z#-w;%PjT>2UF9A9IK?_?#=-85dUCmS8Pytd%nvP} z_E<5ulsb1SU5Ts~7h>?cjFi%?-`{=_p7oJ#7W7`vL8d452p8?;el^Z_G8yAv*mbg0 zZTidamDzH`p<3+*Z9P-}*UwjbR??)Ixu_E4`wSUKa zdiNyerpJ|}GJ84i@b2*UK|+?fk>S{6mDuc4n=f z#FPS8QFpRtl7eKciPDcVUD+RX#&vf{+&fqz`ru!+*d6O19Qfh85jYEy=_6(<*b0Py6Kkq4&$j?2q0yGq$v* z%Lh)KdugLQo^jdsg42@SZ+`sC_B=CmZC$HEnt}cEr-O<5>UKJY^3HFx|40pMn&UA4 z4d>Zq=R5e1KX-N!&scXk+L%kgNae8L+B)uzigVdzi$8CTel$+Ed%IOVw*&uHU%K5N zlRCOiY^`ph*P{OzS^a$8wC#fp$;U268wW4XHlD+9(%vCu=OJ3xdcw)XN87G;yd$#d zk0>_$!a6gjW!pzY>$aCQkK}*89u(cI`hn;1ntIu}*_pPMb%z^^DwdnnO>HUstJLm~ zn5YD~KLu6KER)}I@ef|RFS3Vo;(gDY2+#cTBQ4dR=SH}xflHI^(9g@xVWz$*Zd>0E zm>JmT$cOa)?9RUWLsYKEvpxiWpO8fMpSW+&op3#IFZ0chrqr_CcgWxNN%VjdXRhnK zI-^w`ns&9qW=`?gaoX07YaVhE_(So^`4jneiIST$Wlfrz&iql|EF$f6g2T?S@=Z#C z>y;1pq%)^`w)RZ!^}*wN9@ac3WLZ7u*+Tzb{>RM<3mQ^r?Z@hTU)%AV3o$XU9_1-{ z@@J!z>DQxm3!gRDk9FIw@6lWHT)%ri2cF=*kfuL!J-IgL%Vx=5ZR$8KpH5*0-Le2w4aAb^LHSbX^3KAk^8n(Rk~wda52aeolrw0lSY zmV_Vov-2}@ANOqFv7y_&AJ4!4`LBEqQMo_2UcDBb-{x}U&kb&WZGSFnXMAm&y{*%u?xc_K+7Sj1=h>7%nf2e%kcWPNa#}oWm%pHOJ zNa=!k$FrU1G^Cuyb6NAoj^}c?iNWJ5$M@Bkv_3GAKAP>mw$$#g<6rRu*H+_w;eUUZ z%%0cKUu&IlvZ;5)%ZFFgOCQoc?5+$m`9Dm3dtA)f|NpyEB)PQ=g=?jAJyUoHQBndr48fXkWDOBN*|b;t9I9~ zePMIz-yd#D_7?JKSEHRBUWbzHmDc1d^PgaM!&FIX^+t!ve-=?aVywT4TqmkaJKMMV z(h@dzc}y!e(wc1La$&2syC@>LTAtJPekp#J*~wP5g2qC&a`uYRp33E?TD1>}91e2b z<_jyjJwtjB9H5~#as zaNG*QYCkvqDl2>L?bC95pI>P9^VE6SA?ErLSJ4xTD5fOd>3Ou2nz9k^=hJ!Vh|V#Q zGRn@Lp^{~urvG}NH(;yQ$yl`^(W5t_xsCBEX^r&PC90bOX|DO%QT3)u=QQeRRM&-? z5#`&9Oept^HzH~v{-+X8O@r9Jp|*GLb(m8Pea;g!BDmiTB=QTpP0k9H?g zydD$shbhjhTH>PjpcWRCqJziiFBD z;-hq^$EjEcVf4%wskc8ENKO^bknQZ4BiTBgt5X)Zw;{?cz5e}8ha)UcAvvngwr%%H zD$ZIUP)hfH?xCEWhgAruZ3}Dd&|bo3FTc>rjfja1v}0>#G4sMU@RfR1%VY84 zOHlVL{k2w6*G+kkjVhGcCI8!CI#FbUwa~?CE(0f9I#{Mk&mE4cxGvsrs>LOq1yg(RwQYyS-ztE;#nMp6cds5VF9Bca^N`tbTE21I> zGc>4A*x#4yUbHJqX$EVax36SyoHC3~`yUi{KTV(8XyI_)*+k<1-#@X=5*fGF1xF^p zSgh`<+GHzFH07*gap@()C-(n+VM4`AJuBb15(mz7cTUQ1=l)HJc{9O7feUr{< z#a7+IxQvdk^R(NV@~%~jULQ7Gv6cDZscouZ6szrS?`F5rha<_lO|YYW4cw%M?i zN1d!QpayUfzC8%ZIT;)y^7XAu4aPz&LV-4qA_dxS57yzZq&q8ArI1}}k20Hu*RN-R zS1C50k}msWd~0C-tKZgiW)%eK?c~x_MP`BwQGux_rJC#Ayx+9ttjnKjyh+$2U$=@| zl~?r}iBO=UsTZlo>L$uMX6(#r99oA_FSO%7<_Oi8^g72XR=413M7PN|yLgRGNw>bl zym8LuIs@J_L7jFs<4gy`Q`+jUSJAfS&(=#PS@&%#7>$kZms+O^!C2Ue({HaHA)GxF1)hatmr&eDwW&1CWY9-sVxKs91*L&#=z?7pbPtmAz zb?XN^|C>TdB~dy?UK?VhBgRiCWOzk0e_?Ypc2_<54;?E)V+pAX*XCih&2!A6P}U{$ zEKHT$SECE9wc%Io1CEea3Nh znt^rrcKRAlDweP^5kId-hEBpkC*eenEM%w(&5ji^8uQ}P9>3tX7}KU(;e3Y&Vga&A zK}WT?JCpRt5xhd29|N2px?kDA5qwSaj``!}3e{ZdbA~QSZzbfgl^YjeolU~~*C=P( z>PvV@1L~vd(LbWmKhVbK3vX_rzhZGTvz+uC3VmfP8t)o*)wM}Nb`&Ts-5n#&puEkam5!~>g*URa%D)X;!Yu`!B8Y^OY-O)GBK4VrXm3|aGIR=R zKg(3jMA5UFQ||$1L>JDe-r4ci&-UHZtes&=z!N9h(Egnf5LzEFP}g7aN2`Gs{u^dA z^vIW%WD&F$SK`qFc$7{1d+Sl#hxDj9A~hH0sg|)OZ%|$Ty&cd6yfH6Vsk1n?dPMrj zCWe=$r{)Y(@fBOHID6I&$xmIgPrPyKd|;Yg?eBeTpK0^imH$Ri=9#TeN1yf9r09vQ z{vlcB4bNN4q}U=Q*djhLP7d>8lMS$`GF$wMo&*>RHz#Nf=$STuJz&MwT4i@$O7*>& zB~ZI8{bO-`*;Y<;%ftP6EXv6tA~betA)}n*eW9yZo};5O8N2CY=?ZkjP5}JY)&44G z-7J+r*4Wt~U`Ms6m<^N% z*QphJ8%w&SP6*CvcL=&Z2VI{NX-Uqh&$b`6ymM^8EG6k$to6y6B6az`eTpXDuHiH4 zfZ&LXc%`f$Fe6{V0XF9w&A7S$#pQo@X}gQl z4aNNY7F)TS+w)1~+b>k_2oAcj5u3S7rh32n-f9uU2aRgMk47cEnBkV*_9%>$h2O8B zCvD$!R3&j44t0JC*(vUmoK-w}my7m)I3O6m*m>O+t}QtLZ;xu`9U%QTg@Dkto7qW$ z;NR{koVWtL&u^!U$^LmGHAVJ)HO-+OMES9)1A?m>Z4Hz zR4q(-Z}%E2-A!!NPOmQ1{=Zu8qc}Icdzu*K{`Y)*)g-C3!pLf>FFvfxfH$zqUu((| zd$SAGBfKWQaZBtjo^S|<4zONd#IlMcIDtP`q*g_DxqV&2>wdpxgQv2YUy~+p=!R+V zso?@7@5;;judEcU;~`py13vC{Y>=D1zvixvgM010_TeX*3y(H~@VKwTZ@g$QQQrIH zPcYBE(AgS?1X_&s-fh!S3ddqh4Y$8w3=*r!;SG1KFk5f{OSp9)4G72?uwT8ZNeHVMY3SAF8Jt z7kS*p^K8v*lYf_NV!zZe70$5c3azf!T{`LXJd#KV{QfzX9FQin2(0B@6Nnsw$)nlS zi9Oah#DU}x9}GXweEZavKN8hRS$wix#$|bm8~+BBQZOIG7=jWr@p7{g3A6M0GDQZw#|GYG zM_LIPs)Dx>R|cF3J#%*|@s*WW{GyNj34C80i}w>vFje@kD(BkWC;ESrHvBs4=-zVY zju~z@{5HQ1)e&{k)4SIMHL<$OLR~M&?&^NLKVt0Kg}kOquY~7WRP@V{w_521+?8oV z=b3W~^+iF;9=KQ3YvlcSGoBSJ2sv8O3Sq^-wB>8Pcmti9wwnE6)a4QNWjtA4p!-m= z+POHVS9<>w(M}YCzB)<5KcUYq>u%0bzYJ_TZG}$Jq_Mg+3ktY~1Ann?^-M)Gc5y{k z*MWy+zgeZU(XoR3yzz@Bnn&RDPC}Et&aBns*)IU^NxR(ABP=j24 z{u$He*3Ec-T}9}wW#cK`&ASJq`KV=yC9v#}iR`zjRxjIq`%uKkL>P0D<90yH~Gr@|q?~6a_ zNnDGb7$=%S4WzG(-R3fim&|W8;H`a*om&$H^g9u~G0S}M8+O1VZsx$uqr2s@KHZuX zXpsD`uasQ+A051!6`Js^thv^Mc#u`n&F?^k2S2N<`+pWV(=Vekt7q{bv+GRHzQ-E~qOl&-UsTR0Iq}TpgNL z%JQ7$F8cjC`Oropg#ktn6J;+$oNk>EU^JSmLwayc&RT)bQQ(Nrl zkcE}AfsP912?36=CQtvGpc!vGuu2xeP1%-e2?7vlU$K}#kC?8BDOx6bNia8AjUlWR5u@DjNg|3O7$fp zISmEM_FXRPSuZ~5syc#iA+HA2mUn7Zq@eUCI{SGg!BIvG*%Ki-I@SvUx5EKe^!u0hkE7&>Bn(Xtu19ZN33*N zJ1sb+TH6LlPT1-{VFN*O*}XS#ik__5kk*nG1}-BfUnmEA%Y8E>jtYjC8!2LSC}Q=q zqoUmA*MBl;wdOyJ3EjPxG`SOVZ~tdN9m|L-m?cu5hQ+?km~u$;c5cPg!;RS$-A)-* zPwHcUk2H>FxV`2oS*0ln)XIUxyl&h8HJ&>L8rXJui+E{TaGCki#NLj9y9OgXHNP50 zD|$|E$s1_-o&21(J;6}g`itmPV_I1R^(^GDCeZ2UH`}>1`O|?*)%k7OKE*);&t}LQ^YWqwS#XZhEMr+F6ZOS66aCu% zX52MS?Vs-iYZAUeCbe#S@Y`EzZFKk&}cAYTLsT%YwHk#{QH4pq+=TwUa4ZWv1 z_dmQsU}!b3zEQs@_3ZamO9NmW+Iz&U5slI*qv**weaY4r^)3~_HQ-JJXeJzj$K-vX zesObh?>(w-!&N!yE~!c*{hSl$3f80T+w1>m`|Zbv+ddT6jWDHB7LYP~_M{HAat&mC zyN8U|oM)=iA)f@46W`!(hccw}(d>q6{3{UN1Svz6K1wGZ#8J^Zxk`UsJ{XSEc?yg~ zc1*d1Z96TtZs^0+eKzgmMv!+xXSZx5d+eIC$r!h*S!W$$S>L`ck-nQcQ9f{)Xb8m-1+^aT zN?8Lvd7bu}(@cd|2ueIpuuyIjr~(R5l#_&6Ej`i_8PomPGe(*80W;-}z51RBP2lfU3)3U~%+_ zU8it(k6*6_r0@r%fV3D+M18&?!R?cySQ3{3to)Zcn1#i*Y%Q~Fh`Uc+<&z2eX5#^N z!}h*x#w7N)Avf(eDlbwWO7i6WZj!M6+a`Lv6hom>x+jr&`$zMY{A9vq8`)tflvg%z zMTcSz6OUuuN+_UDJC9vB)@meF_(l$n%-@&NGl9Ps&j4IXo(&!QV}z4RY@I@@?aSlQ zx3X!fg6!scZm=iYkr3yVU;lJa{_1tJPPuQsY4GEec4aolZKiNUujpXR^6c!3QSc)t zEGuLj5;p2wkgDEiRrgL}QD*D*(_q+%tJmtD95NEAU+(h9b`b`>o{}f|m-D&h-htjw z!wX+8opkwi`4`5ae6wR;7;u@+f5Ki~7f}Og>Wi&w>oS>Tpw_Cq6w?KXgT)hW5z)gr zTtCiv#aW_M?P>U~RB;bNwcsaoEG>(z>N{4q>TpuA{h1q!A%Z?onXE0T%D0sy`>3HfsT@lCn*jQcL{MdNJcZFe<+yDKt8U_{mdC zhlVsv^9aAcmGU#>v03)qq+$(Ykvf1?CvdSIv2>uX&n>t?vM!H!v^3JUvMqm--TJJt$ig&uNw>X3ljrgeu+B)K z8k^Po4EEq7M>Th0D}6M#-e0px-01NH@-pW zz<=<^zlf&~)vYGxKPh14oMSFUz|1zsCplB)pIw>`Bd3}FlENEj28c@kO1E^w{(ZP8Pxr;h3E$^BMrU!#vfD?JY}ve zgg6|tTx52zkg-jt#()vHf(Y#9r=ZI}JP)P;?pb7nwHx0&Mron-27WM;^PM*pS;WN> z6;x^k=MyK?X&Q9=vA)ftHz!XO+EPm*t44g}2eIiwhL;ayyO*hFAxB=>%0b$oq_eIJ zp6=6klbnJy*`-VFz^PMck(<|YRLp!;RgC>a$I5-+HB`WBs0#Ush;Lt76&`tE3`-*O z@z%o{!}&^_)?_Ou#9{#DcUOngsvnjco0hBx*}AtSF{>ae^qir{`BvK_67*oPDr{Zt z28F56`M6_ocrM?q1LA7I6^8t$UAJNGE1#^(Dn1GN(4 zKWR|M=jKyhLFZj4mqB_#;7ZTsrOdTO`nfBYOIm9!ZW0Lao*zYCe?__fbSBQtSQFvU z7yjeFr0WCR{xlL%iFRxs)pfTsM7+4FAH~vJP)NLP9U-Hyxvbk!u=&|~RMr!X^8oE1 z&V)PbQIs0YHE;jB>e6DA*9dp^k}TqmTksWc(wJ!rao1QnPk>MI`R9U^GCK)jqMVp8 z7lUbXd0ya$&zU4~aPnqRibButz1*sOghQ}fOPuR6!Go`As{%g7QM)dFHQ?FI%~$GN zJ1RuN8?>{!NLoN3Dtc3V_m$`v7m`k~`w;ZeIA5*GBqyT_zRv{Xim;`vKmuQ0!VoPjs0g|rp^ zwl|zte1n=Ia#rc^*ShF)yyqI+gIHxiXPOlbY!lh2UEj22p#wYf+?4Z`cYPx057axOYnnAQ4n3&yyz|=Qr5>=#r}7L#nrRZTt+RqGq+AsgZ^+}}Xr`n`FEYn!>rlo($ zWoV#2E`e|23f8$Tf5%bHE4T8z>ouipve!GN&ocn%=;dNF!zR>{sxuFQygczFurOO3 zF$Ye-H#}T^@=YAo9sn62!F#?K!IYkYkDE^6$%D}>6T4mhkOte0njjB3OKQ3ecwcQi zl}7?{i&tUEa-)qQ(oQ}k_(<#n0}+A^!kT>mP_w5HdGGx%w@tIzBC{yqmz;3mJd@&| zsz)TcC>RfvLA~DuPw}8V9>fOW+TLKT0Q|zs2#;h*JZOXw5ChUoVM{?#^lHw93n@*! z&)oa$CEqYwMqf;{DAqEHJQZIw+|$%_bsX_xyKJ$wa0Yg|p5et`=;R<-+N7ZQ+&UgbHU4BJsA?&@!g;!Y1(o3~B zzVj9Yx0$yhI0N%|=#uQ#hdjroX;@Z@S8l2y7JJgKw4O`+&lzkVET z6}=SyAm08{ZSSi9SFJ~}YU{2M3=EPC&&<&>_KU%Voh~l$pQ6$ha-@y9H{4D(=1KFc% z=rmd8v1hq%3lJ))19@+oOB~&j^T?dVy1cRiO)na^=Q=VaGf^GmE>u%yf1${Z6sxgQ zd+lFNH_e}6yEuPk^1HibDIuk+43lDTvsrDg(kJek%a#O(! zCRgB-y5b?@0{e?Rnt3Yip|4o>$&*PoVqP3Ye04srg*fFiiRwK0upFRfBNjn+2fUHB ztao^mxkTgC*u*w0HOf&hh)3K0ldY`vvSEA_5<2Ys>+uz-`6m8QXiw}ci20T@6#Mfy zpY+i9!3Lg3Y<@_e3yR~Y;vlWQrMCil-WYZI_6OzP~uLBuqAc46?-(JxultD*=wyC25`y{-!;u(tmudq(< zDH5$mzZR0*!4acee$@}_#7J|vNh)BcV>gjuck*q z7eV5q`cs4lJlC%&>oUNyK0qv;X^+ZoAz4)wzdYlIT5hj^47ZoIE>0d?SB0#@FfTB} zHY?tZmFLV9s!xNcnX0~$2T3-ykGsB^L-Mh;3G~!pJ72_d`}+RgA`Z#4$8iV zVEK0dNGAbpcm+KthDy(Gf&)>&D8_&qyAlX!aNkINQ|SfLPBfj-5e1R01`8X8TERS# z^^uoqkI80i?1vu$3=2CL;h7}K*5>*T@RGBfrK)dQhQp{!g9f)El$8!)cIJEprcbm( z!*lnWjraK7mw$i#o%Y6u^cg&YiT2DQ>7Z+=FW99M0t>_XYZpxeHK=Zdc?zt!!k0_;I0DKt?{eaNhawBN#359-;Wmrs zGtl$pWevmAX^+wA!zDMbm;F?_CahHZgxlzp>cfUw_Pvq2khK01kSv9&z@m8OHXI+- zR&WBOICB5>2!q3V#j58D58f6@TCao`2B+%pd9b~g)$QUW1vX}@cg7&jq&lSi2dZJ; zhCNDl?e0-rx8d?xF}P^@iRG_`79(MAv>%+p(M#N>h&j3hMFvytzd-lwD?q9|eWV4c zVtY?sF0= zZIyA*uRX+`Yx{1u;O92e838X)0yRLck%Xob-)00PWnE*k9ui`!WdR~FYks7{{rF|i zNXVP6fZi@3un6v2BXQL4GIq_}S=ryD2Y;P)!lhuz1rj@8S4IKWW~Dc?HO#hDsPcSF#Ol)w)T!)(8#L3hyEpH=lr7-xOc)$UbP3g?qMr0O~VpeVUXf>}v1%ex4;QwmQI)w8yuXk#D z9c}m(naCwztucSqcm_TElSp;T2J0lQ15b)?AY=bH%t);C`U+WU0?q_1D*K-|EtA+y z3Tbvd~lgN8^PYZ9J)Cpeye$sxT5sR$D+b3SKql03T zShtPKz`>O1tVob97u+C~Ix+xA)nzn_`vE2l!pZtTo=z(5W1<+d^2-d;X6h0)?+s%t9*JEu_o9 z3rVcS^TgQBm^!%m-8*o%;@XDDg8KRhZYMS3QT)=ir4`%s6*f0kF> z(fgb2sG6x>Vw;X@i8MnOe_CIR3?0bl?ehL2NN@HF;s3ZlKpL>Gei>E17SW_EbHT_q z1=95+NY^{_If*+ig6*3J^Jh9yw=j!QZw35b0@PZb(rM7y9sb}1)e*$URJZmxL8YWK;qtPh!0g~7rau_!{eCZv4d}v`8_FVORqVlM}o|@ zpCjE~b4r#120acfg45O+vOQ3XM{=Nk*S@NGeR3-ZY*;X*`jhu(=BTA6`4bed%E!TT zVV}0M#N{!fuq#Q)4I4vdVVsm?)?vh^r{I?(xISZJPiyf5|JlgrHK#918T?FJY#;!* zWuHLX0ELF<$wgx{xJO+!uj#rU793f@XVzEmfqCICIbcczbY6XKO@rZ05 z1eLFLTd?8c?;x!w@`<|7bU^bP3Hobit)N9iiVtkqL{!@6dDnEhm)r}lx}_UvZbFlH zSQmQS_1eH!f?STY-uLV&K-uMJ;*vF<}L{<^K)t?~KW!!hVW^|f+ zZT+PoUqMlJJfwQ}uvi@aJT4L7W9ygLe1fB)T6KY{lc9mW`9fdWzH+ zf<&J+%Uz`KZ!CVa_Du7ZRL3*AHxIj1U4JT=PCo6+qnn-DM?E#wR{NW;sIoVk_M{TzipWL;r9+bN= z_KTF;poR>`_c*9`aq}49KxQlnH2ES)UGn7J<{Ded2pSxb==VX{$#%FQDcI(Ty)B-x z5$5_|U6(e9PYfX(Qx+Px%AX~uJ|;W%h)hWs0kP(nZziGWGgSHCHzcq%M=i{SYugIf zwypSOCz*2TZMoa?nDFl^da)A@L!Yl2<uCwZRrM-+~u=9UE zO}fM7xUWDj;uN+x^Yc3$N z>V!7rVIoxW+7TnA#%6XZ?`n4ndXXxGxsn8Pg~XyFLPgt2eE!8|j%Kdu8LH0?3z%p^ zq!aR5Ivl`IGR=Dp2k`?x;|KPJvgeWsDpNjDpI))Le;b3)w^V<$XKBMfR}ygO?bEO1 zASz=&UWg2XC0nz+ZJA$F7TOYXoPmhxh}V6a=q>(K3^?~oLuqQ%|UOXFYs?gT8bXgOAoL$(%f*Tz} zIpf^c^gZI`o=3penCr}@^?l^No6d5&jLDyPFWb<~_5 z+c^5F^W|u)H^L%XW1vo!aUBth;a^~V%k5Ty;5SzH163eIenVlQ852%JvR(tqGqyz$ zKg`93_+g7u91)8-mYcR;qA`Vd^h(l$?*RW1d&Eh2u%;@0#Lqd5Xq*D~iq^n{e& zMLHdE#b^CcN`^M?6Ke9p))KpxP@-Sv3eH3!nP+_b$OH^#Y{Q}$4eZ|nuf+V`QF_w<23^0F z?L^ySyqW;alr^>x`2fS;j{MI`;%7-OZ4jL3!{Dlf-{LQNY;nHo)@LIZ;9DjPkaAN! zQ=S7M92Jnw{_&1(xr(G%iZS@CU*%v!QlccoJ{MN8O zmp7nduSkIVuvX$hM5W1GsJ9-}Kub)7dc}bqjY;k@SlDwVI>K2+0^bmdeM8i8MU}tv zf&IABuh9W%F^nD8yd9QS6*L5MhC7iz%fGklt+}y@yNt!}m>?LPCvXcBq_lFQP7|n)BaQ zJoDkb73$y#RcJ$&l^mE0D};>KY{T-_97LQ-5pjC=etYyThubmsD{nK(58sO@#f+Kv zDJzds@Aq4Dx=&T!S|r(`Ls@FxW_X1m$_Qw-fh#cEPqgOW6*0ygR&181KIBkSM_obWoKk3q!zIDrW=|zVYFvV0;hD-HI4BTNDGH=wio5;oR86#v6|;E_CO62#^5oWQPcD zh9Rn?2MoVVG3asTzOI#Gir8!s8FhYAk2sp#C>Zq&;ZCL2&7}Jkg#*)7fKbIr0|6lANLqKhy^st=CeT&%9M2kT#2<8@q9}X8BuTYyie)_CPZZPY99qD0z4*@ zaDGQ4+1Sov7E*H@^pnLj{GAbzzRj75-);9+Zpm21$nuid?%xh0+Ex)CzntfPN~r}$ z7eKHlqMABnPe>+;h3mLCZUs$)Ct5a$e@wCNS^EZ!I+8;ifJlvDQibWe(xX}hZF7L) zZKk6(?Tm6#i6M#G!GMxD*~o`XmHf~z;hwr!`OI(AI&b_JIQcM=li#i&5t8w3<=xNW zzYUrw4Qa{0%~>_@O?xBtrW4|Eap_oN7cYGILtCIJkdyVn9l_>X?U0^sT zh-&F#xErQhoxf_)^r`0okSNuc2h4E={O=8iH}ufs|M2M!{2-}*fkD&5}* z`6Mr}VXbT3^5f@OX;An4Hj}J|5CvaYevd$T_l>w_;8&Twxc=(?4g8>Lj(7J@05B)( z)H=HZ{wjDr@VtBUx%Oq*-v`}qhN>tA-JdEdp>3~=Lr@q$D6eG)?k6aA-9Y%Xttl^U zZ|BJDo{&q{h%skD`JbUD+3MjQR~k6`1MxYoA=jIL3@Vm;fmrE8fX*CVwI0T#oBlpf z;NPJ9GXct7m`&;86p@wiMq;p&ftu_5HMbS(fRiv9^u{G9Iv8y;t7VeAU-gpTh-=J( zYYaE>H;ex}f%hUFwd6bweG0s@(d$a;++6i(FwQ<+14MrI)u`GhAjL=E1w zr~TIVYIr8^Y}Bx!m5`xB9n>VmodlNJY!F}JG)%*76rj`N^vS7BXvC{rhc-nf6iI~T z_dH0|ffrJsQ4cty`O6cc>V~P0EKJBQ!UohNb3>Ylf z#8p}q1Oq5(4e*PG6IUrQbL$bBJj;A%5;y?8V({a=eXr=`-T?HKuO*6{TLnu)%s6vb zx6VJnWrp+}RH#~b!rLR9ko-%&M}pnM)iATVS)*p-Lt}Oh7}p8kmXJzKyN%$s4?RjN zOzRd?)ghyyOhrnyy}T^d{;%8mZ1=)08)uB>4NX zC1kwD?(?MN&UDEO^PT$gVIx9j~OL7~_s0 zpM&Acw)bIc@y^52P#HAl66@tTo5E}6hkcKP96w4X+^{#)9@JO~35$wI>da}+`n$s| zL&rBe`g@9)_qb&WbvZ@*l;a_x7Gv=lm{@F>SnMy!lk3WUl0q{MdkB-^?Rlo8$~e%O zJv`m+5D$qoB}tB`&78?{d9lnwh+*zJ40G4d_9T1D`_pKYS&d^+Eja_q=Lm2=hf-pH z6npPq4cSVcodl67R0U5_V4-0}&zS#l#n9lt*gV_++GQ@m7+jF-pS&?%|&B$=wT4pSG_ z?JKWX_td>VN`76#9e!SVfdH}nG>mR9e%G8sd3}D)@2xy5Hynl2zVeV_0)}m}9-)5> z*Xbd+Y)44&$)rZ`np;LW{3?2eOPEr@<;ue%b+DVKv-;+d{KX-1>j{*53`tdBNUG|I z&Rrspo_2x|xL6Ikz*u-uE03@s3xq>loz%Ai?w))I!uNft$GH2<#cVE_a9@jovxoFz zTVlXSvoLb*L36Z3`myGOX0q76C^;i(;9yA0i>a@*D-hmnCG)#SG?I@WYBXaRsYA zsod@x2&$!ak@4B6F(k7jg8!&UO+ISx&A(|F;9NKchLpH%2GSR6k0hOYnnsWZZDPT@ z=v^wQ+~%!hauyLhmT~cp!?vr9`NEUX{#tU{<&Wa~*H9-8%*%$~h_hO_-3yl>gip;b z9}LtjJuMHbedd&E7*1w8LQluaRN*P4R6e>>g|q=$Oj@jL#FUrdJy(sXRWZoRc}e1J zXXnhlKbP|pby_$1j;;_*p4{JL&sX4DIuN?wd3hatqU*c+u=5|(p*Ie_6hTd zYvu%x`e1oG|b|~Bh6b813V4t*Z@}oQ+(}Dn@U+4;td8m?hEwE2N z(wFBfFQx5K9csS<>g2P@Wg+J1RREn1MlBb9=JX!B`S+d2#g}^qP5!~eL0*rlq)Ib? ztiur%*I$s{?%c6$uNCppdDw~49JVG2Hd`+ieKptklh{BC2ow^~tt#>GTUzNe9r)nL zWW0G2Kx!p7E_^#jz;ne9`-o<8FN3(g9I^+eIC+Y)my$A&dHY#joq^ZyY~`b^z)$6; z$Y{aN;8*t{+9}45@9kH_CR2llP3;QbLGdCz-XTbJzu&~U)XBt5K{HW?|G%F0JsL7A z7Onuos@U$By2s{a>k@@w(Nz(mU1W+Q*CGug{cyz(#|W0H*-Ef%w{6Z7a138a}z2CW4oeHc09pT2)O zCK!Tdn3Kai`knSfvlG8(^4#1Ym6I!Q=rpkvS>`oZX57VLLvEcQD7oR3175ezy;cKi zkW{Mr%?B5f%OK3xD%wmKO^}3wBg2Hyf7&NJa`~b~@}{HdR=Wg~2JrP@_n#BzK zmC2#K<_LnQp8E+I8m{cZk#ohAoG49wnc>jquXQ1QJt?rv$_Mf5=J=uqyV_wLO^tOn z>75MgNc4H;(DSfae`%6AyRm41<>>ofQ7w~pwfD@L{+KzZ=p{e-lK5viNiU{{o-g9B zK1+*VTg#Al&W;2AH$-->EVgFE*g!JW{@~=GU1cM|2`>1BF77)6Z69JQTPJ+gcF#XF zgZS=Gz@Kk@{`)$F69jn>>&Y0wn^dZud$O(A`t>j(5i5;U-28P>aVJN}K8f#HTC62x z_>k|Zs^gn{M#($pJyyod@9-5WXK4aRig&_1PHF23-;g|KKH1IQvComY3z8cLKVA?? zb)2XOTZ_~wG^JsW@BqfkS1Y=w!kLWHC;i=NJ*FgU1yiY+gCuRFu>dl`tizgstIL*R zW@~uPwdl!P#UZFeUR#of8P^bPVn`l(=Z6%HVs=WaV2KrpLph%1{D?!vFCIFkzvu$z z*jwxGDQ`W*`SZkMmz!h2(W?U~r*zNn8G8;ws)Y!t7R8&_&LP>f_b_`N7~@Wd$=3o8 zYpBn>2!7ENHjC%*mPmP&ReKs43^N&%e^5-2YUuB=Qq?@bO(xxQ;7?qwGd>BfO?&0R zwEZ+HgH@sm=ZHuHli+DA1)r&Z2tK2{nMLN9BNQcM$E_K^LBV&anKIGU@q)ANRYzCP zC=$v*n$7Hw!?>eI>@yJ|oI-?fVq|pXSw#Gphg#=>83LAs+^aDza|92w1Kbaz&Su3K zbq?$)>>h3GR~-C*srN);4!$qdBQu=y^@eBoP9~G7+POLEGbu=Hr6z=o3_cx_LQD3y%TrpUu)K*u8~mWG33H!c|;zaCCp) zsp;EDEPvFo3fyu4`5gsvtK?<>V*TY3VXJb142(f;W9fSaK}`&6zAYyS92;)XarX*h zn~|7yL&geR0JFr8B`traJ^8i&l0OPP|K0r6eN&)TU!^uBpZEe+>CrpJiGy}$$n7hN z9FDWz8i>^5VbXAm+#f*efwXeg{yF8EGTQTQLC}O*$g2Vb))&tJegU%&2eZe|!+k~A zmPGf@AzEdmIS|b5v1+^`L!s~yo|$IwfZRJ+WGU4DU?3Qu#k!oSfYT)JkzQYH+^xu4 z6?Gf|EXdxB(QRE5yqg`X0c95AOSTm&|A-|m&rt-?h%MMNeJU=<$YPObGD#9MKQKyO9QzujohZ;^#>x!Z*~4wO7`p58Z2|=z)srV8%o=W zxX9PpA3wRJ55E7KF8+Rn&|uew80uVN^?1q<^Bk06O0k=KV)aURfmV5p69XFNbX@V~ zbUn9@-f4?lEu_{@d}7Z_@2(Am+VNTI1qavoov#|vw`84=wMsO-cT{`AC2RV_No&6A zzCQA2VPt^)XriN+qs)V*Va2B{zW1xzcdu=q>*^fnW{eubM@qz#L&gvCVL?` z;sUt%Hfzl0@LmxW-H*g1jpl+g_~151DfijPLF5}gx0K))YS4*cRGAO0tw&H4w#Y3go zoYNZ66!($tIE#274QPDDvkrZ~v5-(^Pai;w#keC$Y-9bnitM10lPkWiVyrj= zye1FfYmlL&!UM74xH9cWP074xPt5;pBw|X1T7|?Vz#Sz&hasqSI9H7wcJ(F^xR4h) zVnZbR-*LCli7-A!k!Lky@UQcpA!u4VxwilkzsDHJ^sSKT+lW^(zwJ|a0}|m`p@%T0 z*8Y@dcn-j<4cGV}U`(pCd%osoLF-FJM8aHP{m};K(06M*s zixA2TZOqr>g6>!gPqr?4&evaBR^|oF&9?aGn@<5(qxT!5n9+X`m3HQ6F zoNv~jZ(=0xA9SO7LxiGVgf-vp+^(xJ>|K4xuk5(8zG#N0D{TV0he_dJY1Ir)cg<($ zr@yB5mo46`Gp@xE2`y&)6Td;he14QNRklV*Y zcIVk{17dE(c#7eg`?zxhUC zHR3vH<7BXlObv@rqk^os3C>f z)jvx7Xt%c7!V+exX>hc&?j!$|uMQmeKHYNs;Ho;JBfS3`qZ7yrBBvb(fhxHbwh!P+UOcu~Q)|Uw|OclD3F)ZHSQW2rk*a zca*&4>^@!Sj8!+KQQpzaQ3H?e_C`X{ncz*dP~05M3c3J|5dlTd1~>^{*RU{eN}VTu z7Xd^cu~T+njwyHxb0IGAg6#TxHV(S2f?Yv=n69(g@%N?QhOQ$wzpuyxD3`>6fVArGZxEMhXg9N!yog#>}Hjxqr)ey?FyKkgt5Ksp0P?I;zKQC3yaw;{# z?U9@baZz#IX@xKQCGrFD3A@i%j_5ORI*bWDat-IrFdMILJ*zTC`js&s5(}}G(^Bs& z%OO`XdpWXprv{A)WQ5#Z)W^{oDc3kF)lRPx<{n{wc=0mT@RAI7X?nx^o#2J=1cnH? zDt-uXmi&q;xE1cxw57O~XAMVuvfj?|s`S!&I4tR{9Pi@8qY>;;$LsW*PLTJdGj-&i z=}_E(VmTU*Cf|&p?6$GN=WaWA+|Isje0p%QWD8M{>}(Hf=H2lfWC%9b45`2M8CmG@ z|Cl=Sc&PWjjSr$l(rKa49xXzfC>1GbqwN&MpjC$q*^{-B&aEgar>s$FvqWKxWvbI6 zMT_iPMaWnZk@dMgzoGN|@tpg9J+IqIGr!;W`&q8*eTh1Jlco{eo}2MwS-~n?359ZQ z)i`Yf~=|29S_+O^1Uk0qe zL(hu%A8j#q$%a2ayZ9pMdumKQrBciVrht58jz3pdfUcTk5thA}qGpXm2a_hINb0p2EDP5M77aIs8>-GuEGh_}FwDo%wqufY8LJ`o$2qtnv|3jQT$a_O_a1=PXB zD&b_2dwMsO{qx^fs@`1XX?;nJvs}f?r{JvRNMqdFx~r7@L$jN}J4gmp#CEi%BK?{U zdmjFxO8w*u6OChO3G{?|SXj?mn$?~&R%58ga&Yz&`DJ}tGH=3~BR1H?BZ zk34W&h@Y^4znH!i27w7?AQ+daRrT&1S~o{vcQ{|rUtRV3 zBKuVHXxGroW@3f@WL8aEbwh&{V2|=;H?E}%fA|*hRWj5s;b`IDXpyXp{f=$d4O7xX z9AvET8zOL2xBn^WEvb}XszlcJ|0psSg3S(^(%Lc1O^@FD z{j-20)(BXh+>ys(kvrYzJgJmNVdVd?eEINKLz^gBpG%|)bHIVY;YHRx{<7Ylotjbd zOAMpIw+Uc})Te_uNE&YG$uiZ?7p@rM9`L~aBhf%Sk7nE}K}>k-`Ae64jG|C=9Z|(- zYCle-94Pk5L0v z;g-F+1Q$ftabGlv<|+o>nCe2WSa1P`0<*`?+I4ugo$zcg{7v2oyo0g@Lzli_HYi=R z(x_`G!BwX4d?f3L1F-^wtg-b+qcH?W{hL{S86BW{ml(fC?j;Sf;- zdS9Gp9v-uLj?oiy*~e!=s{hHd<*nb+CEXo(-)wDWH2STX#9CpTW8nRG0heXx0sw|4 z*CA*_bD-R2)g0hyM=*X@!F^KrgS~GPa*Bh;i!3YE3zRaK`|ktqnw9EDYl)p;7m(AK zd(^|HjyaV&A2DaVvh_d4Por6O>;UU+?)*YGCwqH zhXWT+7G>Mx%o%M2XiwC7IK)R>f()vsQi(#sz$U>JOxIeNnFe0xUCns(n2HZbhs>;eU6f9$Ul>F0! z@FRLwnEyI#Ufs9t@%a^ARpuPA>e`U9VQ*b)3UzqlE7G6j_ncN5mN2TE@%=n8;IgYj z$@FtXyLMUQ2xmBdc zMdt1qY#SeUKDF2;0}7eTPXtKE5VK`qsrx$qB8OqeZv2=WD!df!};9|Nx)LFz$E6mK|<_Bw%QE>;gYB6296zEAQi{=x?>7M^7;$0 zkdJf~EBSnw^+x$&h0T*&m2%5)^aKLjHIF%Z%G}%K9No05bOuGf5wV41J5J%tH+wEx z%?pG|U<`t`gest?piS0YWUI~uZE}aI?R-dUa-Z!Y0+H|-G2dh42qAd(7*^+X0Z9!> zB6WQ62YQ-$5gVL^Y(#(D?xMww*T6O$4aR9?|F|55r>z;E5 zOF*p7Ge`!AjoO)JUYg2gHP-BV7~hXjW0`(>FIj!B64SmttdhQ6Z(Ow1##Mk>gG>0mAo>Sy>W>_ZqROiCWV#Xz{q{y15t*m*nH zTm@~e-*C6pK$)?@?9rKFuCwOz9z4k*zORs+B5vdX61y(<1tOr06yZzf zdJc^ODpXZd8Nbilp_=GPc+Gl`{XdqHBU=9$7Ya495lcK0PgC0xf|P?niaLpP#ks}l z^m{sdoVNUb@r^C#XNW+bf$0cYanQn!MA?&A*$`YXsMTaMks&+O28;vf0)DHO8E?{3 zRJC+CwLjb^VLcAw1j6-#YQ6YIJN>9_0m;P@AQywgTBsTd3kAm;i?CF)mpiS`cJCV} z0ZJV9U`v+b9-hM_o3w9y+2_I3C_Wb{XTkL4Jg%g>wG{O}8R&hUP9M$ELbLq#E6zSY zzfw^!jaGwHaZF{KGi(~R2B-!P#En?}hSq%&6USb#NA)r8)tU=lfC zO@JqchJFtSRo;|d`LlZcJDg%S`3@|6B%hF7FeZ5z3+5=Z>rHvfcM#=@8vz{P=P*>Y zQ=CH!vSu+B{=DZ?HSjeG_mV=cqb_RiFgMgHd-lgw*BDyEcD@N`Q>wuJ(>mH_8k#X{ zJEy8n5c`$9T@*1piqyqNl_vFZ(m4K9IGj`K2MhjG|8-P-4>IF5q~S3VvX`}Cl1i&-GQu!lgq>9f;jHz~~w*Ke4myu~rb-zr_J!TJ_lHSBAl zS7`_a;C+VOC309ck;S%APYH9|_L*T&;IR{YTtIK64xpr{2g^PJ2l>#`5K@!3!7-*SC*yyDLhbeZ*00!HPAD6Jc?dLeE&N1^6{e zQ$oO>xKVM99TTX|(mYMF=PDJfgnbiRKD*7&0M6snB?jV1aZYgC zz1xc`dUPr-bH*<|HprU5n88r=s-6HmoDt-oc{I&+E_QF&*rg|9paY`i1Psb|(mEIa z`Bdwv=-!suXTz^QClw>ZMENio_TL(uL?pqgoGe;xxqyx?vM8^5#aO%&MEqRFtQqpM zbbNMGre97A6x6s7+dtjnCnr{wbUP^0c`yPkcBCRIbj;5%DVa`z6Xm%DgRmF2TELvl zTRU2|o;!dq8r*#j&$S1?qutFzpeyah8xW|1e^fwpS1!QBI~f!2RDVAC`Fybl=qi;r z#Wsv~4NTxs=VAP!jJGwJ(F}dNTG1U7t-+HKpM!*hD8)RfPKT1pP+dry0axvfSeg;qWIQf1ls!aQP2ilBcTLWwX` zBULc0MJ8k1q6O=x{2cJ>NXT{z5HJ3vs1d*)$bzcFxOw(jdx+L^AX>)}(fhvjiy9iA z0EW^S9~8}ic&E`!EnDngk*?=T+y|oCH<;m=DJVZAoJ2Iu%b1fG$bppMiOMvMY+sDzgW9YSCUGDaAQlSNcsCyN zij0JhlSP>j9Y(^{xD-Dy#Po<|f=wPh03_pYEhENiKGCdb3K~jixxH{Olw4wz6?koD z7RZk-cUwEO$vMl^_%G44GB(iYkuVhf@)N-Z0q#X9?>HiIK{t>aJ}dG2P_l+rqsLS$ zjEx>#7z8ZTLyQQVL+bXr?1U?2tYS^fly}-;Xf#r;0(vnAPtZ1<8=<0ZEvp~EaE?FPVM;zMT+DWrbwB2?GU7o?*LSZ2z4_33Jre1vD#%m z3Fh6bs9t;C?ldkWHbLdKQ#Yp6^y^NiapdRdT#CIpkpzj87B@{3okv&0IRQ;-KiS|Q z3D~5{I%w|faTZhSNd}nkGTI(z@Y86V;yN8;>mqFXIClGk% z4*0{i+MeE_<=6Caj3*&vfuS^?y@jDEF{hth1wl)C>r&Q{S13zcFVdDoRGI2oXP?Q! z`zBPiZ91Jg8sWnE8D<(njnfp%_>{373Ff!|;CBRL-hR0Ig`O4Jutg>1ASRLa?;-JexCZg}meaRHj z!#2~nKw>lWv+UIu`g$Hhm z=E;scrR(6)hN1Hr{rX@78)BkIY3-_S!(|&(vn3PFO`||~^P8JJGVwSFZ!cXsuury? zBEk}@9fg!)me&c@lFvQzb5yXjb5RxiD87gVN6)VqiLGoJE!Kyke$M0K7;{FcXjcqB z^q8tm3#zXXpcmaSveYKglah#Xf$^1hTZ7C5mig}LwCR{aAHWUv8#=Dw%b43eEn+5#m+n8{lF9d9*dN!J& zaHz;`RlyEAtaz3=Cnn3_j`Z|Yk%cApFsh>KK^DQ%bexo53z6JnT4TT=)WM!64PgwF z$qu60d_F!ab-T8>hRDCz#qev%Hw~~nCp}rT2^#EVXs}bY8dn`hG+?6Spuy2bmUB?! z+m>6=q5NTu<8d*lVx4Dxb|S5PN^bow+J$LoX|||?8N;Wx2+@Rx;oMra6NU{V#O~;< zWA=VpSAXw{o_#+^`EsXH0sbe2Z1`iRvhZ+i_$XP$>M*-(ES!@uGD-`*0%V603Y8+a z$^CAIy`-7(MOumt1}y#z;}NdcHOA8_18ooOyHgpxGQbgrojw&_&B>75FJ2hTEPgC5 zRbWO-cx%n%SDZrW^WYF#vLLvJ>b`NOvn&%qP>yZ#yS^6(a%C#CnPD5HjV)D#HOJ8i zT8vm#o>`Pg{|*i;t!b+-vstt1N@5^;9TQwC8dlNZh2=b8#4oO})n?8^;VtWYgJ{k_ z9;|qJ*F;VAMmsW2kkTQH!O6-}pKS+r!QPeyV1Qi0DwP9HOfYQ=k2TW^p&KDU2=>=l zFeaS9c!eyU)b37v^q-c3VZaV$5_=mxKETY4&A4XLKJqCN2F5wO$z24k=6}tpMYUHLw z@xBFR)NcHVrWP2I7r4OmKA)bH*rCyNb{fH~^DG_MLVKNs9ByPj{Mm><>d{UvM*3?;Mn(rA8Nat(y{cSZPrY*O`3 zupeLDaSy=?CE<;r`&DT$NlAdw<+F@_bfj*4i=mGSN8Hw|L#Cb z**y9xqPZ5G*$)uac&o~^t8iC^>PtLh0=v!TatQR9E8` z-@FiJx}RHYxM^J4{p1Z^dVK$U6m0wh!gsKJIqK9*pwQ zwT1jg6@?Em(DFGbt=cx1d+S@;l9;|;Npg`hSSEMl91cqm`yQ1ub*u(DG-SO(PP68z z>rhSsjCGN{88?CV-_^TDT_mSdZ~G~QyI)n|XaYfS$T>IC6mSg}5*;N6M4i)!+}eE!oO z$uCBKN~Ya~jQ#y2PuIC6a$?yPSN85atI9FCquzD5uw%ERI=-#ub&sJr#s}fK80(Nk z6{8|He$7yS?ojC3paHxLZDxw;%LMW+BWHI`NKj*>OPP*INIB#7;wJ@ldaA#s;y*NbtDtW5r$+UKL(+2qK!mnsh;O**`Kzt4|Ta>B5-a?wrk zjfP57|Hj-U%^m;nt5?EeK}4bd-?uB)m4%BV0c9x8X%n4v5L0-lz*gh954a>_IwFzV zfQ>@&{S|9j?o+nGh%8ZnQsc>>>WQr;I)f$}d*AD0&hMWNyB4PWcHi(+mC@XW2~CN6 ztW#F8I{cv9AU3K|Z|+T6AnUt;k63tO1UXmRE>+x4{`C^vpIHz~5fk|Y;8mtWd$v^n z*G$_zi_P?wzYuEK5;ucoM%j(Bbg8vaT9Ow@HeN_1_54_UXXN9}Vq5PBsiIW9lG5$- zYh|oLG&u_UhzAA^GE|vPio}c#da0_8|~qRg+YB z{l8*}Jag?XT=xTQnI|EA`qNJKEhpCS5g5ejMojVq*6*tihsNg-dj{5 z)4F*qY6DeLz~6)FwbiH-2PGA3roq2I#k`HQ(#eAW8VR&FS5pO)2EmR~yA-WFCDAxn zBV5cPg;}ktEKaZe{554P6oO3DQ650nDJG_~F^h24lJiJ{0d5bsl zP&80!2MO#gGv{mzB9|8i!4y5*c?-sQ6`VQUkaN4s)0=t%QHzLCV6b%pw|9tqLTy-c z6BloIK*wJ|mY9WIO_J~UkZa6xx23vL99PD|TPl3#ScAnG>UKCql!O=W{HCNs=mTKB zfyXfY=?UO>5Q+taHAWwXnKM|oOg=H+_kZ~wQ*voGBgqK$k5tnDq6)Mo_n`7&O2+vW z7;Yyz&Bfpm32lcui#)cBKWQYfK8blo$}W>5qgah(D3g;sT@SImEwT6WZhHm4&T1_0 zOrv}59lo;J(RZ7W!29euBV0{{a5c65a9`_XY1UFep=Y(`=VHF4fX^GPUe6?tPey2M zz_(Ay;!7`OrlL&zk~`)KJ}J3>@gl5Pb`F11;jD%M{8-ATW7O0Y|r!Y)-e z;x*^IB0dyTXYN@VIhodw`{NaS75Fz(hKt|UV~}7cg(_Dc#ry*Ho}u|^d@8|Es$%D? z@_^0{p(=3KA5hL1xy62UILaKOE8HjhB3NVzm=@h(*t6gDckREQYX8q4jp_WT(LGON zyYXaK`vBq}Am{m;alWDK#59O`$5!b!Gie)YQdscUW z)XnEs?#~TZSw?| zZA7Hgh^JI>%hE@6kZZ9rl56Rw0nj(UT*cDt&LwK5Ecv%yG^xyhx znb4lTfd0JP=kqYuyt69xB5s@EA;2S)fC7x8MEoZ9!&x2|e((l|a_oal4buz*Fs%Kc zZKgj3JPv2vL)8NBnZMItdjPx)F&Z= z2mQvy_*Y=7#Ol37ZFJIaOtETe67Iwq0QaY`7u=v^K01_H=6~Vub=ri4p7<}AAps)h zaAibGWKSAY_)@}lc)#UM7oRw)t&=Ij)SAUQaZ^L2TP>57sEa7m(U&U4ja$m2vF&=H znCZ1L{Afd;i1K>~bG~o5K(Z>Q1|~3QK22`bMk6enqwuLU;q-XTUPEDU54MGvsU1zq z6{fmHH)5=Vl_evQRwk3zcr%vq8qfllPD2NftzYTj#gOq<9tSCFP*yt35c6*g-An$V z4T$Cv0Ey0vbe^S!%WdR|uf?kfDv=#rmDUI53J0(=?dg}isL%j!{&)TrAzeBS!}7Bc z`1S(5QFkStd}3WKQwc4A^Qx=vPkQm>}K7b{$fwi^;5g${KdQpZMP4>d1F>fX9 zre4IPW#K3>O<3LYn#-1ck3EB5Fdy>owPh%O(p1p!LF!V$852GOO(GQB1dh|3tVd7w zI|{37-dFXT$@OCA0f_d~1XQ&~AG=NJ*M%)Btgo?HeO99%h@vjRLtQ0~LxP=vkm!!< za6w>o_>aJ?&VJP#6=n=u%t+g?c*NTv)^JD0sXv~=d^b{r?+jd8tw&%xOwj^$q5%E+ zW9rvEhU6|O{+Hpy{^0+0Cc)oTe?fU-?kQG1C#?-slT3+z58K0ZLq z9=Q9U7PHtjb7hBLGR@b9IeB0?Y!nErlb9ElbiGMrDGKmm6-WQCnDyJ}2j(zpB^B_4afR?Q5E|0iUD;$rf z19EHMniOD++lZMjlH=dHRmrbC4^e#tMD@uL<~g4IhamG+p@X6>Nt-BSHbSeK6KuG4 zK*M?m<3EpIVnc-a^JP80MXBFTk~~P8V@Zv za>k|77M(+*G(?aiTH(zK^E42NP&4Xc0hQnk?A$H!R;S%h|LCgl#oBnoSy~%&y?<{l zVNU*w5?VB}Xb4%q5XV`JpLoIKaeVH*CBu*$?MowEF!ztHwp1n?z)=zB>C z>o7xFD zi(Tf%-aVpt0*n@dqi)MOcdJ(dYCL=`XK8L(*0*~WZl&0uik79<0*R2^zW{{`;*nA` za$EyQBRYZ}N;rS*N^#7;?Y=1lmt`{9rVk}J8{!`0uFeXgy>o1QDY?B66;1v1)%m zDuxMolh|pEpho3v34x2*xqm7LCG`!pvL0>ZM}K3LeR1_K^UYUp`afH^gb?HKh2TjEbFjYG#gY!oN9^|kTI#O076+RZRqRPt1>aiT zPe@oen~lF^k$GT0%f>~pgqEC)MD6n-9ojTIGq%zd$u;TCg3lXJO0>8i!e0-Oir!US zRKA=-IbITefBSFxUs?>c%6+G(T%w@gLjNVf6_83{D{>0ro7LL+;>F^%g~|`h{xbNJ z+DU{}vsFarJh~Mn)3SMob>c@Dp#GAKPu+X_V(INKc^FAe^VC!G*~vNJyVGc)-7yAS z@C1~}-GM>&yt!%NJ+&gaO`=u%dEc63nsaRmKV_94p3;0z@nGM=SVjI7_5-%gy>NNS z2Ys<$&u>2JyG`hWZ&K)rDYUrvOdX0M88@3WR@Tqc!@3d-4i=fzuT{9FE9&R+03l-( zdn{Zwgo?HystCxW_-Y(}WC%-uzRKYyy5vUm<`$A2OW|6ks9o~`v1^e71$NmVplvAQY0bx-~-1|-#Y7ZX~**ja2!D ziAqb3LA3?ChE7XKjHULi6NBryabjsRu&`$^Y|B?BmsZIGDhR>=MM-RGYbl{aN6+pO zaPTJRS1d^I7y73w6K&qib2#?0v+DjFHW#q9R-QY~*{1SwOdG&QT>Gr(9T1pqDVqW-p?cqU?@1@|*dwXIw zChS;3Vslz!sDtniAf*BUkr=iKGbY}Vw-|WR%FP*4otQB_c)&g^p(tqli5jb&C{}6l z^v)iSP2-=)O03*SkPDaiZ{sr|Y1H7}YmWC9gaH2Qep8lTBoOVohMWh+rM~f7-1S=A z1QFIh1;PpNy9k;EJiD{Y(zwGV(~J)+gJ{~5k8*Zr6B-Pv8_hGj?%NsIo>zfd{it(h zBH`O)g}}x%Db!;~lQVLS$vVF=zv(&_@w2I0jFt1|c0{iI)7IDrQbd_3JT|Dl(!D@eqm!Koy(A#FGc_5Eb6wPhvECzpq=;`4Srvfb6xiaQ4W~QNvlZ zI;e`(Rj8Cb@?7{Fv9?fFcPPm6-v|h74z+>#$^`}TTOOKY zI7acBB^|o|qb@oF*_KfqUsE%az%PB~g8|$$lw?oWU6gFSyqR-AoaVaKc?(ZKF0~R} zUl>ddhC!GpeAk^%%wp4y*apTQPw`eiP7PBeFAW}+=P*e^419!_VDDA_0>z3oKkiR^ zS*S~qsNQv@e3y$k|KmI!>sH;WkXV5df9pGpSnflhU)}vD@+t+M9PM?T`UcAg7Rk<# zB#DEb*A@0DX8)XZ!O8Q?Jnm|5HEDwUxZgnqImWKSM$ufpM4Cdl zka@tdJBHtqLbxX4J~_G_R-6!c_C@BnaMb?0nN$BqpXEcWprMjW0Eop#He@@zR)$I| zAQN&27V5axU6g{i4dpG|gkV|%y{|MVZco*L50cj#|r({Qi-ZRy1#k)`qW@gcr!>3nTzT@!4p3r-N9V=FMYc z(Hgn!w#p<#fOJIttfP~q$ahc6@-I7hb8kOeWn?AWC4*thqisf3$(|!rSu4M9Qe_n* z|1R+Xd_d);Px9q9kkyn|oJ3!nBlETWA#nRh<#6s?%xmKh%$it!KY89}&Vtsa>CkeI z+RWsxm1EPhE=fcD=mrwra;&(prECuYi)e};ZP|>Fhf&QY%1k%(CDnHp0D$xk3Wr;W z$&E+DMdJ(k-{T8NvVbAN_P2!+XvJ|zXRn4CXo(%{3mVCi4w9G%9 zUxCNB;Mbg2v#~a?q|$jU<*qfGny1Gd!|r%|j!cC)&h-4H6xg!q%h}n4w2nBA#-d3k zd@Vk|yct}~OcFvK3@ctfTVuDyL&YNRV69N-u{6+j2ML^K=n0Q?9DeF>marXnf#%Bm zsdWn>5E;9LYN}g2Z|frb)r1Ma!W6*4wUSp$`pBs781pF{LPxl47fusoO+cYOUVVM4 z63ocb>Ih|+xcdC#KTB)L8Gwbec??sQL`KWAT!6Zd8ux+`Ix z`<-n?z;Dg${wBG-PU9kcaYyfN;)otm!7BrKC?+_j7PFZtEj<>tiU1pE8Fh#N_lR`R z`M7ej7H046B3fJZh(ofh8f<@E7os&EGp&)C=x?_@uYieu8^PpF;xXiPyJ*nRVIPOy z4on~v!hRZ98oxORol>Vd3b2L*%4esF8{G?%)+$tQ{62eZWZ%J5P*ut){ABpT?Mqhp7lQ2R2Sm_LK%a^+6)RvQ&7S5$o}-ek z&cT>`CPbbm_IB0%eHfz^slNuQp**g(&LzJ(dNMpyStLIW#OKNR6UyTz?r$638^(qw z3|!Ac;JPopn+oG;7B&_C^Y>5%DNwUIQr=|k8`Mx!H^QkdwaprHmEx;tT5P27K*7!f z{O}2Ubdkp)Kh~7RS1I%<39phk3?KFTEJS?snKu^6r>%NnyC^V*Ds3#yf{ z6y0p^bz(pCJeK!q0$uKaIt}?xyNryThTArCA&DA;u^W~X9Wvcxdo4gk5PEnjmXB=r ztr}WWd=8@uW2P+4n)ZLeMH<q*`Q5nV#@!GtFdI0*a#jNPJ7Lj-`=y6v+|2qE)S@P+ zMa#J3S2I?@#(nUTl**dA*w=lj-&zK3&LM~ea4(LXfTgenF@?*tTYj;JFmI-DU;-xk z$3t~crYf@oK3!g#;$?7fvCmSQfYHVs zpNLfSR)DbTt&7O?iuW*4AfOC`p8w#8&(2JMk6SCGgF6}^)yz*nbX>n-`-x#z0$xAc zVK_@xWYa4yjq@DSth{D?6HG))$?@#(w*O{zM$|nn67ADbi)v&+sdn@g z<1_=Z10#pua%CPMack6SaGNnFt;Buo6mZAIBDWCMU<7E~>0;mp3RT>b=WH>t%f`em z8{Ca7xZFEIJ3pGuB*wsAz#hwd-1MgF;VrS_MQ>4iHJXVCYKd>fRSm z?X43lJ}X@?VZxN9BR|!M`l)#UUUf!{_4A`^rk}OFwJO+m^|wP!;|t|uB-D?oc25#(YpVoqtQ!HS+_s(1{4ruUNB(&EycgACOeyD zF7QnGJn=&2KG+5dEd*0J}G51$TYm&?Gb-LuMe?NzO^}U-D8mFvQ z*Z_h|7lnhqS3-k49N&D(bW$~zUw4Fz_)VOCaD|HDMwB#7DTjO+tgOqcmkvdJVkZ1m!>tBd3wA*KAXbZakKoC=xXkAUa_fdA-KjkYs&tSkVE2;;Msmwv45Tb&+9C#cC2T1zz zx=YLs?-nejDgKQ&;;s2^$C}^EvrbST>7v~jOHI9j@lSjyK_E5ec3@EV0W;kqe+O)w z?t~1SG!~MzK?myP1_S})?uLLkehrKX!|_{EN@Ces9AiTiJSk-wP~qKdxlBowNS%q@FmXfX&WGspJ?p!1*}h3|UGvT`;#~quKi({$9(s z;O`YKVZ z$T=W{G>#s`>DPYVzlqHMT$<XdTr#+l_J7)C?wQ^bbiWmm} zxaL5003GR1BIqJ_#rC=}0sai)d$0zsMnywsdvh%=qRu;5u6Otf4K_#L)k>x_g0|pN zHIltz$BUNZ`fZ#)*^gth#_~UXSj57`@ZiZEwMl7;gXhm+JdUXVzFJ}eA|J=T@sLYj zMvp|a8eDPn(5$H9@=qL2tJ;dy6D-Vc3sI9C+01R!i#fx{4U()|*;@1Mjxkx`C2siS zL-jpo?5@5shldB*ut^N?+N5n{(cl91$#s>wV7hZ&$iO*c66utSSpoQd4dON-NU8W9 zp3Oxdfa_es5t|x6L=$NS(UD1#J6827evQ6t%*l2+&8lBG=77OR%ngOD;=-H^)_a@_ zXW?lmW^YiTl3e+oH@E)T^Gz+HRo%^ZvrEOj<1VpTX9+tTm^n&~`eE7X=RLo?uQ^-K z=AQ1f-KqlicgCoeXbV}F%K|rUYGESIAv+^#n{zk;d(ymc^$4g+DPh{vRsZD*xXNCj zjwJ=IT4Xv1tl%JWqunVp`iDu@vJocQidkX5ekZ^gimRd@2mDM8B{JNqvM)!g4*DU`o_PJ~gd+ zgruAQrzs?qLDyZHjUs@(;FtC6B*ZTVqy7a@LPX)r-?`x|XM{WXa zB{CCZ@q(tJGqS*e&2_XUw{R)0}_ThnLH{}7n&?s9>{+VPeGZg zY79i#t;@x{Pr)T_Zi*5vw$OrK;vuip&kbY-`1jaDgA>Feego0XJVuiBCKl#JFPDe- zXXHC{K8DeV*eLVxuVT})t#25M#m_A7)w9W7+xdv>wM3K6PRABG=7*`bIV@&?0)R~I2SI}UaD*Wbntoss ze8a5dOPT3M{VVLSexY_pJBu=L5yo7KFrGZ$3B>hkP{n7`G?rl z<;CwAQ9F6)9zLwo#fZznN}2@RqR<3HTU_-T=TIy$xeb#_7vJxoi=DaZk=2sdbHDF%q8qI6f>&e)Bp60 z=S|(uY{ruCGI+@Gs_lMOjHQ3O@B*LIG~U3UTW}N9q^hi&p`<@TMbtVRv(4={=3Jxk z0z_Txu&Y?=uDXj9x?d)TgXATTdS!htfx?#7QsAj>92-L)D8tNeR-_@6Fn{6?1E|)7 z>gbYGyyqlY=Fht3ianx0#EHh-rYK}VvnyJne4*h$nX2+fTugMbalY60inNV2nlSgledjK#D~h0d*fm<7dQ zXR6Njjv^_-X@Q)b$)qU-1h-AF3<|8A=H=1nubG_{imYDC)%56uU1J!l@`F|FG*9kQ zxTW#tx4a@Yk6~lX??1C{uSe<0JC3<^=SxpMc9wLp$70yOcmoITMm|*5EYF4U&o3}2 z+3Er?nk!0XH5I0z+4~!#!QmI>PGMrY_)t+)u$JxLfe>o6#%r+FQ{2Mgn;_(RqJCF< zIx0cL<&06bHYoTPTo2sN!>+JO@3Go`Gf&xK&+TfNpg(Hvz%W0obdwtEUtYTs-z2+T zls^?W)_oVDXh1&5E@Yj!Y{shBejlprZZl@2 z0@7FF8*m!l!f9AJ#m} z0gwIqaU-i){%jU9KmGPdu{f&%wB$$zk6lk{8n(1jC|hDZ)gFt1r!p@)*{Cx7!FH3g z-T!|50p_CuMxLJbC{>e$4w1XqecmcOkP|Pn^^ZFs!2)hnaI>)5+K%ngtTZ8C)E*O} zn<*Fg81m_4!@4Sv$6_!i9Jjg@WH>-pXO6f;GyL+aR4{IcxE9|Ctx^92c+PtjF}NJ@ z3a5rQM$WG&Mb##JXyTkJbh6B>q1RxhMiAqcQcmAqr|&0xRh1TUA{udUT1fvd9;3S- zx+A&TEe=pytF|uRL6^~4*BmyKCYd$yIOx5TBw3tSsx08UMz-cwCgEPPO=revx&^?; zD)O{feH4`FO{eQA}-WF*!Pn0WF6y@Fhao!afzyED&H(!;w1j z8jamNtlgyBaB!~&uhtjXBg28{DkgJKOU-caf8EwMD@?b{9^#2wk=?WluT3AZYWtm8 zEWw)dWIVqEjD^sB+?waMwMO`?6m-2L6JOlpj-o;^J}s$5yB7qEkExL(U|%G^Z5ce2 zf^&J>X_7M&+u(}HtJRi7K1W8pUNdFz+`3YB+pEu{j@6aEAQeW)?#oQV=rQO6=OSTr zxf)&34?qZY282#hqTK1-5}cYfo5-Dr=}#s5eJE?(Od7}(l*kS><>5;G4U)HZs8vm% z)!V9KtP6C{6B_5$1(pD6)pNJ-7Dz6jUNQwjg`p5lX*XXQZq+7XxRrNkU@7VUpQ!P+ zSLF%z=%Cg&xr`OX1A_XTeu(7P85EkxhO=Z1F5Ikd5grPj3U+Qa1oFvdlCctnTaIpf%Lax(q#VT2BP04?JZG90aD`Rqk;vX4Y*^Qe2%4)~@3vj|*51@knl5V*=i6*ZZ}ij9u;qW&P}DTR z@2v)2AL?5wfoY!;me%J*x-nwB;6Yd3F2qeE1(H~Wh@!(t1R|zoJon8^isE^w8wP_@ zr&h|1`|bEEH&2pheMx8~zWI;}Nyv)Q1N6nq2l(e9(!cFr`uzJWy6ZqkU(0a z!~4w>`<@}O;tbjHI*EeZZS=m zSgA)?X_4BZ+)O7z;iE}gWHsa3Wn@#XP-Csrvj=f_-+l~=3@>u5t+?C{i)7xjzPl*; zOa#m&P%sgre7UuS%P}-vz^_Wai|?#z1iou*#(}4Yh5`xIY}MuoRHbYHiBHI|z~QsQ z4v$9Za29o;Pd-^k4lBO$Q6}Sw0W+aJ%^vi5oJCh{ggJ;3#=r?4g(7Zr&6|p71P0*@ z;!2b|Sc?Dj9c0VD)4K;X5D4cxdIIX9bthkL?G}9#+tJn{Vj~cveIMyHID&GphY1Tq z?^&oNefS$)9*DWU6_W6Pd1LGw)Q@DorRJe~tQVY?LbLfSe02q2bf3$rlVeoB2JdNW zoQQ@D7!x<- zzA=cDfq8gXj&d)|;l^w6x?I^b9EaWS5|-=L{n(X{NhVBM`D!NNok>_IzCcy?L6qz1 z>MXQJh5nK#@DTxl1k2k%ODmno@56|2dOr%2)H5Ywz5U#+*1D~gty5eaf3YX@J~8~o zw&>BzYzNQanePJLo)_z39?M3*WIc!vZJEO|3Z35Ez%i}}&&8GM2tf-py zmFKG03p}&7v29@GP#H5jwg0%j{BYvP#q0$-Lk@`?L5*u4mTz44-(S=pe^H?^8wc0~ z6vmZDdoKcXr|qsT0xvQ)tWRB@FsDkIio2*T7dE#V*xYJ~M**uS-B?Yd;1bHR@wn?l?dYfQ#*XiFvPfBLCoUlw)AkUvqBxhSlOhW*u%6)4tsZM7C9-e; zKfHK4-3X@BhR*iGA+`^!q%hoC#IRkUw_@7SB$N*U;0{jj3kqc}hS)5^F?alzU;2IQ zWl+l`ms9zGtNb9uFagcwj**Bib=gCcc@2?aIw*`^kAon-67f^ch@Wyk#$)`* zt$mxMcg~+!a_2DfjuAI2x^snugEQ047I?Y$Y-5Jz4?v{_j0aR&geeZ#7VaDHGOlZE z9T*qYH_#(Gy>~#4!rSXplmfgW%d5PO&n*eo3Vf-5m1;&)O3(aO*pV9Fvxm=0naSgd zUL#Y}oKv{+5>y!(8|y7cN(BeDHS%K63*nbN1{{M`QAbEt>#tw&Ys1T*=l{^sfV@cg zC5Zkeh`-=SIs{z8lF%&VR!KADG5*wRT>LJeq6tunJE8%Ay+XTqyR z{0)JSttLv$)(%N^R@jpX6~>Sj!sVQ)=yrTO6E<_*q`Zvt; zdV}Oyn1V`r<4U1fCKw^Yak51l$?yep_4a}8k&{JcZ*@jAi#KX&3u!1^3th864yw%k zRmkAvix3^yAL@uy4NWtasaNkUS{IJs4iSYl7<_1j3OjCjTiP5VXaaO=m2$N##Yq&=E)aP@DOIAVK=sh zFdkJ~k*J&vQ91h{6J$hV+cH(bJ&m;HR#E7>yXN`h4S=a1lT8d;9?=vvfGV2d-O#Dp#MDsoMt}UpFF~d=F8NP^^a-s~ zT8$eQ^LA#;qE8t?`dA}WuZP;C<4y#;$PU;tMi0slGSze#HPSlbFp*rFw~fe>W%@e@ z{i1fR=)cPJ-%+eWfcLE)7hzB0%+-vbkq$vAnQ{B4`I|TebsICM9@$e@1eG`T(uROk zOv}oR1C!4~Vi24EQ(TxV{_-L{B`%M;(ZR|ZZHELmRYVb71P}bWCfHplUCl?#5Xw1% zi*j)1&BPA<%SJ{ed9&|~0_hhB5Z7Eb)q}E9GG_>bcI^@|R&9W5sqW@kx8H%3lJ}Xn z2d`@SA{``!030#>mz1~pa_kn3*MQ!x1SaK}ovosrh9Loti)vAw$7}SH;qQTLm(F~w z(|D*0#|U?ccASRD4XBef>mf?oe1D=s)pE(_zddwe!Jjd`?SH(4O#s^kH<*kN7*!E2 zPnSxW0Ox|&-y0!fz+X=VM67i9cfS_y%xQLx|A=(YYMB`!7|O|TgCG=YI@-JZLiu`+ z6Bb^$D&qqvtWi3JrKyf68vEGJwawa{YYawIPWFs3*=>ife#GG%c9i^6f#4#@2Gv=T z%WrCkI0v9}7F@^aFatm(yAuT_PibAepdP6I&8`FA4<`EoU;GKh&&=Ak#@b4NWwR+` z5RSpIUL|j~H$j4m9MaU*-^H2yUgQsOH^4P^l$*Bc71J>9aEuwV1W!Q8a*VeafnL5h z;5vrQTfB5R}Tre%Fn3U*EqyoI^s5?Xwk>@Mg3Qhfem#L}+CUDD0 z?)&mgm3WEF8euJ|}opMsj6r z6Af=aluowC9qccQ@X8Vz5`Yd#*kSx*szF!qFmguNCJl z_`_0r)hhjN7V%FEf_cL6&Fc&RUXazlJxm$_Nus}_0kqzH9Z%)1q#CxVEk^}=Hqd!X zQtghXF5_8=VxU?9rvfpq1k8rCOO3}aRaGwfJ&|aCNq&Nw(}u!bjJ&j3e9cOU-Ij;)EwKtPl98&gEvsC1*4#s=JOfJUnCFw4<86W})AG7Xh za!)(SH)bp4^;W<{$4yoP=Pj7`4GqV9?jC)?E1SZ3+2l69WWq8(#bXVJP6iAb0C!rZ zZb5jQ6_Z!nHXG1F-;8gP_Yl4{&SLS+BK`V_UGvW4y50I0KFe~?kFv<>sGAMp@8F?p zYD+$6jGnTXDv&zH6iFSt=Q%-W>@%;T)B)#;<@Y=hV;Kr}Wei=kiS2maT7k&`lg#${ zZ$#sjsUpfjiKT%HuTBd823fST{1T`!1~u4;O@{IV#e` zDTUz(I$V8+4o3+c&Qwr@y$nAWjP%Mi|w<&Pux8;WkK(Lq63RWrfhNQSN$8s5xAct&xO`uk;v*Q5VF`I%oNr; zxq1q-X-Qo-Sm)A_UE%o72(#C(o3I63jOrW-W5@v^7q8YNlM(moF^_v{lsR(YaR}iy=&DPw9Ly6^ zBrTGDv2MDE6!!dl(i)?LAQ#`aFn?23MzCvu_BgyH`&L`-{=`O-`kh=3LXY5(ZatK? zLX4%L>zsMA$?(jiO1X`=*dGbv5Y9xa#7m@J@h`mIO8&3oaQRaBtmmW;GAIb=Tqkv*!?3}$pCzx|^84m9 z76D9D%bLq~=A&~+ZxY3wY4-(gP4@%z?-0RPu}%jO>lrbTZdlzn0HyCITZeR3EE8`$ zw}ocB+S<|%-7SS|Jotm0kv%_$xqg9$%m3T@TQSjJ}z=hKOYAjei zhl;$DwJQAGu}{YJM70#&kKEP*v?*x3z1JSk9X`%PX04s`tL4 zEtYC6M%qyCxoB?dINgCvk2CicV1K`FlNhxo@!l9TOK_%iTAqi*kT9x89I1mk)`p$Z zN1R1|SCAPT)q=a{0@-@=^KTHZk0Lr7(i&7wpBE82i4S7;P=pC;qh1#-az8c2aTYr- zBdQHysjRNaNZCW3sT70}Jyz)7XJe>_am%JJPj}PiaNX9xrA+IK7=qTt5@fTz4-dfAqdoydgD|_(wAc;z)FOek zy#`r3I`FCgfV022rQD~TtZxZ*FpoU^Ubkij`P<>7fE-E&rkFUFpa*7?S!C_oZIOj@ z1U-zH<})%9K71#Pl6xak!9?OJbX|lYJiKyik=r*KJ?JIE>TqC|J(2*ozqDbYOTeTA zZ**uGhH{j|m7`}`Q;3D3d_n)3`89ZizYw$QU+~==X{G!P?X~7<2#4~}Mec2O)Rv$; zR@401p{A=x{C919E|`c*L*{T@WXc7W9OycXXK@5NX8uvU)Gieb>;iPW1_^#>S*NPg zNAm{;dG%QfwR)CHi2c-(J{MRu?ClDCEP^$jVo|GqL7Be6Q|e(=iD(A^f*%k+@LSrH z&A{N39|Y1MC+QAQ$FROtx2kQo7q3L8t{fKe7jR7ZF}NOuX(PEpvdoCVT9H;B1pJQ4 zliiOc+J_!vSm1C;Hs4@cNtU2L3yOr+=dIFXj43^=*bTV+(28AN{usi=VX)u&NNqOX z51`8G*6&|1`+JEk&L*I{njRktY&N}L=X`~(xcZIpYf>xnS3T-}ayQ!WA@-iop@7^SjzZIPpH0lL*z3?R6d!k9m*-@}-|Ef?`hF zm9Be>7F54?@+#tEN_q8Q2*M7=Q)(D)RETnZ-fIHtwC$Lghb*gkOhd<0=A2v>=bg2B<6Htx21GC>$Q_q)JZ7C#$vU-u>)w_8cP6|U^H>rn}gp4+hz+&(u`(N_ka`3-_2=VMVpp-!iHNuf^t5qkif z?pm{s3oe$kNM7^G)d+GA-RwNz+EtS5uS4l{Ts)W0A4)6_l24Yoh7gBvigaB^#D#}A zHBGC(jRwwa`NqQ2^`G9Nga#F3>pHlAUfbc|M4b)!g!wHC6=YOOz)K z!ATY+%(|7FLwCVN14gR9)t>F*T$geJ6EtD{`-12Yq{PyJTu}!Cx~9Q-MIadp$V?dD z_m7wtP=a*F^*BWt>sxty?8L|?Wen;Jn8BfR?RAGy=;+(uiKgzsOibJbkfAGFv$K|@ zRkn=*h^sIJ=Du7>ob9chX&}X)OJ=#?Iv8@%hxlu(qa}vJF3P^Pk3F!;2@o$7!+Se? zZxeF0z)>s;lMj*ECN__~YXe5V!ipXuDdfBYD?m@m3m%y5IpN_R&^H|LUX3cPh*CQW zfJGjKm1+a6Q3IsA@nc`{W6ds{GcW!}DKYhkt7?+{iHj=^nQwqYFvFs|ir$t0%drOj zmjH$4viF?6eeXgmhCkMND!uadz?U*V(1Y)Dq^6;uecf*@W5v^aFmO2Bqr)qUl{k=X z&N8hYn8n|EvR@sOeh07?H}`uu4)oUM)Q$&{uFqG8G$P^mx-XK%BY{TKsxl}Rfhtxa zx;Be}?oo^w;5tfoeg_jOY$NuPZhxd0<%YOrUg+2_(qLc_^utsKQVC2b8Td-q3Ilgm zWBBGRneg{seuT`ce|CNzBdrr_0FEX*qjek<-RCD}Woe9^v^*c1n|SYD z*!S;u{xI9fAQ3Jc$@nO5w`o+u(D?QlvRpb`a9)si_=Vh<$IpqzUUclU807f5U<3nV zs2{Q_e%laY@T3|Jzk?b?o;j8q91RX zW$#>~-ZvP0m!JO2Vra&qu;~pWITq8zouWLKfTOpyCZ&B%y@eM;dM?lW-yO6Lk6_bE z_4E1*blo;*#4dq4YkYWqvWhoBB^Uob(*95nm7g+Q8*ehIVDZC_*2|zD?@DqyW0N^&dlC)$g;Q9RF^z^(lgKy@ssVqcLqsNS z3HLrdGisc7CsuM#65|DvY52z%lYbn`>W0xY8108H$MY>QeMIs1Y)!z0bUIorAyJmJ z=(I>lduY?|-Q=RAg+~51Y?rT{mP%I}8U8W*~H{p1~(#-Z7y&Lnt zeLFM(2=mNg7IEcv)GpPB;7=RO1Oq!PtGQs6j9`cL>lxb1(ZYPO2;3u;7GCl~{C&7q zLgwJn9mf4P@R0R_KEzN_{>HI9VR63=eK@>>D0wG4{R<%9vqKUhP+GBK(cy zkyhL|<#Wb*M28s7W0#oYZS6JN;&+8!zNV0*Kk>$M7E_yx_A}4R+;Q1 ziw_Ei_zCh)W(+-Tw-dDr7%AI_Be0p0z+v;p_yoF#D1XKcuQeSty;}*sb<4d_t-D6` z;VyTnzEU@ns=(etW91fq6H!+A8dU7nJ7ls#fb0#Ra6BW(ej;WJ=BHx3N zFJ+1$kGs8d&d@uAoQ|DZJ^Fx=d$x$Bb~(KcK7%&C`i(=pCxVzx#wZg+WEx#nsO^ki z0j326ny0m3JhJn{s~KM>`4^@5hG}N|2VULJq_y+R8QH3e>{x;w{*o^sc^o49x{VQo z9=-vPQD+ulp!wL$CL{j1h@TV|9jk90TM?VJwq&`@Gh1P|p{*uk zYnO~x%`BCD6UZ=UC;r zTTg_SDo!yr<0D?G1+XbfcE^kX_K@{aeBou5T4S_PXBWxj+%xxW^R7NLpK}_2Sg|tx zur&n5tOz4y^2Lo6Cov=0@zib$<#{19L3mjL^cSSskFT}@S~%?{fwmUs<_V&X;w*+u zI^KXg1c3*&w-VQj(B9%PCtR!lNmt6tkv#;g>6hc808w#;OZewj!$Nmzu{7WofctA0 zq!o=`TuBILz<8}sv{ZvR_kZx=tKxRhDt%#Y0Ish^xng%~X3Pn%5h+)#HhPXYj+U4Sf%6EMc@zptx|DhvNaR{u^f)1@K<{5)&GYT;0={BCHi?92i4q&zZcjT(wgz^mH zus!nGJ38;fgNz*qc*MVSE;LBm5W%L#*oi^!VA6)fgeXLSY4S8e@TMWT9{ncJx7L^M zX0kln#Kn-V^fM-@(aDS6I0}(CoNXz0n89pV%q+6#iL2Y_wvohXN zzm)Dd|Jww*i{ENcrO5zmmAM?AZv{?nkWU;2FA!k!rk-bFjNNg)t*Ce#5DL`)hn$Av@xmz+lBX>nAPFvi1PTnPoi(j~h*n0`HTH~g&2+ux1p?@?d7J&co2wL3ZfTMWTxj*WB`c$xM3T>g^54;)&$U=~ijk)??Jmi0I znV7l3E~^4|S(W5=3>Rn}_aq)+bT<Ah~< z!Yo4Q%w6{E_&DZw7!2-2_4y#;>#!+#;_F477YqPcQ`G3nor|)OsBOHVX2{}XVcgQO zS1k^c$x?@m+tJe^E^b(#?Kxl9D~4l%z)zU-5;A)jXTx&|L+|UI_>&vm!m9~}-x>_m zRd=`nIw;v!cGOxbd;?yVC}=vh;pdiT6o+0q68NM;V^oSD9qiPH{EhlJ9r;}B`8ZGC z-zJa7*8avsx#)DDQO?c9ZA8?=T9b+7KHS?T_D{zMYL*`Gj9LCz|CylvKR$;lSKYz| zFe$&!ZIY$D(Pef8lz_}tIT~6wa&vwY1PCDT?l51x$BHvupU81ICa;6e@Bn zz!A`$#C`j5;at=F?LVKc)VVbNJi9{2|Ct|(YYRFJ=-Q$&Dfnb=#*ev$`zCU|0u5^9 zS~n8+LjDEFH+^JFojWBTcv6Y2BhUTeuk*qC^=%Z2~rgD}4)E&{4x z&hNAYk)E)S`c$F?V@?=v3GF4ngwI8Lrn>kr#bkG1e|XgJVgOn-Ovb7Cjenp?Wv@yey7h zfm*2~crzfl7aMI$DlWt=^L-S4NX)^h=2t!dtiuHh&PElEsAW}Fb%Ab85WHggg?&!~ z7JE&Mtf6KxOi&dHpd+AhvxeANm@$Md7GqY+m(H7))ns9`fAQy$JwnR}q8--R1SFGg z5f?32sRluA*b#yAzVr5I0|zBE zd=S~m1Mi>QwRbCjP9C37QFfO-L190FkUkjJJrWzmx)bxHcB%}+-v82=0 z*$&*R8?a}dZh(tHYA3TuQWNC1WJ45`op}Wdpzg18g{hE%^`N@KA5*qvGu{LKaU7S| z9!w}C3~~RTQSD<=jYoxb9lJdP1~qDaWk>y)5lD}N{ti8JQVdGcVss~WTz6>O_Z=g` zWZZF|n7dsVnjODRtrp1veV^00Kg!h`gvpt_hhnU)-~z}zBz9~M%=;*g-QA%gZ9wu2 z6IOOZQQ*g+1QS!3Q*JSS{jxu@{M$FDmhLDo7An~_WezRD5z}y~{!{6m!ghp!5s7iY zf=JOhP5Lljd+?6X>SI`>B12pP8F4jkJNE4KKaicyx@M+>0i+Qw>P5R4n_46YnyRK@ z=(!_hKNWux(u7$4s*8oJL@+IDFm7I}MskyF1+JiC9?S*4f>ulc1Jq-H#|{IX_+vNK z6=3(s!fT$Z7uN~f5a-Evp%i!tr2q{)5PCeaOPBWX*L4wJaX&rX=%bodcIIj-@2O!d z!f_Z?sY(zH2bIaAU)hVxLQ)Efn;@=~?+V;PjY&I)Kw+p;eg+E?17|-Sw^6mBup*=w zDbhn2U^&TVTB4sWO+*9Ms=IVLK0_9$ zutuSGh z6;jVuyNDLRrNZ=)Dibx?ab&P@1+@U0#g*NgGMeqggOqp{c`Voxu{^C4o`|tL&R3ZW z!OjR@XX=BZErMNdl?wc@0m{q-C;f=% zq&qYS@>olE;o76rvB>vpL1myEoGz9B1Ys0Cc`*FP|MUpqf4r9L_XBz$5qi2FZIb6D z{3r*hg(IR==kZ5~6p{!}3gxp(L|rKcqp|NY@(<0(M6)ObCYqh!;5|20BDZlgAR0&$ zq`0{wy#0=lFuv}ZcJp`fmejfwu#fWABrQa6*i}S4Z?Qm)@psl$KmJJ4R;XRf*+ZU} zixui#ld;`%LKwV06L>xOz?pSCKn_^{2jZ*L6d)Wz;@lsszx6=gwRKfl(g3>w0$*(= z~3&&Du#ZnPnIv zkBDbfRg^oE#cRVFe1cZXh?O4g0AWMsRz{gBHexWj3?h$U#!C$RLS~Z&XFNRY)#(c8 ztwN?$!LJc)^+rZ3O<6?MfJ61tHoz73nHuu8Pv7kr%M2!Zeh4G-z@0#8V{T@UB_Qcf zk$ge{RYZ)wMYKeViI_^v4S`j3%~}2iQB6xT?XtgJ9yZtWQx|%MxvBGCSQ=Uxp+C-E zIz7{ml$31Dx+BiDvGcIBg9nVQlsItx=#}Mq2Msi?P8jz!5NA84pnEz0r!*^^kcts)sWdwNYgnz`e>c7KH+R2BN_$x;8(<~c8G4kU zSEcv=j$|2vWyvS-MUcoblJ(Xm+Q#;hZyq!WX%-vzf;}K}H46((YiXp#aaXS^j9Rtr zCqdi9jK@qCt$cH2D8uh%NrXN&ec;sCzx9`@n29VgKg-n79$ z{8f6w&W=i{FrPz;K&8qt)IbUT-$8k>6$@{HJtTCxdEMJx0P~_8dHjhBkI(h|_t!62 zo=U`@yO@*v-n+0}kEGIiY9_rd_Uafn+I6Vs6IHFPdH*hYT6Vdug5`{yFB3zCpKeJB zC?v#`9og?=Q04MnXok?)@#K3cKin&(&9h|fZL);Kx~VX@>fxdKK2C-0DVN~+6{{o; zX*nKBn|V@tS_sYZ-ov@O8tsiXfrxK}bq*_M@?eb=%LC%nPJ5o+ZY)vj-REC=(%Gh} zu+7OpJ`0`Zn1AY}TR+!%={vEtT-l`@^_SlA1H!OFfVNl_%v09jSUsw?<<>`#H&B5L zy-EZVI#blIms>hZ@8Lo`6LAd}>z6eI~*yUuys3TY56Ny`R)oQg6#!Ou(@ z&H2Nq@|#Dy$B&s=dh)xh)^GK%`TNFotMQX>7q;!{KsMbPRYNpl85aD}Z(ww9{r8Fu z%kdvio`UBVI|qLeUXcPn1MpY40?mc4aVvC$%U9EH#KNqV zmrwV3d=Pnv9NV(!&dPGn>TA-V1FEaip{CnyKgN*V>+PWp^!muF9k`d zPVmfMOq>>lbmFuWomo}IYfZww_J6RpZLFCDSIExeeV+`T*fcXME_vWlgwC(F(S8#xZkNN<@Hh~Nr9dFg zFmI|2-B%Vz_R#`Bh_EH7)me$UD9`qFam@YzCd!9@?+!Z~QN6aD2vkV}Jj~md@P?Nm z+kiF>;>4Ugex}qp3H2R)j`UjgE z`+4fkSWC;`>m4FXWAP9h_#0u)!bTcS3PB9Bk0Es`B^A{|ND30QFPJm0@(JjW5bQp01cjWOZqOnzt1zrWy6~B$qy(7m%8CA4?*kGpz{JeBxHjDTXYg=h!w%P?W zn+_G-4`E7p!eV6?*f0sSHrjxI@Eq^>^}f-0dI&4UkbLSJ_tAB1_`U88JoVZki7dkm zUK$TkhG%dV0Cp_8k458`!No8_o*NSzarC(=hvjhU9~_pOOz3itT*1(_Cn5Syey@~; zF-Jk`ex5Jwc@##ONcgcWSso0)$Fq#f+i0<0c`LMP>p^|g~!Z7L>S33nr2jns~ zwU?32H6rhL&Rog+QC#n}Wwk$H4gG`v_EZ85O4kD*Tuz5&Ch~~Na(-dR%go&k0PIH0 zrWN+3jVTlU3WN~p{7ft)9{a43w7rSvhw*az-@XX{#h^a{d> zrIz^W6HY~5U4!|w`W;F`c9P+#0|a@q0eMph*nWmz`F17J**$G0BvgMzh|AEouz)ta zrxK8^4rZ(}scj5J4xefJv-tmDs*O~}UT>cVOt|4rOp#SyPiH$~$|6y&^-iQkNd+M>8#lORtaEB+UWUxuosmGgd32I5B zb}sfsgYJJ+eA680J}5z4xs;xXvGPQ(fquIs`K5fbzfpmc&~V2lAo>oGX!i|i5H*Jn zLoMj{6`^EpJIsUB^Jfd_O0QXgZN18r-+;NS+ZSPB{IBjK`@?xx>4H2*D|z zho}PEUMqDL*->A#@#%rS9lUSfbq zirU{1eyKwy=np5X)N8j?b0*tt<~O7dYB3Hnci%~su5B0FsqK>OOOVQ^B=o2zwPNXA zPsR^6YJ-exmF+B1GU76k`1_!r9@PoI)c^x*5O$tD?#bK@K%`d1sk7eWZ_JaxTZD}f zt7X=#60xU_U=X(;wZ(T-q;e~~Lh;~p%2c~ZS@HIq6ljN9 z#WnWP$xMky6kD5kQm()H@o`1zK5tN@^#F&J@506+wO3{>aqFXoeg$+_ppW`U+M(9X zhjM?MW=w}5uz``uX1urz7r{iw30MSpvi|F#%W#ElQ+>LH79P{h?X#WhirI5Op&K++7OF18p^mhG z{c`sIrl(Y$fj!7b?qUFO63g0Z3SM~YXcb#(!|favnfl#v_$;e^V%bJ1)Do;;vEZmqp#c3L;Vq<|}_1w0EV_&?gz{F`(j3*aljoWZz;wBzPOSbf9 zOQy+r;e5~uerbjrcQUhv%eR2pCe%4f7!M(y;8W0_!Lji0x4lY~m&xF04qc5JOrh}! zaUpYQS#<`HFCDg63`^rm4<&#SuYCZzM_X5q8W8rG04UEiGk3>iy<~D9jQf(V1%#}n zs;E`cVpLCn_!jg>0puhn9#k`00udQveuL5na-A0$|1!*@6hDF--{0txzFU1?{5&xs zOW^yFnuC*5sRS0Pr*KlEW6O;P*G2(WU^7*GEwdc+@>&;&Z}ha|pA z=gYR+x!jlir#>wYCfa549@eB#Cn&Ysg!xArWzgJ)=sWnh?XNhg8POd~&21ru*RTNg z?OKG&ycJmz-t)R;Zr6Cvz1z*6P3>#C)b(lnGnZ`D#c-fqc#FUX3xE$6GAaEJCt{-X zCrcnQQW#Tkd&B#F801D@sOmcwdGn`DVwv1$xjehZ$xS0~ZG@TkmHE^uJqRJ~%TbuM zT+`%<xr-T&F&l-Xa3jjx&qRfvp0oN`vs|IA*ESNn6c^WkjYe)B(lea|@PMk$<3R zioE_Xf>oFNgdCQpex`2K5?cW`M+3%~U;NNv_pd}ZJMNl0?nU7DgUE0Y1yS@#QThpZ z`zwLOl9~T=M_k?XG5YCcfE||SncSQ>qS6R;mckECy9cfAqYh72?I8hCR`xUpt9JG| zWw@TNhgOD{`3JREjgPO`VjQ*9v@iJ{XO5oe?Z5SkEZ2YRSa($+*p}We@*bPz{bj~* zmvDuX(oRu-C&F<@Y^Aq%ABkqH66cr|)K7RL=AmbGb~H zd4z^m1tWwCXhawRg>2XYfv@ObBZeI2dgL%)BN85LZ(knpsXGQQU6_0izn>OcG|>`M zO-go1L>|A?C;*N?!2Yn6GZaSBp&HuNv#l+sg5j6($;UG^ zUy8W+RK@=x@44?{m1*McttkOEsys2zLRva@5&g2~T?na&sP}|<8$I%wmz-?oaM$&Q z`-iQ{O5Y_%HS_g(Qi1XQMBF#|G65!e{iL04=use`ypo!%0dN`eIPvEg78Nlp()aQV z$Lv`kB<}`EEn(`ZJH2)*zhXtZQ|Bl_B8|TR%tf}k`(^O59gXc_IF>D|zbt#D)x9c9 z=tSeOyEjvPpN2(lrA`LonD<2ENklHdnb~UwJ?p(4Z|Rri`P&udzqFMrEBIll8lr}%HIa;=J&Q!#3yBQNTCHDWQ>Q(t7~1u+o_m^X*~mNJs3 zf-rzk?N?jYMlh3B^oY|D;p)mpu4=WP04bfVxi^K++mYdYBlK zKjVlA5rn}^>->s4Mn??d%!hSmGaKqF?j)8mQ@MOw_TbjW^OhsIyZq``n4)#4#0(V)KWo=Ql2F>BQ|^xH)T?62 zxo!hQ)=WU=`?UK0M&4P;U@%fGd*G+#k2TbJGI&A%ffdWrf@-PG>lAt`rcT|*oE_*r z;GI%r87??n2CVief@md}rwH1dWxPSXtpJwW`TvUsW7$avAsXtUhp(gIh&TUkz-kJE zcwp>z@S*}gi+~ruX4z?hz1$vFXeidSvZEiuhICO+D#g}HG<$--+Gq6e%8})U|kp1qKx&PE|Jc>MJN#d zu%u}RgH4UM1bA#i?x!iy{%4uXYy{kth{Q?S8)7&_Ovrc(uz>@tfRHh84$^fQgO}4k zby!%cfkTMDO)K*JNIGNHH40L2KKq}aw)7>sezaaK73>;8KD3qM!W2m^CoG&*;|E$F z^OPImuV~s{vVc|==4ifgvKrSgD)4iw>1a7l1XrvhP#%g<Z(mL~I*x4ex=zz2C<$yW3FZir1iOX?(+~?jQTTcwfi#$q66n z1wD7gk00W=z$Sy>7v>{ZRpayR&-4va;mlr536PX!|HJrdJIC4F?qb)WgvQvSV%Pd* z(`tj1Nr1sj3q`-2pv`2A7;k=4TF1R!b{@{YRqLa0LPiI9;(|8Vg({uD3AuD8HyyzN zmn_^LE;pZP-R~77t*OkPi`=ri77|=E9Czm;cG$l`{dht3+vWAxZ(Bk$%OG*Dj^zHx zdexD83AmFgtxDeFF8B*MDb1MhUFD6Y^IS@q)Mcw7ZwOR)H!d#`Wxgs-`vFsUBcRWFp)Fu==pt2 z-GIkSnee{xS1or26Gzzwtnr?K?_;8kdYI(B&jofRGkkzgN1wqmE^`|GZBH82z1K!R zMHCUER7`30WM@mi>{fx12^-u~Ntjv4Rl9(bfVF7O53l!Q4sg?1KS?sqg+@~d^)-BI z8R&W(jV-r(Z9C6R1z$?0I=u;%$eYk5A=ApzX;?tbzAJFSwe0)d_2FD5fvCtFFVe_Q zl)ewQDvZ-Y;O$Z>El1ft_rQ+Yjt1gH z_h^VoHOj?nr%`dg7rT14diMd zxY^v~*54?*RtQX*{9ZL@{dkMoXJJm6%++oJCe@cPT*kj+kojLM%uSo3hIYHd(y0LZH5sQ#0L zM)9Lj)Pq`^8VIH4>~NZSH1cm4P7m1sJ}K|zJlL51Q1c}ZhPU%R^qd=Uz%^OK2{>VP zJytLSaVnR?Its(GgQZ=%_cLXdLM~qsiofS=!YazW=Ps+OaHp>2Xk2~X7F#>buD-M| zyZaOp?4HH(ap@SsS2hpA1&52rg=(uq&E@J!9e-dC0nog#daA=BYNT}2up34~h3&*} zMF6PPfH@@Ow1o5W=Ywhg;V5CYvSO`bNJwaPKTy&7)fl)dX`{PWnjt9V?-@-{0?B!^ zxe~7`ouAv?$(vz<0<@el7p<@oC{|;Z!bXI+g>^50^^&=0LrnVoESTOyet$66B7d^g z64Yl6PtSDUu>ZG!2-WoHJ{EiF_P6&p?pnHa(ZWPby*rlI+~M^=Y`S(M#D0b#U_&B^ zShG8yaUlT6v3ZYUrH$2ARX@q9-TGi2B_L6S`7bhYx|ZX0qd)Qt)e(~Llh2{FgXKl> z8&#K=p$iTo5jW$Q-{=Pfp-n6)_kAFIgjqk~JH?xyr89LoHv(~cV2iNwRtfqNzE94E zyKugU%#3aEGgXOA{Jee^*VyUW@Q~3DmV+>|Ek1PJCeVk%1K-2XR2zP#^GGh}rzwJO zAHE67?UPVg-_vEPe)fv>*2Ymrha|QCodQ>!@##Yj1C3tmBp-(RRV2KdGEIc@wnZ*w z0DZ+&|;os7)Y{qdkC zmL#-+6uMX4M0@Stvb>j!Byn`$2Ps)}gqS|s0G2bpsjX+Fbr9ho?)xnfcmegEeM#VR znYKql)hYN%tFp?$Sj6II|6LykBY>wHq*Ax+S>j-qfI?6chYj+lx@ZS%jGXsq`2q@C zhCl|sYhz%jH>eKZL3J3=LdXiuEu?^&0ttY*8^Sfi3)t8GJgg$ ze&iHFll}zjMVr6-KWN5L@_Ye6DR)?)OM%byzMaPh(BlN7R3}Fcc%VT8PwkzHJuRM1 zpg8C4b|t?pg4D=)-44sKn2Rt#fGc;mvS8v#C?8)Y`h(D-LWcFqvfktIgEE*^!^d@) z7za%+@kR5j3T=f$3zcMn>$pH=pE=aBIu17t0-j`&`G8Oy|7vhKZcj4QhwOX&J8#(q zBEDu>^}-kViDOKK2aR^XUyi=XhSK|vh!Ej0Y#KH_OBfk1dxi9W~0Capd5z)T#Vo*=I#1J(d-eG1%T z7XY8fcR%J|hKOcT2GP6*Y@LaSs;JILdJ;Dwt6Cai6PStxnRXmElh;PVV{+{lt#DT&f`8SOxb05 z_ga27CIS9TJ7a#I`8CNAF6+P=TroYnz#@pJ_Of|`P$#GJ4M0=F-aXbge^Py_U>qIC zc3~D=j!m>DjCICbdte(rECJV;NI*n8fG0|H@J2E|Tiva*<0YAO8X5$v7C#xrwoW?@ zfP~TnmcwYY_Op#_5rP6nnL|N)P47m7v6eGlDKoJ!;X9n9(D_Q9htBz>3acyZxeDtU z!ZSPPo&v>X+yX2zd2b_M%@|I)`f)N_{%(LiaRxNUc$1@RrHXVWjSvpTuxRhS*ZO3< z=X|DKj;o!sm$s*k`M;6_)J4tHX?IsXvNVDsR~hGP&qre6uAZe|+qrp^ugwKBx!9_r zd2ehn>u|1^KCvB|akbbY@x}m0;8;ieuF6@`aG9CK!9Swp*3Rb$Ih1TM(X-+wnqc`| zdC*H>N?DM!#mBUP9rF9Oz zYxeC4Oin^paW!JHPB7UpUuu*<-(eB}g9*>K>?I^cYvf^chFabeL2vRKwgDQrLC&|j zy#C1S;=nPdg@rwDa62g~jKP6=b@@6bRhT?6(g5%Fz5gMs$Af5{_VhSzoqIT54aswG zD4$`wG<_9z6<;Y-X01F=^swuZE%pY46A%qou}STM`!U-$qyc$T0;9?7w{Nf9P{Kfs zr5~=k*8at?@|E$95@p5D=2~2BC|dB!7P&uE5K!vPrKvt{@SWQyjiX8ocuL z=p`#bB%~lltJalDh-b?yg~c9R@ot z{5#)1CId-{H^m*~WeGxpG*f2w1`@SwZ?8YTR-VHgsusOo`^W$_T!m}#>~;Qy0z2Wi zU$3+Q5y^p%d*f`d3Ogjg`N|mR*)p&d6)_1F5fXl4O_q_3@HM;?e+f~C_$?L7DlGl- zIFs=`{T57pVq;!s>7P!BxY+l$kh8f7lz6?fkOh7mY8{xnfhqGq44TQkb6o8N5RcaB zg2S*FwcxPp9PN>CX11Xo-AC4DT3$q6y$4S*2~|Zq6gKq?0Vfm=wzOn1lWzj^_HFJ> ziY&A+!lv0e`{`xq5kJ~JlGcjaM!n`KW9Wg(BJva(-_D$zN7|vmzaetS+qj9ynyz#I z%YYa7h~zM9D^wfEZtdXZ{7rI+pE}Df1wj1~7<~BGWT*ncnWe}58Ke5}3{}KPMzk(4 zpUl+9AJz)e?2@u!P-Wq?OWk|TUpq0bHEL&L%h`o3XLsFsicxK7xh}xJI}+uObCtCc z(>22l z&JKDrAhsYpb2AmV$WM41w3>O16+l9z#<;NoNbyDup`1yy5gMz)GCx`GF2eESo;x^V zKFwpB1GzZCu3t+-Nor7Q7UI#YhhNWRouss6rBiq_kuWDDvpRnl#5&uzQSweUY-Y1t zj}lPgh?k49xy?FyHBzT7@tsThp;>tD8vl|6^AVImWnF@q*>%PY=BOd63}oRHM2!)x4l*5SkFJ}d00N%aG2pxlDBkZ* z9FV>tTH%XhVVt445h{_Nn`Tg@FF1YI`g>E-8rRdsk>3=IAs490Uxsebb0OYg4HGI= zMBmE5Y9pcwA9O)J1o7L@iXZp~tsP0b17Joi{P_&-TYFD@0M;UCuR#I-r0`p{W$!`2 zZ_*Cy<6O7C3ee2$Qh9}hAHs?h}r!gt0o)SQ_i-a_cGJb1nlnN(O!)N&arhkzgq=8Q4S$O*g4mb~Pu-tSeC|^rf<9F!^APgs{0< zYJbHJGp`-@o@Xn44;#P^gmaR*pqAWa%Nh|_*EL{dw&ZihKzC6JB;23>4rz(z3>|yt zDFJ8ETJA!Gw*(r{@Kmx0erHD-Ct>Px#?-aAB3-lhp|b(pk_`_>yc>Ra3C_os5dgS4 zCc(rQGv3iIaSRU;8E6buZ=oej_-WW-=UCu`l|y`mPY5B470qZuE(K9mXBDB(|M1@xIbML=*yuM=vj;^2NGfBXyJ>kjTSmqPh3T~1?s z0mk^kd^P=~TjvXZ=>GZB2{R32&`=NzoA?my722{|pMxZ(#H4)I;WJwp-vtA3?+iJx z&<3XwL|cI`JlgrFCU-HY??LoD?f|8!VHPH^Alz_K4cN-UV&Z9ShowMz3`_ zXZ*g#x%M2xT~Xf4E8kGjEiB$?v=nV84l!t@MElcaJgk0;t&-k|BqKQ_%~^?SuzB?v@fmMwc=``hOj`7l*R<$bhgpu2 zP+A5{mppmMd1H*=?XnX^;?bfC;rCc|G%X+Y8`y)tD5*BeM?LJ@nIY9 zoR<4vehi4^i4GS_`Of^}GcM)mU=1t$2}U=yBZC8-tH-w0*#)zWR8s=rLx3OK-|S;Z zTh8har^yKmrj@LmA6v)!cI>VjWp4UNF87^)JYg@MDTw`hzZboPt^*WZ8UD6^x&R;$ zH)c)XplKeoo{B13bM5gMur4NP>bz8dtCbmWesjY4RazMoBWXU2_9Dt<(S*!Q#E^== zk%HO(&5qB$r8XS_q(Z*{mq5v%yj~D5R2f559vr(iSi(mCQ8r43q0=_fKixyx5O-Y` zvZz0mI={SPJ|7DtXj``p94D4rGRQ;)QSqskGggcJk+)nQ%-$Sh&^YHdE~krA9DX8+ zuEN?sF~_z#LqhIBq-YF$0G9)=c@zM+Di-x7kN~zMv<2XcG7C%bUx5t=PBZVu{_!NF z85sTyvt~0@Z{q6IG}8MBmkRR8>{az%y@;O%1{y$ykaK*?T(2Lx@mk(X=}J1YiI)Ed zusLC7)~(iMzzc4!M>Un70+h&}2i!m*F!1Vnp#IqVoAU!{56{Fmfdk{ZCoc|dRZZ^2 z*}h0hx&w$BK}i9KOEV)3_tv;G>ZhNpNbDqeQMo^wUQTOLR=44jQe$z}m5oy^SO?nT z)P-_VE>w^Hj2o+Va&-+1)=!z>yj-SJ`q#|8Wif4k#T^nCb2Ct7p&Ru2+v3BknUiZ% zW+TpHW3o`ZYx~we{A+9$bH8`jr>T!wxu_mD`&t-(9?pe6F3WCtO~+o=r#DyJ^wEFx zAlFUX15bZ#EMxsJ>h&*@X?nHuMtX-+#RZqGt(3aU(P~(X`LEyxMsK(q2L$2NHjt8^ zPTEFPMJGpRv$2|^RCW>AuxyQ;c-GR{Q*rT!J+)NEy?i(VKc&Y6mFgW#(_dte*F9J0 z5;-1vBPORpcW*sO03u4g>q;6Zm;D|R`Ct_jT6NRMN6J6Xyx$p2z$Cyoc>EFsE-B5u zJ7RfRr6Mt(8v06sUt4>pY`+~0%{oQ%cJD&1n5CGFuIz+4m{!K9Q2Kc7vktplnog}m zxoCyj=jy!V^*+r{b8bVBYwMHL`VGd{i8^@XdyrxNrDn@fZi|>9byt#S8>g5N(qgPBy|e zz!5p(BJ_;Bey)zxZA4(eB;>+QRB#_-a_5Rv7#wztE<075eOxa3Jd$IeRb~v@%NAuP z442MKD_V+(@6P(g7_Xy|6ERw%iH+@-4NO}!;pP7*6l~_r<9^(h{2%;Eclgne^dJP3 z2;|0>@7#xS=>Hpj(^%vV$W#{qfRE?C`sIN4>``v>sm%{mGH_SsWSoYoT4Fo;`A`eF zSQ9JzFoBo+JisvzkvzWJFvJ@cBi~^$GLS!GD8caAltF~~BtD24^3Gm%$M23*;x6~> zyyeyKHW`aOd|r(eUi{Fa#yPjYspPqD7&F4zKIWL`^G=8~*?reYmiBFnGj6I6jr#z} z7#)+W-Gib5-O6%SXIBtA*@`y`zppH6n_*AqoJl`!kD@v0+k4f+Coi9TkfEv6Q;tnV zaRt8K6fGJiOt4Xz0v_>iZ{YXrju6NSgg{p2fBS5Cbma*B6oB$jwwi+P5OkXGe--yl z+?6OVbQs)H0)#7|iQf-R{QmHXp+4`vY<>Wm*4r5qGT7!>0vLxvUh0Y3^%@pwHe<2lq!u+z``shL9ftH8h7Ke4OrA>EC$;ubgT%jDK96R zJT}wfG^53_LR<8*FL^}_5}H)VJTc((4Hy8^0J6>!BUuJ0jMY7O!&JZq*60#JF~z*p zNEB{$(e~clX7PLi%?m-lSIIqL<}L+hWSMd{E9Y%Q-WtlngAex@NaO)KiuA+sDWqC! z6|c2P_XZV@q9;i?JnaG9`wi;*<7ymjr`C+tDBR&G^deuYamyD2-;WmupDdSIecBw; z$ds)kazU5uXNb>%jqJ%fU<$Eh?3!IJC+O;hTF+t3cB6%pX&h2pdWUzN1l!UYY|EsL zjQn*ocHYexLSoh7Yf!<)0E(v|nn!YH4Mv$ZcL{IaM@7ygY+ur;V`x1=9fPy+Do$cr zOMe3Y=G=>DZiZb9u_M+$j*i1**}O7sUeq8^3qcrLZQUt>1>L*h2a3-~LQ!c!F~}N0 zC(so+ZnP7YOfY&YU`+N+2nVPmCW#1~pUEx9na#2>aU6O(H#=vy&8bMEr3~aw1Tb#~ z2LwLOJ$g(UdOeW(KhwAkt#gRzMa@)O&m>fpa3_p75`k11jj$<(%Lz;ewN*fU94h$y zE9q=0Tq3Ua8V&cxVuHNa1c=P}?WzZ)B_=QrpgEMps?gI-R|Mf-^U)u2%}`w4C_4#} zfjVRU+Qn{`W{{bKwB#c`f*ax{crk#+)$yEI>Vip+nDrt|mDR}LJwFb85FF@6;8({vI4u`L-(#OSW3tBmrHk_lqACLj zH9)vYnvxW${hMD{?-=-|ZVo*DE@G};tG#kMR*AMEG$NjZf~Ii_G|L1MJB4nKdVp79 zMK@f@-oiz_3?aJxNu))AsVi(W5!7>~54D%1nziQp0LKv3+--U`MNRJ_0f_k((qoj{|6pEAIOhYT5P)Z|{RdNK6Dp)R_2p zGd6?cVz`xf(nlm1M>1?_u6es7=ed%MCem>w$Af)UwH$2o5≶<#y^21<#&y}u?t31ThN!)@Azy5DIcg*_=~(ys=3sm7R`&fU-3QNy0nRdie~rAwtV zap@gE@M#P0?|Rw;G|z|ka)oO=UpQ~Z`AVRw+@YHp`ymqf(Nm7^_Gto~QxBz%+1Aov zs(j_sJED$y?!Yaxx41E{+?18coXeJ--W>)jPA8U$dK;N1^W zMIg+lWzEjJ&#eHMGdMmJ)8bU{T|ivTT;M5sEGzLKNHU|KLsnw=5)rdGqE(Www#_T^ z^-yU=o}$$N)ImB}qfFGrv3cbz1utirTbv{Ou4xa$0wN5kGWDz>Js1F4(C2^zml$Df zD6@ zkQ2j9{0kiE6n$M~Y5UbEgK&opXi?JOa($gCGPXbI|IWp$dN8;7XG}Ueyw(_%E$$ge zK+FFUQs=-Yo)4dRzU=Uow>79S)+5Fgc1ly^ILv`*oX$01@yLmDGAtW7Nn0L0d6|gK zr*gYwL+PJc4XYMm#8bB0byS4WJRf7J`4JJsfW>A*N3p6H9#|EY%lxF(umcHfbqZD@ zu%ldrp}I7Mz*E`JQ_b(@$Aj}YTQ@Xc#{*dExD6OpKgifs-n+y(TJ0Y%O}f9R)BbUI zr7k+et5`cGE&%BFQK#Tk(dor91n_VtvuIiD`d?W zGWRf3)1y#O(q!#g4vFp3(p8^U>ygqbsy&nzk@w8QWhY*1pb_&q`-3CQ&n@Da%NUWK z)dlKuCMQ<~!9-i1p216qy{et0Hf%q@kK(G;)_Yf%G$GcOKkeZaY@1u-2-blH z5w}VcM!i=4ahUDPj!J6W|5v%TbowE|YPC{#_TG`%05hS<4xsmxWWYqhcR#XspRA!q zti5F!I~NUW{bCHHq4kOJ|<@*rlDXQHJ^p@ZyLkE#-Xp|ccJRuLlaVwQ35D? zHUC-_c3&>oeYse3$Wr-z!!4{Wp*{O22{pp`Q*kgbMxto?md2t`xPW)A;dwvB*KE(t zV2}ii3+<$=?+|)w&Nu??)Pwv2eG^VSdM#GpI~grzMYPV2^rqr3z&h*nE`fhOFmRvkbNDs0Habf_AwtU~@(Hcw45$5+F~mr+3+RS4Cr~z=M$840~-5 zSF36XDjB=K+wYEjbka)eg&d?Y3!USOLN-92F#FF$LpjBVa;mB>WQsXBlLkS=<6dQK zhoC_R1-w99LdeLZx^t~4I4i)FE2GA!UK5!7Tjr_JwoRZ@{G2r`U3K$O6ltb^8^s!} z{rct9&Yh_5oQy4V3t>-ic~urITVUAX{64yTG%>eQgJO|gsd;NBi0xR_d0;d&y>8D5=P0%_FU?AlfAOF!=_4(fbo*M?17vkrcm-d?AW;Se)llV>$hh z!05ZFp~gR)Ks=jJ;(iw|X7+*9ln+K>p7s@|c?^G?uiSZ1HIi(9vA=N26U@MhC2$jW+kaTo-gjc=KK;nqUv82QqVk}qqhe3-hH_c;uFD(1?|Hm}tEx)8li>zttrY?j8Al!^nTWG_K~D$s9U#d&rvtd^cMminDc7a~PD?nBdQ1Dt_FmJ|c@T^1o%vQ`>7 z7e(y~zCYQImHAan9ilB|VW3Twu18`G zD~CsW15(a(!8$M!8aJ91sGG*JA~b^jE;Lo3HU$UM(>7)tq|bRGHK@k}-3=n>gi?~B za4VNb{}`U|1pc)%4>e=zgZ+I&w0}5}%a$^hq+tIf1+xV%dLZ8LR~uiLiNH> zs(nOns)*iH#q~-^bT1nYsFqr=^^oXj41I0Q`0*97drRI)$9fY3A`vOW4BHak@S=9V zoR#y{5UBU_H8nIRtD(GLoZ`KfV0mC|06S4&sPc?CZ0og-VQ0B_l!;fyAHRtF!Xl5s zTG`BUC(JCBa$=F3UG{BqZSrB9kHOn(K}!fw=89#m>y3th==IdK-0~Lyh-XVFDRM26 z8tQ_#GqmjkCQj*R{r5v5&^ps;=AP+t$DCk1v>kS4{L;q|d0vGZ_ZFtzXLy+>Te2!2 z_9`{n92f0Vn?!G^h$3E^WHUSm;WVbyF+krCE0 zz|Ts-rIztlM)dC<&}4~TjtB@ym_d#by_ZWTOb}a2Llos)LF|vjBk&SNJ9sR}5|ycH z@`hCe?Buce<+=UKG}Fr%R|+dZ3J2m)ym6TVu=$4ZL_=2>cUFhzG>3a6Ur2&{LFLE% z`^@qlDT>L!PBH>ubAzJrI&j5Ie_WDN74V71PhtnS&L01x1RUyYs$xx$$Z@1lHRgFD zvqHD~t|^a~EeZ)Z7j1s5!>Y&$J*}tI4$yYeK`B8N3VCiZo8A#%$d2b?E*ud4 zN`Rz;hpy9Q=et{o@)~DU_wR{S&z^Wf{j^WeMW1&yw|ke20ZR8{I(Fh2gT=SZR4>>0 z{8sz#K#e8Kr4Np|eLpOPYuvR=209)MG}@~<36R~j|FpWh9A_Vf-#oK`&-YU1Zmp^Q zBYNh~!(2888=9!PAEF1i--@1n#(4?FdFeoAy)&arb^JsR;p-((lih6Yk9Kf{I=ge# z=1CW44sfO6duxbB(OqfqKf6dn(kL>$si~@#$6yIuA1o?B0rpa9m4w6tG3KVYu{wvg z46y8Y>AC04{%7YTwtG+B5O^$t*9hW{>aU+3%N;{m=|E;2C`g?{&-13nSOz{=R1OFB zpOddFn+&^FaKJ?a1x=CFBd<32dWUXRQ-rxDQXc_hn!|UVgh4b#6 zHy30;D7!}NKfqZZLcR(mX&Yb$O{5Ki6OysGXc22^Joh?`-*;?y%wfFnAI^xfW-jJh zJaE!VZaG4SI}wMw4JtR~LA&vGspFiml#8`6y1N}g5JA`mcJ%j3ts7f=BMhmS2)%_w z2a<&PU-al5H*0~JP!1I$3^*$@(UsP&N9mNK3j#YwtcXE9JM3!l^imZ=_vfitXva|& z(TnSV=1^F0mv_h70GzqH9^a{@sUB2kOBLv1fgF-yHJVL?2ip59Zh&%}q6LZ1UWLZJP*? z0as$?Otb>I%^37M&EdnSabI$BKZziqO#BosH-ia;SpO_}&4AzP?`oa0HKQl3{to=F zX0)PLv1}pPtBcxw!DV>^mt~UFw(CS)C^L$~Ge;6ZTP(z=TeT(}8W$;R16!(b_`~>e zPymH#9^FrhKL+`4&G-pCdA8k8;_#P$QQARoPx2?B7|o-ncOKu91`GXCd14yg-@dk8 zj`FH3X7q*ZBK32*UkK3u`XpFruq|$vH@68+@=O} ztdCHq`4tI`{}QJ1%tqBiUG3zOmwHFB^n;FQl^b$_j$Zc|Loi~-+ zk%E-fw%da?Y8u72h^=s0h1F-`;w&Nq>-?P^e`x)u?zO(o#6ST%@@&b1|7p1#`JYZw z#%$dAn*^&h2EfdLA$lyNgJh=UoB$gH+PwN_U{NalX^)6%sW>JQuymAN|PIQK3k zq;qdCADt)l7xN%#>C+4pANPV1%(sJJG1Z&`nY>u|h+^ZI+hWvd&r92xI6G$N1Hb;I z7!3_O{@dVLXB#z+VEO39%ob8u5(|eoTL)bLd^Lq4nOI-6I%ba!&+Z;Ef_YoGA@L!$ zqNx)Bt8J%c13HIh|6Ys+D;9w_l)L;k-42Px!f@mKSfz!AnDO}6RcDObE!UuJ0j9nU zO&s@G4rzeo`tLHzINB8|F0t)iekv9giBCo0?g!#gV@MT6Q5IQ^cWKOn1vomuB5Wz) zFR}pL^!+pB_tk#gqRz!y^%f7@Q5@Ydf#2~QYicQLSXP$1EbqQhEppdl z^*#9JcAfnSV}(DxC2NfnASv1o<6Nu^qt)EZACit};~P@x{24;syLwV9bW68@80X!h zyBP$VJd?lhO}Qcj5*T;%heR$g?rR0r(he*CYj26I%c53T{iJU}pxt=3|K`!`cOakul)IyP5A*iIds`cOH(y^S6nVTv+Tm%G zKHdsFB#GQ@P1Q9e7}qu8?eK$p0%G?+iBMc?C6}+Cr8EcFhi9<7(35RIA6IA3!#Fgr zBopn~8F+AL8qlgLiESsI^QpAkCBSY0XY14IXJGV21BRIK+%}0Qgrg+dBS)Py`}hnT z)i47UO9{Fj>Ru?2vP3z)Hmlm{dxR6djn`OZ_(-}HH1{y_w5_hg&vzhl^t+rP;m+S+riea5iE;?WGmq<`+T!KgfQ7x zHo9bMfEXr{ox)JLV04|;=509mO)p>tTmaz6X;0#w;owSEX08(!_&F}8bK7;8IQdb5 zP6(gLR|M#mbFT`~GrV1mA9HXG&A>I3*`W^$uQI-fMrP7dNqHlDLx~#!({P4>w>1znZHF@B4k5I4z>NazA>hb zEN@TJ%bT7A@yKY$^O4X6S&Ji@MDvc?*p^(A!VFVOGre=t0miHc>lD;R2w~eOYk3I0 z7trlgybYlRcCIchZ>2{X^7kt5ub7?`YRMLUmrFCFM+xwPUwEQa!B*OvtqpY7 zDdGCyrY+JYOl<9RR?!-#>=TbP{e7!)J4QuJy1#7D&xJ9-EkB*c%gfNL9A1|$aDyte zE1g*LM&I|x$3MZv{kHR-C@ZrZo^)n5eZ2LdOv2f9!V>Z?F^9zbSyD^;gq`G6ZL`Kt zin5wgg*`Y#h=ZK4B`S2Un@tZiFm7oaQT}VHM^tlDKr!=r2xsB^lUr#;e~@b5?DhEa ziTsjDcJwZdqSyGy{BuI)pA*QC0&e0(TJ?N}r%p?eis%YZH!oK^FH8e@6Y9R%{4{`$ zvKHVbuDB_>%6_t}a7wVZFnBc7ZHd76CY16ai%VlLA(KUOSn2u>=L_!CvP=EeTcH4-qh3 zseIyA23(W;$O@pzZ!roVlqT+b#@0?DcV|MP2J9BF_K{Lrzhqrkj^O*{m={54taOvKr@OMr4To{20e@JNaS5b=3}n1hSb zS~xAk8dYm$m}lBRv3>4Kce$TC`kMas+nT(ZWJGd~2Fz0QGR{;-*ni`6mc&-@@HnNN z*G_`~TMSnPvg3j@G97P&na$4bu#&!phRgpoNm(f3DC7mP7kgG!44tZBl$y-O(+%Xz}~F&T3SoAYvz{{Fu^oHwk1NC8VUMOr$Uu?6imJ)6>X4OSILj6ZXQ_3%6-vp${&?`3c<`56-BY8-C*LY5Gz!077US{Am8jkn zi|kKJXsu!LXXJ?$U~A?oZk|3ukzuPOZ6p-j;@^2_kYRk-P^Sp(-?ydGgzHos6OPY- zq7nsDx0hKthl^Sm(6DV9gy$O)*Nl-mcfC2wW}Yh>R+APFSax#&o2br1 z^@JbMD2*me!i_yhRHkEn@vztN8hELq16_*b;a{rcV+@myJd+4*mIxGL?bza$ePZS# z^LgEHrFq-JMa2$Ki)8>reoF@bB7bFs0 zcguj}gHW@RE&-xRz&iKjT?IgKI2twSocwi|I>6-4s&Nb4(yMpD@t_`s^iRywjOSUt z0h$8K0nqE<&N=o9d5ny9BF1zjt1m*FtMy~VYq(+>TTI1xPLCqo$NZ(?e&AZ>$Ti{6Ood=vDp z%tZ@Ph(d6cW$yyy`AYR&WKuU*b}(dxW+>lnrL^}+v3j5a$}_TjjzC`{80ro&Vv@=P z7_vTg9M_>bah{pm_kIe0k&;4;E@i)zx|S8Y&N`%^?k&3?dZ!8h;6coNmUvv>vTr*i zM;M{m%3l?zRGeFU3;rEaJBDr=KIksitT?dJX(r2<1P`(YS(7F*b`14PIU|dchB~(p zat}+U9?);*J&`iy4v*2IzEB;Q3!#M=H@os5Fn!glL^75Cl^98fXsNq=9Rsu>&qucG z=e!Y~1h4Z|Ac$&|(^y+Ix|3x>4q)p57z@5Ze{7yH6J=IL_LT9}55OZX*f(^+YTx440y#-CJ|x%!a;0RD^@>zy&d4( zDp_me-}OXZB05U7_BIC*W){VYW;V4|2~(^7DrS z05dt??NOIq0rq2t*fD4+$Uv8WbB`B>1Scg7P&!6n>!rx!sx%;s%nTTrnP5-(hXHMp zzGQ}(l|}K7y*qXS@Y?3Xt5Fjg|BtITkBfQl|Nm!7g%plu9A#g!HE~FhlqDi%38B>* zswpi~q7BJ89ik{yB1>6Xl$L2!Ll;VvNc&0@t(F$8zsK`E<$S)se?GVCbGu!xYUcfZ zy`IbCaevIg)#a@ZRmHS5u=`gCbZ1hkmnkl1@O?-w;E&`-#DYLb;e}_U^hLoWjOL=D z5PtqT9vOmm9cMpDgfIaE12Th!=n)UKzfkO00`xGsw4M1Q;dl4Uo#%9VQ0xjkDt}DI zPknDjW6p@9dHr;e0U}r3y*Q$zCT_E|>roYMu2p#lA|d4-b%?hh}j^+iI z$vlyj^vLas(OM2H>(Rai7TKYu9^pM3A1=`TjvVhL(XRFHXYS3ZE&9u;j5^ZYS5+lF+wF5xg%T4|GvolETqv2T92)#dWe zN787%Z5Zx~6DqpWj0>m(P~B1rk1fl3;!D)knz+Fj5j*VV4X~HT`|2VB7-N^~ZF}Xr znIRGIRWWF#+O^Vp6-A|zh!~lBJpC`0x@N)S6Y&~D{!@96WHgj6DuINbS4%_*@+*f9 zb($=NK!bVaA5`Ovpx9w3A_p+$kqIj2PGy+&S(yIYIPWS5uwgclt{5#?^x*|D*afF% z2yyvCZY@3OW##gl@`*+1-TbZ}R@=KgV_Z`qwO)>0;;%pd#ob&=lb!_3|0_L|>JjN? zGCiX|;a~ufUkpqMs50f%p$k3UVwXO7CkoxWs?$Bk;EL@qa-rcDr>=)dqA`~Acn^)7 zRO%T6T0DoYeM$j~t`T>Yv3x$oVJ%LEZ&C|?Bj+d6@lWH5KTVaVTWO>$ zP*f#jO`KakztX}qV(~Ui+9D94F1iK{l}n{5>d#U?F{RKtMHlH0CrmTxtKirU`YH<= zU;9Ei)~<_iW5YG8IJ4Tst1oh8b?Z?1<`BsN_W5uX1Ef@72e7kI=_mNQ1yEZe)(=5d z2tVs};mEc)z;kFME?xWYvpSfbP2x(aPR4k_^anXN6Mbg_DHvi_rsVoyhNs+Cuo!7d z`!nY}3N+Hd*2d5JPs9K%X8ak*>I;pY4|8mg{&nAx ztuvW^&G0B(bNB)}tx(I6UR<>YeT||zI3T+2#;05w&_m(Ovc{&M7gP%|ulsp~Iq(-R3q57-5+H|jU zV%u6*KrjW$VL~YS5YF7+)cPr5nv&E~pbG`ST_^yo7}V;ERBBO@WxwvXey=6Bv!Ila?iuZhyR!G@?z~ve@>vVl1jR*`Y2)p!E<6nU z388xi(muHB=thboCr49A(K`(UVw7?d3FA^80BF+Q!2&ck)NiIZIc-IALp@*~c(OVL zF>@Xd(LRU6*5MLdeRDwzI9LwN<%9Odg&|taAMu>1ws2C(yXbpud+2U2TfPxhWvFeN zZpO)0l|uHk1Shml8o~e9YFl;0&lJyE#0O?l8hvX!B6k7(Z<-un()YMA_mZZXPmQ#; z^B7YW0xjG3BF9^UF%Ba;c(+`u6^Ny>m*J^ zz_zP^?7+ZYE?MQ(l!IhGHQhKlllG)e8+E90ET>vYFGQ>Ek>3i=CS)B zHwa1cv8A`#hDS5Bbp$a*CzWSC8|6kdmfJ9NdiHz08K5uL-FFuX!O*J#L+{g6fBMT9 zV2>qoU_aR^;&EJUh+DZA|KS0tDqZ)^uS(Ns|EmXT+8-FQw1YlMVc|41Z1YWd3g-4i z3?GoWsR2;?9@=dn0PvTQRm;!Mn=8|N5~P-k;EJ@@nZ zb;piDnr!!^omk3tNUg!Y&PP_LJb7^^^bLS##WTI@oNCDWN!0w#7xc|DOG_@|_)?ma zw7GAB=h9V_kuBZ8H(>MnQYZ$xKvelN5IVU=>#wfUj4g!TLQ1xRQ?+$R_R^*s_Q9>I zN~PxO|5&mzOTX$3AE}QKdT(uBPY){V{q%5ucB9Jw5RvdixeV#@MZ5^}sKnT>je!o^ zr8pv!lK2x1&qJIJ$_|--h3JxqDRYeYwfXl*LYK*!9JGprj+vVsP1{#BQjCl_DhS1A z_ZG4UHXZHRb#rM35JN>M1_r#DOf1^q2zp8Z+QJTI>?W*jdT}dvpAH40>nJ8C@03aF zfPcj(7VvT!(;F)`B~dC&0_H+^6%0Wv^1An)5!u(Cp+|Y=d!n8P#SCyM~W0iLv1@150vOnT^?)L9h7a? z<_VD!Rutdj}$(aW~bmiD~oKD78M@H0>jw{x2gklSMrk<(2}&^eEFpIDf+r;3%YYE zo0(z1?)G9+IO=-hgkNpijWOuA;fRvT2GvDlFQmHFkpmu!WY&xnt!42W96kEv3}`j; z;Vsk<_YsElY0ZT8O;XNLm0G!lUPGa$yKAqoR{i)CS9T*mW${VSbi|tCHfGXvLMe$U zPm+QKAGhbe?wp;xTw6t?Qn3zmNiIH2Dr+8|p-43;Hzm=K!p_>QqV7OCRmeZQh#njrR!RQ%Kbg0}8ChCMF4#W-<>!db7y z5HA=e!}7g*T&zBz65WKJnWHS8tUPabr1{hZeQ(N$o4vo@81!1Fr|JDbW+c_UzYXX*_5lVg0((q+u}wsNO6jjy7Y9ln1s5 z;*rW|tP*;^sIpA{0c!?I1Ly?GJRJWYY|m}u=PQX*U~*;rNd_j^K>3o^_nXB!F6Qi3 zDuoaT_L&z*kL&*^d~ZXgflLXrIe@$sf+1B3IdH9vqrU>HZ_zb8!R@<2oD1yg+|+e+ zQvRu`OJ3<8lm)&>UpQ2tP%MG7G^lJFa*%=`5B1E03Hr^h^(rjuO#sa~%n}D_I(h(% z@ptry60z^&%mE#7oKa=t^U2S4gC#4H#{2n0*YywV)D+GB99z|rmikxsgNKk$24okE zOZ-x^gaK?bIU5DzwwLp(*T6e14Gk-W6GIhTgnBggM4VOCf!`yC)%1LDuR%CXu}~G? zTYmT}IJxgM!G`PK!z{bOps*O^sago)B{WtQCl@Q93T2CpIzX9V-yVJ!9RLOucs^WG zus9g*v5-akF*sA&U`FO;0l122m8@$}T5L3*&jf*J9ns4oUYN6eeTr?@(eYYq{mU?@ zqbqSRiQ*RE9Zin~N~EM|9x^xohu8E5$o<-oR#`YtyyJ&6ftc#H!VaW|bxwg4EUmCL z#1pefJ?v}^Y@Ude$Ms`TzeSoiR$qF1pOXeh# z6jB_qm92A)aU*(|%n(RVFmc4zzA6nNFnRhGyq8K>sY*`QVtL-bP_d(W{`z@v7A=WW z$^Rc_-ZwDw)}@)Z&PGt3V<;Xi+h`{~`!4uHUL|-S3Bf041Omav0gtJa(G)`gGR?A& zKgUrXNCNUUmp*nmu+4>2)w0L?E&Acgd8tF@yCO=rY6Og|m8k@L`-+i9){MvL%Mz@s zKPk|afiA)|QW=UmfKyISAEXEMkVl|02G3h(K*Gm^?JAjl{~H%%M%7I`F$t0{h_Cp# zfkt;cz5Q4OS?+*=q8LxRMU}8wLYotSRtb7~Hs#Lapd9!Hz|qHs61bHog>?|O$wOXv z4TpdJ@JW6%M9xD6XUB}Qp$U2I=qqCLst^gC*uU|C&X8qBT0)(M(fIsd;vy`|$7z== zi~lre9f>X}xAZZVeHZo(=YF3B8dPlQ<+j3QdPpWnlP+|sY=tIX0!1$c_;owc4#9y& zF&S|H=ALsK$eS4mV=LWm^Mpa?anz9BM?q|?wL5Uv&(~uilvh3*PXHf2$$sHV;eg5p z8r}YQ=ofzj)A4IIZh2T%4KbYVky{RkLO?T9ZLaF7q^cusjkIfCuF)WBF&W=%!LPM3Tc1w+Q z?#){?pg9u%^5h^xy|y+nTGUALIc#{t2Tc6PG|ISG7P;^$%B*vsVptp_QK^rbY;vnN z_|VI>R)O}ID%;*{4hN`d7V%ed=5QQ>KLlYx5WTQoO0-9L^_(6eaDmH}0i zFdd@m`YA&~N}`PprUoo7fhFodp(L2=H}C->EOGxOs@{ECK>8jZp7!bUG&L4qA7kLu zRX7-GBh#!z#i3&k(zAhxS)pmo3UQ10P60MpW(9f7YOrT>9J<)SNYc^n!>_v?!)i`y ztIuj%*GZ5ub;~uU_jYW0<9oKxk8S?6YiDGuyQ*3K!`wd2`eVmp(-Cl1HMmdD({@6i z8swD)VR=1WN#oUf-5e*K;vIQzU!Nt#dst5g=aBB}glsp_YElII*CGGj(?QohoPfhJqHh`L2uz-V#U__MZFTGYG#X zp~5rM$!5qrTa-`3NVd3B83l3HX0$`5`D4rqD>LYC0ub;*?-0SK^SgtsryxFcOIYL@+2;)89(u<~()vZw z{V;V>!K)#wsHN2_HL}kn`(E|jlBQ^*N@C7wp#g@`im&O^g#%l(e792 z-qpKM*`tp~qZ6R9vGa7z{;2ZwzRH7Xsv;$SWXyz&Mw2t$5O3pLZy^43hy-mq9P)j^ zn2CpgY%O|b{1D-EjZf3SKY4*PD8?-aAqOZn>v1jEVG*S+beOh~f%}|Kt)C-IuH28g z;|KT);pF1&Lxi03HBRnw5bXcG6DMAw&A*DLHEufLPtZnV*~iDSuUMyMAL$Pi^4(V= zL6H#n>CUGIp_Zbx3Uwh<(1q-6E(T!}>iB_5mZwHfjLV;teHmn~gQ&_KDsN+2X4<`h z2qYBF#+9y;*F9**u4Fx|A1Xf}M@v?rB2$M;O}mCt@0VelUo0mFe8>arwwTg}$)5)i zM9d~{8hZppkS~FK#+R6_*tDc*4Z*>q=*F-^##I-=7A?sH_I2kfeEa+)xm*7&GBYTw zHuS}pQJRoRJJjkH5~8?SJsEqm0!=={ zytx8kc*3HO4EYLCi)9B7u!RdV(wDD}v2)q43*Tn<^Px1a)2r;cd4R@((5&c^fkt)- z37p9Go}}<|HT0d8rVu>v?!_s{+HDFfWy#0?4_mQ~wtK1bCv&(k)VTT`X9Gqy@S;Q7 zt3jGl(3LhrGZzBJ!-jXqxrl|ec=Z0yVP*beRC3`b+g%uGi1n5>oYGr0P2tKCI_wiFR@p&b`8c=FrE zy&JdT+Dw?8T*1q8!{lClB-WW)ob5bG3%x+G_mWDu;?akT@HsAv6Y7}M&y%{F(yKV^0^!W%m47eq%_rP@<`ok?qHa*KlJ${k7x$ z7~n8|DU~9-*KWRWYV~fS(2q7padp02N?jOpwmSFf8k8Tgpt+`#`x2XP94=NVRyT|U zy+_w7$lz*e(Y;vCx{Og#)%?}e#ar#Rw<^GNLLC%{9xlU3-Gn;xrBnI$wDgH_V-I?& zT>$xK11VfkX0nRZ?;%d0@tj;g#HZ0dlCc*cRSg8=n!76Koa{awPT8!5tKInu4UqkV zS+2oky?9qJJLxneAGyG z6l#po53FKpsTghi#Au^+>Xx_AQ5`w-GI~XQkNX_~OqicgF3Bh32N`Tbj9e!kv5=E! z?qFl>Z)N)bHu$V)970R8ffS-ib6(mY;Tb_cQh+#2;9#QEpDg)-A7pG;-6qo)F-M?! zFzJUnCMbWpG|M6b8NcI5k`9240qPS-G{OI!D9cE72Yl12orZ{mdBe~|pZZkia{<$5P7CBQc^s>YQqxdRk*WOU+h1X&Ke zV49pY?j6=IQdwBVh*YMIqr+<=Mh=NSJ6A!~X@G*NK@q=a^D2DXKB(vlx{mIR_)q-? z12S%(nF*89pCDl7xD66m%2yShU201P@-FC#=3k`)=@Qg^(fxOqvpbg+nAi$@&;h0A6SZO5 zN(eK^ne`^EgigyQ`I4x+7*?EwcUdg}RZ=-#f;@3)rSZ_k-36fu0uI6KqjvP3N%A!QI}G7z1!pzRJQK z_f9yg-;82x+#!2p6RxW!MVAC`@WV|~{Oi3t-ySJ7GS2L*{yUIy5FvK#$k6V}tMA&tAH+{6ue&xkI|Ulu>D9S8P5tZ9)-<6@^1u1JanO` zQr>kuQ>K|4r9y2%N?qfJ)YWjZBEqI>Fb;@oIp~YpH!_x`W%g*Yk?5eVOPDPvFz5%` z3X<1CY~u5$I(xYvY+M#bfp}L}l@RQ(cc0@xzz=}?XP=C2n96~P=q$Sv!Uw37S3qw+ zYAuSJ5Qy#pLB$icz=qxE{MYJKjA4FaOx^n7)MzuqyFuxr7(KP}8gf50`@LXQZ3S#x zywIrK9EVJRXm&*VLMv3$jO2qaj5iL0XU25dMNqmje4U3A&$R{hl&8Z5Yy{7&LrCXg z^cm{woEYcJ8^o1G4yo3Yl-OL&urtEkFkO38k((Ctq69G%|l1Ms|* zV)MWVNZY-SK7aRHPLo`D3B`j(Y3Dk+78b^&5lqr$Y8HiUWs(Pd{(2U+pQy>AG4KZD zTcRAp6$ea?oPC2$v0lP*>cv3zFq2u<)P&hUNhzk2med&?V)ur-2h(acArLu zc9V55{R<;dbj34P)v!;Cw^wCfMK_h@7K8^C<$s_lm(Qe_pSWGeoMq`R#jpBCmA$ae zjtZF@a-x3BJm;ppGk>ci$!>kygeN2c-1!)wnM&Pry8lii5%wx{-ftEH>#4nk?&d(? z#Kig=9+o0g2huZ-RMMa-4M3XEQGJ4D<(^ zkF#6J95B=oQCVAIpB?}wv+X<9tJ^AqA$Ei33RrJC^kC6ATWu+)7*sdZ%d~f`BJE#B zYSO!Rs*z2BeZV5|c^Z|zns!*gbI zEe@n>!JBKbF1p@rf5;J-C)^{IVGO#v9rvFdsCRZQk#wx-{P$vr`~H4GKJ-BanThc#Gz~o!Ew~V zGaK(6O_=^s3_VXXa6q+p@BvL1rY;8Bq8V4hT5MA&O#JLDY-O4@S7;7xtLag%}bU;}veNZ!V{`YG_y@9D=CZ>jW_XTOxYrY6DA^ZC& zfAW#_=m0kH>4P?kq)a0_z~KL7V{nCF4@~YKrhS__)z48 zNE43kmPBME$DRm>3B{Hb5l!r{ieu-YsohL?_7PXU3ukqBr+pWS+I$0ziWxLQYeu9r zYb``f=PzMR(x5m7jUQhnGf`ReYfra zmUh2>t>+b_pCtSI#8FkLQxei7WSp-xJ7VGsQbi!ZGS2j?Ci4Z*79NqAl^iWpVKTpI zaaUwU<6c<=jx$cFL&EgKRoKgH7)WIcwQ=*GK_h$oUwo)#@%T^;jdfX;nB^T;D<6cp z`P{OSm08JI%7Zl9l@=S)?^%O`ED&^3+6Ie5RT@T8wYgWScguPdB1u7Xi{*?2YqkvK z^lHF|l7w)+XYdx5n2YNWN&_0+Tdn55ajzX6Nf*30UlOqax6Rx~u7`-=4&~G( z{j{8heVE`8ItEt9@)@{wCHF%hN{Fn*J_91)k%O5^_Xg~LG%B{0A5v8SqgoYqwP@_o zVBA&4D0TMa$9-i$t{gukQa0yvq=fH&gdJoOzXwG?Zh}pIWXnvEf)KTfbP(Vet0BO? zAJxLe+N%)Gr5TU=T>hfR<;*Jbp;U z+AEC-!)8v2l9}_6dNygf=LXNp!1KFes;Y8QSNu-@`5hEV?#9A9q+pv6UWI=MZ)0ux zNSM3pU>UZs|7CKY`ZtH6cmctd#-dXBoKn)Ax5`8clMXfhxezmEUWzWmT!vKcETWH* z9-!v=PWB|*()shcP9Q)&0|C;6m!cbK8g-y~Aatd*K;uaVhW9Z@dQXY!h&5uZkHX>JM zdzBTUdr(odZxXvb&h9Qa7QK@>X&46M!M#L3@#8se18L!d4f{^fjfSe!auLpepIH#}Sy&1##6;t6kog&M3_G{=WI@&omRlQUL&rnG zO`UTEI9rswCHu`Kf;`_$NV@cE~$tsZXo zWmr0;Iv>aVZcbMCGY7IvVWz!wscajB+2(n#J6CX7Au9l4F$7IhFn!h8*K1~& zJtJl1+otC3jZ5~CJag{L=qE{O&@pf(=<-1VtF^RvKaOSLfv?WOk^#@RZlYJ;fyR2M zVgfgqcl4;0HPL(c?K8#<%Fas*4hv;tQ1t_)R5E?_-(ebBk2qN!CU~U$qriamMR(A&BSXBXtPD- zu(rdz&BUC%Ri<;wSDvF{G}&=Rp;NmQ zMKeP-Gl*i4hAX2@)2EtdNoF)VsXUkS*MCXix(ss8iqVi8%^dhedw$~MIf1)(GRk{V zdu3K9D^O#j^Z*ou$7vTbtc~RtX@7LE5=wBZLMHACNFyrG$?~Iv-Gf2Fe?Ll$d^9U3 zCCmQOi)NBMIo%|Dcny(|WzPa7xU%v9%g*)QQSUa52v({`89g-nMH9?Pntk37&W{2Y zC@3#9#mQRu$B(y_@OduF@`*%FY^;zKfmg5Msvh@CPsYvcK(hk|%=_b#+6?O4599-p zS$N&hE)&dx`ue%{ZUY3mjUU``xyNcu_(I}Idy2XO7h>V@oSFyb zM85t5mrVq+>k6Eh-C|uz_tOUildu-1Pz7`B`n5y%D|m0V=a20M-T|GiwS_$~wv*T) zAb7%-^_!Nj#A)|O1@n=2vP6aQftWSLs_%G4eA*ull5gHSq(yQ(0=b|RfnkyLJ5jbj zy}Q}QAM68ST?>gTnc&Sbh(Qy+3(L{~dZ=8de?p&$f)yRO(3DQTYoBR~`{89ib>U>} z54Dx->yfgMYW0TsiRdT`2W#dHOICTDbI1ci1F;&S)RcmV-2YrpvK~g?X$o%bO?g-g zS`FXnvw$@e|3I!+)^AK>5TKh?{Hr~+HczgXO0Z}t^s50|bSQH=dON3WS9c<;okD_> ze3WyORvo6flw2jjy-U`hh-u2HXpB+_|8^b8yvv(l@;QGBIh?U~xAWPrrqv5hAI407 zuS*i?ogRC*9zX>n<4xWg+x@ru+xNzODr!epW=wP45dRl!XK@1iKO&sS3R1*|kFhAMI zkzE&4U*P+h{+lPUk3WqSnEGQswrKB~FRdh-9e3>au84w#5SoJ|6YErmJz=$1f!X*L z1mV+j3s&+wI;g{tVx+yA_L8(>yn+3M1NPA*&U)Ik(Vc@QCXG*#^u&nT7)pByD4@_~ zvLb4)!rcEC`W1gT6qSW04R`Pkl@-5NLN`xJXD8{x@;?uF_AM*?L)&&UXktlMpa{mN zvttERG7UNF0A!&4sB-*>GjBn>)q#RV9Oi7+eO&A&%ZX{egfQnx!Af>6_mt5)H0mU& zI+=ub1<3>`ryQ5hL?V=q(Iw-Pgq!30>R&YOdwlckv77#~7Tlh!w3^RD9gMZKArtBd z+qKP}Q&nT|=+J-HB~2AgO@c8nO~9Ub0wy3G7k5v1QXFR0SND1h9&-!qPer#Id$)-R zDdk+A5iRVJZ6SlP!rZLf!WrhgN$zvmtcZKCY^a}#Q(%?GVdkQGnu$2O%2l{P2TRQw z^1LlNhf#3nF~?NTfFVb}B9V4PT(D>g*2--NJ4&i6*aVk=V80(D%6-2ZwA)__Ae7*Z zO}>EH^F;0jj6Ai{>Bd6JZwQ*rxs#`0aAMQ`QDs}*DtrPFYWe;rW-Z|S`%iF ze?f!1#XBf9LK=%tB))?=?!>VWP|BiMj#v7OKQ{$8WF9Ib8)WY}0_k?SJ+n1VmIW>M z_NsQvTeL60Oy92n0~90j36K?{m28z@_mFRwJf9_hhP!vj1lF@E!dAK9q$NV~nKNjK ze#gtVzj3CxW7UmRG-7z%lc2hKf}3gH+0G|$k@WqATxGEqyW*cW<9gHl4z2uf_C^T^ z#j}W0%gbAVz|2zRvaNe}h=;TH+Xi(ESxH~<9AiFv@}&LFY#ZkjYXqwCCMUX*UR>2o zKDd<%jyx@BD2gKByH0R%7 zKN2HlDM9igOg$-GK4zGf3X`I@+;u}$i-syoMsVaz#weR83&AMWHNRCE(~&Ilglk|* z-&~mkOg%}O)SyhjC}K^h+bWwWY?FU5q>GpdB6c>JWf*k-G490c_E4W$8W#Sr_KL}B zU5Ut!PLrbeG~|r7l&)tL0pK#m;E8Hgl|enI3``cD^^;Eufz180YJAwUp(rw|#2I?I zoC0>4+Ih(tNK1ya$f8D5ArhsjFkbVb@eiO>)?&!UJHY&PwWQ&OSkb`5^of)3*TiY8 zs)|hnS7?I{b~5EU-&H{yR-1*ass8QKhY5PrX!BNDQq44chv1rf*nr6eLIAaJ zJ`3BW`Z3n+t!_84QDibU)i2P%1?CPc9EcidD=1RL-}r@L_+rmmIDQN%XXnqOApy{> z;3@3OkLhAdC6tf#XOJoOw@2wDDK((0r__}qgXiFw1p=(9qB_m+n&!4P8gpt z-0-}wcnY$W9?-()EIQSfuZ$5@E}~ru08zSUe!6-WXtXOe7Km^=Ux8LpZ;K-y7*}j= ztc4DH>fNm0BNi834Y?-t;WHrW~ zfMhWFEL~W)q*o+qMV?mJAqvbpB*)IdY0&=H3(FRJ}Vcn3obRJ)Bf z_&d1Gb}^tEp9v_AbQp1QCt->KJA0tyUp}wm;l6^=uW|yHf8JMM5&TR)stj-YnDCrG zjSowzKLZ&koPJr3v37R(#H+7tpv4zLi!VHQDGnpg3$loLD9ed&8)X8H`@z50<5alQ zjq}!YmxSWz8tiVIZ~|gAg+3qiUzMiql!y20P&(aPMN05NCuXmp)!9&7sX5!QJpjUf zrl-q&)p2&NwPpugag2R|s<{4{GC)7qo#nf~$Vro~u!?1U(LQYA}!z8;qa3IC9mHk>?Ffn{N; zM@;-|ewAgt`L$o|oXD9tx3$2GmH;AJ@-(;q zM6qEXJx>_r(p_{Pgd{^SV1MK~K*&s}2P0(j3@9Bm0vTyuM%FK5dXn4fh$`Sbjgydl_9gj?@+mj=-waGtk3q+F!PZmCttdoc z0}>dxvrrzgdJ&w3STR#cp74kDjs6fy>o1?!w`tCz@UHiN2{0HkS;-AIF=WZdkGxKk z*b%ttDo?*3Ka7H0Ftx9x1LYvSrJ0Z_S_?AKwx+~WKp5+|!ggH#)s!1^4sR&}#S%4! z>~S2pc}RHSf)CUl7?*OF^yRz31(j7Lh~CmyfI8OoaYwk_}TL>6jbODMi|%ozi$i!tk8_lsY_#B|B3jF z>hzxyo~dtxS>~2{DxO&t4oZP$7|?w&^=wV+LRx`;h51Ciwx1vVt%0xPL!!U=Nn1DP z_r@wevuVwvK9X+cD@6U+iYF5SYE`>S1FpEHWz&s5_UwnJR5MHUpddD;WxSosky&VU zbM=3rK>UXDE1(i3IB@dYX* zUwZF^ImF)5xlYW?evT+mrpt0)*&j7!7(`*l(I)r>o2{@)D%14GdPoPyv>u}1(FFD0 zq`^I3GtfHgQ*dAdH9-L-=DM_hPN?sE81)hg6JXhT^2frii7_ISEpTo8v08xAp$4VH zr<{e~-|^AX7(j;wF$MM3v{cl3cAiz4G#a8}^SleBrTwwfvoWW9#edmE?%V0SY=D{q z^SI9Y<&i&<Q+Ft3?wMi>=vCW9@S?5-9Er{w?2)`q(yU%4}^mhltjqVToTD_%At~O~67+}JOuOs`bK34MN z-y*^9q*wP;rhB?Yw|k>|m1VW8pC&wV1`ESCe5EP>G7-p7QD*=MYa?K1 zM^QSW$MKDapmnTMz$U-U=^;p&nBRO!83Op47zFim=>eb@N92>9BF4vm!2Gf6OdNwV zEbu*xaLLP>xAE#&;(XweJ+Yt2y07y4;_Wsj#y zXtiOIsdcW$>kGr6#O;yV5O>Y6W0J)2h>l7X)^MLbEI2|n{&kHBD9Nn^cq#qJ%eR=_ zUr1#*xv%;hzS{U9bw}|L;76j_;B3{sev6TjLa|J2MUbDJd+&C`taMws;ZIw_cfX8& zp-}Y9h7oNyNfe)5GKAtSeE!6Sw!3=+PqM>(ieyWBVGmcg2FtrEL z{b<)Z4c`Tnj^{VvSgM^vh^5h3hb%a?6o|Ia!4DT+JQrNC^0H~j1#;l*!-65v?B_Od zrZEnPU-umu-8-wI9q07oO?)|%MmR;|;S`lsF;5^>i*xXM_v_x7(JM+rm7e~1bHPlq z89&Mg%Z#-2Su0t_v(g_vZP#d)L7dgvD;0p1xdT?_K62?Vq(^3+>qhLBgR$Gsl-{cd zUo}67?o(Z|^)xFIC%yVDG`(rd3l9GUjeZNXT>-mj!eS3Q*aWi&x0uuR&|&!@8|<$2 zKtFJh=$T6hTz2Xz{c*s`Wok8=2Xp{~8CBqU>4C3G>Phza|ADC5=& ze_mHmWFKFjbs)*tc``M=XXtRp#zxu4HXfhkyYB^~l-VF0VAU2so~0NLODfm2y8_@0Yzg-i{%b~yp_}7-0Ii#9`HjBvw zQ6N<3O-7|9Si^L9CeYoR5U=}$iQ@=dC38qk83xbn51Z{Uz5a!pQgJ0NNtsvpIpcr- zoQJ`2R&yGAJ14#yixX2e0WCcRs~zF6Jibv#a)t^P_z8%qG^WSxXaKCnV6dBO2J`UIT)qa2vHhCDITN=NbnVGLmp z?TM;C5ZW{y5gplqDDE%kvqWh%uHJ#n&zQlu>!m=ub+S@L z)rQh68GJ70bu^hWNIoPM_doYFU;zGn2z(TpBlZ)&FndMqrc%&Sf-+ex-rBVPlU;{z z+~h$6;{qHQJOrAi9UzT=)8fdUmGf!lt&{kEJbYov>tIJaj;Qugm-Rf_Hll=R_s5Wv z^cQyx`==^=fy-;kKOqfmi)u=A`Wm&bMT$_unxFo(nALO+?<$nSxPZch$U3gVRB;0o z#fyL3S|OI{NCKM9_Z?+qhk&btbBB^@Z9Yphve##B>|8yb;)!%$W+d4L!_a^j^G`}) z?aE!Y9+oE5X#W2AOP_s);B6zMJuu;V9@E2rIL=G+4AdwDWurfmC&x96p3O(Yp|`in zMo|^MAHM7<=B87=UL>=w^L_!6eL;T>if*ZOTR-YVkhi(Rw0TLsCyXEY*$YK#Nf647 ziIZ>tw76a-i8Ug?9@erk+$7n9Ne+K!HioHMo7m4i#mgIffA%~~V>D|DvJ;HwZPnlX zzEpXoq2P6AwazeB*)}_5q?}=kQl|(OguhN*Cs4IQnW9)6Eb*O54G+Td$GEAX(?N!D z8TGOB@t(EK!tHt%)5Re>iP40jovYlQdsP)R=DC6B;krq21Rwg}epDR*#4+-a{`Cgl z*_ct{rSIi(#@?ekN=Im4^j6WRSGX1zXqb2mi;wco98v@B1DDB>ym^mswR&OV02~%ZpNmG!pw}P{GV)3|n7hmv zFdX^NJOj`X4s#fMsy(LbA{DfKuUzLo_B~-%#z(eC6enoAt5Lb@Lv3#kYu8$wE4_LY zVplEY8SucTMB;&S)Bdli!w-A74L{tsVNzcmM$isbK%3!M`4R{V4?65(II_p8cTXJ0 z3ZDv{KsCm82$4aNZ*St7VSa6WTZLy&bVcl}BArneOjQc`#6b3Flw+OeeR(~`Zm>5* zPp)Wv6)`?XN>n5PwHWok;wEM?g`9iy4EV1;WJOk-XUs(uKZg{*uzlK1ZN-t|Gask_*pCU=`y-Y+ zx>^--AU#JW)osAqWP4E549^(PI%Qn^dd!q>}ujMrv zQEy~3jsywlSRVdph>cSat&8!ps*HMqvL+s7jT*Cbcr@ad>cR9d;nz`==h_(u$B@S; zZCu`~^zc7Hx~%KMFLw`A9cXXvN}f60e7t*~+~2cl_!i;{`lOXBr|RdPY1t~Q5WQc3 zWgKN&$btax;~a-xB%@OG3d6~+UGQrk?Fdy;&VXM`7|!yOCVkxt%Iu-$dK8F&aZEqu z!DT~y+3H0V>HX1gYSPw;6jqabfkJ=s5R~|}k!R3dyjrSIt9jqY4cPWLzNe*=3U>6` zUGK+@t$N;ahzIga|IA`MGoLSem~=#oA}qzdsxmG5$h;4 zaeX2+XeIrc$h%{3bcOgdR3_kcLpGkYD1v58Rw!fDg_83hBYmL3)edVdE2>V)Y_@(J zg`x1$#~q3*s#U96CW0EMn}jJCs-cGa--B75LBt_5jHno|2ZW#i2*I`FykVf2h+?IT z-k{eT%2<51?YNg3}yiDXGY$nL)v3!_|alCjL}LEgJa+BvmL5 zA+ZN*@|xA=S|brY6h%0hJvFHN>7qt*-QZ6sy8}>mGfH2?e~YJ>K|?9X8~+fKYyI_f z@c=Gwr%$lN#Y#|$$m>rEEJGBz48 zBe%wzWf-}In?1qiCfi~=z!PI$ay^?9&x@XLJ#B@MlEyzdD64gNreHeqcf-d}EveIo zEH)^On2F7?)p-0!PvOwG(emyc=#yZ$;f8~gEIvst;?w69VjUKTJswU{sg;TaL*Oa2&Z=&hU@B(KbUKzipOXQpsP)Ntg(O}T5`f&fk zz?d(nM00#jD0jF!-<*~PCPGO60oaN{2cdQWAAR~5IP~6Jh3}9iL|Biv;oUAlm7)E6 zce#L6ei6Ghv%nB6Z4BvfefN54`8wV_kqSK5tm9)yplzFi#H`xshmt;D0PbO)(Dbn+ zW0ll|($BmxrS~wD4e*}d_NahZmW8uuvAhmVz=Xc`kaUw^FZ)?4=xAHGNeshr(S99N zzu8N)F~H9xNN(>OC?So$;2imKo>UXx`gX`>np!C(H35 z3j9WvhqW(YK%^_&$?cKjRoL}ZLYY&#wb;}%-q#8-*)3moAushLkO(30Ly)uQQN@zA zC}cnTmxoO}*4FUhG!dtL_3k%t0YG_GU}(dR3IY=4^L+PKBobdvOdhY|+59{h$KCKe z*IN1872|i|jVr_(_neyPk;CY%d3YXpq72_OxEMNRvafhJE!DXOG2oeO*Gxdpv3g3`M z$&Atxz$~P@_g+KyJcVe-J#ejRZ{0_VLQMBVce^|2q=G&C6YSxq*+xKFK+CiyLFHzG9 zpbBopjJ1(3*1{w~3zOtBER#mGg+FiBmVnQFpN5L^D895_Jz>QPK{jkzHB$;AxcbXp zR_}frKDk zLJ`8lw;S(pQZwC`4!PvQ_y&oNL`-Li>?K2o$|%)Er_C|R562`wub%#>r_AC7crE-S zMP2)w@=o?pK5pD<&hi{nvv|Au@#TrEcJC!?A>P0zxGKAXbDl$k?)dxn>$&I#7EG&# zY#7?_8IZGMrB1^82b=sJC7ftXOXYUogWY1=_m`4O@FW2MECx95ZIM7WjdhU%P;*~^nyY^{fwnFT z_}5s4r$^(RsXGoM!sYnpLEw9!CzHR4jrGl?CyipuizmU@1DU}|$P8?EF>SGCY3C_J zEZk1xv62OSp*5pY9$B}SpfAA-5P~G9gF?fIvhho?mJMpKe;Djf3*D8pxO}F09ksH3 zUJxWVrA8Ll%EcH$9{f_c_BZ?$wu-S(CUI&8Qpi+7j?lTX(kx3HLY9j}Vs zJAM%BaqFxUv+A+sIEMH*hWJOo5s?zcGK0BBq{?Tn_=%zfcHmLkFg<%6ovztC1}Qvm z02hyPcAPIBo$#eY&eNU$Xv7zcxEZHBm^io{!%)xqq8m4edVDXd4V-brdVN6f zo2ow0leIdO;=eyred8iD;MR!s6an}>$S#4pG6SoK-_wvhIp*JCCPEcArG7VKrg{j4 zP0zbOu`R&E=98Plv8zWr&@br1Pug12^G!2Sx#c}Iamn^*j(p6!uxo)QsBs1)4a@iK zz!%Wvmp3rDcOL(G6gb-0;75!$g~tE;Xw$+8ru)qC{By>@$?pl3F>4k&eo@cu=N8u+ zdFl2BsjY=NASFz%`14-#)0bjY!on_!)A4T&GfXl&)t8>eQmjr-_xw9hBcs+NSED1{ zq*}P}`1aU}C4*WEOuje2>#A4t;~sOh)Qo6fwL--e3tvHjZ_3Z-w@v}|kUx@#op*c8 zdsa(!D$YM9a4SCDk$?wLwNMTJ5mASN_R$Es(DRnm6tw1y39I!-pj%1&>o|zin~{80 z<`Wk@_j*!yC9AOR|3^^2i;&|2*q@1@u7K;HZ6`*M2eWPR1#b4pxH;{CJqQocpdcuA3qnv3Z$Jm3K*xG$7`GXbdQL(C7xYF z4Yu(eyjK|w_M8-*O*_oB+IAl4RMNf_wf~@ztj>J+eJX3BJB#&aa9AmP9W{2!Y$0pJ zYur6PJNH1BLZ-$G7`Ih|8GvycQ+?S0$yds?H-u!(hU2EgPxWLka>5PQ@)Qg{j2Z0c z`mfe}ta=fbKd-nohaVN)C4?bgQtLWeB{{HIhX--NhU^{Y1GyQ0uXn~YITlX@$9(dB z^2wM07Hv|t0rhjH4pP{0W^$pL*SK0&ipPlu69WzwEP-hdUx?g}T2a9!#{ctCXEJ^C zIbK?XP{ODzwc{wT#BIfu4lMkB`FK;M?=76}d4^fG?K?XFyV)OPIgcUo+-e*31jk0A zNrOKGsmD;y)Z-NDU|&XoNa-;6!;0OG75Ajh^ar>>S!imVM1Ha2f{io;S=LHu1K;w^ zjyDa+9}Sf?IBuhHj15&-&$K| zo_8%HFZDe*P@hC%A?WZAlxlV~c#)q%CRPM~oZa1!f!Hxf+$zR(cpaojhMdIcM9O+m zdv6%i5RC;nQ_q%Qbu4JB9dVn(nkaW$%_}3q4`kJNFL8v2hs(U;c-h%;&{5>AoFkNF zDoh-K4j=pw8qqmL$dadYrLibGLRMjp67;-ft(-DcDOP+zofBP^NA~z*hWvg1HY)4R z1JN@1C_WNhOvgp-g?j7|2z9WP@+!tC7|v%5$;7N*#$us^l++~CMLdkxY%B1pUyo~lL&`<*rbRaOI zYa9A-;9ngK*Tul({_6Zj{HD&9BH4KSf;4>Y$j2NPD}9oY_whM!qIQp1gH8g`Bts@| zcnjtYFL(RT(^}2%2vd8!&-8-1?+Nn|*I%X(xx;{WzxS#cE4l5hEbAK=Q!iIZ*8hYg zKahdQdIR@c&%2E5iRNY8F_k(iR1mY1YJ&KTFK2fS(K4@oy;SLs;9%RO75m@q2<0KOyNj@?|{c*4$F{6kfWn#S~Es93JRy7^#28E1AST{VxBOQQ8 zI%d~D(SWVV&~gK|3K%({TC?^Ghcev5KnHSBN{=A+8clR13ls6#AQdm5oNKU?D&icp zL=3jRkzq(CZ);^xF@`i?9~DryF5fM6(K|u77`< zCzGLTl1j=vOJ7~&{RPRrUx5PmI5SMPmp+QsE3^?)~nWrUv17@^ax@y%J zZN3epm?oi*9OOQu=#OS(2X*_Az?-?(%%t!ujqhbdDV8F?> z8c~ehD%;R?Dx$O-P*NN>M&dpGI;74o|8TSH>RR+AaSit0{$VZnlhGfRDEt}uqJZhYh z&Tc7`|BfO>*IiQmcA@CK?O8?OwAS;}lMntvEp>3}cdOW*mFIq@@KVp5`=G$GrHD?V zzmixNFCL{sj;u^?rbc;Tw`Nj?tL2W-Kc51uUu9fxO7SA|ggaj#=Q%#7J<4CU${203 zfTDlrzOy+yJ*cj?@h%j}6`SWExVaSUzz522qN;!Bx_li2ab%ME`LgFDoLnBTMNPWA zXitPPkE&|h`q31r=iR2T!7;qf99qI4CkY}Z;h99_GFgiBr>3**b`YLe9)7Ek|J4w! z)*Zxo#S>qm1fM<^-h2%kT)=P1yR$(<040+k+j@wF%xw%(9F)B>j!8mf`m=LHL6<

}RpvUrrM|lu$B-V(LQsYVaSE7rp{R4R$LbMohxwD>TK) z@iM9eSohgtyiWFuYNL;hCF0&7e3}{cTvpkcx50B28B-XmQGB*Ii<@kRD!=}MMHa-t zRvKg8#TYXLr4EW|peFww|EXXDJU9>c`*Qn^V|Ipy`Q~_!LueVHMLIGo1&50DIml-@ z(N$|gl_n<*`S+@2*BH!OVL!&!)FICX(tO4|UU$jf3VhMe_Es(Lqv~Ux;0%lQCRHlj z@bV73B$SY_r4ORT79JFi0t9>u;&yrnB@4PkTDRNoz~^rI!*jp0 zmkp=wzS;x8U2~1BGM6R_!h@aMbMMqhXxB#~PNF#-Tzn84R9;5i`20tC*tKJAbszqv zGsWc520bsW`-8&101BWq|$MAbJydvP8})#9y~Lp(r&#IEKtvsb^L zW|thY)IPfc90j;;ZJDrfQk*#MtByOm55%fIb&Zzz$%2VkA`HGr zW8JbMC=}o*JJv7yVZ95Uo-6A+D0g=zcr@OZpLrt;zGEHKbkgB|Yn1dzV=@Knx zi??FQ+6-gLRt%X0ZI&m|<7p4N1wE`G!jcZAz6<%CYHS+vkjl8#dISCx8&2o@@e&q` z(N2=Jb-w*XvJN1FoRqf>y(!cv=d{QwZ6$wu-4y1L(MJzNzzxtt>bu{%|9?bXcU;YF zA3hC{ROnGDq%;hPG8mS`-bDtzDX@aZpIgs!r>)MAT`}LdkpG zCy)1^_wziT&vV{$`u*a~J(0ouA zv1LXH^)o-r2{^m6$m7({_KS&E_m8JK{FK@~*g7UA*jcSbJpX5Ko`=*!WY}sz-ijjQ z!Gv|49TqL_Nos-Gb~9|vWn~lHsjZ}7aR~a7zYXT+yA^3I@LNQBKV_bXZ3KvfrA{@o zHv%utFQRvvOYsh!lqqtbRVx-vWDTbNc+zQ!oFKR#78Z}sz}NBbevA=Xr+^_uCBQ%0 zXu2QjTl-=$&rt_yw1q7MG(9HS8W&Vdgwx#%*7hqmf(TGHh6+Nd`2t3a5{iVDiA%v9 z`47r?Wwwwl*=|S4LMTbCUpkY^YygUCv*U#2TTkY=7P|D{0tjOT(})QK>4G(8vNx{^ zbxPskFai&U(XPu^2o1-ENO5USOtE4}C2{PNAZCg;#*yzvFmG8Z{|@ELUZM<>h9!_c z_bEk$9btlcSCoRc-ScWgApaxl4f~MF&+LX}>UWaUwNbUan$MTjzINtMG?$;yTn>0Q zOdOxNZ-_5|R4!8f7c%=UDU(>8RgZ6hNg3}VY#D7&?n2K{TQi6DyLG#&q>uA=hb5P* zVZaP(|8%%%*-z{{Br^f>&ps?d_x2I88NWY7{)H?6^%BWT8QO0j6&Nh7-%kP+hBLlJ z`C-MZVi%f5G@eQs+We*QD9FBlk|Y!aktamHW;Xn=rz?N#9I-hWIY?$ywo$Y$;U`<0 za!#xAcq<{l*XX`g1y1?9t`*dZx6p?le?l_g*~Mf#;O$zr0}5H4%l1P_FpqeFZ48NQ zpJDQTS%08G|WId4a?p2|GZT7Jyqx%);9+zV0sT`_t1v zVRNce4TB)Le12-st&=3M;b{B1V*ocTwQ^qp#mDs{SQCUJh{gX$yj(j;O8E_Y)J%P7 zT#iF{c+n<|Ap&HvfhZD94$2vlE01|+t*(26KdcCx5i7QB6mbS`QR?lTL#&F@cqsRz zXhod(11XbUe3Ws;~(<+J4g-r+P34=~;~}(R^Q# z?qwawvN0cg^g4&CnODsbTXP>E9b@f}2Yl2ZQQ4v|6=EBh9~#=JWY?4<$W9J!A6O zqRNO9IM#`$fpBVmg^uSVSWgEY-r9kMqE1vocdxGky94sOhEgm$G}h3{#g%Ht_UbBOYt4R9fe5_X!b;R zg3)moj1FO|Krd9Qy%qUK`)8)Gx3^&VV!1JNA6|YxuHMo_G^u_x)Vd2sY*xGJyYeql zFTIXFKi4vOoCk4YHG7pLa|T=6xUc(|G|6UYh_Q7KTh>&x9F78T+!;+zgMFXnYoH)I z49RlG6O6-Kl$3zbxYEwuMX^MagY(MNHZDrp{A%YkHxFvZr~GGVzo405{_nI~b?Lb(8Vqb1`hKPd#nL`z%kBC9V zOKY@s9M}%T)M|G>mR9EgN=GUCEwhw^?PS`Nl=XOEaNJ#gmX(-~K5+%oY$>)96K?eS zy4TPPhN)7<3z%s^za>{uUU`AcQ?^lN*^sk$`ZU)oA3LZtxdg3ZH^OK0_8MJA$}`4g zsMm<=aPG1?48u$!g4bUDLozt*J}YB^Qo#5)cpYBgb$GcyBk%j|riZWu>W4__%73$! zA=^gu%{ZU{g;|mvMWxAKO6spn@gI+u=?{LbV9Nu*+Q)K`ReOG;h%8uXh2iVu2-jl5 zJmL{IkvDDbFZ{Dwn4mQ62k}SRv|Q_5!)uzW&G0|1Cc&1bNJn-M&d3UyO|(X7I{#4# zPgOrZ!!CA@HSbP@=QCE@f0|y8CMCu6T${usvIsf1y+v6YS zSGOzNR~F5(vY;WVzn*m)qfwX(CSE_v+u?zJR-g21 zza0sB?XExOAML-3lh`iWo2!#PRj{x>7lZw|xG<4_2x0$6rX}F3+^~qb=w))lbZ|l% zB`_m(-i3Ryre18mXh5<$TO;$&>Z-xA-)J00x?bHON;2ok)SmAb;>rlP8elpTUJi_> z*w|s%7N6g2_DU^1LTd$xaF&nAUSWP12u>JTdV@rLeI%ncTi;QC;cUZIm2X-7~@W_ z>@mV#{7b``R@{OJ+O{^^AsH#fTshDRqn+!fs9^$MV4c@L$e5e1n_*n|GX23vS!k>% ziKMd?`=h6KfCpG9WD}Qdxovp>&jV6u+*zmVy+quoZ1v;0`Igg4T4rSO>p<555<8Tk z&T$*cq8)tMBp~3`eUBsa#$MK(zeEHP;?W(-49T-T*3naoX%LD?cFs$AK&qBAJMpDl zpc&P9|EB|^bc%S7vd!p{ydz)R)qqt1fR(Ky*`IwX!Ayv4+3oJ<-{CQ%i{ zL=J38j6twDWIeIDuKf2vWe;e|RW1;InY|VK1(kzzujf2D6FmWYg-#iVY@AobUKLw> zo27&+?oNsok1VbFg_I7phiHiU4>(YQ<-lGEPQUd8`o%53azmntvHQTIuUCkbP==*f zsRayXs$4GW`rCs)B9z!e!hteH!ldA7D$~|r>(uoDjui}Cfjgt%mIfF zkUdM{o#2+o&d_69OW8cQd>)IKX`ViTtk_Ft$}oU8oOVLkD~T;0A|;7g2wD09KlvC~ zRSHcx)f?NvMMQrDyD|3SmlqFF3)_YM#)kY1k`~+tzN6>! z`OLEP=hJfhbzjU z$W9PGoxR5*NR!z#YLe3e$x_!tfAB-%v`!4Nk|cg3jA6ly?QI4tAD&jxyT{&;a705m zqG1a)w32UYsVWZbc4(PA^s?X+!v5kqRETT4Z8g2S6X7jb0gXD zSVvY1`>|HwgS;Sn+&6)~;9DjwpPM+nWEWC6ZkrwQs zeus4r(c)kHR;kEzW61!g_8#z3-n8r-;LPxV!t9oD*WEIH#~pHwjzj9{$WkO9Db=FVtZ)sYUxTOdFV$iQ zd@VEf5ck{=3EK_BVeYNag}yi+P?ylsVxm_91D^q5@9Dm|2z|3>U-9X+4pY#?MHjgh zhY`dcZZ~m!r^Xp{&i%EVe`K28Z?&05@+8*gfElvcsI zWda!6&5tg>9fRNg-4rCtiPPnGR=-p;dsEOG8Y#nZrMSCL7XW3v13VMRLo*3ccG`C) zF6@IYx~R&0q9;c*d#%r{tE+OZ+r9e{cUEaHAO%-qY2-}Q57>I@k9HC()E^pPDrY|S zWNLYCSo3TB+xZw>1*6u$HxYe#4gVPq90Pp0oVUoImbv}!TA>)BMc1R6wLbUrAh*@b z&oc}n9+`C3d2(s6ueKZ{_X`D&ZXPP5KhA|v29N+80du9^`s2o>%v~#t;D7tw_9z^~ z;O2G1^T2T-4gWQS@hT|%5{f_3trAOijCH5%BYzW-`E4ZYarr z-gv@mkMD;?0!_rmHuZK}{0{VakI?7+%U(1Wz%q~dVC(+ZSJ(tyVx-2Nqc;!@UVf59 z&iOu6gm1=xcJCjiT80SQ@|-UKnuT8~?exeHAo1tDwbH@qvF+S*U4MY&X7Cbq(OMsl zv56(^-`t1IXPN(TT1kPBVT*F_I}C6UM}AyDL{R{SUMPxH%Q`>66}QiQ{nIQ9TerEt zW3z0j{<3yTg;*@mBo-(+##NBT#TeANar1!sD>~RB2 z7v8ygZb5C3^YS^^A-`*eH`I%H_7bPcY~7Du^-STikFxYoDnusxp({I-p$vQWd2CoE z;rv`?vT7_LPx`vQeMhLW`tXFvXD>K6gmn-P_YYRS0cWgErt88^I0*fk2zD`CI>A0A z#$#=wLvsN*WrewcJ27pOo*#CUNO?He;0mBlfv86s_=Z^|Fl<$!f%QUI-2Jt_sr^%H zV3x7u|A4^FZKP_r%R!$F9#vKW5In+-Y+m^CSq%(>=J>?2%OOQbdE{GGYzDLm8L)nD zrM?HTeApBtM44no{f?m@5b1pjmkh8ptAs7{S5*N~DXTdeB&9)E6H>y+9SQdNhw-{i ztequ$C-Wka9`y{dIAm<}p6E1ebRrImYzMI}9}gh>Z#Q-~z%x|5$djorVrh<2q2)4C zPr@!-@Y0pi!8D+zkCLLD4Ra6bx} zTv@AhWK0y5{@((Kb(byt=AA(zCQQ9RnemGRfl|5U7{{eT@?5ZBMid7bbj9NTsO?=| zYy@3E3Iah1FdNrb?~TmF@S=S?+>+fyFoOSViOl~vpr5aN;26+;rA1STFH)9@+_Ul! zA&aBYv|dP-nSch_j=^DE9wPe$6ka>tz`DUhuJQBia>wREZsS?ZT1Xd?<25E(U{&kF zfhnyz^E66JlNB@*jwvV$X^cR*XPY5Ape)ljaF~L8$P*HJ z)YOk-g-AP*#F6D2>gZM*(zjlk^HOo4dePY|)sA>FDI>3(t;Z%vdg|xriT=c9$!QVV z;C&E(BlcD5SiFjc@{VR~E13o9G+UozPqYhHd4gZK3$vi>+>$x?%iTXm9u|eS`S|lSTaSN>*BDQ(ErCj)%oT#=;!R7#(33vP+XdTEK^-M zGmP-3wyq&;?{%mXgBu9to6IQhq0LSA_UpOT9Al$QL-1@#la@;e(FSZr97;i=>^NHrfmrpS&8CogGWDo zV0yY#^+@UF;)f;Rc(!QqC?N%agay%cS(U0uX`=4bGyCHom_kpfJ$rh{{C?`$dCabW z)lRJdmGSTl_37121~1?n^$4?!lU|w$It4f`t-w>5UHp1viL`ZPax4{u7>0zl;2JK) zxCn7*UO}U*!%~rK-D6;Lnl$Gvn|>0*AB3_25eI4bG>C{~Vkx0q;~0DCKI&hZVRFa% z7HGLFo{$G|znZZ2X}jS%=W=h<&{-cAx=Uc8t0I+mcW=Mode_?xHmQ|bOY`7^d-lHT z%^!u(EWY(|-uJLWFt!m500*L@b_zn{;P&8iv=?kmHDWH0{cF~H;=3pmb`OKm#p)ra z#7CXSf`kcOgIKw;c12U^9z99|ML+FQM2f;YJUd+z-A-w-hFGU437))1r(REu>d zJ|J$gok&iHfZdG-BUY0)B8FFi}6}QGqn5J>)|WK7@Th0e*ak{C20Bnx1jYe z7CBB#?$hCZqWDdU$YQFEerV_bWr{CPlchg;Hf{L5PSq$!V!-+Zg#Dzsi?k^NN*(cJ zX@Si-e0z@cHYumk6gZ1GnW<-1t?ycGZ7s2-0NR zaIjT1c?gj9+T58$yFctZ`sczZcKxVNF((|!6?NisT1QX}5)ENJW$Q;6>w;O?5ZKks zp6rg7kqOE?ebA=L?}L((Bbra*+Z z23CV8GPHbQu+H()%`Hjm2!UgIHq;+WYC1>`|5?r>;tNL?T|mCri7&%?1U7>Vp-%;& zDfq)h{pH|RrUO3TJCHf3>wMCMW-YNg4NLAPr5Q6l9-+9yN;ruV3K+G2NqP)nF}16I zvs2Qx;c1<{b#Be?7wW@1m}zJ)0D1>f%JjZ3CeSX8n=USN}nhj;iQi)FXeUG5X>EX=5iaa z25tP;_EOb`MJW@f<&ss4fq4OLesX<8Y>}^FW`<_pQ>B4<5SJV5N2C!i;$5Gc;Md`> zKDtk9QSpGF>gB|4Ul-GlfYV8yAqvuxBASrL4_%*Tfremk4G!8vQibk$xRRK{XN~zBq zw;SHScqqK>cEdk)W4}C7Rlh%M7`+)QalYD_a~5%4>jr1YscNOQdu6L>WP zU#*BV-+5?}plNz3n(Fo$L?{dJ!WcwMeco+g=&6AH3u*W#wZmr_!J}gf;A5wb&qbyA zew_^%YVY89Po&!8n<5ZJ8+_rL&4mud*vwbxbDp(&BtfK*D7-M~c1`9Y_2fI$ll5V5 zbcs)|2s|hSN?%+j6Y|2ycLdBpi=&1AgC2}DhT?W#vEtHkOWyFB~#W^^T+O2VWJmy}s zYH49-Hw44RPP&%!gjzo``r;Yzd27y!5>x99T15hTK%){=Y6@TGRJK>oW|+5@+n}^_ zU(F&p@S%)gVn`y5)Y^J+Sq+vHGpBEHDfsXoB8-c;rXHSVJzJvI{y-+{$B;WGw#yej zy%)dM0NUJX9#LR4LSzw=qM-O~$d*5W#z&JY;}UMZ!B&*b#1z^K(tE8zy>oa%m{!u_ zI!zkzcn%jCPbFNC;{+gY7PTm_Ov4KM=R3?KNy>)H2-_ACqfDZ>1M>N=5fGNw<9#G5 zbbh48jzBd`>3y^Je=AF&R>uV}*vQBQE!XlmSBH39x9ppN3zbbS$++a$z;O8ie|A6@P&pYbl!8*vFEWAk_$h$if2yQA@^+}xcRWtq775t4l zJ1|P|hpNV87iJXR`k56fcZ>D2$5{jx7u;Dh&#DL441SiOx7{4_ z6~w&nL?X*q!?a&&C8?h#a@x`#cVvY%+#D))@q1m%NBI)l*2+cb?g@iIl%;y_5Z3&3 zzGy&~FiGS*Hi+JY$)*e;6lO2`;>m>f1nv>xtrE}6jve>f=F&gC58<6tnk1PY60c?8 zrFH$dkA$*0Hl=G*XXZypxG^EZo7EzxW-V?X&{$a?W%0YDf7!2Sw%;(v(CJ;M+xXGADgQ0X4aqC&Hz40?F)`{lUE6rd`jC%T@^ z8NXwxWChMRq@k@_HrJ^KNv{`F@uHiWdg0LzGC4YCS7(gd&;tD40!WqvkZeR_I%G_f zEcgLgtfK`m2Q#QPjh#UJ#{T*ei z{3nC=DV4{ZYTq!Fm;X)kaY36(pN_IiOiqGl;*P4Cbu>5>*enyF#P0Esvnl%3ai=wY zr$FbguE&S@T?bu5y!WzalT7|1pIi6GvrQ%7uCmkRl_5(DJg!g5dnwvhTSX`X`x&&Y^)k%y$Uhb2C^6p15foQ#&ufi%)bV_GR{gT+E_$Ni!n zVH#HjUU0qAl3TrefZE65nBq@_QpV2S|F9&Q%pkCzRkF@Q9GjS!Nq6Qe3)IJ6h-u#3 z=;0US?WVs;F;*#$C)BKN0g|EFeGse4`ewsdB@+8LK!Pact79#=1Y9IAXl&DH8r_k@ z9Y@{k23}R%@^EW!@ahhNl;ve9;gx+HvBsRN?6@pO;jN1Sjh8d(vN2-NOM>Z6Bbv`f zc2&wkr+!cbvi!tTA*uX2ru8?Rk)cX9;NjF}oZM%3|NIAOY~HSb?i{I@E!g?mv&u8z z#hvxg*C>4WtPc znVhJq`T2=2kNf-AT~#wE6EY%{+MC@5HZLq|Io|#<`|wP%7&5sIWKp4D@R~f9Ke3TX zY8gj7%@j)~kL-r~vnFO2fo{tS zII`sB3wf9B@PL!^O)ltCx}xHeHjS?KRsaO}-16?4Kt5FKp%yO;$)V1MwpTAO9dQa< z=D17}>@mEpjyhq-Rt+MK@UoJLy|<+z9@3a*zb6R)dy)B&K*C$khxdkBaxW*{@i4>B z&1*s$lSWdNM5p=UNHfT8_rN<+&bVQCZk>zw-9EEN;CoXXvbB!{=*WA@Sz@AI?c$I= zl>;%@sHiX*FzWI+V%Ev@Ol}|F1r_<5bz&tmxk~f#~b0!Z}>4So0a5p2BP$${r(*5Kk#)lEt=oxzgdmr zdBN+GfmEfnKd|@tvyw{}^7^jUjq*v~sBYiS2Hjzd9u#yr1g)++fV|YwMYL%}28NyC zT25wz+)f1|#FhxhWeqOTTauC7djK&X6p7QtR+uZj`Hnhe!x&E3BMGuC4+Nh6>FF@9 z$>6VvY>b}_y!a0GRWjMzHy&UkWQA2@k5G`tc36Ox!L2KLg0byDIIA`Hr3gYcWEMJ!N@Sd=)jhfd*& zzII@axh=oXEBYc^rCKQ#;xiVA_l;nUjDi`0nyr zLMv3tRn!i!Fy%XC!~GrQc_w&#@F)nQ>CY-f_c0erRT~=djX0?cw%$=qQCjr z#X5cB&SNY(zH^ly*E{|AV8P%6&0^dElj0N@vO$OJ=eG$<28XnIFjHQK!V-7n<54Ie z(sRe~a}`WKj#U@DLLXr1@*gyA z9Qh8uu3RWzc=v{Ic9a?DwvRn$9(#WbJ0?IjCNrS8Mu##9C4rI6t5LL=A`3n@nht3_ zj~}sUR(mUASN8Ko!+9~(D)0&1Fte;#n-HF@R{%JABZuX%vwDFvU(ailb2lXHV}!RyI&(JbGYJWC-;(~*R+9x;lV=FpR&5F-=CZiA&sb z&5|P2kII%VTsA5o)TMz4I;X&LcfqK#Wm2ovj*?aT&9&PC$G^Y>m-lzT>8H-tBYgtj zbr{Tj6R()Z2bV3>R{8zCk!$2P7l(jvkS|4}VxyW0E1$m^3NEg4;~!=UDpEb>u_5Eg zWu&5D?La;FtvHzpV8stQo&=!g)R+OrK@)1pd!K;>L<0%95~fO)ar#qzs~~lyqXe2$ zhUT?dZS6vhP2pN9*YIZwFGKf9a`nVFRCOLWI4ey1*(R0@=!={nn%rS|@(A|ktQ{_v5-vqvxW5sY z3EH5xAl7Wbr{V3A)wTiB6D4^2QHR2nmTYAYx?df&cJC!c#o0w{^x)B93>(TpXHlji zI5wWfaN~8o40Nl<2+oYM;`$EZqV0+yrsp*q1*kb zgg$ppxh0g!G!RK+(*Dy;@*vwrVn6_nYoVY^=!iXcXnU za+)jSrzJgB-eq=B9fmH2Sa$D(_|9q%@zEX$4$cns%{!3;%Wd#m+#Ej7RQ?F_+h~~I z{&@*opDn=N7AedCS>38dam_no>Bp?!i9wGwI6-D@Op!TrXaScZC%&$~$NN~GE9g0` z+W>0nU!yf2s~6>N=3jC$m=%=j`*7V@^o6|z#Nj3YKET|Qy)+?F--%hT{P5>;-H9@KIy8yVy56Z)s~4mPdSVD7>?nJfj@xsGqByjw+^d2apf zsRy>PV~mzu9t7TzT|$#LrJ>=g_yg3~(4iZKx50#AicOn~nZM zP^|VHCY4s*-}9W?;t(i<6^GByM`r-x8xrv&>t?9dIM$2TiOrc)YUuzbEY77xPILb+ zOFgWL9Ua#ss(*0%+`xJQL+w)6mo3h9-p=YA3gE1Dh$q9$?fAso&3`KxTQ(^&%AKI* zW9KbB{(+dmEdWY4AZOf`@|h>gPlC^8{H2Y}=l(V>T5>IW5z>FN?aKl5Mvwoc2`%z6 zRK`hRf$)1gxAvYbJQTH%Hbsd7OoDO?ije#{*h=f3%iMk4tl{%mWqiQFy^&!T^)kHG zyKT2ei|fp{T1$2yzwJj7T7uGi1LjG=`X2b?SpW7S)hLu&M^I`_xuDZ5$n2egp*04{ z8=}J!%&^yP@zS~Ono|+KjR-J)g42)HY%fraOlUM1-xa}Nu;5H1)zWMjIK|h@1eaqe;h77E_?@{Z%yoO_@~v@*@Nm81Ey9hN^HD#%2FB}nPTORI#k61$^%di z1q%j*uo-~Az8GO~Ts793>)ud9A(GztL-l;iXOlYc-EFkqK7WGHsHG1VmzfkgB;-{}Wg6Hi0Sr~@KAL;zgEOZ_dp#-Z}t(-M!LnpsV% z-Ri3x)%`HB#2~=~g9MMSJgFdrqiA_MeNMjBi$a^5X1LuNI^cu&zUpP*ptmUI&EV2; z@s=(8<$wL{nU3(z)t4`~=ss4QZ{;HQUAWaW=vcyN&EO|M@hn*mp4@Iu?MT2dA+3yz zp`vF|I&Nq8C}prmasO>!M7BIAJY}inJvDiMSYqG(ZdrQIfxH=%Sr@vWEzfd=&Y5HZ z<3%?fNi-fw|LlNl`|4j#XdpgKlUj(M)F*GR9u6mo09}t`f=3ik*0uLw3(?PId$<=> zdTrBa9rE(RD1m`*XRxdg+F{WsW27N^_?@}^pZrg#_SvChENVleAia6H* z+ZfFx0br0S>6=Z8#dPZ8HkQ$pl98>n&;*wZqM%nW0w7EKb?D%6Q~_0}0=8jghiC<9 z-TgJh@%Az)s@nHMf1@mWULaBs8QXgWfc35oPyW~6z* zAE9a3qGa_M4-pGdLfZ2Iy=>Ws7zl-;r!Lk@8h?3Qe^1T}UxS5Up6+9%SR*ev4VLZU zD@;@PmOjTDaGlKI>$rx^#mCNI>22NbCFk~HAWm$pK+}TFGz~k#g_tgE6AMZ3>sp27 zL)yohjD*ok^#?LL?32pVmGaz!You46jA_O%bi^-o=8%tui6WosUaH&uO4VpH#$pR; za~H108JLNXW%FZX3Sc&aLC0z-xYt# zas{>!vz*z-^L3Pm-ZNd0^JbTp|JX8NJKJO8p%pxH{rgc!7atM7fE>QQ7kJ(*B$l8L zpcB%??~rObPJMGP_`0_l%c|ln7wsWVzLuZXY||qXIiH(*aC3bncLT?Ya3*!w_6S~; z_#AP+#uDXSz*qYaI3p1_?M=JCSwCUJvyou!f}bx~lmHLt@sL(j#Vx2D6D0X5u{XMX z1r1!(H@?IdO5+Pxh@519=G=du`F`R*B=95NcmJne%bghDlA=QZMaT5@Bd|CP3hvd< zi}2@RbtVn`YW!j%2vVs`#Eo2uEtOsB4 z`f?uZbmc64R82~85za6AHn;FMI@lc()Nw5zdOW}whD5jP9BaRz)wGyXmS;*>25yaK z6LQFa*~kj~JfJSqdFZ=xD;{a1zvBjk3QfL`4O=|U4H%;tI*!vxP-`S2OqtoJHOBDj zy`Nuthe*6X@kmE_1=;}8H7$Jym|j7u+g$iNZs>h-c4pa2@{vo*ydt)EUy=n znMiSlCN1ETx5F%qUfZ~rV#cjK3_+4N&372|2dnG0006srIPcH;&U6W`xtDxZQ~-KC z8VqP71JS~ELi_hB5cdvNnO0rkdN?W$JsDcYdB8&sot{rs5=uvyPniZ$=a}}~-czLy z{GE?N#VK{VepE=*!;k+n-$uC5?#P(?vR^5XnNC2ds9m7F#kP_m(T$xh4N-bUqf<;{ z3V^*E5bD-aXhj@`go}VgtKaErgR*sCmUs7osDFuoAEZAG5@*+$denPwRv7CFleg@! zcSESL8+W?yFmPxhR@!)y0Iv(R{JVw`W{KWOG1u&8;2pG8p zLKvy1$LOfdc$eyddf3^2j}KBXq}CJp@6isR63QU`;WW3 zu@&80kjePfV6)=aH)WNN>^;k0d0)3BC2v8%(;zxu-d6!#4}_Dv&I@FKg~IF*hFRv9 zo{)>~QKkBMs7=4Gcqf@qxFmmPilvl&nPYg*zX(PmK<5%q!Re-MVOcWinh$@!WPXRB zEbhHB-luewT>7Fl`&{M}UW76H`cYZBU>Teu8s$qVZs*>SA)mQm%0%g1pe<+LC=s)c zfT>Z}py8mPi67M>89Qxj=42Ocp5OO#F5lO0Vxv~?uk`lLGVR$u_nnw#qkmQcrDy%o z(Ip`bWg~TFPoL?g_C)0^v#EOL_%LsC!lU?wW>F4DJp+zZzSg7GJ@8_oOBVvB~nQodx)By#7f3xqJDRk?lU1O9K4{Uog_%XMpcCje^PE=E?j`BqF z=~uFpQAchLx8gmv{E73;oxe)w&sF10jI4-v%q}#PX?Qg^?0|fBhM=oP$b3{kdthdt z)~!0G?ffmCvgGkMM;o7hy=sF!A1bR-Q`M>#>#HL zv~qbz9u6>0ad+s~Eak8eJI`+;*Fc}!5_Y38Ue3T)%OlN}R%D?UZL&`>KjK7~>gozx z!})#1l}{4lHzD`UN8=DH4P;iwme9ttd0OWTYznodUe!21T9SRCGC(Q&u1j{pprqUf ztKb7wY2K?|y$gFK8~i@9iCZlS6JATxfrG=(%Y?F;jFKJu+GlD#D2?=A`TaWw|B!dG z%fotGX1S~V{r+RctA2%MXy$&F4cZ;-niAws(WnXX0iK(@gyNDGwd$qio;Gv$4ke`WIBk8n1pT&zVjy-cWM$>`N*fL&HjV=r_%*V0n161oiKJEB?fi zhNbS`dQI&{XFGgz>>c|#IWlD5YByLGq|P~L=Tn&%!?^#H_Gnwu;IVh{6eG!W-laqD z9Bq#DuWQk+nJ1UNMAazWB>GXjV|roD0=#@P%b;*-ou5AAa8$$n++RDXoXka;T05we z*T(7MqGsk?c@6)#zw6y(SARi9H}yfog_u~Q)tQ#`(VGi4X5wr1T`7@$lUnwuippsc zQo@tfm%(G;o<6UuyMEuZt}DxmOX3|f3!it_zZ#nD+MAIfm{}4gqXw}LTa@)`9P1a# zs0AmPaOtqVeH9ZjUtLj^_WWW!%dYof(AMMr2Jh|X&Ag^M+&s%7NZ$$5s&wu*7cMta zzT3n!f(S+rt{l?|wxx#PonOT}UoM}6cWy0d&AzpU3rrb{OE~_|`)tROAQAy$P2PNB*yo=3n z+_+AFqqhyOA@ypBn49fHmk#Us@GBYa)r@y$cN=w?wm~dAt6k@la0!J?&nJyCDmb-2 zRXcI|ms~NWXoRjxpvz_piP}#z8#>j9hE@cQh~~%&AAMM1@UT*%m#j9*E(|4S?5zKJ+=|U% z6~zM;wli@dHacEu%u(HvSm#@7Qs1Q%W43Q! zKSMAep|ytoin`h@;M`MZ@~XG0K`CXY6K;70Pu8_!S+{@8?J9KBZd%B!VMK&qDVnWji@Bf^9O&zb>Cv9-w<4>Mz3fPb)Vm-Yquaw+|pJ*uW`etB$L%T z3S&2|I*R=^wc9fU4ykcitn+Mw45t$Gx9Q`EFlN})XU!?oTQDc1ky;3?M0G>pzOE#a%e zeQB1=5DH`Fi1>o&#fPS}OlZIXDoBL0MP4j$z96X(O% z2`OfCusAW8y@_k>xijsgO9!qE5ZKhgRPjnuB7F83PfU0lk zLgDf(!{-4CnT9=zl9?QCHdh$jYA00PoXBY`LC7k#tsz&f%T_+q-fFlPpGb~l+#hVS z<7&*q1(8Vvl%}k%N_{YPVPd}(f{)4NZ{&ljc$D4| z85Eyn`791r8|s>MAM1m;T9V5*v3iC(WVnYPJG6Goc?s=#a%|nxr+%_s_PyI0L zDQKymJ}m;0+3x2^B6b=KwxXUxU6PpX+h6P9x#Wauy;Y}`RZR&`!)PbJ`q`3g0V2r0 zC}vX-!)qKugfzTP#Y>@NJCbJWzKz_N4d$#vAtvWCg*E#G4z(X<)W?`gRA@i{h|`aL zq<%JM$5VYoADIUFTPM8lT)gkxEZN+dZvcS)#yB*bg$TZ0yff>dKRIr4drGEr4MsL=TtA=3OeW(}}{8olm9P zPBdp%{fRyEs@Lo!@x#xOlnMU)S4_Fe80yYylnwP)5O>_~sGSr(mM8Rp--cn2X?Os4 zeEO!YLk+pl9EJJ!*z4z+a&NP*De*F8DCS$wA5==9Ji_hXQA*OaFDXlG`R8N@d|jT; zb3Vr8wOB!;vcz|qDEXzf2j=5ARuylkNHM-IvLz{*`vsM=u>PYerLC9T9r;Y&MSh!b zh_jcd8D$5|v^a?3x1cf8MjFLE-&e;O8JgLRCrKZGI;J`56;IY`@J45QB0jc^D@jd! zT<^zwzA05IO!Z2WZeCNFzS6{DuT=v%g$%uZ?lj>6J!j4YB|eJnPDRS?;?01#_BhJf z_ohyT1Qj*Wrq!juwSr$x5! z56iiI&arlE#v#$p@$K(hlW@}OwoQR?;-ixI6A@_~+l7s{A&N*o#HUt+5f)@Y-u5nD zQUU#QwNXqK@yIpJKHFXfb%ockNODYe({s6;+^KjI3A;LX38dg_M?6na8uf0ga;)+7 z4BkaG4btwb`VQKu^2x74&-0{A3O!GyvutjLV6HgQq5qRBnjM47b~=F}@Q+e9 zZ-;5h3o(tnQ)1EvR$5dAs~=a&O5%%4U8Y)(t$He7Qk6QsvP3Fkwo~1_?H^TpC)aE; zL!7;>O39ynR8{4X*YU=K)HfPOM-_4$`=5D~&%f%Jo*+QAKXO*>DEXC|sAX z7{%{CD#CsDD-6(gI*8{rTqZrlA?F#T<>sjm9*k}eH8D5-ap*%N+oQYrM_1~sK%o`Ga5F!;!fa^ zOPJs9u4nUfCrag$`1<8hJ7^$}>RO01uE8MO)I-Dl4HW|-%OZk2cwFkNgfw&kc0P zwiESd({Fq_7h@73mTIzSkF7q_cCCnR+BHex6EP-?B$KOgh$!tZoH*yo;lUp;#!*}Q zBJJd@CY)t^EoTM$rX$SKwH1`iOz8Jl$yL=$ zeC69}Qe*p;oXN43$}34HzP0NzxvAU+wzq0;BKuE2!h0%M1p9m)J<{rUTXdS|(P>_& zTxLoVv4S3neJtTsRQk2Ez7NQltC`|M)rIo?>Ecaj<;Aj^r!Me12Cd(1y;)_MTiWux znBsa5(>q?PbQFC(uO;DZjmqazt}~aOtf^L@v>G2)!#}XNLz>Ed{$u|BnPl!p%wboz zjMEe6%hua=ZnZ6ybI8ve%M-d5-V}N>7H4tt!7I+sp4OrFU&+#Uyd-f&K-R4{cOzIt zd%+?)5JpXZ74Mj5bGzYU{gcuAL;?^-A zCKusSy~2`W@@%A3NHHp2=#o7vuL2EfvD9+hnKq=8H&HlXmiE|^*%U5>=1;>YJ5rX^ zuLfr1q3j4FXiu2k3u@ihA+*H9jQMv|IVyC_xH{f%If1J>CUBJzFN;v*mS&bMeN@$x z`tc50VjcM>(&-t3>4ggK#71k>FHqb%yH&@752NGvmx(dvdM<4K6p5<`iAz|Kd>#IU zU_Dc92XP`>!PHgoH@Dm-Jy^J z(wmG*BMvU0M%UjTrr93Vr-bi7Cw4Z9LHWKyj&x#HTqS{;yDc}Xc)E)&&x~=*40zSV zEj#?lv!VT6JjQS#yiUdP!S@*4g|*+-o$SoZ)GBQ_=l-HkeYYglDvFzw7w+%sXUMKD z=~Bupsr_kgm0RojXhkN)Ef&R=M!%62hYkO?Ue98|k#N0iRU2GW9@EOr7YOhbuyT+d ze}bBMOd``3q|34&N94WfTl5f<&&MJjv%h1plsTyh6M1^$K{SNLd)XXNs7^YYhBSsv85<%?9y!gf{aB;V5rPN2}KR{ z4DdO<-~`qZlgNXpibt^1lgmUkOSSO{aOGCjMw#~vHKlAE0d{IOlQM7Uu0UV$@VPa* zPLvT@9L9HOBQ($<*^GZ)#jXysR5#*}t3andH9*H-hm#w>(AM2uy1_FnAaH~e-D1+& zicd@2oMixd-a^F@XMyDClAUxSKAjgeiq11zui?R1|J9xezh<*T!&#AQp1<-IY*`HS z;?|{9<#fXyy{t#rGvhg`>Q-mA42}A|iwCIIcQv!_n#n)XO})l2==kYpBc$Cbt#&fJ ziQ+ZL&A~EDJ9#kQoOjr4H4g3biw6{LKd8j-^ErE&bRUoY&CD=Y5W8*W#5p9J%`vpW z=n#SAa>(a6w&&~9S>wZvGTe3y2ZiES1`lhx(yCD&nzC-asx7V=)3qModTqv=6W6qa zDRl^!-@nV}@;bHU%i83Y&W_g-v}#X2&G?k8bPZuL=TL*6Z(nxqhF4>2+sO;RByW7a zCV9JHY{T~xfsyj*@G6LS_}rkQ&aRws)&0nf&7vmjofn{rYN(Nr(*JaT`f9yJJ~|Gi zL_9o)2;hNQFOctzR8HF2P%i@RxSg$L+IofrkPQi}Lsm7u5}7B%*GcrE*{YNH+v&=(0Nd}S&(6gd?-olnZaqVK0NVqO-1Z^HC8qZ)iwA_m_{a--J&ay&%~2ez znr(Q~!$vA-F?F&k|K_zZncTb03ZmCk?Q-`h12{E{k7?%iH64F1&v6z1GQRyGMMZKTY)m@uu1j9~+?@|pSJ&A#tpXgwH;k4$LW36_($tp_Bt)$pP86EG z4c*o+>L2r5^4`L?Dr_t!c&aekTLKsBru7Z*?6{4ma1TK^xMiC?SBL9cJP^%XnA$3D ztZ7g{_I0;YZ87dG=08jl6+8YUdopV}0@YfTEexMu0o-^?pMWO+Bkausp=`sx;TA=U zL|W`2TSCcFmQe|bQVQ8+-SW)A!aQwxQjWH{kp~1g9|&*(-^~*H+yXw}YpfqE zi2Cc_Gco4T?bv38hNOcmU%8=t#_uIK>@i_HT?Vlt@(K9B0Deo z_kMP6Z!T&G4E3FMi2<*F{=IYXqR_hjv&_|o1xZZ#pEAwbfq%E+7j<3#S*FjVb0SZB zq4Bi_hrSh`^Rf++GYt=>hflTmIpp!6wj^p z!0owq3MRYupzvB+!1j8=df@y%%kFKsQ+MMo3T~!$8;5ZWBvW?Z(b!AJx@*@ihFxK| zC$3yKIsJx*XBRkz-L;Did=>5};pOtk!QIx%%EMiP`r*O_ak!Hscmt6;M`gvnF_Ph9 zN{9w7?1Wml$WXSyghG2)vUyAR*@{1+BFmR4+s+4kt9D}>?5kELUKSuuKQHHCl*#m> zY`6DGxNKMX!>f@L;lWhGyC^1|d+Hqs@qT4~7Hhw??i7r*9#U+8L0AiGrJ+P8hl za3YS0LRP{B3@dFC)@BwKx;U6?6l;{o__;Z^U7e%57pX9JuXATCQ-XEaM6*M^iahT*-f? z)dwkSGb1E5Tgv+CSzK3rE0cGjEu!yxwC{Abp3@tmKZ?BON`X_>b5@qOF@}9oWbq-F zp*r&BM#q(XDFnjwcwucVMPm%NG96G$eneUwO{jdae+2fY4Z)*yR;flw7Z%W^3+K9z zg8Py^wn&p*TYYVxJ*GI%x)GbB;Tljf|{YMiofJRw6! zrES01hHg=b*%#}ZFr{kW&y;1=h9^?^KTleI{%}85GpfMUJMR*uVTWm)*(-T@V*TBW z3`)WE5BJ9u6!Y5MBjg$7f{n!mrOsanpQduf%z?v9bDx#xl?Fa-B^oGhCZ;N$u_j-T zFH*Ya5Q_cH%~G22hHEG-M+N6<&J;di_p1%t-fi&EVTSnfjq!JE=eFhopQRr3Nh7ua zd?IOC2|gM5fkkg?7I2l&``-A)Z9%jQ%nINxNj%~i=-B9-HL1i?rC;Y-s21MjQGHLJ zf2?^Qe~rnD!F=V^pGkYP#80gfgq;(kea<=@Rj4u>?#uXYCAXB5ufH@E{LU0{En%)d zyQHBm?vQGr;!oqO`m~=(3|it0R}>>mvJTv6a`~W5IoJ0nQmjw9(8#ozS^E=*#N*5C zp?!;0(=F~%H}e7pa#Li*Ia*sbRJsvdUbdnV?cWzr=!M3`C!du^opcRad#y_EI+SrN z7%1jm%;@Jj<~4yN{8T}qS(mCi?4<`gY%WHPu({2=^A$0}Y_61y*vp7#bc>sNsSo#H zMjm6GpCbvzFmBIcq|joW7v^{`Q)9m(vuw+?2dagK$6weZA9v)da=o=Xy2AW+Zb>3i zHES>TfNk&8#XRr_zO9kmDZVAn!_%63@0`QD^pfOpO3bQrD6>v~(|Z>;YyD@X#H7Gj zCU>DhWkG?xDRKX|4C(zp%8qR6l^a|f???(YH)w=?NqYTG(_*}X{h7Hzn37!Pz(>>j z61fGc`0C!scITwSh+YNOuB2VRPZoG0jSKoXSe#r^*;z3@cE$1h0VgoFyG)TYOS`*= zqU?3{TOoVmy^i1BEw}i4GsPo(=#a7Q=0>sn>BZk(9Isn+Crd_N{_Jz?;pk|#Vntd^ z+`d-nGXQ=SjSfeYZUJ-J`|M(Q{>5Q0?{g=Mk!Kcvf}c?>*L5kI?@`56yK&zV=`BX` zF3NbQ2MzwfrWS?0w0fw}uo(VXf4ZJu@X++_Qp~Y@@DTDA>zW9!xB^23vICM_IIg z*%yB|Z<9ik?x9v|#TwxjsT14<55bSGg~YqBso>v>5El53cxKftSw<-r=O1u=R2qAU zk*@s9U4y(o&(q4~&VKD%yj-2CnTwfeC3=&q5bp<+8@ZBd9=Mv13=zzX3PIpXnmHW1#OiCZ2Kj|7K zB$PjUE0Ejq4ghES_LuJq>&_@`Cu5^ttA`)_@4h}}aOoj#2S`nl{wq?KBL*%!6oR$P z*mU)$Fne)-!A=A+BQ+*I`6Z+oQfuGqrD6XVyBO{ZNBKsM9CIuE6}GN^8X56NQ?2%e zxzzAQF5GiIF<O$5{)~pb{Ze)iWLxF2{9NsThR09d%FQw0jm*m<~Jq( zjmPl2b@@4#%9CHP?tl5t>Jpihy^zFd9oF3_~Y-qnY;&W9;--U)n-6?{OpcjV(eH~94*VnQWpGRqHdPkNzlA{n|meIZ=Iz74xFgTug2ATyMvt>2lvA zsOu5;8@Uo|W5gf&!dirExB9t`dd(vJ-g#0N=$BwhuL-ql6|NKWMCF(G0pvmb6GR%J zjaWZr#2Q0&S~9K?^xUbG#(bmBIUBh(W0njvOF4ARb(yGUse|4!l8jd_6ex2OLX2Cj zllCKe4}*%#o5sv&;>Vhkg3a|C6*od!nIxk^)f|q3Dw5Of^c>D97}SF`E~y0;H5+F& zgOVy=C^)cdE6KZj*xR6F|B9c>+1@Mfbs8N=M$H)1@M51^*fcIvV>lJJ;<8PqQPR3J zjtad{aYNGEhQ-Lw_}>EA->7R@(Xa6+j~-!kt9&=)TxnlmjW^QG%UhUj0e|z8wk+b` z26Q;S?p!@!-_&Qf(%Rvz;P7Rq8(&3gHX>i_$4zQxytLu(+67iMWg7QIvums)DF~Dc zmGQ^g^m0^7!Jd^?yw$}Tfs6lOk8<`eJ<}`6g|_FlHh#1NFx(8WZf=ueH_6+nTk}w7 zFj(&^W9@uEIX~pStk!t8j~Bc&?{rg}cFEM}Pi>F?m1p5~W%wN~ewcv;VqCuj3EiE# zt+==Fc_w@}ek#7+-+KYci;s{K8Jq@<1B&N5sN&nTGiz7 zng0~FQ=se2R7aD?=E<(Dq8<-Mo%*p3_8@Z~*3PNDzod?&=JN{2Kkm;^vdxfY<}SDl z?tDrp3>x(*ShFOXT7{sal5&m)YGJVa%<)^=i+!FZ!@_I9f|euSRy@pG=z`5I>BvTs@nf{CbA$ zE#BTPG59FWP4uj?gR;vh6r*j;V%f#j)Q&LIbi^~*1q089&vy}TIvt3jAuZf&vFrm} z$L1Y(S>I4kO+Gx}YIXXjsy<6#FA;04j{2><{RM9o3C^=cqr7qGN!#Mi`pJ#T$Rr!b$i@St= zR7IGv(q8TL4r9kxo~!+vTONcMbL7c>k4Pe;V*2X&_X9KMC5dka4CDe+hx;hX3S0F8)^FkSs%FBfr3p+HAyCvxwCu8F25Kk`EOgTKVY@B3%Lx+e=Cxo~BD(Y@oEH2T;;qJev zJZP%7RbX%R0fx@)?MdsEW%W1iJ>&>eTErB4yD)xKjC8ChH@C!IC>IL4HB)p?xm{Qh zVJmY||CF!#f{vw-^+ALANyH=N1t&AS^zRhz2uvC zJQovkqF8tjP#dg!!xi4u{O5JYhu+eq8wDiq0Ml39K3=ZeJoTf>j_UZDO z0wCgxmbl!`rwDc-kq+@Ho$y0N@EoCpRFL0ICS!9uoIhi7YdfMxDT5src-ihAwbiZb zo)Sgt(Q!4!^xfR5GF9AcY(AQE>R0f2+d0KH-KlCa$SG4=r+*lS+kr{OzMWw z$x!0QZL!D7KlG9(lTB|lSEIS!GP&ju&M9hR0)x~H6u6m1j=cPZ@voW6r3+eyXP&9! zXA^F4l)70Un-Y?F1|GWiPo(AjUf0Oz{4*Zk_sS*9sOQKkOvH}G9BoX92erL$fSdO! z<^>sA#^X<58AGeN9oApKGPDq*^k}e*;=ju%8IaZ;?cZz9v^Tjudxr^r@YJ_BTH4RD zeVEzZs>OfELLvth;VARMfWsF8j8Gu`utpj-5|vHlEn1Hq=;#-+2k2;&#juJH7RUUa zXygD2(B@eQKjbFsuClY9S3YSoaRQ0G$-Vpn2e|8830YH`!N1_N^6XCiV``7GQ~U-BHX69^_?{ZT#+{-zni*bnh*}qVPyJ$q?35UFIU0tT;&q!U0GuN4 zo&h#rtp#PvQrw>C2H0K02>(kp1Ed~p>?C)BIga}*_k=c9IrS6&X>srD7WN~5m=ASd z{IciicesLitgT|~@>%Y8%kVRxl{i0&mASvJ%%bOOtWh-4MIVNK-K($cvR+2`{eYO{|vuheW6xYgB{ z7{Vsk_Z0ua-kLdm?f~~XTnEF7$Nhn%nYO}3qmAQqxZE(s*eNN{J-m!qn&PD6zX-x)x`QsQB zG6keYuhQ7HNi*>hJ=FvQz|Q69ne{s{2Dl?_c>ciD=#?A$4&GkgVi$&#CSo!%D!3uR zDE_ph$z%+mYuof?zvGQW#`gdxO!qZ544=ku780I=0$uyzxVFn z3?#?{KkZRND_IikPR^)L>&Y`W7r%5{;JpA5K#NHjwxAVfgfGzO5luK-z3#F3sLpv` zFU5S^;pakms=0}BlnEcCLdFaq>rRy#43L_}^j{btHM?kw0aDX+PuLVEGLMUMG)`Gf)l@z^T1#BN$?)0DDFWC74m?8PMco=|MiJqMXjH!qq;+kDYRtBQN$t0{6Z^;o66-R1W0v7l06pv< zt+5GFH*&n3mf_dIQn+T{en0tk@jZPVAaU?H@7OWX`Dit`0(UsD5aE+?riY$=FsX2S z{o1E8Ps3DdaMZ`xy?tWu!xtX_0|crW`)Bqqs>mQk3U+WaLs+h<0G1}EHDGW3eMBqS zQgy-G4FBWhj`c)hjUb8!e~NU+2Y5PD?Mx1Fe3#8$6+zNWSem=QEx~P{ z5I(SK^z{3b#RX+emQ7(>|B{K%!Owof6=FeW9brA`DJ|TC_BaA@Gt<(lW$-K@Z4(v+ zzTg_0dTl{s7U8*Ou-eVv8{eA_}SPy!Mx+u=HO|krk<-oOD^`M;=I!{Jbd^YJD zE`{InJU#+s6oJe`unwWVP9Lw@DG|{jlC};v* z3p)zRcvHEj3QDOwJ04I$f{yPTs~3xY1;$R9#|K4$4(!1ta*ExHuBs~ zbvNCx+!3HI)O6-EnQ3zLC@t8Sor&{Zi&@<-HkT=`Q#UnFvx&@Uv54W=4ve=U->f^RjXEb!X>?+%BI7@v7vXTM6(GBT{kMnVe6M$vjX+@ z1AhAk$huFXX7c)jm9-lM*$UT!TszGptKkaQz>Ks0tk*>m)qHiDu=qerO_N0~HppDP zR{ZLYveIunYpaf-ngoSC6L6Egncc~4SIt;J({^5dn3HhJ#_9ulK?4+q)ZY7z(I+38 zuF(&7=s-Sdl{ylX3^*O#Sp{r8mD+2Tr32q~3_)u~FEpu<4-wn?sgup|r?h$i$OOd3 zs&G;v(+?n1%;Zh9s?pr>1G;Y4QXfa@`FMds2U>=YpvRvT3hY{qHPbO85&i2bFkM+$oM?25Qy4HX0^fVw1DQ z>oXl6JS9p7NCW;BOwgDn8O}vB&wXbL@CN1j4ze643v~JCYj%u*=?|kFW8lJ0T@pvX zpNg{$RcFJuFVR za* zxq9~ffNac8M6fNo;7Ofw1{^nhXe|b0RIjzlu3ht>N zlgzObaO^xG~BG- znvgoB>oZWUqdPa!AnxA*CpnHNzNmb42{~H^L-T<_TD-zHrnL>}uPB2n09GxiRe2}q znD#2uj8e=XDip0B#8G=}PjcGUPC=?i{_2e{nl=rP=-~r=(H$SUL4$$8*)!?q(FDJj z8UQHf%SmwS8zAQp{IUDB0j@GNP$!mGiW@w%?(jIO_pXO9*N2%o-G;BJM-7zi1zQy1n*s` zm08%@-R8plG8`p;iDz7ULEkTPkg^9sa{}pyi?67s=XFxo1zaaw2X%c1?2UQwsfI~r zkZAZ_N*z@LQtDSmbxe zQ5zfh9AoZcuv4B*XQjkJ4(=Gh8VA zK|Z{;Z`ZDxQ@eH@`|s1JPo^HbFX*=-IHXx?`InU5E)y|x`e%0vZXSXX?KIl$pZznzF6V|5eOI>LGew*|CiO_WW+ZR(u zeFJ!ENt-dEdOT;OF8we%8ZYy$^M~+ZS2;`m*xT&m3jw5W&Zii{JDJ~~`w`_Dtpa~c z*&=;PS7e){qd%P%q1eq}AySG;;kpp|@QirL;p`=+U+~~F)ho?y&oeImPX3+ph_%O) z<$CA&8+Z5E<5E|@Z9Q!}vhPO@tG(F`Z!Np;qF+18GGQ;OZ0~Zv>~ax5%Wq4ooqTyABg_Pj zx;M{V=Dx6CS@_yE6%TVUTdvpI=IyFlc4Qcwp z`lb!%XV1)?ZrnQgoL4B(F_g!e;o!p@LJuBiq8P|t?Xx|#IbMnnQ%Y6x@z`FX&uC#* zxIXv&gx`8=cAy{O?h?7H&=j^kj5sN?oq$u?Ue9jdydwPmgNj5Ad<9b~BvG?DRq4Xx zJ4VmR=m<|c^MFovN#FH_z*zE;NQcYZOMP*(jn6N!2=5=^?%`sS|H|Qh-T$+oXNXsr zGG%FZVe6uN1<@Q9_x&QCaLMgSV`PWmBzl*Tp1VHtVtZ$J;3HV6TjfzXLhH!2oVdZZ zb0MG9{mvR*@cgClPWZKL@V#?;2~oE$5aC{kqe7n=Et?X}EZBzmuO4G|xv^n6cGOP9 z;|5Dp%dpMq%)#*1<&^a1kL?&4*yETxN1yvd;w3R{Sg zswn1pE^>!;pOEIpSmUpPql6>gSLPZ#MtS?yNkmmw4!LZn&e+rQEs?&DycsWs)uJwQ z@#iBCdpyoI6*@CASlxOUH|WW)F!tS0AxyN@=h$Lk|N9}^_*Aox5d?vG=tm9t3=Iic2XZ~Edcyeku$VdXi1+B#9R5&7l($I#WQ$4=50pL?dJ z(~v$=ck9wwOF_OqDdwvUbev4}QMujpavILjjni=bT)hn23qi2hZ=pV4!eKe$_v3$s zyJwhKypP?jaVW%$|L9lZJLY(dD)(*r=MyoK7ZQrLiqcHGvfw^w+#~q$H(`~)4oWS|inWor4m@nU>*^ zVV%}l((gZ;nc#Knt*<1TD99b!@6q7Gn{F?1wud!L?fTc{TK3&3-G_|ybVR)g65*V# zf;bj7lKHE;*Y)wyPi;@|D;vKtSGGDSI4AX>H#pBkudL7^)lDJmD8uK=p`zdR{&}8s zbdgDI>5)jF!d)j_-}0r({I^B~ynJ>N@6W|$O`!WHzAamc=MuEbZ>Y>Y zvNSOfI!^3KiP&{1`5ZZM^sl1XbD}w7b8n8fjGJE=`R3V@tMdFI zp|U{oE#2T(c%6HF)@X3aVkB9jZHWUyFP0@qDGXr{e9e3%B&E88WQ~ zA9YJRjh}X{V=QzStXOEgdB*-wxu_c%s>R)@0QNxJ*p>m zYtk)NKL~$n5#q?)yw~zv@RK!xZONPfwsp}ZQxZ(_cHhR;{k-N^x+7lUagPg8pU8vc z0X@ZRQJ1X-C2xwT#8z*Hkk%-9YQ3g?Yf#bo{pNUT{BiiL_KxNw^g5=;oy2qm~AWuiqd!v?27Nl@Bctqfe- ztPdn?dQmhEZOtYt$!R2g@bi?G4fJ;kTrUkA8S-8mt83koUk_L>9bMO%F+D)}#H!VgeZ8nU0@7^9rgHh13u&p+n4ouPHoK}q%W$7d( zEO2r?aI;OQc8&CSFl~8RiBgK7tY%j&KP4(rdhw&{(}mpI`bId@z?DO5^-60m(gN|N zN{U3JzZ-e`cr|IP4#O0Hr?@mw9?NY#KD0vFu&$nCpsZz6CQ4H`)`V*N8U2tHG82iX zwuG|Qv(;F*pcLRwS>_-kMu!9a@Vk`4cFCSv-5-ZG>*o076Y|jI`~qVGs;;{74e10P zZH_kl<@>_hT|s9OY2WpwvL=q)s_`yo6D!6v&qI1BA4=_!nT;v@wzUPY&CxPAZFE;E*kMwr?4x7`SaOt*@~fg=rQm^ z3yinf>jwG!2F3ca)JH!Df@`{&#?>^BoT?i{R~Ld0naueMt>h%BJ&kI_>=A|ELJcps zz+YBvR4d{L!$$Lb%N{?L!H#WUfL(BQzGO!SEkJfKiqMgX7dn9%FpLt6!hXtCjYI#; zkOeQN%U!Uan`@8WW3K@(3+biVmkW0OZ%HRAvbjnY(v;WA9?P0YV}u%b{RVwD^x}FS zJhmLt&))Cf=|g^tv@e^tmmz`g&kXYpnOvgN!t{n$9v#^1?fP={S_(s2#m0iq;C!WW z`s2#mw#IC|C!mET2`)H?m#eHvp{kry{E`#~8CgC>e5Gez8|&H9)Jy_Dl^U+s>LbX# zM-TNSExgAgWY}3N%*<)zbR~WxS085%JwCQxMtJr}(MfTOf8_Ld2ZI88P~MlTD|Rck z($FPGSh%CU>WrK&u3$(7FZ$)`w`FG7tr=U{8?alrGWIpGYmB{QTi9%G`0?xKnVfTH z>>gYt-6eK-8#4+<6(Me~EEe_GF%vu3C|S27oL^oNd4`QRGT`M;XVdi3xPzB`gnI&p zeBX1WgBQD3CEI#bpBa8%76+U9GVpL8vu1?+Izj5KIU(l#=Yq8Chn_BI_hcaFr`3TC8oCtfuZu`cYL!13^S;V{NTBC>Q80sGlp}J=XV6E` zTv?m?=t4HVU=;BnNf8rx6I4t8-`)yD?Z`s@UM}BJl7TYtjluhnC*h_9x z>1~g_k-)0SK5)DLUWmH9YWgha`IfXEBP~O%8s%a7nX5UB=(Fwb!tmP#ZoX}6cm#$g+7A)1+REN3KZ3j4tXK?_^XrwwaO><=j}rM zJq`)G)XRgKF61PQ$P3(rdo+ETg^CF(m>2Y3xt~5lcdtqqc4mlLVdu!N8F7_fxWjb^ z`QAvC_-1F1hjM*`EzNeDb(Y`*V)gbSjs$suJH(y;qls4K$$Fa;^xn#*x{3iRD!AkK zzcdRBxUH;{l5TZ~%P;K|k-OxUPfSlnnB&Y4FSgWYwcE9`Cqu7wzC*cUYnbwy-KOtBLY>eF4M{esxfUt$0}ugv#D1AOqY(0ROjy(VAf=JU1c};5bVb8o*|w_T7&gO@9nvSK;N8 z`t10WED=1nudDYMkq>ig7C^J)qV7?E1h5^@@;fqn#!?_$;xey#`^rCL0#s4sZeOJF zv+a%49ul?Ze^mY{U>uF-0bAbeWq&D$6?_3)F%EZhRYYEyw)M==J;O8%3`6~=I_!&P zezsxxRRDS-KQkTgu~F}Pq{$xSC73G4rZ}?kxiQn7*^E)JpuzvVoi_&>G!TTMuAbSx48FsV?Kch{y?KFDjy7vq$wO`u`XHx1O2Sy(RAKYg|viw^&q zp-hyO1?6NQgQmLkwn+KBoh7NQ+iaiJ%t%HL_%?LCv5wSdpvK@SpsQa!7`vPGR(;}* z)Hj%R+2&r{^?tR8_!N?{lKNXfQ=q5UPz2bGF;K+goB)kY(> zy8(YjA3fXF(O)5v0X_NTRoa6lowbV1?y(fz5LuFIEpAoHa#eXO*Z#bS|hnp5_B?-Rh)@dkLhUdD$=;wb4O|q?sSH!zlZNNRUVBw6KP8l z4WV9qm(;=_0c}tDFWZ({ud<3!utMucX^a3?Vz7Hrr{GEiUxukx{Q>zLAJXhmxX>Ql z*wBjZo%kTo8SGcn7+8PE#`GP8Zs%SpZbN;7{7Fx>HdRn1F%g)Jj%buodBNDrTL6j( zD%%n`frhq0HGP-{ajnmx=Tm!aj{+<5z>v%%KE-Vj-~w1bpyq#W4JrYK%|8vQ-7oOLUX%SH z&&ZzKx=es;pqA`#Az*d@-`??PLfgH8p-9d%jc+P$q$&(~l zu3B}(wLFzeR41S<9$*tXodP$klQ}qW1NX`CRhHMu><-^99W#fmr*yov+2>w zh$5q?uzYE|=SoVplh7#F!?cAdd1(MpwXyG8Ln}yjc=mlp1f-de;faW^ES}+`ZfQb$ zY{zK`Sb$^5qrx!%pKVLGsUpl!eb2Lj>Un_m`LEQyN`W?l4laXb83FORqS`C`tW2$li*;NMOC2K$10MO$c*2H%6LIZ43peB2Lw9R>TX(F_MZmI( zj6&F>#JXFLV=qBsuX!0SC2a8XA&-bbYYm6cGN2SOiWzkQi=*+RgG;0FqcN@W+17@2 zRK-;EfwU8HKM=X@sOLh%i+t{=sa&T7BTIlj08IJhLM_JLc;yOmola>0_$z;vBVE6< zAv^F!DADlf<)B*!hYlLrRLx))HpsOGUjg|~&cK6sPz|EnRe8RXjo zY>;bX@KmRRnh@cGa%SX$PW=mP6esiOybaN!N3X6aq_pMIcXm5 zJ0K59We(`TnXNO0(9nmwK1`2(_%rc-6b$S_5b!{de+8Zu7)zj?fL&7s5t0{gwPwvW zRr#*Ibn4u3J}SM2U!kdl>U`?e3+j9-v3B_Ol9?lQgTXs>>$lk&{+|wZX!|mq3kMr2 zsi{JX=_-%qYM%8-cGy>xfE#$>8GX`Rj}7>|sNH8Jg}u5;o8ZZ(1N4+Z_YR{VkUVfR zy7jQZ>>gKO9>9LQ>?qW6=;P1OgPx-RrylqiJ@=?vnA(wxMji4)8vp#H709 zp}-7(SdzwH!2~uG{D2~u38jI;wG09Fr3$7~t5S@%G);ON?29ll9fjF;eR}m^KcK#7 z5IQZnQC=aP0X*17zM3k|4vc$|0ro|~fIpyH%xd4T2gFK6uxkx(hN*)gUMur{6i`Vm z#=q;xI#$6>><|Oq)?H|i3V4a~xlkY)#w;-%Oh6=aXmw;B&U;4nv|GcF5rUwKbc0;Z zpL_o?LdUxL&fH~GkOM}upPqZc?$X0BU~T23mu~l>y|#?#Af9Sd9eCWb3hDDdW(Y7u zrm&>XA)sW(K6nD91eyuTD}yt#MCk!K&r{QC^;|Tv)LDJmDj(*EzWm)Ed`}u9b~<(x zc(5UX?ERv%@Vxxt~eC?dp{onW|z#)`80jF3=5{HQJ6Mit7QukvdZ3P52Yn&pQeZ)HQnJfo)t zP*kcZ1cTux2^|ZF^1u}G;Oamk#IS!aL>nvt^Y2U}kk(KYdq*qBGquak9KnJ4wF#Y_ ze*jbpfRTK7;5ZOxT124a#Ruk3Nj`lpdN#pqmL&172VP_NFZK zFx2#r(;1-D#*KQMO@N+8C0Ri+Ua0c`xq<|NmrAzKt<{O8Q%mSi4SkM-d#7S=rtK&( z=x^qe2j+XpI7o4!E0y3EQ<{g!RTm+GRqxq(kQ3xZtaU*dE9Ll%5|p7C`%R)CG^UZE z>2jk9+7d9AVUabUG&4zGM)w>U5Ttt5p@ZTjXQ?W=!?FKVP^-0qgTKli_}MpQ?9hI> z_f&8c!Y~JX0fH)@|t&?lZ2R6A0{u{<=Veh-WeJ6@~|LJKue0A+crIHuKtdL{^|0*Ya=aon{>p{d38iAnx6ZY&V4IgMq z|2K~W!-0ie1%e4I1z4C$9*FJExIrxqZN;4q!s4hj1NVPRNF0DeW@izk13mvvnVyp> ze?2Sijbn{77~cSolDn(z!3aVfDS-fypkeVm6Bx7j^#F6;3-Qhk%3E?;CzL%-;|`V$ zb7|3H9DY&zryvQ^Nib{x9bp%d3q1NIlLWFm0E?#CzOJdenw8H{%OgaL~e@72yCE|IBx4 zke)&54(Vl{DhLIPd7!jpr-WdlWDaaGjN{AT2|j*51iG{Ag7ulBpmG{Gh@v6QJDv}H zMW4c%^LL)isXIs;Xnm4y_uGRgq`*|G>wqCk8kSHSi(2+c1F6v+v#P zy34jRfs~}}NaTe*h}&p1>LL}HO#ql}F9_~lSwRC!rWfRVK5)|Z z;+N*nS@)jbD0?cy$f%Gng{d(ORJ%7-1S`v^NR;@jzFaVQ46w$nDE-!hFslPxED*?; z>X3338PhcOe6g@AAx)k{6D`B`?;ukE7KoY}*cYKgbHR|9%HZ+hN+rWIn7aB7W*SPr z0r6R9L3NZd%R?SaML@iiRt|fF>ex$aQ(Mg}Od)lP09At|YtFAHKTRO)3h=cMC7KK< zrC{#m{>zF~VgYPA7P=FLQr+tyfrUzSkT`C@EkQcU4oQ}GSv8PJ8Z90$~=E6;jim^LF1szy!gV3Q#Os-Y`8i_ZjV) zqOn#$hCk*a&jTbVsAn_eUZG5VM;WzRW#&|LRcNK=fU>tNgIfV1y}%9(py#~VbzhEx ze$+FjmNotAr*A{z@>H_`1$YLY);zZi7^lO5aUE4pSs{9UNX9tmSkT3s( zs~~#+UKxior~|U?1 zs1ne&4zT^r?e4wZ$pfI~tuhb`ujS%|>IiTOa7@j4pz)L+I-`)2#Lk1M^1lInItguv5(oZ%l_AG}Y~SZc5XWv`H_`YJ!b3Jyx3FaUZjw?oiWNmWIm z*Y8249|C^2#NF!+-Op@$-m=dJ{1KFwTba+l>L_~_gki}xK+g6Khu#cx?V+Y~H<8FZ zA9f>YV9kc<C3KL6nN6d9t7uV z=k2sCcu-x6LATNv1V@hb8-pRLE%?3f9(k=H@Zah~{a0_3=sZ&^7GmW~-qMFTdKL3p zW&OE`iN4aI7?hF(x&kC^Qcpn(I}ac0pW{~{;jZEA#{j3zZddxYb`j}3!D~pr@z64x zu^U<-MnfaNOnoNxBC7){-?)I)z+KadQurcNloOubp89nWjPos;OS7q8+q%H)0DOSP zJup7P!6j^*w99^ls*~tsw1$rLb3v;C(UI|bv{@(hZa(>`rGuY?t^n>MJL^pl4P@YO z;j>Ut=^hdAB1m>k14)C$DG+iEj4;2IS8Vn71gUm9fLRJd+jm~F;i-}|UT|JDe}C^| zU}L%y**|tIc#;g~_6BfJ2mVxWIH<^&{Rd<;LL1${!hEqQEtPp2Pl$Q%E0dhPFo2E5 z%EJMxC)$nb$7PK{^oW(u%Wlqy*;-9Y@~3BV13|!+7s93S3&fVdlp5Ai*%3TSUOh?z zF}Z!O*6L1XUhN(u&8D)#K}(DVhtRhZ^4fir!KD8w`(bL0%lBOV2ZU{|KcCMAlkN@v z0JcNl#S@$$x{vd97L*|u7VhmG$$jUHY5kP_+LIdARoufWFpBoqX1uMWosa-NW<_q~ zXZM5HDAgRIiiK~qi2`zi8c3RMX(Ii%Gp_>SK(^%6v6Td>T|Oex1)fJm?$YhV6LE{9 zcT>xoq0=i#F&auhOyhME{CqGi0kJZG+~v;E)q?ro6ix#P5+DTi3`VT$n>4*+rZJ$QJ0PM#5;OdcqVPE^tdu}BugEM~W0r2l^&T8+n zB!=nmu~wCI!vSw3(#XGeXpHwaNL0+6ZoH|>@IO~C!A~Db)NWtJ|(EDFXaVgZP%Q52ixj``2QwRJo#|YZn0raU} z6lJe4=fjaN$O9tV{L>|N{;B&5@VmkL1j_yiQtZI2Hzf~po3OEzBSxO;N{c+S!;O2O zOM&VE^MdfG_v-1(#H8Sk&V$BNArK(AgpGLs zVFXHVLmA3;!Q4CYuNhsq2Buu93VkppcA!7)hib|#wqX8GzG9c~Z@$7J`A@zAq=Xt2 zK#D0~NlQ;V7d`XrXh;kh`Ak{pD#d6Zq3HyYv}(X8e}h!;TK^s*Bj?M+q4H9b)CF_u zgB|hu|0$ue=VQJl@D6|!UUC~dz*j*6hnv9>+9~b9pLNL5`MtG_(AyV+Mt#_Cw}9i$ z+J(S4kL*8ZrT}eH%jHSpQUE;+Oaa;mm^tw2@Ik5rHItpFtU`L$gVX;w=wu2EhARKE z=)WhA)$Y(N-)6ruM7+&Zm)YZp13@`X{G`5;9TR{ggJ7#XJe#??3#LsyJechwqCGA0 zQln}!Nx%Xr==D5M69W?3 z0CUbg;AoQA;e0*!lNO!-%Uo!(qn~W$)dBO@x-KKAB()Z3PHjTD3h!ojyb?mfLqVePaZp( zvoT+qHLnc1LM3<64rH(Q{XvNO=sdW;np7f2Wadw{RvHSg^gn(B9(nIdwCtW;yIz4e z;xp0STM7LJJaZQp2k32;QLl_$lFzd~`+pj{3a}`bw!M@f4N6IOcb9Z`*V0QP4bmNg zw19vh4bn(ANOwq=bV!RdtNe?e?|2R$|9}0%#k*Yd&V4`6JQK^#ynD|P^??w{a={~L znOD#nmVugug+-Bh3sW0`G9}QGwG*J!^W~TR!ou=uW!@vJ-}b%-wA2e(6rPKOfCOH~ zITnydZDGXdw7wj#W5FGcrNZhrjXz0i+`&oQ`Emoca$H;c5%v8g3ar!D>>$-{0#iIf zOUVsFW=m8yUs#Fm<>JH-O>#-1YG|h9RVUM4KDq ze4fk@mdC7yUsCDh8MFRD*GY1Qfldi36I($voT}?SlG#mAU~OtXiU=m{xro@wBaD`W zUc&w&W)l5UT?0zOXJg<>!x@`D?6ET`oI`v9Q+o zXRA3+mzJbwExc!sG!ziEIFPx?tWL?QoeCv)aT|5g6-IYu=Se9^rBllT(L;BCSe1o$TWPhr~%^$l@85V9}ki-A|bAJZdDGJB_T*(TClxIQ34~S75S#Gm+giX5KnE$;t3V) zf=77UoOjhV>TXu@218Ulib}Z~8w5(Yh&hU|Uhr~ST%Uj|uF;fwYD8)(KT-|Ob+Npi zH$IbHP&eeeem6>BTS719<(*}v2^Xquhgyu2RO6{#Zl8}cZ&K-DR8~#t&CWgZIvmb^ zX8UZ|x>Ug&f7;4;QZGufyft}eut>0@vzudt?Oz@57#qGX=bY@O%KiJLnCj-o*JWn#awZDO#xrkNQI|M#UfJ= zl8stQ>O!8Y_JJ3%#=dQqGOXKRfljS8HTz4kJ3&Yu$Ql_yO&Czs*%Lh|`}|M;gZ{KSGMFxhqeJsGK?4Q1Ns z!NQOSNu4Uk_OWM1Z#Un>d|54JqS{00DqH%vWSsG>&sCSnLmVHm(HTn7N z9ij<=o~9zs(o$p#x&V7ZkVRf4E}l9{DH2h3#Jv;1T`Ni_DGL%wif6R#>Kd?`gNA(L zhLxf>tz8^OQTaXSd!LvzkSlI?6PAKjjNi^t5v?(Lv-w+c3Qzo!K$ti`ljsTn7S(Mc z&OJ4fc8uLpxe2x_k`{S;j_M?{GtrGfj%$77*0cWmwdpx?QlHP{US(WAM|`DcSF-p1 zVlHVJXuT0#v$pquHKCEVhk%trb-15i-iV+7JuF-_@tKmzwCWAI8i~WuPq~R)(w~D$ zP2vzCGr3TjNBFSAE=$;Cwmg9;BvUj9Skrsv-B55PFKI3b1 z?1iqrSaq4V#Y4#;AZ&Mw&ntav>aON!Ak?7yiOlmczac}yo?Fwa>FvFKjjHbLB6mWr z{H#&ji0>E%jh%|G@~ZUndtjcIXYd;C4W_siev(v+!P#?#B4-equ^3q|L-3Rm; zV9Rx<3_6(rYMp@P-+=L1ZqZ$&Ip(1z0!{?nJpyk)H1w8TC51{lQ7)B-nOiu|k)#68yqOSHe|EQ?_A9-nN zSy9veA@z9u%)gPLgT9L)ilpaKCrBTK;{B9vzN0YAvhlOeu-8kLtN|}3iQ3%~f6R>s zWDPUU259eXjcW}f5O1WvLi@--61kO=2 zy(u;0(<-0TVYdL|mhz&al1rKb_DrJ2=QZhC6{q2V3tQG3@=)IJaK)f^Ly1gBWd3ya z-psiewbZJP3z?fTY9{_2HMEoaBm^OHBCRh)#9uQfnuhGYvO>g`PAfpj`&L0CH@Db$ zu|r`rcKn#*DHr9sIp(XZ$qvcyDX#W5tHx>&y-ueL=eN%N6ZVmMq*%UPm}$#*f7q#!xbAEZ5lU{d`vYcJ96NXV-8RRq1A_J^9qI zPY$*1#!@~-cs-`IXFn1f>Po*D*WntDj0?6oaC0?%i(k?lGU!Mw9Fg-vTJm*vVPQS} zzA38Laga7Y|G8k_e2lhvYM-Bnd7HnpL!z9ur&L~(e%%`Rq`~EeQ22P6@VhD0?GJLC zu-kEZn~Bf)*lkVCP`i|&1NI2fYyp_ctFx5zIPxHZV>}0Cv zVJ~kE*5vhKuI$M#Ke3JQH?n|uY8dfA37GF<$H8f{q4w^L@yRK<)yVPKT=av8Yt4j+ zABCyf1*h_YhJ2lKK$_;^3a||*jlpqmS;+NHYPHid`6M+-5Lg2PG(P4an~J|DD;vq0 z74<-}GddYUoO!ywftZW%(WWOdm>y2wo*Rm6;0jR5qixx`9H8-`W-RRs>>#O4z(GV+ zlC7dGOb@!cDJI$+W>g|N)A$NyB|*I|R;1;$DOLd*n?N~%MVqZyN^TSt-(?82hDvrJ z>LIBz7GrGvUk!t8qcIA$irRG?}K!uR;6Xam_4Z)#O(Sed8N zy;x*jw~2=2AeZ2H4XIrVvf6kisJpy z=~g-mpFP3ghi1SwBg~jyu(;TnZJjd}>P`bMwmR`HUjT?_H;FiN1T*#d8`c+YG|oky zb8I(hog3&n$2{?%z=v)00*P}Wgp)5wI_>X6qjz*R~8jSd-PmE8RqxQirjXriUY>GVQp1?iKKum6X z1$2Fry*SD>nn0H3>~)q)Z)&P5yG9$3)ns>5HiFLM0ZANy4!dyh0br%~m?j(KacbUy_}i-w!6IwLlHSc!vTm_8%%K~*;mDPpkcC}O2V65UEl948US#Z@pH z3R;6cN#D(qBT1rmd2EX%_71ptW0&C2wEI^0p-j*6pXiDxs$N9wKzLe z#>GImmv3E ztqD^vQ2GEE?Ga+4>2460_c+lMon}RI3}m3fgI@s6TW2djhjg@KTMFuyXDz5>Pw+hJ zCmYOThAVYQjs2#z$q|rm9Zxm8xtB0z#wavbilhF7QtXYkp;=F6KRV_s!$mlRC+1tW zRUCl`;B(RF*s%4 z%z=_$kJy64o~CuG1;^#q0(vktL_ls#G7=(@#9bx1XRI;GvZO`1?Kz9GR2`5tu8Jb2 zFkqjZb~?WZJ-eHXJ50VSXWYnpN`ZPBW8-e=JnJ~JcPYAv87~J|;N!#NuLKlsSuJ6pwofGb$GVj9I&wHEm29b;xka*7;^Y)lH`3FVoGrC4ENWhN>jd)1{4j! z0(PGz=8i8$rlvIm7^y%`^t$^JzH53D${eg(Iq@*KS-aQrsLxteus9-EOf09SKg}%_ z@G+%L#ImaA!8bASnp-0@j4Cu5rV^ zrKlX2)z4J%HEybd-lLyn5Q%Y$rFY#0;2N5ycw^#_ss^3^74Li@)GpiNrF=tU1*4qMR8V|1tbEy^;Oi1|;&ZGN%Zo`2D^(c$#5TfBSO=ro;i(UkFeXPXskyyqZFj3OJ=~3~Tz?Og{3vY&F zfJC73W>VwIlzU>}KRI#?m#)-#qS?wnwsQiD88onoqRQVRmEP>s zKlAeyyUT4Ag^UBd3vVR}T&dHuuD57$0?8`g`C9G?A#J(3bp894orWO=IB5_qk4w1G z@X9O7foZc;BZL_ZX)o|q^0B!5&3JN5DZSW&dj6K%Vv38SP7v$vD-j#alaW>dhU61-L%|r^EGDCF7lOcotwtk!TIf%wx7ot zOQ;OruL=3GQ6Wbv^pb3Balc2OO%(HK%zi$Du%Lx+=$t1ql=)szMG2p17X}VvcLL}9 z>bCCi%hlx;{859G5z6apWO1J|zl(*1ZNEmZi>m^mALj>le)TH^XT%ZL%iyE(qxU|` zSbe@sGu-4QY7(KhD_S!`;Ge@W8B5^(wng6(7KtC1>%1?2cz^$H@v`kQd?BbjKm{l3 z%6|El(!a@L-G?s9KIF=$Nz`|Cjjo-dsbX8F;|O+v0eUG-v7M^m$tD8$(TCdIkp4v*Oi8no%4@Puebc(FExLI z*CM!a#aNW+E8M$yelkB%0##S|SiR}zl5@GB8O)+0iKX8~Pu=sYV;BfKbOJDtX~qxy zjBTOg`jIS-rkQ#Z#69p$aWV;fdEo zp-x4N8wtXM%uG61uLPE`G3BhW>~UFO@Fe?K3pK#TG)MEIUt~(x&|u0dR89CEHLOt* zLGB9oDgC-@u^>7k3%M(nvVhH|WsT*BI{Flf*$LsfiFm-eeGH z0J20*(*0yfXdonY&eQxBx{8){VNn$w+W=kcue5&^Dnv|#Lb6fvt4tLksRg7=Sk}-1 zLJIvI!z{dnvQ!^1K*Qf8TEmD&z(2N1wfM4AdBiOwEm60dIFzl99#r<*fc^;Zw&6l~ zew1n3Kn0Bx^>$^)KV6iN5VF$ok58B)S#7K+K962(Z<9~3%wX+_nw|;O1B!gK2|0*P z!#YIyvWe5@yYHt-)8q+s+?hY-!$9twXV(hhS^G$w7J6* zO#O3!Y7 zC2ridKchK*oqEI{2WOySC~McE6#*fgH<`!S%qV5xaiBccTd~_# zt5?@Nt({wCNX&K`5%oC4yJpSyveR?JNzl7~$|7vaZx>Z5+AC=K!}I|%f6d6(eyanO za@G%=&vI6+UM}LI=^faMN^H`5Shph@TWK(~`nvz<;NV~)OsIHk=zT_GcHeH%IMpzO4J^TvG?W0po0d0|MywlJ^JA{ zpNc<^J?Hw6Zs%roaM7vh2BxDH3AyO>HGB81)l{$LX9YJdignAk%iL+a8m}6u9F;0A z0iQ{N3=a69!yT1m)1c@|?ggLv1OzChPjP&cmz7&=ay@59(X^|vjIy)q2Ri7cAL_Uv zt7#*_Ke7c!v?~QoH7DP0KUb?CHIw`Z7vXiHfUMIywE@K6OJ())aLUKSS0Y&E3*SH8 z4F5Odww?2txlnqDm))C1MODv_0 zo)u~?mrNVA42R_FAmx0q<_JAA_F-K`62RS9?eW*Nq5j7A`1IrLoH165hmKI2zrY}N zI$+_akXH7{+mV=**qk=NodUwciaL)VE2xG}X131vR$0Ax+?sD8_m&~6`AC14VY(|> z8b2!A#e&{*6nKQb)vE9k3uDfOnQUJH+C?BwpvBwM9gQVX_fECgp1D-Lf~R z34e*ifHgn5InY%lP}siDtySgN+g*DpP`adL3dTd-p#!#Q_r&BTIA}{CVV;R1PTyN~ zj4h0x_Knr}S9N9K41P|D0$w3g@*u7jJ7v3p6Um+oB4q`E?k{w&yqX?4@`N;B+1nTG zjjRZ!v55(@@&!gt7SL{~pV~ z)QKJnC%#Bv88Z|BAcg<{Jo~+9{kzydw?}?Ow`FSBx|0PNuySK`gzjxfQ1D_tny)2N zq+IU;K&9eqX#ziZ)4!kuDzV9Of4d?l%oQg@L4I^@=!4_q-#u;FFP>I`;9@+WITPPP zm_f|NAX?y3$d@Bhi4lA7{ibON$z@<%X|@_hGC?8-6y@AWzOBtMMjts0NOhw#_1dJV z<|I~kROLM8kYTf9cCG-^S-8+pR)skYX0P*%_1|uDX-r`sgCZ`7s+$~PZ#m9`QT%gq z2c}mj_?byF+-h0F@!F!YOklfhy^~#yhUUZip-tI{&9QK+PK=WRSmlV#F>tGnjX$?1 zPljPsoj+ch9nTd|O39e@`dL!?Nm7T#Fg=ggx4#~EZf$-Lm9q`_8NnLjeT~R03foH3 zF`8A!x^s#XUdNZk*@o+TcDlX%Z*7ly4;s2SNSF;Fo&8P(N>9w*&c)2m#ZcYD!OU6z zZVzfWNnfesZVyTUj3#G~LZ3=BMHkS_cZ#@fpWNpIowX|UhX9N-B8v~%*ldH;0! zg~zp>+%!HzB}Z~lXV=cFnhq)?VYwVk!SLDMoxE`~D9@}!>8Q|Gj8Jo#ejelajEqLY z6VJ%8z3hp3r0~S3SU9jbN+Y8NgA3HSS2gFxA97ry#hZb=RJ2f z7~4z?4|=L|T;IrQAtA5*j!M;?ZPU5bjV6kdG`D|^DDuf`t=vzS2BNJe{6>Nol2i5K zA}miw+9D!3>e-xjA|(_>S634RQ_TewDU^E{au7xP>Pmz;86*O~KL+y%XlEwE_&iaNvfK0pyZ=H9_U)PF z`-V87*OPg1ZVHGEW#PRF3IcXEYvYCCz4{6Qjhx@=Z|%_xz(nV5kR3!Q=%>GwSbm?P zb-xWE%?N-3kU*}t$EXjr=x>7meR{hi007V-zm$ile@}M*HhO=$yF>goD)Tqy*YNzm zjNOg@-|5cST>{ygDm&Rb+)b|kwl{v(3#$U@sLx=2dv;g&w>|2A!i*gp?)vO~bZ<>V zsU`$%44IrU?x2wL8=Viy{oAOiy_4BP@bm477+Od{3<&&gl-#A?aC(S4f8egpF7_|} z5Ih`V2;#4FSLqPgUxGUS|0p>gq24L*{AbSmca-kWnspqeH3;G{5yMNdHzMkD5i`V~z{ZY5O@ACb< z_&)@G)4%NgGi?8t)2MgIU+J!e^MAMS9r&+eV+wf`5+6| zLoApYKK^7<000qW`ucZ|;huSrh5I3vcOu2OU&$eH`7d8$h@c+oF+2~kJcTKRI&nb+ iC|Ezg=S!LBgDkwiS>W#elLp{Je!3xleLA@tHU9&_WG3bS literal 0 HcmV?d00001 diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..19529dd --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/nls-sample-16k.wav b/nls-sample-16k.wav new file mode 100644 index 0000000000000000000000000000000000000000..b6ffc373bde1b7350edd5aa77de13ca5e36997d2 GIT binary patch literal 106826 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

使用凭据初始化账号Client

+ * @return Client + * + * @throws Exception + */ + public static com.aliyun.dysmsapi20170525.Client createClient() throws Exception { + // 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/378657.html。 + com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client(); + com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() + .setCredential(credential); + // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi + config.endpoint = "dysmsapi.aliyuncs.com"; + return new com.aliyun.dysmsapi20170525.Client(config); + } + + public static void main(String[] args_) throws Exception { + + com.aliyun.dysmsapi20170525.Client client = Sample.createClient(); + com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest() + .setSignName("西安精彩数据服务社") + .setTemplateCode("SMS_489840017") + .setPhoneNumbers("13868246742") + .setTemplateParam("{\"code\":\"1234\"}"); + com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions(); + try { + // 复制代码运行请自行打印 API 的返回值 + client.sendSmsWithOptions(sendSmsRequest, runtime); + } catch (TeaException error) { + // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。 + // 错误 message + System.out.println(error.getMessage()); + // 诊断地址 + System.out.println(error.getData().get("Recommend")); + com.aliyun.teautil.Common.assertAsString(error.message); + } catch (Exception _error) { + TeaException error = new TeaException(_error.getMessage(), _error); + // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。 + // 错误 message + System.out.println(error.getMessage()); + // 诊断地址 + System.out.println(error.getData().get("Recommend")); + com.aliyun.teautil.Common.assertAsString(error.message); + } + } +} diff --git a/src/main/java/com/xy/xyaicpzs/XyAiCpzsApplication.java b/src/main/java/com/xy/xyaicpzs/XyAiCpzsApplication.java new file mode 100644 index 0000000..026f9c2 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/XyAiCpzsApplication.java @@ -0,0 +1,17 @@ +package com.xy.xyaicpzs; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@MapperScan("com.xy.xyaicpzs.mapper") +public class XyAiCpzsApplication { + + public static void main(String[] args) { + SpringApplication.run(XyAiCpzsApplication.class, args); + } + +} + + diff --git a/src/main/java/com/xy/xyaicpzs/common/DeleteRequest.java b/src/main/java/com/xy/xyaicpzs/common/DeleteRequest.java new file mode 100644 index 0000000..22ea8b0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/DeleteRequest.java @@ -0,0 +1,19 @@ +package com.xy.xyaicpzs.common; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 删除请求 + */ +@Data +public class DeleteRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/ErrorCode.java b/src/main/java/com/xy/xyaicpzs/common/ErrorCode.java new file mode 100644 index 0000000..a6ee793 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/ErrorCode.java @@ -0,0 +1,39 @@ +package com.xy.xyaicpzs.common; + +/** + * 自定义错误码 + */ +public enum ErrorCode { + + SUCCESS(0, "ok"), + PARAMS_ERROR(40000, "请求参数错误"), + NOT_LOGIN_ERROR(40100, "您还未登录,请登录后操作"), + NO_AUTH_ERROR(40101, "无权限"), + NOT_FOUND_ERROR(40400, "请求数据不存在"), + FORBIDDEN_ERROR(40300, "禁止访问"), + SYSTEM_ERROR(50000, "系统内部异常"), + OPERATION_ERROR(50001, "操作失败"); + + /** + * 状态码 + */ + private final int code; + + /** + * 信息 + */ + private final String message; + + ErrorCode(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/PageRequest.java b/src/main/java/com/xy/xyaicpzs/common/PageRequest.java new file mode 100644 index 0000000..41b592f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/PageRequest.java @@ -0,0 +1,20 @@ +package com.xy.xyaicpzs.common; + +import lombok.Data; + +/** + * 分页请求 + */ +@Data +public class PageRequest { + + /** + * 当前页号 + */ + private long current = 1; + + /** + * 页面大小 + */ + private long pageSize = 10; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/ResultUtils.java b/src/main/java/com/xy/xyaicpzs/common/ResultUtils.java new file mode 100644 index 0000000..5c8e1a7 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/ResultUtils.java @@ -0,0 +1,51 @@ +package com.xy.xyaicpzs.common; + +import com.xy.xyaicpzs.common.response.ApiResponse; + +/** + * 返回工具类 + */ +public class ResultUtils { + + /** + * 成功 + * + * @param data + * @param + * @return + */ + public static ApiResponse success(T data) { + return ApiResponse.success(data); + } + + /** + * 失败 + * + * @param errorCode + * @return + */ + public static ApiResponse error(ErrorCode errorCode) { + return ApiResponse.error(errorCode.getMessage()); + } + + /** + * 失败 + * + * @param code + * @param message + * @return + */ + public static ApiResponse error(int code, String message) { + return ApiResponse.error(message); + } + + /** + * 失败 + * + * @param errorCode + * @return + */ + public static ApiResponse error(ErrorCode errorCode, String message) { + return ApiResponse.error(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/BallAnalysisRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/BallAnalysisRequest.java new file mode 100644 index 0000000..ab9dbac --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/BallAnalysisRequest.java @@ -0,0 +1,24 @@ +package com.xy.xyaicpzs.common.requset; + +import lombok.Data; + +import java.util.List; + +/** + * 球号分析请求对象 + */ +@Data +public class BallAnalysisRequest { + private String level; + private List redBalls; + private Integer blueBall; + + @Override + public String toString() { + return "BallAnalysisRequest{" + + "level='" + level + '\'' + + ", redBalls=" + redBalls + + ", blueBall=" + blueBall + + '}'; + } +} diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/BlueBallAnalysisRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/BlueBallAnalysisRequest.java new file mode 100644 index 0000000..f07a61e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/BlueBallAnalysisRequest.java @@ -0,0 +1,29 @@ +package com.xy.xyaicpzs.common.requset; + +import lombok.Data; + +import java.util.List; + +/** + * 蓝球分析请求对象 + */ +@Data +public class BlueBallAnalysisRequest { + private String level; + private List predictedRedBalls; + private List predictedBlueBalls; + private List lastRedBalls; + private Integer lastBlueBall; + + + @Override + public String toString() { + return "BlueBallAnalysisRequest{" + + "level='" + level + '\'' + + ", predictedRedBalls=" + predictedRedBalls + + ", predictedBlueBalls=" + predictedBlueBalls + + ", lastRedBalls=" + lastRedBalls + + ", lastBlueBall=" + lastBlueBall + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/FallowBallAnalysisRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/FallowBallAnalysisRequest.java new file mode 100644 index 0000000..8a1207d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/FallowBallAnalysisRequest.java @@ -0,0 +1,26 @@ +package com.xy.xyaicpzs.common.requset; + +import lombok.Data; + +import java.util.List; + +/** + * 跟随球号分析请求对象 + */ +@Data +public class FallowBallAnalysisRequest { + private String level; + private List firstThreeRedBalls; + private List lastSixRedBalls; + private Integer blueBall; + + @Override + public String toString() { + return "FallowBallAnalysisRequest{" + + "level='" + level + '\'' + + ", firstThreeRedBalls=" + firstThreeRedBalls + + ", lastSixRedBalls=" + lastSixRedBalls + + ", blueBall=" + blueBall + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/GenerateVipCodesRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/GenerateVipCodesRequest.java new file mode 100644 index 0000000..6b5c722 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/GenerateVipCodesRequest.java @@ -0,0 +1,20 @@ +package com.xy.xyaicpzs.common.requset; + +import lombok.Data; + +/** + * 生成会员码请求 + */ +@Data +public class GenerateVipCodesRequest { + + /** + * 生成数量 + */ + private Integer numCodes; + + /** + * 会员有效月数 + */ + private Integer vipExpireTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/PredictRecordQueryRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/PredictRecordQueryRequest.java new file mode 100644 index 0000000..8bea26f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/PredictRecordQueryRequest.java @@ -0,0 +1,23 @@ +package com.xy.xyaicpzs.common.requset; + +import com.xy.xyaicpzs.common.PageRequest; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 预测记录查询请求 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PredictRecordQueryRequest extends PageRequest { + + /** + * 用户ID + */ + private Long userId; + + /** + * 预测状态(待开奖/未中奖/已中奖) + */ + private String predictStatus; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeActivateRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeActivateRequest.java new file mode 100644 index 0000000..be191ee --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeActivateRequest.java @@ -0,0 +1,20 @@ +package com.xy.xyaicpzs.common.requset; + +import lombok.Data; + +/** + * 会员码激活请求 + */ +@Data +public class VipCodeActivateRequest { + + /** + * 用户ID + */ + private Long userId; + + /** + * 会员码 + */ + private String code; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeQueryRequest.java b/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeQueryRequest.java new file mode 100644 index 0000000..ad106f6 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/requset/VipCodeQueryRequest.java @@ -0,0 +1,74 @@ +package com.xy.xyaicpzs.common.requset; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +/** + * 会员码查询请求 + */ +@Data +@Schema(description = "会员码查询请求") +public class VipCodeQueryRequest { + + /** + * 当前页码 + */ + @Schema(description = "当前页码") + private long current = 1; + + /** + * 页面大小 + */ + @Schema(description = "页面大小") + private long pageSize = 10; + + /** + * 会员码 + */ + @Schema(description = "会员码") + private String code; + + /** + * 会员有效月数(1/12) + */ + @Schema(description = "会员有效月数") + private Integer vipExpireTime; + + /** + * 是否使用:0-未使用,1-已使用 + */ + @Schema(description = "是否使用:0-未使用,1-已使用") + private Integer isUse; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createdUserId; + + /** + * 创建人名称 + */ + @Schema(description = "创建人名称") + private String createdUserName; + + /** + * 使用人ID + */ + @Schema(description = "使用人ID") + private Long usedUserId; + + /** + * 开始时间 + */ + @Schema(description = "开始时间") + private Date startTime; + + /** + * 结束时间 + */ + @Schema(description = "结束时间") + private Date endTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/response/ApiResponse.java b/src/main/java/com/xy/xyaicpzs/common/response/ApiResponse.java new file mode 100644 index 0000000..b09c6bf --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/response/ApiResponse.java @@ -0,0 +1,29 @@ +package com.xy.xyaicpzs.common.response; + +import lombok.Data; + +/** + * API响应对象 + */ +@Data +public class ApiResponse { + private boolean success; + private String message; + private T data; + + public static ApiResponse success(T data) { + ApiResponse response = new ApiResponse<>(); + response.success = true; + response.message = "操作成功"; + response.data = data; + return response; + } + + public static ApiResponse error(String message) { + ApiResponse response = new ApiResponse<>(); + response.success = false; + response.message = message; + return response; + } + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/common/response/PageResponse.java b/src/main/java/com/xy/xyaicpzs/common/response/PageResponse.java new file mode 100644 index 0000000..085d45d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/common/response/PageResponse.java @@ -0,0 +1,67 @@ +package com.xy.xyaicpzs.common.response; + +import lombok.Data; + +import java.util.List; + +/** + * 分页响应对象 + * @param 数据类型 + */ +@Data +public class PageResponse { + + /** + * 数据列表 + */ + private List records; + + /** + * 总记录数 + */ + private Long total; + + /** + * 当前页码 + */ + private Integer page; + + /** + * 每页大小 + */ + private Integer size; + + /** + * 总页数 + */ + private Integer totalPages; + + /** + * 是否有下一页 + */ + private Boolean hasNext; + + /** + * 是否有上一页 + */ + private Boolean hasPrevious; + + public PageResponse() {} + + public PageResponse(List records, Long total, Integer page, Integer size) { + this.records = records; + this.total = total; + this.page = page; + this.size = size; + this.totalPages = (int) Math.ceil((double) total / size); + this.hasNext = page < totalPages; + this.hasPrevious = page > 1; + } + + /** + * 创建分页响应对象 + */ + public static PageResponse of(List records, Long total, Integer page, Integer size) { + return new PageResponse<>(records, total, page, size); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/CorsConfig.java b/src/main/java/com/xy/xyaicpzs/config/CorsConfig.java new file mode 100644 index 0000000..20a8cd4 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/CorsConfig.java @@ -0,0 +1,27 @@ +package com.xy.xyaicpzs.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** +// * 全局跨域配置 + */ +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + // 覆盖所有请求 + registry.addMapping("/**") + // 允许发送 Cookie + .allowCredentials(true) + // 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突) + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*") + // 确保SSE相关头信息能被客户端访问 + .exposedHeaders("*", HttpHeaders.CACHE_CONTROL, HttpHeaders.CONTENT_TYPE); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/MyBatisPlusConfig.java b/src/main/java/com/xy/xyaicpzs/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..9cec705 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/MyBatisPlusConfig.java @@ -0,0 +1,31 @@ +package com.xy.xyaicpzs.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * MyBatis Plus 配置 + * + * @author lihanqi + */ +@Configuration +@MapperScan("com.xy.xyaicpzs.mapper") +public class MyBatisPlusConfig { + + /** + * 拦截器配置 + * + * @return + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/ObjectMapperConfig.java b/src/main/java/com/xy/xyaicpzs/config/ObjectMapperConfig.java new file mode 100644 index 0000000..a4242f3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/ObjectMapperConfig.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * ObjectMapper配置类 + */ +@Configuration +public class ObjectMapperConfig { + + /** + * 配置ObjectMapper Bean + * + * @return ObjectMapper实例 + */ + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/RedisConfig.java b/src/main/java/com/xy/xyaicpzs/config/RedisConfig.java new file mode 100644 index 0000000..c2ded59 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/RedisConfig.java @@ -0,0 +1,38 @@ +package com.xy.xyaicpzs.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis配置类 + */ +@Configuration +public class RedisConfig { + + /** + * 自定义RedisTemplate + */ + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + + // 设置连接工厂 + redisTemplate.setConnectionFactory(connectionFactory); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + + // 使用GenericJackson2JsonRedisSerializer来序列化和反序列化redis的value值 + GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer(); + redisTemplate.setValueSerializer(jsonSerializer); + redisTemplate.setHashValueSerializer(jsonSerializer); + + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/RestTemplateConfig.java b/src/main/java/com/xy/xyaicpzs/config/RestTemplateConfig.java new file mode 100644 index 0000000..b1a489f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/RestTemplateConfig.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplate配置类 + */ +@Configuration +public class RestTemplateConfig { + + /** + * 配置RestTemplate Bean + * + * @return RestTemplate实例 + */ + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/config/ScheduleConfig.java b/src/main/java/com/xy/xyaicpzs/config/ScheduleConfig.java new file mode 100644 index 0000000..a2a8244 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/config/ScheduleConfig.java @@ -0,0 +1,12 @@ +package com.xy.xyaicpzs.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * 定时任务配置类 + */ +@Configuration +@EnableScheduling +public class ScheduleConfig { +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/constant/UserConstant.java b/src/main/java/com/xy/xyaicpzs/constant/UserConstant.java new file mode 100644 index 0000000..9db1298 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/constant/UserConstant.java @@ -0,0 +1,36 @@ +package com.xy.xyaicpzs.constant; + +/** + * 用户常量 + */ +public interface UserConstant { + + /** + * 用户登录态键 + */ + String USER_LOGIN_STATE = "userLoginState"; + + /** + * 系统用户 id(虚拟用户) + */ + long SYSTEM_USER_ID = 0; + + // region 权限 + + /** + * 默认权限 + */ + String DEFAULT_ROLE = "user"; + + /** + * 管理员权限 + */ + String ADMIN_ROLE = "admin"; + + /** + * 超级管理员权限 + */ + String SUPER_ADMIN_ROLE = "superAdmin"; + + // endregion +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/BallAnalysisController.java b/src/main/java/com/xy/xyaicpzs/controller/BallAnalysisController.java new file mode 100644 index 0000000..996bbe1 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/BallAnalysisController.java @@ -0,0 +1,1805 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.common.response.PageResponse; +import com.xy.xyaicpzs.domain.entity.LotteryDraws; +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.domain.entity.HistoryAll; +import com.xy.xyaicpzs.domain.entity.History100; +import com.xy.xyaicpzs.domain.entity.HistoryTop; +import com.xy.xyaicpzs.domain.entity.HistoryTop100; +import com.xy.xyaicpzs.domain.entity.BlueHistoryAll; +import com.xy.xyaicpzs.domain.entity.BlueHistory100; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop100; +import com.xy.xyaicpzs.domain.entity.T7; +import com.xy.xyaicpzs.domain.entity.T8; +import com.xy.xyaicpzs.domain.entity.T11; +import com.xy.xyaicpzs.domain.entity.T3; +import com.xy.xyaicpzs.domain.entity.T4; +import com.xy.xyaicpzs.domain.entity.T5; +import com.xy.xyaicpzs.domain.entity.T6; +import com.xy.xyaicpzs.exception.BusinessException; +import com.xy.xyaicpzs.service.BallAnalysisService; +import com.xy.xyaicpzs.service.LotteryDrawsService; +import com.xy.xyaicpzs.service.PredictRecordService; +import com.xy.xyaicpzs.service.UserService; +import com.xy.xyaicpzs.service.HistoryAllService; +import com.xy.xyaicpzs.service.History100Service; +import com.xy.xyaicpzs.service.HistoryTopService; +import com.xy.xyaicpzs.service.HistoryTop100Service; +import com.xy.xyaicpzs.service.BlueHistoryAllService; +import com.xy.xyaicpzs.service.BlueHistory100Service; +import com.xy.xyaicpzs.service.BlueHistoryTopService; +import com.xy.xyaicpzs.service.BlueHistoryTop100Service; +import com.xy.xyaicpzs.service.T7Service; +import com.xy.xyaicpzs.service.T8Service; +import com.xy.xyaicpzs.service.T11Service; +import com.xy.xyaicpzs.service.T3Service; +import com.xy.xyaicpzs.service.T4Service; +import com.xy.xyaicpzs.service.T5Service; +import com.xy.xyaicpzs.service.T6Service; +import com.xy.xyaicpzs.domain.vo.BallHitRateVO; +import com.xy.xyaicpzs.domain.vo.PrizeEstimateVO; +import com.xy.xyaicpzs.domain.vo.BallCombinationAnalysisVO; +import com.xy.xyaicpzs.domain.vo.BallPersistenceAnalysisVO; +import com.xy.xyaicpzs.domain.vo.RedBallHitRateVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Comparator; + +/** + * 球号分析控制器 + * 提供球号分析算法的API接口 + */ +@Slf4j +@RestController +@RequestMapping("/ball-analysis") +@Tag(name = "球号分析", description = "球号分析算法API") +public class BallAnalysisController { + + @Autowired + private BallAnalysisService ballAnalysisService; + + @Autowired + private LotteryDrawsService lotteryDrawsService; + + @Autowired + private PredictRecordService predictRecordService; + + @Autowired + private UserService userService; + + @Autowired + private HistoryAllService historyAllService; + + @Autowired + private History100Service history100Service; + + @Autowired + private HistoryTopService historyTopService; + + @Autowired + private HistoryTop100Service historyTop100Service; + + @Autowired + private BlueHistoryAllService blueHistoryAllService; + + @Autowired + private BlueHistory100Service blueHistory100Service; + + @Autowired + private BlueHistoryTopService blueHistoryTopService; + + @Autowired + private BlueHistoryTop100Service blueHistoryTop100Service; + + @Autowired + private T7Service t7Service; + + @Autowired + private T8Service t8Service; + + @Autowired + private T11Service t11Service; + + @Autowired + private T3Service t3Service; + + @Autowired + private T4Service t4Service; + + @Autowired + private T5Service t5Service; + + @Autowired + private T6Service t6Service; + + /** + * 获取近期开奖信息 + * @param limit 获取条数,可选参数,默认15条 + * @return 近期开奖信息列表 + */ + @GetMapping("/recent-draws") + @Operation(summary = "获取近期开奖信息", description = "获取最近的开奖信息,默认返回10条,按开奖期号倒序排列") + public ApiResponse> getRecentDraws( + @Parameter(description = "获取条数,默认10条", required = false) + @RequestParam(required = false, defaultValue = "10") Integer limit, HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到获取近期开奖信息请求:条数={}", limit); + + // 调用服务获取近期开奖信息 + List result = lotteryDrawsService.getRecentDraws(limit); + + log.info("获取近期开奖信息完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取近期开奖信息失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取近期开奖信息失败:" + e.getMessage()); + } + } + + /** + * 获取最新100条开奖信息 + * @return 最新100条开奖信息列表 + */ + @GetMapping("/recent-100-draws") + @Operation(summary = "获取最新100条开奖信息", description = "获取lottery_draws表中最新的100条开奖信息,按开奖期号倒序排列") + public ApiResponse> getRecent100Draws(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取最新100条开奖信息请求"); + + // 调用服务获取最新100条开奖信息 + List result = lotteryDrawsService.getRecentDraws(100); + + log.info("获取最新100条开奖信息完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取最新100条开奖信息失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取最新100条开奖信息失败:" + e.getMessage()); + } + } + + /** + * 根据日期范围查询开奖信息 + * @param startDate 开始日期(可选,格式:yyyy-MM-dd) + * @param endDate 结束日期(可选,格式:yyyy-MM-dd) + * @return 开奖信息列表 + */ + @GetMapping("/query-draws") + @Operation(summary = "按日期范围查询开奖信息", description = "根据日期范围查询开奖信息,支持单边日期查询") + public ApiResponse> queryDraws( + @Parameter(description = "开始日期,格式:yyyy-MM-dd,例如:2025-01-01", required = false) + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + + @Parameter(description = "结束日期,格式:yyyy-MM-dd,例如:2025-01-31", required = false) + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate, + HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + + try { + log.info("接收到按日期范围查询开奖信息请求:开始日期={},结束日期={}", startDate, endDate); + + // 日期范围验证 + if (startDate != null && endDate != null && startDate.after(endDate)) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "开始日期不能晚于结束日期"); + } + + // 调用服务按日期范围查询开奖信息 + List result = lotteryDrawsService.getByDateRange(startDate, endDate); + + log.info("按日期范围查询开奖信息完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("按日期范围查询开奖信息失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage()); + } + } + + /** + * 根据期号精准查询单条开奖信息 + * @param drawId 开奖期号 + * @return 开奖信息 + */ + @GetMapping("/draw/{drawId}") + @Operation(summary = "根据期号查询开奖信息", description = "根据期号精准查询单条开奖信息") + public ApiResponse getDrawById( + @Parameter(description = "开奖期号,例如:2025056", required = true) + @PathVariable Long drawId, + HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + + try { + log.info("接收到根据期号查询开奖信息请求:期号={}", drawId); + + // 调用服务查询开奖信息 + LotteryDraws result = lotteryDrawsService.getByDrawId(drawId); + + if (result == null) { + log.warn("未找到期号为{}的开奖信息", drawId); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到期号为" + drawId + "的开奖信息"); + } + + log.info("根据期号查询开奖信息完成:{}", result.getDrawId()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("根据期号查询开奖信息失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖信息失败:" + e.getMessage()); + } + } + + /** + * 根据开奖期号查询开奖球号 + * @param drawId 开奖期号 + * @return 7个中奖球号 + */ + @GetMapping("/draw/{drawId}/numbers") + @Operation(summary = "根据开奖期号查询开奖球号", description = "根据开奖期号查询7个中奖球号(6个红球+1个蓝球)") + public ApiResponse> getDrawNumbersById( + @Parameter(description = "开奖期号,例如:2025056", required = true) + @PathVariable Long drawId, + HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + + try { + log.info("接收到根据期号查询开奖球号请求:期号={}", drawId); + + // 调用服务查询开奖信息 + LotteryDraws result = lotteryDrawsService.getByDrawId(drawId); + + if (result == null) { + log.warn("未找到期号为{}的开奖信息", drawId); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "未找到期号为" + drawId + "的开奖信息"); + } + + List winningNumbers = new java.util.ArrayList<>(); + winningNumbers.add(result.getRedBall1()); + winningNumbers.add(result.getRedBall2()); + winningNumbers.add(result.getRedBall3()); + winningNumbers.add(result.getRedBall4()); + winningNumbers.add(result.getRedBall5()); + winningNumbers.add(result.getRedBall6()); + winningNumbers.add(result.getBlueBall()); + + log.info("根据期号查询开奖球号完成:{},球号:{}", drawId, winningNumbers); + return ResultUtils.success(winningNumbers); + + } catch (Exception e) { + log.error("根据期号查询开奖球号失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询开奖球号失败:" + e.getMessage()); + } + } + + /** + * 创建预测记录 + * @param userId 用户ID + * @param drawId 开奖期号 + * @param drawDate 开奖日期 + * @param redBalls 6个红球号码,用逗号分隔 + * @param blueBall 蓝球号码 + * @return 创建的预测记录 + */ + @PostMapping("/create-predict") + @Operation(summary = "创建预测记录", description = "向predict_record表插入一条预测记录数据") + public ApiResponse createPredictRecord( + @Parameter(description = "用户ID,例如:1001", required = true) + @RequestParam Long userId, + + @Parameter(description = "开奖期号,例如:2025056", required = true) + @RequestParam Long drawId, + + @Parameter(description = "开奖日期,格式:yyyy-MM-dd", required = false) + @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date drawDate, + + @Parameter(description = "6个红球号码,用逗号分隔,例如:1,5,12,18,25,33", required = true) + @RequestParam String redBalls, + + @Parameter(description = "蓝球号码,例如:8", required = true) + @RequestParam Integer blueBall) { + + try { + log.info("接收到创建预测记录请求:用户ID={},期号={},开奖日期={},红球={},蓝球={}", + userId, drawId, drawDate, redBalls, blueBall); + + // 解析红球号码 + List redBallList = parseRedBalls(redBalls, 6, "红球"); + + // 调用服务创建预测记录 + PredictRecord result = predictRecordService.createPredictRecord(userId, drawId, drawDate, redBallList, blueBall); + + log.info("创建预测记录完成,用户ID:{},记录ID:{}", userId, result.getId()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("创建预测记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "创建预测记录失败:" + e.getMessage()); + } + } + + /** + * 根据用户ID获取预测记录 + * @param userId 用户ID + * @return 用户的所有预测记录列表 + */ + @GetMapping("/predict-records/{userId}") + @Operation(summary = "获取用户预测记录", description = "根据用户ID分页获取该用户的预测记录,按预测时间倒序排列,每页5条") + public ApiResponse> getPredictRecordsByUserId( + @Parameter(description = "用户ID,例如:1001", required = true) + @PathVariable Long userId, + @Parameter(description = "页码,从1开始,默认为1", required = false) + @RequestParam(value = "page", defaultValue = "1") Integer page, + HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "用户未登录"); + } + + try { + log.info("接收到获取用户预测记录请求:用户ID={},页码={}", userId, page); + + // 参数校验 + if (page < 1) { + page = 1; + } + + // 获取总记录数 + Long total = predictRecordService.getPredictRecordsCountByUserId(userId); + + // 调用服务获取用户预测记录(分页,每页5条) + List records = predictRecordService.getPredictRecordsByUserIdWithPaging(userId, page, 5); + + // 创建分页响应对象 + PageResponse pageResponse = PageResponse.of(records, total, page, 5); + + log.info("获取用户预测记录完成,用户ID:{},页码:{},返回{}条记录,总记录数:{}", userId, page, records.size(), total); + return ResultUtils.success(pageResponse); + + } catch (Exception e) { + log.error("获取用户预测记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取用户预测记录失败:" + e.getMessage()); + } + } + + /** + * 球号分析算法 + * @param userId 用户ID + * @param level 高位/中位/低位标识 (H/M/L) + * @param redBalls 6个红球号码,用逗号分隔 + * @param blueBall 蓝球号码 + * @return 分析结果:出现频率最高的前11位数字 + */ + @PostMapping("/analyze") + @Operation(summary = "首球算法", description = "根据输入的级别、红球和蓝球,分析出现频率最高的前11位数字") + public ApiResponse> analyzeBalls( + @Parameter(description = "用户ID,例如:1001", required = true) + @RequestParam Long userId, + + @Parameter(description = "级别:H(高位)/M(中位)/L(低位)", required = true) + @RequestParam String level, + + @Parameter(description = "6个红球号码,用逗号分隔,例如:1,5,12,18,25,33", required = true) + @RequestParam String redBalls, + + @Parameter(description = "蓝球号码,例如:8", required = true) + @RequestParam Integer blueBall) { + + try { + log.info("接收到球号分析请求:用户ID={},级别={},红球={},蓝球={}", userId, level, redBalls, blueBall); + + // 校验用户VIP有效期 + User user = userService.getById(userId); + if (user == null) { + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "用户不存在"); + } + + Date now = new Date(); + if (user.getVipExpire() == null || user.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + + // 解析红球号码 + List redBallList = parseRedBalls(redBalls, 6, "红球"); + + // 调用分析服务 + List result = ballAnalysisService.analyzeBalls(level, redBallList, blueBall); + + log.info("球号分析完成,结果:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("球号分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "球号分析失败:" + e.getMessage()); + } + } + + /** + * 跟随球号分析算法 + * @param userId 用户ID + * @param level 高位/中位/低位标识 (H/M/L) + * @param firstThreeRedBalls 前3个红球号码,用逗号分隔 + * @param lastSixRedBalls 后6个红球号码,用逗号分隔 + * @param blueBall 蓝球号码 + * @return 分析结果:出现频率最高的前8位数字 + */ + @PostMapping("/fallow") + @Operation(summary = "跟随球号分析算法", description = "根据输入的级别、前3个红球、后6个红球和蓝球,分析出现频率最高的前8位数字") + public ApiResponse> fallowBallAnalysis( + @Parameter(description = "用户ID,例如:1001", required = true) + @RequestParam Long userId, + + @Parameter(description = "级别:H(高位)/M(中位)/L(低位)", required = true) + @RequestParam String level, + + @Parameter(description = "前3个红球号码,用逗号分隔,例如:7,24,27", required = true) + @RequestParam String firstThreeRedBalls, + + @Parameter(description = "后6个红球号码,用逗号分隔,例如:21,10,5,15,23,28", required = true) + @RequestParam String lastSixRedBalls, + + @Parameter(description = "蓝球号码,例如:16", required = true) + @RequestParam Integer blueBall) { + + try { + log.info("接收到跟随球号分析请求:用户ID={},级别={},前3个红球={},后6个红球={},蓝球={}", + userId, level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 校验用户VIP有效期 + User user = userService.getById(userId); + if (user == null) { + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "用户不存在"); + } + + Date now = new Date(); + if (user.getVipExpire() == null || user.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + + // 解析红球号码 + List firstThreeRedBallList = parseRedBalls(firstThreeRedBalls, 3, "前3个红球"); + List lastSixRedBallList = parseRedBalls(lastSixRedBalls, 6, "后6个红球"); + + // 调用分析服务 + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBallList, lastSixRedBallList, blueBall); + + log.info("跟随球号分析完成,结果:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("跟随球号分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "跟随球号分析失败:" + e.getMessage()); + } + } + + /** + * 解析红球号码字符串 + */ + private List parseRedBalls(String redBalls, int expectedCount, String ballType) { + if (redBalls == null || redBalls.trim().isEmpty()) { + throw new IllegalArgumentException(ballType + "号码不能为空"); + } + + try { + String[] parts = redBalls.split(","); + if (parts.length != expectedCount) { + throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length); + } + + List result = Arrays.stream(parts) + .map(String::trim) + .map(Integer::parseInt) + .collect(java.util.stream.Collectors.toList()); + + // 验证红球号码范围 + for (Integer ball : result) { + if (ball < 1 || ball > 33) { + throw new IllegalArgumentException(ballType + "号码必须在1-33范围内,错误值:" + ball); + } + } + + return result; + + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字"); + } + } + + /** + * 蓝球分析算法 + * @param userId 用户ID + * @param level 高位/中位/低位标识 (H/M/L) + * @param predictedRedBalls 6个预测红球号码,用逗号分隔 + * @param predictedBlueBalls 2个预测蓝球号码,用逗号分隔 + * @param lastRedBalls 6个上期红球号码,用逗号分隔 + * @param lastBlueBall 上期蓝球号码 + * @return 分析结果:频率最高的前4个蓝球号码 + */ + @PostMapping("/blue-ball") + @Operation(summary = "蓝球分析算法", description = "根据输入的级别、预测红球、预测蓝球、上期红球和上期蓝球,分析出频率最高的前4个蓝球号码") + public ApiResponse> blueBallAnalysis( + @Parameter(description = "用户ID,例如:1001", required = true) + @RequestParam Long userId, + + @Parameter(description = "级别:H(高位)/M(中位)/L(低位)", required = true) + @RequestParam String level, + + @Parameter(description = "6个预测红球号码,用逗号分隔,例如:26,20,18,32,10,14", required = true) + @RequestParam String predictedRedBalls, + + @Parameter(description = "2个预测蓝球号码,用逗号分隔,例如:5,8", required = true) + @RequestParam String predictedBlueBalls, + + @Parameter(description = "6个上期红球号码,用逗号分隔,例如:7,24,27,21,10,5", required = true) + @RequestParam String lastRedBalls, + + @Parameter(description = "上期蓝球号码,例如:16", required = true) + @RequestParam Integer lastBlueBall) { + + try { + log.info("接收到蓝球分析请求:用户ID={},级别={},预测红球={},预测蓝球={},上期红球={},上期蓝球={}", + userId, level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + // 校验用户VIP有效期 + User user = userService.getById(userId); + if (user == null) { + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "用户不存在"); + } + + Date now = new Date(); + if (user.getVipExpire() == null || user.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + + // 解析球号 + List predictedRedBallList = parseRedBalls(predictedRedBalls, 6, "预测红球"); + List predictedBlueBallList = parseBlueBalls(predictedBlueBalls, 2, "预测蓝球"); + List lastRedBallList = parseRedBalls(lastRedBalls, 6, "上期红球"); + + // 调用分析服务 + List result = ballAnalysisService.blueBallAnalysis( + level, predictedRedBallList, predictedBlueBallList, lastRedBallList, lastBlueBall); + + log.info("蓝球分析完成,结果:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("蓝球分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球分析失败:" + e.getMessage()); + } + } + + /** + * 解析蓝球号码字符串 + */ + private List parseBlueBalls(String blueBalls, int expectedCount, String ballType) { + if (blueBalls == null || blueBalls.trim().isEmpty()) { + throw new IllegalArgumentException(ballType + "号码不能为空"); + } + + try { + String[] parts = blueBalls.split(","); + if (parts.length != expectedCount) { + throw new IllegalArgumentException(ballType + "数量必须为" + expectedCount + "个,实际:" + parts.length); + } + + List result = Arrays.stream(parts) + .map(String::trim) + .map(Integer::parseInt) + .collect(java.util.stream.Collectors.toList()); + + // 验证蓝球号码范围 + for (Integer ball : result) { + if (ball < 1 || ball > 16) { + throw new IllegalArgumentException(ballType + "号码必须在1-16范围内,错误值:" + ball); + } + } + + return result; + + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ballType + "号码格式错误,请使用逗号分隔的数字"); + } + } + + /** + * 获取红球历史数据全部记录 + * @return 历史数据全部记录列表 + */ + @GetMapping("/history-all") + @Operation(summary = "获取历史数据全部记录", description = "获取history_all表中的所有历史数据记录") + public ApiResponse> getHistoryAll(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取历史数据全部记录请求"); + + // 调用服务获取全部历史数据 + List result = historyAllService.list(); + + log.info("获取历史数据全部记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取历史数据全部记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取历史数据全部记录失败:" + e.getMessage()); + } + } + + /** + * 获取红球最近100期数据记录 + * @return 最近100期数据记录列表 + */ + @GetMapping("/history-100") + @Operation(summary = "获取最近100期数据记录", description = "获取history_100表中的所有最近100期数据记录") + public ApiResponse> getHistory100(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取最近100期数据记录请求"); + + // 调用服务获取最近100期数据 + List result = history100Service.list(); + + log.info("获取最近100期数据记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取最近100期数据记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取最近100期数据记录失败:" + e.getMessage()); + } + } + + /** + * 获取红球历史数据排行记录 + * @return 历史数据排行记录列表 + */ + @GetMapping("/history-top") + @Operation(summary = "获取历史数据排行记录", description = "获取history_top表中的所有历史数据排行记录") + public ApiResponse> getHistoryTop(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取历史数据排行记录请求"); + + // 调用服务获取历史数据排行 + List result = historyTopService.list(); + + log.info("获取历史数据排行记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取历史数据排行记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取历史数据排行记录失败:" + e.getMessage()); + } + } + + /** + * 获取红球100期数据排行记录 + * @return 100期数据排行记录列表 + */ + @GetMapping("/history-top-100") + @Operation(summary = "获取红球100期数据排行记录", description = "获取history_top_100表中的所有100期数据排行记录") + public ApiResponse> getHistoryTop100(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取100期数据排行记录请求"); + + // 调用服务获取100期数据排行 + List result = historyTop100Service.list(); + + log.info("获取100期数据排行记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取100期数据排行记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取100期数据排行记录失败:" + e.getMessage()); + } + } + + /** + * 获取蓝球历史数据全部记录 + * @return 蓝球历史数据全部记录列表 + */ + @GetMapping("/blue-history-all") + @Operation(summary = "获取蓝球历史数据全部记录", description = "获取blue_history_all表中的所有蓝球历史数据记录") + public ApiResponse> getBlueHistoryAll(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取蓝球历史数据全部记录请求"); + + // 调用服务获取蓝球全部历史数据 + List result = blueHistoryAllService.list(); + + log.info("获取蓝球历史数据全部记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取蓝球历史数据全部记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取蓝球历史数据全部记录失败:" + e.getMessage()); + } + } + + /** + * 获取蓝球最近100期数据记录 + * @return 蓝球最近100期数据记录列表 + */ + @GetMapping("/blue-history-100") + @Operation(summary = "获取蓝球最近100期数据记录", description = "获取blue_history_100表中的所有蓝球最近100期数据记录") + public ApiResponse> getBlueHistory100(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取蓝球最近100期数据记录请求"); + + // 调用服务获取蓝球最近100期数据 + List result = blueHistory100Service.list(); + + log.info("获取蓝球最近100期数据记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取蓝球最近100期数据记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取蓝球最近100期数据记录失败:" + e.getMessage()); + } + } + + /** + * 获取蓝球历史数据排行记录 + * @return 蓝球历史数据排行记录列表 + */ + @GetMapping("/blue-history-top") + @Operation(summary = "获取蓝球历史数据排行记录", description = "获取blue_history_top表中的所有蓝球历史数据排行记录") + public ApiResponse> getBlueHistoryTop(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取蓝球历史数据排行记录请求"); + + // 调用服务获取蓝球历史数据排行 + List result = blueHistoryTopService.list(); + + log.info("获取蓝球历史数据排行记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取蓝球历史数据排行记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取蓝球历史数据排行记录失败:" + e.getMessage()); + } + } + + /** + * 获取蓝球100期数据排行记录 + * @return 蓝球100期数据排行记录列表 + */ + @GetMapping("/blue-history-top-100") + @Operation(summary = "获取蓝球100期数据排行记录", description = "获取blue_history_top_100表中的所有蓝球100期数据排行记录") + public ApiResponse> getBlueHistoryTop100(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到获取蓝球100期数据排行记录请求"); + + // 调用服务获取蓝球100期数据排行 + List result = blueHistoryTop100Service.list(); + + log.info("获取蓝球100期数据排行记录完成,返回{}条记录", result.size()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取蓝球100期数据排行记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取蓝球100期数据排行记录失败:" + e.getMessage()); + } + } + + /** + * 红球与红球的组合性分析 + * @param masterBall 主球号码(第一个红球) + * @param slaveBall 随球号码(第二个红球) + * @return 面系数分析结果 + */ + @GetMapping("/red-ball-combination-analysis") + @Operation(summary = "红球与红球的组合性分析", description = "根据主球和随球号码,查询t7表获取面系数,并计算主球与其他球号的组合情况") + public ApiResponse redBallCombinationAnalysis( + @Parameter(description = "主球号码,例如:5", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码,例如:12", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到红球与红球的组合性分析请求:主球={},随球={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证红球号码范围 + if (masterBall < 1 || masterBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球号码必须在1-33范围内,错误值:" + masterBall); + } + + if (slaveBall < 1 || slaveBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球号码必须在1-33范围内,错误值:" + slaveBall); + } + + // 查询当前两个球的面系数 + T7 t7Record = t7Service.lambdaQuery() + .eq(T7::getMasterBallNumber, masterBall) + .eq(T7::getSlaveBallNumber, slaveBall) + .one(); + + if (t7Record == null) { + log.warn("未找到主球{}和随球{}的组合记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球%d和随球%d的组合记录", masterBall, slaveBall)); + } + + Double faceCoefficient = t7Record.getFaceCoefficient(); + + // 查询主球与所有其他球的组合系数 + List allCombinations = t7Service.lambdaQuery() + .eq(T7::getMasterBallNumber, masterBall) + .ne(T7::getSlaveBallNumber, masterBall) // 排除自身 + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球{}的组合记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球%d的组合记录", masterBall)); + } + + // 找出系数最高的球号 + T7 highest = allCombinations.stream() + .max(Comparator.comparing(T7::getFaceCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T7 lowest = allCombinations.stream() + .min(Comparator.comparing(T7::getFaceCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T7::getFaceCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallCombinationAnalysisVO result = BallCombinationAnalysisVO.builder() + .faceCoefficient(faceCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getFaceCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getFaceCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("红球与红球的组合性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("红球与红球的组合性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "红球与红球的组合性分析失败:" + e.getMessage()); + } + } + + /** + * 红球与蓝球的组合性分析 + * @param masterBall 主球号码(红球) + * @param slaveBall 随球号码(蓝球) + * @return 面系数分析结果 + */ + @GetMapping("/red-blue-combination-analysis") + @Operation(summary = "红球与蓝球的组合性分析", description = "根据红球主球和蓝球随球号码,查询t8表获取面系数,并返回扩展分析") + public ApiResponse redBlueCombinationAnalysis( + @Parameter(description = "主球号码(红球),例如:5", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(蓝球),例如:8", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到红球与蓝球的组合性分析请求:主球(红球)={},随球(蓝球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证红球号码范围 + if (masterBall < 1 || masterBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(红球)号码必须在1-33范围内,错误值:" + masterBall); + } + + // 验证蓝球号码范围 + if (slaveBall < 1 || slaveBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(蓝球)号码必须在1-16范围内,错误值:" + slaveBall); + } + + // 查询T8表获取面系数 + T8 t8Record = t8Service.lambdaQuery() + .eq(T8::getMasterBallNumber, masterBall) + .eq(T8::getSlaveBallNumber, slaveBall) + .one(); + + if (t8Record == null) { + log.warn("未找到主球(红球){}和随球(蓝球){}的组合记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d和随球(蓝球)%d的组合记录", masterBall, slaveBall)); + } + + Double faceCoefficient = t8Record.getFaceCoefficient(); + + // 查询主球(红球)与所有蓝球的组合系数 + List allCombinations = t8Service.lambdaQuery() + .eq(T8::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(红球){}的组合记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d的组合记录", masterBall)); + } + + // 找出系数最高的球号 + T8 highest = allCombinations.stream() + .max(Comparator.comparing(T8::getFaceCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T8 lowest = allCombinations.stream() + .min(Comparator.comparing(T8::getFaceCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T8::getFaceCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallCombinationAnalysisVO result = BallCombinationAnalysisVO.builder() + .faceCoefficient(faceCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getFaceCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getFaceCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("红球与蓝球的组合性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("红球与蓝球的组合性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "红球与蓝球的组合性分析失败:" + e.getMessage()); + } + } + + /** + * 蓝球与红球的组合性分析 + * @param masterBall 主球号码(蓝球) + * @param slaveBall 随球号码(红球) + * @return 面系数分析结果 + */ + @GetMapping("/blue-red-combination-analysis") + @Operation(summary = "蓝球与红球的组合性分析", description = "根据蓝球主球和红球随球号码,查询t11表获取面系数,并返回扩展分析") + public ApiResponse blueRedCombinationAnalysis( + @Parameter(description = "主球号码(蓝球),例如:8", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(红球),例如:5", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到蓝球与红球的组合性分析请求:主球(蓝球)={},随球(红球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证蓝球号码范围 + if (masterBall < 1 || masterBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(蓝球)号码必须在1-16范围内,错误值:" + masterBall); + } + + // 验证红球号码范围 + if (slaveBall < 1 || slaveBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(红球)号码必须在1-33范围内,错误值:" + slaveBall); + } + + // 查询T11表获取面系数 + T11 t11Record = t11Service.lambdaQuery() + .eq(T11::getMasterBallNumber, masterBall) + .eq(T11::getSlaveBallNumber, slaveBall) + .one(); + + if (t11Record == null) { + log.warn("未找到主球(蓝球){}和随球(红球){}的组合记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d和随球(红球)%d的组合记录", masterBall, slaveBall)); + } + + Double faceCoefficient = t11Record.getFaceCoefficient(); + + // 查询主球(蓝球)与所有红球的组合系数 + List allCombinations = t11Service.lambdaQuery() + .eq(T11::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(蓝球){}的组合记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d的组合记录", masterBall)); + } + + // 找出系数最高的球号 + T11 highest = allCombinations.stream() + .max(Comparator.comparing(T11::getFaceCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T11 lowest = allCombinations.stream() + .min(Comparator.comparing(T11::getFaceCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T11::getFaceCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallCombinationAnalysisVO result = BallCombinationAnalysisVO.builder() + .faceCoefficient(faceCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getFaceCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getFaceCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("蓝球与红球的组合性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("蓝球与红球的组合性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球与红球的组合性分析失败:" + e.getMessage()); + } + } + + /** + * 红球与红球的持续性分析 + * @param masterBall 主球号码(红球) + * @param slaveBall 随球号码(红球) + * @return 线系数分析结果 + */ + @GetMapping("/red-red-persistence-analysis") + @Operation(summary = "红球与红球的持续性分析", description = "根据红球主球和红球随球号码,查询t3表获取线系数,并返回扩展分析") + public ApiResponse redRedPersistenceAnalysis( + @Parameter(description = "主球号码(红球),例如:5", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(红球),例如:12", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到红球与红球的持续性分析请求:主球(红球)={},随球(红球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证红球号码范围 + if (masterBall < 1 || masterBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(红球)号码必须在1-33范围内,错误值:" + masterBall); + } + + if (slaveBall < 1 || slaveBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(红球)号码必须在1-33范围内,错误值:" + slaveBall); + } + + // 查询T3表获取线系数 + T3 t3Record = t3Service.lambdaQuery() + .eq(T3::getMasterBallNumber, masterBall) + .eq(T3::getSlaveBallNumber, slaveBall) + .one(); + + if (t3Record == null) { + log.warn("未找到主球(红球){}和随球(红球){}的持续性记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d和随球(红球)%d的持续性记录", masterBall, slaveBall)); + } + + Double lineCoefficient = t3Record.getLineCoefficient(); + + // 查询主球与其他所有红球的持续性系数 + List allCombinations = t3Service.lambdaQuery() + .eq(T3::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(红球){}的持续性记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d的持续性记录", masterBall)); + } + + // 找出系数最高的球号 + T3 highest = allCombinations.stream() + .max(Comparator.comparing(T3::getLineCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T3 lowest = allCombinations.stream() + .min(Comparator.comparing(T3::getLineCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T3::getLineCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallPersistenceAnalysisVO result = BallPersistenceAnalysisVO.builder() + .lineCoefficient(lineCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getLineCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getLineCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("红球与红球的持续性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("红球与红球的持续性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "红球与红球的持续性分析失败:" + e.getMessage()); + } + } + + /** + * 蓝球与蓝球的持续性分析 + * @param masterBall 主球号码(蓝球) + * @param slaveBall 随球号码(蓝球) + * @return 线系数分析结果 + */ + @GetMapping("/blue-blue-persistence-analysis") + @Operation(summary = "蓝球与蓝球的持续性分析", description = "根据蓝球主球和蓝球随球号码,查询t5表获取线系数,并返回扩展分析") + public ApiResponse blueBluePersistenceAnalysis( + @Parameter(description = "主球号码(蓝球),例如:8", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(蓝球),例如:12", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到蓝球与蓝球的持续性分析请求:主球(蓝球)={},随球(蓝球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证蓝球号码范围 + if (masterBall < 1 || masterBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(蓝球)号码必须在1-16范围内,错误值:" + masterBall); + } + + if (slaveBall < 1 || slaveBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(蓝球)号码必须在1-16范围内,错误值:" + slaveBall); + } + + // 查询T5表获取线系数 + T5 t5Record = t5Service.lambdaQuery() + .eq(T5::getMasterBallNumber, masterBall) + .eq(T5::getSlaveBallNumber, slaveBall) + .one(); + + if (t5Record == null) { + log.warn("未找到主球(蓝球){}和随球(蓝球){}的持续性记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d和随球(蓝球)%d的持续性记录", masterBall, slaveBall)); + } + + Double lineCoefficient = t5Record.getLineCoefficient(); + + // 查询主球与其他所有蓝球的持续性系数 + List allCombinations = t5Service.lambdaQuery() + .eq(T5::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(蓝球){}的持续性记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d的持续性记录", masterBall)); + } + + // 找出系数最高的球号 + T5 highest = allCombinations.stream() + .max(Comparator.comparing(T5::getLineCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T5 lowest = allCombinations.stream() + .min(Comparator.comparing(T5::getLineCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T5::getLineCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallPersistenceAnalysisVO result = BallPersistenceAnalysisVO.builder() + .lineCoefficient(lineCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getLineCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getLineCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("蓝球与蓝球的持续性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("蓝球与蓝球的持续性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球与蓝球的持续性分析失败:" + e.getMessage()); + } + } + + /** + * 红球与蓝球的持续性分析 + * @param masterBall 主球号码(红球) + * @param slaveBall 随球号码(蓝球) + * @return 线系数分析结果 + */ + @GetMapping("/red-blue-persistence-analysis") + @Operation(summary = "红球与蓝球的持续性分析", description = "根据红球主球和蓝球随球号码,查询t6表获取线系数,并返回扩展分析") + public ApiResponse redBluePersistenceAnalysis( + @Parameter(description = "主球号码(红球),例如:5", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(蓝球),例如:8", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到红球与蓝球的持续性分析请求:主球(红球)={},随球(蓝球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证红球号码范围 + if (masterBall < 1 || masterBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(红球)号码必须在1-33范围内,错误值:" + masterBall); + } + + // 验证蓝球号码范围 + if (slaveBall < 1 || slaveBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(蓝球)号码必须在1-16范围内,错误值:" + slaveBall); + } + + // 查询T6表获取线系数 + T6 t6Record = t6Service.lambdaQuery() + .eq(T6::getMasterBallNumber, masterBall) + .eq(T6::getSlaveBallNumber, slaveBall) + .one(); + + if (t6Record == null) { + log.warn("未找到主球(红球){}和随球(蓝球){}的持续性记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d和随球(蓝球)%d的持续性记录", masterBall, slaveBall)); + } + + Double lineCoefficient = t6Record.getLineCoefficient(); + + // 查询主球(红球)与所有蓝球的持续性系数 + List allCombinations = t6Service.lambdaQuery() + .eq(T6::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(红球){}的持续性记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(红球)%d的持续性记录", masterBall)); + } + + // 找出系数最高的球号 + T6 highest = allCombinations.stream() + .max(Comparator.comparing(T6::getLineCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T6 lowest = allCombinations.stream() + .min(Comparator.comparing(T6::getLineCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T6::getLineCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallPersistenceAnalysisVO result = BallPersistenceAnalysisVO.builder() + .lineCoefficient(lineCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getLineCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getLineCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("红球与蓝球的持续性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("红球与蓝球的持续性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "红球与蓝球的持续性分析失败:" + e.getMessage()); + } + } + + /** + * 蓝球与红球的持续性分析 + * @param masterBall 主球号码(蓝球) + * @param slaveBall 随球号码(红球) + * @return 线系数分析结果 + */ + @GetMapping("/blue-red-persistence-analysis") + @Operation(summary = "蓝球与红球的持续性分析", description = "根据蓝球主球和红球随球号码,查询t4表获取线系数,并返回扩展分析") + public ApiResponse blueRedPersistenceAnalysis( + @Parameter(description = "主球号码(蓝球),例如:8", required = true) + @RequestParam Integer masterBall, + + @Parameter(description = "随球号码(红球),例如:5", required = true) + @RequestParam Integer slaveBall, + + HttpServletRequest request) { + + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + Date now = new Date(); + if (loginUser.getVipExpire() == null || loginUser.getVipExpire().before(now)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "VIP会员已过期,请续费后使用"); + } + try { + log.info("接收到蓝球与红球的持续性分析请求:主球(蓝球)={},随球(红球)={}", masterBall, slaveBall); + + // 参数校验 + if (masterBall == null || slaveBall == null) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球和随球号码不能为空"); + } + + // 验证蓝球号码范围 + if (masterBall < 1 || masterBall > 16) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "主球(蓝球)号码必须在1-16范围内,错误值:" + masterBall); + } + + // 验证红球号码范围 + if (slaveBall < 1 || slaveBall > 33) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "随球(红球)号码必须在1-33范围内,错误值:" + slaveBall); + } + + // 查询T4表获取线系数 + T4 t4Record = t4Service.lambdaQuery() + .eq(T4::getMasterBallNumber, masterBall) + .eq(T4::getSlaveBallNumber, slaveBall) + .one(); + + if (t4Record == null) { + log.warn("未找到主球(蓝球){}和随球(红球){}的持续性记录", masterBall, slaveBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d和随球(红球)%d的持续性记录", masterBall, slaveBall)); + } + + Double lineCoefficient = t4Record.getLineCoefficient(); + + // 查询主球(蓝球)与所有红球的持续性系数 + List allCombinations = t4Service.lambdaQuery() + .eq(T4::getMasterBallNumber, masterBall) + .list(); + + if (allCombinations.isEmpty()) { + log.warn("未找到主球(蓝球){}的持续性记录", masterBall); + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, + String.format("未找到主球(蓝球)%d的持续性记录", masterBall)); + } + + // 找出系数最高的球号 + T4 highest = allCombinations.stream() + .max(Comparator.comparing(T4::getLineCoefficient)) + .orElse(null); + + // 找出系数最低的球号 + T4 lowest = allCombinations.stream() + .min(Comparator.comparing(T4::getLineCoefficient)) + .orElse(null); + + // 计算平均系数 + double avgCoefficient = allCombinations.stream() + .mapToDouble(T4::getLineCoefficient) + .average() + .orElse(0.0); + + // 获取最新的一期开奖期号 + Long latestDrawId = lotteryDrawsService.lambdaQuery() + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 1") + .oneOpt() + .map(LotteryDraws::getDrawId) + .orElse(null); + + // 构建返回结果 + BallPersistenceAnalysisVO result = BallPersistenceAnalysisVO.builder() + .lineCoefficient(lineCoefficient) + .highestBall(highest != null ? highest.getSlaveBallNumber() : null) + .highestCoefficient(highest != null ? highest.getLineCoefficient() : null) + .lowestBall(lowest != null ? lowest.getSlaveBallNumber() : null) + .lowestCoefficient(lowest != null ? lowest.getLineCoefficient() : null) + .averageCoefficient(avgCoefficient) + .latestDrawId(latestDrawId) + .build(); + + log.info("蓝球与红球的持续性分析完成:{}", result); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("蓝球与红球的持续性分析失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "蓝球与红球的持续性分析失败:" + e.getMessage()); + } + } + + /** + * 获取首球命中率统计 + * @return 首球命中次数和命中率统计 + */ + @GetMapping("/first-ball-hit-rate") + @Operation(summary = "获取首球命中率统计", description = "统计用户的首球命中次数和命中率") + public ApiResponse getFirstBallHitRate(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null) { + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到获取首球命中率统计请求"); + + // 调用服务获取首球命中率 + BallHitRateVO result = ballAnalysisService.getFirstBallHitRate(loginUser.getId()); + + log.info("获取首球命中率统计完成,命中次数:{},总次数:{},命中率:{}", + result.getHitCount(), result.getTotalCount(), result.getHitRate()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取首球命中率统计失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取首球命中率统计失败:" + e.getMessage()); + } + } + + /** + * 获取蓝球命中率统计 + * @return 蓝球命中次数和命中率统计 + */ + @GetMapping("/blue-ball-hit-rate") + @Operation(summary = "获取蓝球命中率统计", description = "统计用户的蓝球命中次数和命中率") + public ApiResponse getBlueBallHitRate(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null) { + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到获取蓝球命中率统计请求"); + + // 调用服务获取蓝球命中率 + BallHitRateVO result = ballAnalysisService.getBlueBallHitRate(loginUser.getId()); + + log.info("获取蓝球命中率统计完成,命中次数:{},总次数:{},命中率:{}", + result.getHitCount(), result.getTotalCount(), result.getHitRate()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取蓝球命中率统计失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取蓝球命中率统计失败:" + e.getMessage()); + } + } + + + + /** + * 奖金统计 + * @return 奖金统计信息(各中奖等级、中奖次数、单奖金额、奖金合计) + */ + @GetMapping("/prize-statistics") + @Operation(summary = "奖金统计", description = "统计用户所有中奖记录,按等级汇总各等级的中奖次数和奖金") + public ApiResponse getPrizeStatistics(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null) { + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到奖金统计请求"); + + // 调用服务进行奖金统计 + PrizeEstimateVO result = ballAnalysisService.getPrizeStatistics(loginUser.getId(), null); + + log.info("奖金统计完成,总奖金:{}", result.getTotalPrize()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("奖金统计失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "奖金统计失败:" + e.getMessage()); + } + } + + /** + * 获取近10期开奖期号 + * @return 近10期开奖期号列表 + */ + @GetMapping("/recent-10-draw-ids") + @Operation(summary = "获取近10期开奖期号", description = "获取lottery_draws表中最新的10期开奖期号,按开奖期号倒序排列") + public ApiResponse> getRecent10DrawIds(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到获取近10期开奖期号请求"); + + // 查询最近10期开奖期号 + List drawIds = lotteryDrawsService.lambdaQuery() + .select(LotteryDraws::getDrawId) + .orderByDesc(LotteryDraws::getDrawId) + .last("LIMIT 10") + .list() + .stream() + .map(LotteryDraws::getDrawId) + .collect(java.util.stream.Collectors.toList()); + + log.info("获取近10期开奖期号完成,返回{}条记录", drawIds.size()); + return ResultUtils.success(drawIds); + + } catch (Exception e) { + log.error("获取近10期开奖期号失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取近10期开奖期号失败:" + e.getMessage()); + } + } + + /** + * 获取红球命中率统计 + * @return 红球命中总数和命中率 + */ + @GetMapping("/red-ball-hit-rate") + @Operation(summary = "获取红球命中率统计", description = "统计用户的总红球命中次数和命中率") + public ApiResponse getRedBallHitRate(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + if (loginUser == null) { + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "您还未登录,请登录后查看"); + } + try { + log.info("接收到获取红球命中率统计请求"); + + // 调用服务获取红球命中率 + RedBallHitRateVO result = ballAnalysisService.getRedBallHitRate(loginUser.getId()); + + log.info("获取红球命中率统计完成,命中总数:{},预测总数:{},命中率:{}", + result.getTotalHitCount(), result.getTotalPredictedCount(), result.getHitRate()); + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取红球命中率统计失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取红球命中率统计失败:" + e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/ChatController.java b/src/main/java/com/xy/xyaicpzs/controller/ChatController.java new file mode 100644 index 0000000..8c98e06 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/ChatController.java @@ -0,0 +1,126 @@ +package com.xy.xyaicpzs.controller; + +import com.alibaba.dashscope.app.Application; +import com.alibaba.dashscope.app.ApplicationParam; +import com.alibaba.dashscope.app.ApplicationResult; +import com.alibaba.dashscope.exception.ApiException; +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import com.xy.xyaicpzs.domain.entity.ChatMessage; +import com.xy.xyaicpzs.service.ChatMessageService; +import io.reactivex.Flowable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.atomic.AtomicReference; + +@RestController +public class ChatController { + + @Autowired + private ChatMessageService chatMessageService; + + @Value("${dashscope.api-key}") + private String dashscopeApiKey; + + /** + * SSE流式聊天接口 + * @param message 用户消息 + * @param conversationId 会话ID + * @param userId 用户ID + * @return SseEmitter + */ + @GetMapping("/chat/sse") + public SseEmitter chatSseEmitter( + @RequestParam String message, + @RequestParam(required = false) String conversationId, + @RequestParam(required = false) String userId) { + + // 保存用户消息到数据库 + saveMessage(conversationId, userId, "USER", message); + + // 创建一个超时时间较长的 SseEmitter + SseEmitter emitter = new SseEmitter(180000L); // 3分钟超时 + + // 用于收集完整的AI回复 + AtomicReference fullResponseRef = new AtomicReference<>(new StringBuilder()); + + try { + // 设置AI参数 + ApplicationParam param = ApplicationParam.builder() + .apiKey(dashscopeApiKey) // 使用配置文件中的API密钥 + .appId("ec08d5b81ca248e8834228c1133e2c78") + .prompt(message) + .incrementalOutput(true) + .build(); + + Application application = new Application(); + + // 流式调用 + Flowable result = application.streamCall(param); + + result.subscribe( + // 处理每条消息 + data -> { + try { + String text = data.getOutput().getText(); + // 发送数据到客户端 + emitter.send(text); + // 收集完整响应 + fullResponseRef.get().append(text); + } catch (IOException e) { + emitter.completeWithError(e); + } + }, + // 处理错误 + error -> { + emitter.completeWithError(error); + System.out.println("错误: " + error.getMessage()); + }, + // 处理完成 + () -> { + // 保存AI回复到数据库 + String fullResponse = fullResponseRef.get().toString(); + saveMessage(conversationId, userId, "AI", fullResponse); + emitter.complete(); + } + ); + + } catch (ApiException | NoApiKeyException | InputRequiredException e) { + try { + emitter.send("错误: " + e.getMessage()); + emitter.complete(); + } catch (IOException ex) { + emitter.completeWithError(ex); + } + System.out.println("异常: " + e.getMessage()); + } + + return emitter; + } + + /** + * 保存消息到数据库 + * @param conversationId 会话ID + * @param userId 用户ID + * @param messageType 消息类型(USER/AI) + * @param content 消息内容 + */ + private void saveMessage(String conversationId, String userId, String messageType, String content) { + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setConversationId(conversationId); + chatMessage.setStudentId(userId); + chatMessage.setMessageType(messageType); + chatMessage.setContent(content); + chatMessage.setCreateTime(new Date()); + chatMessage.setUpdateTime(new Date()); + chatMessage.setIsDelete(0); + chatMessageService.save(chatMessage); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/DataAnalysisController.java b/src/main/java/com/xy/xyaicpzs/controller/DataAnalysisController.java new file mode 100644 index 0000000..6458e40 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/DataAnalysisController.java @@ -0,0 +1,138 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.requset.PredictRecordQueryRequest; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.common.response.PageResponse; +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.xy.xyaicpzs.domain.vo.UserPredictStatVO; +import com.xy.xyaicpzs.service.DataAnalysisService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * 数据分析控制器 + * 提供用户预测数据统计分析的API接口 + */ +@Slf4j +@RestController +@RequestMapping("/data-analysis") +@Tag(name = "数据分析", description = "用户预测数据统计分析API") +public class DataAnalysisController { + + @Autowired + private DataAnalysisService dataAnalysisService; + + /** + * 获取用户预测统计数据 + * @param userId 用户ID + * @return 用户预测统计数据 + */ + @GetMapping("/user-predict-stat/{userId}") + @Operation(summary = "获取用户预测统计数据", description = "根据用户ID获取该用户的预测次数、待开奖次数、命中次数、命中率等统计数据") + public ApiResponse getUserPredictStat( + @Parameter(description = "用户ID,例如:1001", required = true) + @PathVariable Long userId) { + + try { + log.info("接收到获取用户预测统计数据请求:用户ID={}", userId); + + // 调用服务获取用户预测统计数据 + UserPredictStatVO result = dataAnalysisService.getUserPredictStat(userId); + + log.info("获取用户预测统计数据完成,用户ID:{},预测次数:{},待开奖次数:{},命中次数:{},命中率:{}", + userId, result.getPredictCount(), result.getPendingCount(), + result.getHitCount(), result.getHitRate()); + + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取用户预测统计数据失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取用户预测统计数据失败:" + e.getMessage()); + } + } + + /** + * 手动触发处理待开奖记录 + * @return 处理结果 + */ + @PostMapping("/process-pending") + @Operation(summary = "手动处理待开奖记录", description = "手动触发处理待开奖的预测记录,匹配开奖结果并更新中奖状态") + public ApiResponse processPendingPredictions() { + + try { + log.info("接收到手动处理待开奖记录请求"); + + // 调用服务处理待开奖记录 + int processedCount = dataAnalysisService.processPendingPredictions(); + + String message = String.format("处理完成,共处理%d条待开奖记录", processedCount); + log.info("手动处理待开奖记录完成:{}", message); + + return ResultUtils.success(message); + + } catch (Exception e) { + log.error("手动处理待开奖记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "处理待开奖记录失败:" + e.getMessage()); + } + } + + /** + * 按条件查询预测记录 + * @param request 查询条件 + * @return 分页预测记录 + */ + @PostMapping("/query-predict-records") + @Operation(summary = "按条件查询预测记录", description = "根据用户ID和预测状态(待开奖/未中奖/已中奖)筛选预测记录,支持分页查询") + public ApiResponse> queryPredictRecords(@RequestBody PredictRecordQueryRequest request) { + try { + log.info("接收到按条件查询预测记录请求:userId={}, predictStatus={}, current={}, pageSize={}", + request.getUserId(), request.getPredictStatus(), request.getCurrent(), request.getPageSize()); + + // 调用服务查询预测记录 + PageResponse result = dataAnalysisService.queryPredictRecords(request); + + log.info("按条件查询预测记录完成,总记录数:{}", result.getTotal()); + + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("按条件查询预测记录失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询预测记录失败:" + e.getMessage()); + } + } + + /** + * 获取所有预测记录总数 + * @return 预测记录总数 + */ + @GetMapping("/total-predict-count") + @Operation(summary = "获取预测记录总数", description = "获取系统中所有用户的预测记录总数") + public ApiResponse> getTotalPredictCount() { + try { + log.info("接收到获取预测记录总数请求"); + + // 调用服务获取预测记录总数 + long totalCount = dataAnalysisService.getTotalPredictCount(); + + Map result = new HashMap<>(); + result.put("totalCount", totalCount); + + log.info("获取预测记录总数完成,总数:{}", totalCount); + + return ResultUtils.success(result); + + } catch (Exception e) { + log.error("获取预测记录总数失败:{}", e.getMessage(), e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取预测记录总数失败:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/ExcelImportController.java b/src/main/java/com/xy/xyaicpzs/controller/ExcelImportController.java new file mode 100644 index 0000000..fac6f55 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/ExcelImportController.java @@ -0,0 +1,156 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.service.ExcelImportService; +import com.xy.xyaicpzs.service.OperationHistoryService; +import com.xy.xyaicpzs.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * Excel数据导入控制器 + */ +@Slf4j +@RestController +@RequestMapping("/excel") +@Tag(name = "Excel数据导入", description = "Excel数据导入相关接口") +public class ExcelImportController { + + @Autowired + private ExcelImportService excelImportService; + + @Autowired + private UserService userService; + + @Autowired + private OperationHistoryService operationHistoryService; + + /** + * 上传Excel文件并导入数据 + */ + @PostMapping("/upload") + @Operation(summary = "上传Excel文件导入数据", description = "上传包含T1、T2、T3、T4、T5、T6和T7 sheet的Excel文件,将红球、蓝球、线系数和面系数数据分别导入到十二个数据库表中") + public ApiResponse uploadExcelFile( + @Parameter(description = "Excel文件(.xlsx格式)", required = true) + @RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest) { + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + Long userId = loginUser.getId(); + String userName = loginUser.getUserName(); + + String fileName = file.getOriginalFilename(); + log.info("接收到Excel文件上传请求,文件名:{}", fileName); + + try { + String message = excelImportService.importExcelFile(file); + + // 记录操作历史 - 成功 + String resultMessage = String.format("%s成功上传并导入Excel文件:%s,导入结果:%s", userName, fileName, message); + operationHistoryService.recordOperation(userId, "Excel数据导入", 1, "成功", resultMessage); + + return ResultUtils.success(message); + } catch (Exception e) { + log.error("Excel文件导入失败,文件名:{},错误:{}", fileName, e.getMessage(), e); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%sExcel文件导入失败:%s,文件名:%s,错误原因:%s", userName, fileName, fileName, e.getMessage()); + operationHistoryService.recordOperation(userId, "Excel数据导入", 1, "失败", resultMessage); + + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "Excel文件导入失败:" + e.getMessage()); + } + } + + /** + * 上传Excel文件并导入开奖数据 + */ + @PostMapping("/upload-lottery-draws") + @Operation(summary = "上传Excel文件导入开奖数据", description = "上传包含T10工作表的Excel文件,只导入开奖数据到lottery_draws表") + public ApiResponse uploadLotteryDrawsFile( + @Parameter(description = "包含T10工作表的Excel文件(.xlsx格式)", required = true) + @RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest) { + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + Long userId = loginUser.getId(); + String userName = loginUser.getUserName(); + + String fileName = file.getOriginalFilename(); + log.info("接收到开奖数据上传请求,文件名:{}", fileName); + + try { + String message = excelImportService.importLotteryDrawsFile(file); + + // 记录操作历史 - 成功 + String resultMessage = String.format("%s成功上传并导入开奖数据文件:%s,导入结果:%s", userName, fileName, message); + operationHistoryService.recordOperation(userId, "开奖数据导入", 1, "成功", resultMessage); + + return ResultUtils.success(message); + } catch (Exception e) { + log.error("开奖数据文件导入失败,文件名:{},错误:{}", fileName, e.getMessage(), e); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s开奖数据文件导入失败:%s,文件名:%s,错误原因:%s", userName, fileName, fileName, e.getMessage()); + operationHistoryService.recordOperation(userId, "开奖数据导入", 1, "失败", resultMessage); + + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "开奖数据文件导入失败:" + e.getMessage()); + } + } + + /** + * 上传Excel文件并追加导入开奖数据 + */ + @PostMapping("/append-lottery-draws") + @Operation(summary = "上传Excel文件追加导入开奖数据", description = "上传包含T10工作表的Excel文件,追加导入开奖数据(不清空现有数据,跳过重复期号)") + public ApiResponse appendLotteryDrawsFile( + @Parameter(description = "包含T10工作表的Excel文件(.xlsx格式)", required = true) + @RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest) { + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + Long userId = loginUser.getId(); + String userName = loginUser.getUserName(); + + String fileName = file.getOriginalFilename(); + log.info("接收到开奖数据追加上传请求,文件名:{}", fileName); + + try { + String message = excelImportService.appendLotteryDrawsFile(file); + + // 记录操作历史 - 成功 + String resultMessage = String.format("%s成功追加导入开奖数据文件:%s,导入结果:%s", userName, fileName, message); + operationHistoryService.recordOperation(userId, "开奖数据追加导入", 1, "成功", resultMessage); + + return ResultUtils.success(message); + } catch (Exception e) { + log.error("开奖数据追加导入失败,文件名:{},错误:{}", fileName, e.getMessage(), e); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s开奖数据追加导入失败:%s,文件名:%s,错误原因:%s", userName, fileName, fileName, e.getMessage()); + operationHistoryService.recordOperation(userId, "开奖数据追加导入", 1, "失败", resultMessage); + + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "开奖数据追加导入失败:" + e.getMessage()); + } + } + + /** + * 获取导入说明 + */ + @GetMapping("/import-info") + @Operation(summary = "获取导入说明", description = "获取Excel数据导入的详细说明") + public String getImportInfo() { + return excelImportService.getImportInfo(); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/HealthController.java b/src/main/java/com/xy/xyaicpzs/controller/HealthController.java new file mode 100644 index 0000000..4af335d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/HealthController.java @@ -0,0 +1,15 @@ +package com.xy.xyaicpzs.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/health") +public class HealthController { + + @GetMapping + public String healthCheck() { + return "ok"; + } +} diff --git a/src/main/java/com/xy/xyaicpzs/controller/JwtController.java b/src/main/java/com/xy/xyaicpzs/controller/JwtController.java new file mode 100644 index 0000000..977ed7d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/JwtController.java @@ -0,0 +1,108 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.service.CozeAuthService; +import com.xy.xyaicpzs.util.JwtUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * JWT令牌控制器 + */ +@RestController +@RequestMapping("/jwt") +@Tag(name = "JWT接口", description = "提供JWT令牌生成功能") +public class JwtController { + + @Autowired + private JwtUtil jwtUtil; + + @Autowired + private CozeAuthService cozeAuthService; + + /** + * 生成JWT令牌 + * + * @param expireSeconds 过期时间(秒) + * @param sessionName 会话名称(可选) + * @param deviceId 设备ID(可选) + * @return JWT令牌 + */ + @GetMapping("/token") + @Operation(summary = "生成JWT令牌", description = "生成Coze API访问所需的JWT令牌") + public ApiResponse> generateToken( + @Parameter(description = "过期时间(秒)") @RequestParam(defaultValue = "600") int expireSeconds, + @Parameter(description = "会话名称(可选)") @RequestParam(required = false) String sessionName, + @Parameter(description = "设备ID(可选)") @RequestParam(required = false) String deviceId) { + + try { + String token = jwtUtil.generateToken(expireSeconds, sessionName, deviceId); + Map result = new HashMap<>(); + result.put("token", token); + return ResultUtils.success(result); + } catch (Exception e) { + return ResultUtils.error(50000, "JWT生成失败: " + e.getMessage()); + } + } + + /** + * 通过JWT获取访问令牌 + * + * @param jwt JWT令牌 + * @param durationSeconds 访问令牌有效期(秒),默认为86400秒(1天) + * @return 包含访问令牌和过期时间的信息 + */ + @PostMapping("/access-token") + @Operation(summary = "获取访问令牌", description = "通过JWT获取Coze API的OAuth访问令牌") + public ApiResponse> getAccessToken( + @Parameter(description = "JWT令牌") @RequestParam String jwt, + @Parameter(description = "令牌有效期(秒)") @RequestParam(defaultValue = "86400") Integer durationSeconds) { + + try { + Map tokenInfo = cozeAuthService.getAccessToken(jwt, durationSeconds); + return ResultUtils.success(tokenInfo); + } catch (Exception e) { + return ResultUtils.error(50000, "获取访问令牌失败: " + e.getMessage()); + } + } + + /** + * 一站式获取访问令牌(生成JWT并立即获取访问令牌) + * + * @param jwtExpireSeconds JWT过期时间(秒) + * @param sessionName 会话名称(可选) + * @param deviceId 设备ID(可选) + * @param tokenDurationSeconds 访问令牌有效期(秒) + * @return 包含JWT、访问令牌和过期时间的信息 + */ + @PostMapping("/one-step-token") + @Operation(summary = "一站式获取访问令牌", description = "生成JWT并立即获取Coze API的OAuth访问令牌") + public ApiResponse> getOneStepToken( + @Parameter(description = "JWT过期时间(秒)") @RequestParam(defaultValue = "600") int jwtExpireSeconds, + @Parameter(description = "会话名称(可选)") @RequestParam(required = false) String sessionName, + @Parameter(description = "设备ID(可选)") @RequestParam(required = false) String deviceId, + @Parameter(description = "访问令牌有效期(秒)") @RequestParam(defaultValue = "86400") Integer tokenDurationSeconds) { + + try { + // 生成JWT令牌 + String jwt = jwtUtil.generateToken(jwtExpireSeconds, sessionName, deviceId); + + // 获取访问令牌 + Map tokenInfo = cozeAuthService.getAccessToken(jwt, tokenDurationSeconds); + + // 合并结果 + tokenInfo.put("jwt", jwt); + + return ResultUtils.success(tokenInfo); + } catch (Exception e) { + return ResultUtils.error(50000, "获取访问令牌失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/OperationHistoryController.java b/src/main/java/com/xy/xyaicpzs/controller/OperationHistoryController.java new file mode 100644 index 0000000..1e94b03 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/OperationHistoryController.java @@ -0,0 +1,96 @@ +package com.xy.xyaicpzs.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.domain.entity.OperationHistory; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.service.OperationHistoryService; +import com.xy.xyaicpzs.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 操作历史管理控制器 + */ +@RestController +@RequestMapping("/operation-history") +@Slf4j +@Tag(name = "操作历史管理", description = "操作历史记录相关接口") +public class OperationHistoryController { + + @Autowired + private OperationHistoryService operationHistoryService; + + @Autowired + private UserService userService; + + /** + * 获取操作历史记录 + * 支持按操作模块和操作结果进行筛选 + */ + @GetMapping("/list") + @Operation(summary = "获取操作历史记录", description = "获取操作历史记录,支持按操作模块、操作结果筛选和结果信息模糊搜索") + public ApiResponse> getOperationHistory( + @Parameter(description = "操作模块(0-会员码管理/1-Excel导入管理等)") + @RequestParam(value = "operationModule", required = false) Integer operationModule, + @Parameter(description = "操作结果(成功/失败)") + @RequestParam(value = "operationResult", required = false) String operationResult, + @Parameter(description = "结果信息关键词(支持模糊搜索)") + @RequestParam(value = "keyword", required = false) String keyword, + HttpServletRequest httpServletRequest) { + + try { + // 权限校验:仅管理员可以查看 + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)) { + return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "无权限查看操作历史"); + } + + log.info("获取操作历史,操作模块:{},操作结果:{},关键词:{}", operationModule, operationResult, keyword); + + // 构建查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 添加操作模块筛选条件 + if (operationModule != null && operationModule >= 0) { + queryWrapper.eq("operationModule", operationModule); + } + + // 添加操作结果筛选条件 + if (operationResult != null && !operationResult.trim().isEmpty()) { + if (!operationResult.equals("成功") && !operationResult.equals("失败")) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "操作结果只能是'成功'或'失败'"); + } + queryWrapper.eq("operationResult", operationResult); + } + + // 添加结果信息模糊搜索条件 + if (keyword != null && !keyword.trim().isEmpty()) { + queryWrapper.like("resultMessage", keyword.trim()); + } + + // 按操作时间降序排序 + queryWrapper.orderByDesc("operationTime"); + + // 查询操作历史 + List records = operationHistoryService.list(queryWrapper); + + log.info("操作历史查询成功,共{}条记录", records.size()); + + return ResultUtils.success(records); + + } catch (Exception e) { + log.error("获取操作历史失败", e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取操作历史失败:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/SmsController.java b/src/main/java/com/xy/xyaicpzs/controller/SmsController.java new file mode 100644 index 0000000..828751b --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/SmsController.java @@ -0,0 +1,48 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.service.SmsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 短信控制器 + */ +@RestController +@RequestMapping("/sms") +@Tag(name = "短信接口", description = "提供短信验证码相关功能") +public class SmsController { + + @Autowired + private SmsService smsService; + + /** + * 发送短信验证码 + * + * @param phoneNumber 手机号 + * @return 发送结果 + */ + @PostMapping("/sendCode") + @Operation(summary = "发送短信验证码", description = "向指定手机号发送验证码,每个手机号每天最多发送3次") + public ApiResponse sendVerificationCode( + @Parameter(description = "手机号码", required = true) + @RequestParam String phoneNumber) { + try { + boolean success = smsService.sendVerificationCode(phoneNumber); + if (success) { + return ResultUtils.success(true); + } else { + return ResultUtils.error(40001, "发送验证码失败,请稍后重试或联系客服"); + } + } catch (Exception e) { + return ResultUtils.error(50000, "发送验证码异常:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/SpeechRecognitionController.java b/src/main/java/com/xy/xyaicpzs/controller/SpeechRecognitionController.java new file mode 100644 index 0000000..ee5b360 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/SpeechRecognitionController.java @@ -0,0 +1,83 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.util.SpeechRecognizerDemo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * 语音识别控制器 + */ +@RestController +@RequestMapping("/api/speech") +public class SpeechRecognitionController { + + @Autowired + private SpeechRecognizerDemo speechRecognizer; + + /** + * 识别本地语音文件 + * @param filePath 文件路径 + * @param sampleRate 采样率 + * @return 识别结果 + */ + @GetMapping("/recognize") + public ApiResponse> recognizeSpeech( + @RequestParam("filePath") String filePath, + @RequestParam(value = "sampleRate", defaultValue = "16000") int sampleRate) { + + String text = speechRecognizer.speechToText(filePath, sampleRate); + Map result = new HashMap<>(); + result.put("text", text); + return ResultUtils.success(result); + } + + /** + * 上传并识别语音文件 + * @param file 上传的语音文件 + * @param sampleRate 采样率 + * @return 识别结果 + */ + @PostMapping("/upload-and-recognize") + public ApiResponse> uploadAndRecognize( + @RequestParam("file") MultipartFile file, + @RequestParam(value = "sampleRate", defaultValue = "16000") int sampleRate) { + + if (file.isEmpty()) { + return ResultUtils.error(40001, "上传文件不能为空"); + } + + try { + // 创建临时目录 + String tempDir = System.getProperty("java.io.tmpdir"); + String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); + Path filePath = Paths.get(tempDir, fileName); + + // 保存上传的文件 + file.transferTo(filePath.toFile()); + + // 识别语音 + String text = speechRecognizer.speechToText(filePath.toString(), sampleRate); + + // 删除临时文件 + Files.deleteIfExists(filePath); + + Map result = new HashMap<>(); + result.put("text", text); + return ResultUtils.success(result); + } catch (IOException e) { + return ResultUtils.error(50000, "文件处理失败:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/UserController.java b/src/main/java/com/xy/xyaicpzs/controller/UserController.java new file mode 100644 index 0000000..c09e0c1 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/UserController.java @@ -0,0 +1,578 @@ +package com.xy.xyaicpzs.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.xy.xyaicpzs.common.DeleteRequest; +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.requset.VipCodeActivateRequest; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.domain.dto.user.*; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.domain.vo.UserVO; +import com.xy.xyaicpzs.exception.BusinessException; +import com.xy.xyaicpzs.service.UserService; +import com.xy.xyaicpzs.service.VipCodeService; +import com.xy.xyaicpzs.service.SmsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 用户接口 + */ +@Slf4j +@RestController +@RequestMapping("/user") +@Tag(name = "用户管理", description = "用户管理相关接口") +public class UserController { + + @Resource + private UserService userService; + + @Resource + private VipCodeService vipCodeService; + + @Resource + private SmsService smsService; + + // region 登录相关 + + /** + * 用户登录 + * + * @param userLoginRequest + * @param request + * @return + */ + @PostMapping("/login") + @Operation(summary = "用户登录", description = "用户登录接口") + public ApiResponse userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) { + if (userLoginRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + String userAccount = userLoginRequest.getUserAccount(); + String userPassword = userLoginRequest.getUserPassword(); + if (StringUtils.isAnyBlank(userAccount, userPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = userService.userLogin(userAccount, userPassword, request); + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return ResultUtils.success(userVO); + } + + /** + * 用户注销 + * + * @param request + * @return + */ + @PostMapping("/logout") + @Operation(summary = "用户注销", description = "用户注销接口") + public ApiResponse userLogout(HttpServletRequest request) { + if (request == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + boolean result = userService.userLogout(request); + return ResultUtils.success(result); + } + + /** + * 获取当前登录用户 + * + * @param request + * @return + */ + @GetMapping("/get/login") + @Operation(summary = "获取当前登录用户", description = "获取当前登录用户信息") + public ApiResponse getLoginUser(HttpServletRequest request) { + User user = userService.getLoginUser(request); + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return ResultUtils.success(userVO); + } + + // endregion + + // region 增删改查 + + /** + * 创建用户 + * + * @param userAddRequest + * @param request + * @return + */ + @PostMapping("/add") + @Operation(summary = "创建用户", description = "管理员创建用户") + public ApiResponse addUser(@RequestBody UserAddRequest userAddRequest, HttpServletRequest request) { + if (userAddRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + + // 参数校验 + String userAccount = userAddRequest.getUserAccount(); + String userPassword = userAddRequest.getUserPassword(); + String password = userAddRequest.getPassword(); + String phone = userAddRequest.getPhone(); + + // 如果userPassword为空但password不为空,则使用password + if (StringUtils.isBlank(userPassword) && StringUtils.isNotBlank(password)) { + userAddRequest.setUserPassword(password); + userPassword = password; + } + + if (StringUtils.isAnyBlank(userAccount, userPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号或密码不能为空"); + } + + if (phone != null && !phone.isEmpty()) { + // 如果提供了手机号,可以进行手机号格式校验 + if (phone.length() != 11) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确"); + } + } + + User user = new User(); + BeanUtils.copyProperties(userAddRequest, user); + + // 密码加密,使用Service层的加密方法 + String encryptPassword = userService.encryptPassword(userPassword); + user.setUserPassword(encryptPassword); + + boolean result = userService.save(user); + if (!result) { + throw new BusinessException(ErrorCode.OPERATION_ERROR); + } + return ResultUtils.success(user.getId()); + } + + /** + * 修改用户状态 + * + * @param userStatusUpdateRequest 用户状态更新请求 + * @param request HTTP请求 + * @return 修改结果 + */ + @PostMapping("/update-status") + @Operation(summary = "修改用户状态", description = "管理员修改用户状态(正常/封禁)") + public ApiResponse updateUserStatus(@RequestBody UserStatusUpdateRequest userStatusUpdateRequest, + HttpServletRequest request) { + if (userStatusUpdateRequest == null || userStatusUpdateRequest.getId() == null + || userStatusUpdateRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户ID不正确"); + } + + Long id = userStatusUpdateRequest.getId(); + Integer status = userStatusUpdateRequest.getStatus(); + + // 校验状态值 + if (status == null || (status != 0 && status != 1)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "状态值不正确,应为0(正常)或1(封禁)"); + } + + // 确认操作人员是否为管理员 + User loginUser = userService.getLoginUser(request); + if (!userService.isAdmin(loginUser)) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限"); + } + + // 检查目标用户是否存在 + User user = userService.getById(id); + if (user == null) { + throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在"); + } + + // 更新用户状态 + user.setStatus(status); + boolean result = userService.updateById(user); + if (!result) { + throw new BusinessException(ErrorCode.OPERATION_ERROR, "操作失败"); + } + + return ResultUtils.success(true); + } + + /** + * 删除用户 + * + * @param deleteRequest + * @param request + * @return + */ + @PostMapping("/delete") + @Operation(summary = "删除用户", description = "管理员删除用户") + public ApiResponse deleteUser(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) { + if (deleteRequest == null || deleteRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + boolean b = userService.removeById(deleteRequest.getId()); + return ResultUtils.success(b); + } + + /** + * 更新用户 + * + * @param userUpdateRequest + * @param request + * @return + */ + @PostMapping("/update") + @Operation(summary = "更新用户", description = "更新用户信息") + public ApiResponse updateUser(@RequestBody UserUpdateRequest userUpdateRequest, HttpServletRequest request) { + if (userUpdateRequest == null || userUpdateRequest.getId() == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + + // 参数校验 + String userPassword = userUpdateRequest.getUserPassword(); + String password = userUpdateRequest.getPassword(); + String phone = userUpdateRequest.getPhone(); + + // 如果userPassword为空但password不为空,则使用password + if (StringUtils.isBlank(userPassword) && StringUtils.isNotBlank(password)) { + userUpdateRequest.setUserPassword(password); + userPassword = password; + } + + if (phone != null && !phone.isEmpty()) { + // 如果提供了手机号,可以进行手机号格式校验 + if (phone.length() != 11) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确"); + } + } + + User user = new User(); + BeanUtils.copyProperties(userUpdateRequest, user); + + // 如果更新了密码,需要进行加密 + if (StringUtils.isNotBlank(userPassword)) { + String encryptPassword = userService.encryptPassword(userPassword); + user.setUserPassword(encryptPassword); + } + + boolean result = userService.updateById(user); + return ResultUtils.success(result); + } + + /** + * 根据 id 获取用户 + * + * @param id + * @param request + * @return + */ + @GetMapping("/get") + @Operation(summary = "根据ID获取用户", description = "根据用户ID获取用户信息") + public ApiResponse getUserById(@RequestParam("id") long id, HttpServletRequest request) { + if (id <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = userService.getById(id); + if (user == null) { + throw new BusinessException(ErrorCode.NOT_FOUND_ERROR); + } + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return ResultUtils.success(userVO); + } + + /** + * 获取用户列表 + * + * @param userQueryRequest + * @param request + * @return + */ + @GetMapping("/list") + @Operation(summary = "获取用户列表", description = "获取用户列表,支持用户名/手机号模糊匹配和角色状态筛选") + public ApiResponse> listUser(UserQueryRequest userQueryRequest, HttpServletRequest request) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (userQueryRequest != null) { + // 用户名模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getUserName())) { + queryWrapper.like("userName", userQueryRequest.getUserName()); + } + + // 手机号模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getPhone())) { + queryWrapper.like("phone", userQueryRequest.getPhone()); + } + + // 账号模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getUserAccount())) { + queryWrapper.like("userAccount", userQueryRequest.getUserAccount()); + } + + // 用户角色精确匹配 + if (userQueryRequest.getUserRole() != null) { + queryWrapper.eq("userRole", userQueryRequest.getUserRole()); + } + + // 用户状态精确匹配 + if (userQueryRequest.getStatus() != null) { + queryWrapper.eq("status", userQueryRequest.getStatus()); + } + + // 会员状态匹配 + if (userQueryRequest.getIsVip() != null) { + queryWrapper.eq("isVip", userQueryRequest.getIsVip()); + } + } + + List userList = userService.list(queryWrapper); + List userVOList = userList.stream().map(user -> { + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return userVO; + }).collect(Collectors.toList()); + return ResultUtils.success(userVOList); + } + + /** + * 分页获取用户列表 + * + * @param userQueryRequest + * @param request + * @return + */ + @GetMapping("/list/page") + @Operation(summary = "分页获取用户列表", description = "分页获取用户列表,支持用户名/手机号模糊匹配和角色状态筛选") + public ApiResponse> listUserByPage(UserQueryRequest userQueryRequest, HttpServletRequest request) { + long current = 1; + long size = 10; + + if (userQueryRequest != null) { + current = userQueryRequest.getCurrent(); + size = userQueryRequest.getPageSize(); + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (userQueryRequest != null) { + // 用户名模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getUserName())) { + queryWrapper.like("userName", userQueryRequest.getUserName()); + } + + // 手机号模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getPhone())) { + queryWrapper.like("phone", userQueryRequest.getPhone()); + } + + // 账号模糊匹配 + if (StringUtils.isNotBlank(userQueryRequest.getUserAccount())) { + queryWrapper.like("userAccount", userQueryRequest.getUserAccount()); + } + + // 用户角色精确匹配 + if (userQueryRequest.getUserRole() != null) { + queryWrapper.eq("userRole", userQueryRequest.getUserRole()); + } + + // 用户状态精确匹配 + if (userQueryRequest.getStatus() != null) { + queryWrapper.eq("status", userQueryRequest.getStatus()); + } + + // 会员状态匹配 + if (userQueryRequest.getIsVip() != null) { + queryWrapper.eq("isVip", userQueryRequest.getIsVip()); + } + } + + Page userPage = userService.page(new Page<>(current, size), queryWrapper); + + // 创建新的Page对象用于返回UserVO + Page userVOPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal()); + List userVOList = userPage.getRecords().stream().map(user -> { + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return userVO; + }).collect(Collectors.toList()); + userVOPage.setRecords(userVOList); + return ResultUtils.success(userVOPage); + } + + /** + * 获取用户统计信息 + * + * @return 包含总用户数和会员数的统计信息 + */ + @GetMapping("/count") + @Operation(summary = "获取用户统计信息", description = "获取系统中总用户数和会员数量") + public ApiResponse> getUserCount() { + // 获取总用户数 + long totalUserCount = userService.count(); + + // 获取会员数量(isVip=1) + QueryWrapper vipQueryWrapper = new QueryWrapper<>(); + vipQueryWrapper.eq("isVip", 1); + long vipUserCount = userService.count(vipQueryWrapper); + + // 获取正常状态用户数量(status=0) + QueryWrapper normalStatusWrapper = new QueryWrapper<>(); + normalStatusWrapper.eq("status", 0); + long normalUserCount = userService.count(normalStatusWrapper); + + // 获取封禁状态用户数量(status=1) + QueryWrapper bannedStatusWrapper = new QueryWrapper<>(); + bannedStatusWrapper.eq("status", 1); + long bannedUserCount = userService.count(bannedStatusWrapper); + + // 构造返回结果 + Map countMap = new HashMap<>(); + countMap.put("totalUserCount", totalUserCount); + countMap.put("vipUserCount", vipUserCount); + countMap.put("normalUserCount", normalUserCount); + countMap.put("bannedUserCount", bannedUserCount); + + return ResultUtils.success(countMap); + } + + /** + * 激活会员码 + * + * @param request 会员码激活请求 + * @return 是否激活成功 + */ + @PostMapping("/activate-vip") + @Operation(summary = "激活会员码", description = "用户使用会员码激活会员服务") + public ApiResponse activateVipCode(@RequestBody VipCodeActivateRequest request) { + if (request == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空"); + } + if (request.getUserId() == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户ID不能为空"); + } + if (StringUtils.isBlank(request.getCode())) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员码不能为空"); + } + + try { + boolean result = vipCodeService.activateVipCode(request.getUserId(), request.getCode()); + return ResultUtils.success(result); + } catch (IllegalArgumentException e) { + log.error("会员码激活失败:{}", e.getMessage()); + throw new BusinessException(ErrorCode.PARAMS_ERROR, e.getMessage()); + } catch (RuntimeException e) { + log.error("会员码激活系统错误:{}", e.getMessage()); + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "会员码激活失败,请稍后重试"); + } + } + + /** + * 手机号注册 + * + * @param userPhoneRegisterRequest 手机号注册请求 + * @return 用户ID + */ + @PostMapping("/phone/register") + @Operation(summary = "手机号注册", description = "使用手机号和验证码注册用户") + public ApiResponse userPhoneRegister(@RequestBody UserPhoneRegisterRequest userPhoneRegisterRequest) { + if (userPhoneRegisterRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + long result = userService.userPhoneRegister(userPhoneRegisterRequest); + return ResultUtils.success(result); + } + + /** + * 手机号登录 + * + * @param userPhoneLoginRequest 手机号登录请求 + * @param request HTTP请求 + * @return 用户信息 + */ + @PostMapping("/phone/login") + @Operation(summary = "手机号登录", description = "使用手机号和验证码登录") + public ApiResponse userPhoneLogin(@RequestBody UserPhoneLoginRequest userPhoneLoginRequest, HttpServletRequest request) { + if (userPhoneLoginRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = userService.userPhoneLogin(userPhoneLoginRequest, request); + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return ResultUtils.success(userVO); + } + + /** + * 重置密码 + * + * @param resetPasswordRequest 重置密码请求 + * @return 是否重置成功 + */ + @PostMapping("/reset-password") + @Operation(summary = "重置密码", description = "使用手机号和验证码重置密码") + public ApiResponse resetPassword(@RequestBody ResetPasswordRequest resetPasswordRequest) { + if (resetPasswordRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空"); + } + + String phone = resetPasswordRequest.getPhone(); + String code = resetPasswordRequest.getCode(); + String newPassword = resetPasswordRequest.getNewPassword(); + String confirmPassword = resetPasswordRequest.getConfirmPassword(); + + // 校验参数 + if (StringUtils.isAnyBlank(phone, code, newPassword, confirmPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不能为空"); + } + + // 校验手机号格式 + if (phone.length() != 11) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确"); + } + + // 校验两次密码是否一致 + if (!newPassword.equals(confirmPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致"); + } + + // 密码长度校验 + if (newPassword.length() < 8) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度不能小于8位"); + } + + // 验证短信验证码 + boolean isCodeValid = smsService.verifyCode(phone, code); + if (!isCodeValid) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误或已过期"); + } + + // 查询用户是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("phone", phone); + User user = userService.getOne(queryWrapper); + if (user == null) { + throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "未找到该手机号注册的用户"); + } + + // 更新密码 + String encryptPassword = userService.encryptPassword(newPassword); + user.setUserPassword(encryptPassword); + boolean result = userService.updateById(user); + + if (!result) { + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "密码重置失败,请稍后重试"); + } + + ApiResponse response = ResultUtils.success(true); + response.setMessage("密码重置成功"); + return response; + } + + // endregion +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/VipCodeController.java b/src/main/java/com/xy/xyaicpzs/controller/VipCodeController.java new file mode 100644 index 0000000..c646b47 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/VipCodeController.java @@ -0,0 +1,298 @@ +package com.xy.xyaicpzs.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.requset.GenerateVipCodesRequest; +import com.xy.xyaicpzs.common.requset.VipCodeQueryRequest; +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.domain.entity.VipCode; +import com.xy.xyaicpzs.domain.vo.VipCodeVO; +import com.xy.xyaicpzs.exception.BusinessException; +import com.xy.xyaicpzs.service.OperationHistoryService; +import com.xy.xyaicpzs.service.UserService; +import com.xy.xyaicpzs.service.VipCodeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 会员码管理接口 + */ +@Slf4j +@RestController +@RequestMapping("/vip-code") +@Tag(name = "会员码管理", description = "会员码管理相关接口") +public class VipCodeController { + + @Resource + private VipCodeService vipCodeService; + + @Autowired + private UserService userService; + + @Autowired + private OperationHistoryService operationHistoryService; + + /** + * 批量生成会员码 + * + * @param request 生成会员码请求 + * @return 生成成功的数量 + */ + @PostMapping("/generate") + @Operation(summary = "批量生成会员码", description = "管理员批量生成会员码") + public ApiResponse generateVipCodes(@RequestBody GenerateVipCodesRequest request, + HttpServletRequest httpServletRequest) { + + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + Long userId = loginUser.getId(); + String userName = loginUser.getUserName(); + + if (request == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空"); + } + if (request.getNumCodes() == null || request.getNumCodes() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "生成数量必须大于0"); + } + if (request.getVipExpireTime() == null || request.getVipExpireTime() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数必须大于0"); + } + if (request.getNumCodes() > 1000) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "单次生成数量不能超过1000"); + } + + try { + int result = vipCodeService.generateVipCodes(request.getNumCodes(), request.getVipExpireTime(), userId, userName); + + // 记录操作历史 - 成功 + String resultMessage = String.format("%s成功生成%d个会员码,有效月数:%d", userName, result, request.getVipExpireTime()); + operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "成功", resultMessage); + + return ResultUtils.success(result); + } catch (IllegalArgumentException e) { + log.error("生成会员码参数错误:{}", e.getMessage()); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s生成会员码失败:%s,请求数量:%d,有效月数:%d", + userName, e.getMessage(), request.getNumCodes(), request.getVipExpireTime()); + operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "失败", resultMessage); + + throw new BusinessException(ErrorCode.PARAMS_ERROR, e.getMessage()); + } catch (RuntimeException e) { + log.error("生成会员码系统错误:{}", e.getMessage()); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s生成会员码系统错误:%s,请求数量:%d,有效月数:%d", + userName, e.getMessage(), request.getNumCodes(), request.getVipExpireTime()); + operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "失败", resultMessage); + + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "生成会员码失败,请稍后重试"); + } + } + + /** + * 获取一个可用的会员码 + * + * @param vipExpireTime 会员有效月数(1或12) + * @return 可用的会员码 + */ + @GetMapping("/available") + @Operation(summary = "获取可用会员码", description = "根据有效月数获取一个可用的会员码") + public ApiResponse getAvailableVipCode(@RequestParam("vipExpireTime") Integer vipExpireTime, + HttpServletRequest httpServletRequest) { + + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + Long userId = loginUser.getId(); + String userName = loginUser.getUserName(); + + if (vipExpireTime == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数不能为空"); + } + if (vipExpireTime != 1 && vipExpireTime != 12) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数只能是1或12"); + } + + try { + String code = vipCodeService.getAvailableVipCode(vipExpireTime, userId, userName); + if (code == null) { + // 记录操作历史 - 失败 + String resultMessage = String.format("%s获取可用会员码失败:没有找到可用的会员码,有效月数:%d", userName, vipExpireTime); + operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage); + + throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有找到可用的会员码"); + } + + // 记录操作历史 - 成功 + String resultMessage = String.format("%s成功获取可用会员码:%s,有效月数:%d", userName, code, vipExpireTime); + operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "成功", resultMessage); + + return ResultUtils.success(code); + } catch (IllegalArgumentException e) { + log.error("获取可用会员码参数错误:{}", e.getMessage()); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s获取可用会员码参数错误:%s,有效月数:%d", userName, e.getMessage(), vipExpireTime); + operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage); + + throw new BusinessException(ErrorCode.PARAMS_ERROR, e.getMessage()); + } catch (Exception e) { + log.error("获取可用会员码系统错误:{}", e.getMessage()); + + // 记录操作历史 - 失败 + String resultMessage = String.format("%s获取可用会员码系统错误:%s,有效月数:%d", userName, e.getMessage(), vipExpireTime); + operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage); + + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取可用会员码失败,请生成后获取。"); + } + } + + /** + * 分页获取会员码列表 + * + * @param vipCodeQueryRequest 会员码查询请求 + * @param httpServletRequest Http请求 + * @return 分页会员码列表 + */ + @GetMapping("/list/page") + @Operation(summary = "分页获取会员码列表", description = "分页获取会员码列表,支持根据会员码、使用状态和时间筛选") + public ApiResponse> listVipCodesByPage(VipCodeQueryRequest vipCodeQueryRequest, + HttpServletRequest httpServletRequest) { + // 权限校验 + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + + if (vipCodeQueryRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空"); + } + + long current = vipCodeQueryRequest.getCurrent(); + long pageSize = vipCodeQueryRequest.getPageSize(); + + // 构建查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 根据会员码模糊查询 + if (StringUtils.isNotBlank(vipCodeQueryRequest.getCode())) { + queryWrapper.like("code", vipCodeQueryRequest.getCode()); + } + + // 根据使用状态筛选 + if (vipCodeQueryRequest.getIsUse() != null) { + queryWrapper.eq("isUse", vipCodeQueryRequest.getIsUse()); + } + + // 根据会员有效月数筛选 + if (vipCodeQueryRequest.getVipExpireTime() != null) { + queryWrapper.eq("vipExpireTime", vipCodeQueryRequest.getVipExpireTime()); + } + + // 根据创建人ID筛选 + if (vipCodeQueryRequest.getCreatedUserId() != null) { + queryWrapper.eq("createdUserId", vipCodeQueryRequest.getCreatedUserId()); + } + + // 根据创建人名称模糊查询 + if (StringUtils.isNotBlank(vipCodeQueryRequest.getCreatedUserName())) { + queryWrapper.like("createdUserName", vipCodeQueryRequest.getCreatedUserName()); + } + + // 根据使用人ID筛选 + if (vipCodeQueryRequest.getUsedUserId() != null) { + queryWrapper.eq("usedUserId", vipCodeQueryRequest.getUsedUserId()); + } + + // 根据创建时间范围筛选 + if (vipCodeQueryRequest.getStartTime() != null && vipCodeQueryRequest.getEndTime() != null) { + queryWrapper.between("createTime", vipCodeQueryRequest.getStartTime(), vipCodeQueryRequest.getEndTime()); + } else if (vipCodeQueryRequest.getStartTime() != null) { + queryWrapper.ge("createTime", vipCodeQueryRequest.getStartTime()); + } else if (vipCodeQueryRequest.getEndTime() != null) { + queryWrapper.le("createTime", vipCodeQueryRequest.getEndTime()); + } + + // 按会员编号升序排序(从小到大) + queryWrapper.orderByAsc("vipNumber"); + + // 执行分页查询 + Page vipCodePage = vipCodeService.page(new Page<>(current, pageSize), queryWrapper); + + // 转换为VO对象 + List vipCodeVOList = vipCodePage.getRecords().stream().map(vipCode -> { + VipCodeVO vipCodeVO = new VipCodeVO(); + BeanUtils.copyProperties(vipCode, vipCodeVO); + return vipCodeVO; + }).collect(Collectors.toList()); + + // 创建VO分页对象,确保正确传递所有分页信息 + Page vipCodeVOPage = new Page<>(vipCodePage.getCurrent(), vipCodePage.getSize(), vipCodePage.getTotal()); + vipCodeVOPage.setRecords(vipCodeVOList); + // 手动设置pages值 + vipCodeVOPage.setPages(vipCodePage.getPages()); + + return ResultUtils.success(vipCodeVOPage); + } + + /** + * 获取会员码统计数量 + * + * @param httpServletRequest Http请求 + * @return 会员码统计数量 + */ + @GetMapping("/count") + @Operation(summary = "获取会员码统计数量", description = "获取系统中会员码总数、可用会员码和已使用会员码的数量") + public ApiResponse> getVipCodeCount(HttpServletRequest httpServletRequest) { + // 权限校验 + User loginUser = userService.getLoginUser(httpServletRequest); + if (!userService.isAdmin(loginUser)){ + return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限"); + } + + try { + // 构建查询条件 - 总数 + long totalCount = vipCodeService.count(); + + // 构建查询条件 - 已使用的会员码 + QueryWrapper usedQueryWrapper = new QueryWrapper<>(); + usedQueryWrapper.eq("isUse", 1); + long usedCount = vipCodeService.count(usedQueryWrapper); + + // 构建查询条件 - 可用的会员码 + QueryWrapper availableQueryWrapper = new QueryWrapper<>(); + availableQueryWrapper.eq("isUse", 0); + long availableCount = vipCodeService.count(availableQueryWrapper); + + // 构造返回结果 + Map countMap = new HashMap<>(); + countMap.put("totalCount", totalCount); + countMap.put("availableCount", availableCount); + countMap.put("usedCount", usedCount); + + return ResultUtils.success(countMap); + } catch (Exception e) { + log.error("获取会员码统计数量失败:{}", e.getMessage()); + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取会员码统计数量失败,请稍后重试"); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/controller/VipExchangeRecordController.java b/src/main/java/com/xy/xyaicpzs/controller/VipExchangeRecordController.java new file mode 100644 index 0000000..a18c3e6 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/controller/VipExchangeRecordController.java @@ -0,0 +1,139 @@ +package com.xy.xyaicpzs.controller; + +import com.xy.xyaicpzs.common.response.ApiResponse; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.domain.entity.VipExchangeRecord; +import com.xy.xyaicpzs.service.VipExchangeRecordService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * VIP兑换记录控制器 + */ +@RestController +@RequestMapping("/vip-exchange-record") +@Slf4j +@Tag(name = "VIP兑换记录管理", description = "VIP兑换记录相关接口") +public class VipExchangeRecordController { + + @Autowired + private VipExchangeRecordService vipExchangeRecordService; + + /** + * 根据用户ID获取所有兑换记录 + */ + @GetMapping("/user/{userId}") + @Operation(summary = "获取用户兑换记录", description = "根据用户ID获取该用户的所有VIP兑换记录") + public ApiResponse> getExchangeRecordsByUserId( + @Parameter(description = "用户ID", required = true) + @PathVariable("userId") Long userId) { + + try { + log.info("获取用户兑换记录,用户ID:{}", userId); + + // 参数校验 + if (userId == null || userId <= 0) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "用户ID不能为空且必须大于0"); + } + + // 查询用户兑换记录 + List records = vipExchangeRecordService.getExchangeRecordsByUserId(userId); + + log.info("用户ID:{} 的兑换记录查询成功,共{}条记录", userId, records.size()); + + return ResultUtils.success(records); + + } catch (Exception e) { + log.error("获取用户兑换记录失败,用户ID:{}", userId, e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取兑换记录失败:" + e.getMessage()); + } + } + + /** + * 根据用户ID获取兑换记录(带分页) + */ + @GetMapping("/user/{userId}/page") + @Operation(summary = "分页获取用户兑换记录", description = "根据用户ID分页获取该用户的VIP兑换记录") + public ApiResponse> getExchangeRecordsByUserIdWithPage( + @Parameter(description = "用户ID", required = true) + @PathVariable("userId") Long userId, + @Parameter(description = "页码,从1开始", required = false) + @RequestParam(value = "page", defaultValue = "1") Integer page, + @Parameter(description = "每页大小", required = false) + @RequestParam(value = "size", defaultValue = "10") Integer size) { + + try { + log.info("分页获取用户兑换记录,用户ID:{},页码:{},每页大小:{}", userId, page, size); + + // 参数校验 + if (userId == null || userId <= 0) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "用户ID不能为空且必须大于0"); + } + + if (page < 1) { + page = 1; + } + if (size < 1 || size > 100) { + size = 10; + } + + // 查询用户兑换记录 + List allRecords = vipExchangeRecordService.getExchangeRecordsByUserId(userId); + + // 手动分页 + int start = (page - 1) * size; + int end = Math.min(start + size, allRecords.size()); + List pageRecords = allRecords.subList(start, end); + + log.info("用户ID:{} 的兑换记录分页查询成功,总记录数:{},当前页记录数:{}", + userId, allRecords.size(), pageRecords.size()); + + return ResultUtils.success(pageRecords); + + } catch (Exception e) { + log.error("分页获取用户兑换记录失败,用户ID:{}", userId, e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取兑换记录失败:" + e.getMessage()); + } + } + + /** + * 根据兑换记录ID获取详情 + */ + @GetMapping("/{recordId}") + @Operation(summary = "获取兑换记录详情", description = "根据兑换记录ID获取详细信息") + public ApiResponse getExchangeRecordById( + @Parameter(description = "兑换记录ID", required = true) + @PathVariable("recordId") Long recordId) { + + try { + log.info("获取兑换记录详情,记录ID:{}", recordId); + + // 参数校验 + if (recordId == null || recordId <= 0) { + return ResultUtils.error(ErrorCode.PARAMS_ERROR, "兑换记录ID不能为空且必须大于0"); + } + + // 查询兑换记录 + VipExchangeRecord record = vipExchangeRecordService.getById(recordId); + + if (record == null) { + return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "兑换记录不存在"); + } + + log.info("兑换记录详情查询成功,记录ID:{}", recordId); + + return ResultUtils.success(record); + + } catch (Exception e) { + log.error("获取兑换记录详情失败,记录ID:{}", recordId, e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "获取兑换记录详情失败:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/ResetPasswordRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/ResetPasswordRequest.java new file mode 100644 index 0000000..fbcad14 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/ResetPasswordRequest.java @@ -0,0 +1,34 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 重置密码请求 + */ +@Data +public class ResetPasswordRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户手机号 + */ + private String phone; + + /** + * 短信验证码 + */ + private String code; + + /** + * 新密码 + */ + private String newPassword; + + /** + * 确认新密码 + */ + private String confirmPassword; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserAddRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserAddRequest.java new file mode 100644 index 0000000..0fe715b --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserAddRequest.java @@ -0,0 +1,70 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户创建请求 + */ +@Data +public class UserAddRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 电话 + */ + private String phone; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 性别 + */ + private Integer gender; + + /** + * 用户角色:user / admin + */ + private String userRole; + + /** + * 密码 + */ + private String userPassword; + + /** + * 密码(兼容格式) + */ + private String password; + + /** + * 是否会员:0-非会员,1-会员 + */ + private Integer isVip; + + /** + * 会员到期时间 + */ + private Date vipExpire; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserLoginRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserLoginRequest.java new file mode 100644 index 0000000..2eb2b35 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserLoginRequest.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户登录请求 + */ +@Data +public class UserLoginRequest implements Serializable { + + private static final long serialVersionUID = 3191241716373120793L; + + private String userAccount; + + private String userPassword; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneLoginRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneLoginRequest.java new file mode 100644 index 0000000..aa9bf2f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneLoginRequest.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户手机号登录请求 + */ +@Data +@Schema(description = "用户手机号登录请求") +public class UserPhoneLoginRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "手机号") + private String phone; + + @Schema(description = "验证码") + private String code; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneRegisterRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneRegisterRequest.java new file mode 100644 index 0000000..f67251e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserPhoneRegisterRequest.java @@ -0,0 +1,34 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户手机号注册请求 + */ +@Data +@Schema(description = "用户手机号注册请求") +public class UserPhoneRegisterRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "用户账号") + private String userAccount; + + @Schema(description = "用户名称") + private String userName; + + @Schema(description = "用户密码") + private String userPassword; + + @Schema(description = "确认密码") + private String checkPassword; + + @Schema(description = "手机号") + private String phone; + + @Schema(description = "验证码") + private String code; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserQueryRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserQueryRequest.java new file mode 100644 index 0000000..e6cab54 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserQueryRequest.java @@ -0,0 +1,57 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import com.xy.xyaicpzs.common.PageRequest; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * 用户查询请求 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class UserQueryRequest extends PageRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 手机号 + */ + private String phone; + + /** + * 性别 + */ + private Integer gender; + + /** + * 用户角色:user / admin + */ + private String userRole; + + /** + * 是否会员:0-非会员,1-会员 + */ + private Integer isVip; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserRegisterRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserRegisterRequest.java new file mode 100644 index 0000000..e16e3de --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserRegisterRequest.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户注册请求 + */ +@Data +public class UserRegisterRequest implements Serializable { + + private static final long serialVersionUID = 3191241716373120793L; + + private String userAccount; + + private String userName; + + private String userPassword; + + private String checkPassword; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserStatusUpdateRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserStatusUpdateRequest.java new file mode 100644 index 0000000..dd47854 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserStatusUpdateRequest.java @@ -0,0 +1,24 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户状态更新请求 + */ +@Data +public class UserStatusUpdateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户id + */ + private Long id; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserUpdateRequest.java b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserUpdateRequest.java new file mode 100644 index 0000000..839a43d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/dto/user/UserUpdateRequest.java @@ -0,0 +1,75 @@ +package com.xy.xyaicpzs.domain.dto.user; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户更新请求 + */ +@Data +public class UserUpdateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 电话 + */ + private String phone; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 性别 + */ + private Integer gender; + + /** + * 用户角色:user / admin + */ + private String userRole; + + /** + * 密码 + */ + private String userPassword; + + /** + * 密码(兼容格式) + */ + private String password; + + /** + * 是否会员:0-非会员,1-会员 + */ + private Integer isVip; + + /** + * 会员到期时间 + */ + private Date vipExpire; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistory100.java b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistory100.java new file mode 100644 index 0000000..c2baf7a --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistory100.java @@ -0,0 +1,50 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 蓝球最近100期数据表 + * @TableName blue_history_100 + */ +@TableName(value ="blue_history_100") +@Data +public class BlueHistory100 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 出现频次 + */ + private Integer frequencyCount; + + /** + * 平均隐现期(次) + */ + private Double averageInterval; + + /** + * 当前隐现期(次) + */ + private Integer nowInterval; + + /** + * 最多连出期(次) + */ + private Integer maxConsecutiveCount; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryAll.java b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryAll.java new file mode 100644 index 0000000..298813c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryAll.java @@ -0,0 +1,55 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 蓝球全部历史数据表 + * @TableName blue_history_all + */ +@TableName(value ="blue_history_all") +@Data +public class BlueHistoryAll { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 出现频次 + */ + private Integer frequencyCount; + + /** + * 出现频率百分比 + */ + private Double frequencyPercentage; + + /** + * 平均隐现期(次) + */ + private Double averageInterval; + + /** + * 最长隐现期(次) + */ + private Integer maxHiddenInterval; + + /** + * 最多连出期(次) + */ + private Integer maxConsecutiveCount; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop.java b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop.java new file mode 100644 index 0000000..81982a0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 蓝球历史数据排行表 + * @TableName blue_history_top + */ +@TableName(value ="blue_history_top") +@Data +public class BlueHistoryTop { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 排行 + */ + private Integer no; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop100.java b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop100.java new file mode 100644 index 0000000..f1ae1dd --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/BlueHistoryTop100.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 创建蓝球100期数据排行表 + * @TableName blue_history_top_100 + */ +@TableName(value ="blue_history_top_100") +@Data +public class BlueHistoryTop100 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 排行 + */ + private Integer no; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/ChatMessage.java b/src/main/java/com/xy/xyaicpzs/domain/entity/ChatMessage.java new file mode 100644 index 0000000..2cdcc7c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/ChatMessage.java @@ -0,0 +1,56 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 聊天消息表 + * @TableName chat_message + */ +@TableName(value ="chat_message") +@Data +public class ChatMessage { + /** + * id + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 会话ID + */ + private String conversationId; + + /** + * 用户ID,关联用户表 + */ + private String studentId; + + /** + * 消息类型(如: 用户提问、AI回答) + */ + private String messageType; + + /** + * 消息内容 + */ + private String content; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 是否删除 0-未删除 1-已删除 + */ + private Integer isDelete; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/History100.java b/src/main/java/com/xy/xyaicpzs/domain/entity/History100.java new file mode 100644 index 0000000..6992743 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/History100.java @@ -0,0 +1,50 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 最近100期数据表 + * @TableName history_100 + */ +@TableName(value ="history_100") +@Data +public class History100 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 出现频次 + */ + private Integer frequencyCount; + + /** + * 平均隐现期(次) + */ + private Double averageInterval; + + /** + * 当前隐现期(次) + */ + private Integer nowInterval; + + /** + * 最多连出期(次) + */ + private Integer maxConsecutiveCount; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryAll.java b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryAll.java new file mode 100644 index 0000000..80acbce --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryAll.java @@ -0,0 +1,55 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 历史数据表 + * @TableName history_all + */ +@TableName(value ="history_all") +@Data +public class HistoryAll { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 出现频次 + */ + private Integer frequencyCount; + + /** + * 出现频率百分比 + */ + private Double frequencyPercentage; + + /** + * 平均间隔 + */ + private Double averageInterval; + + /** + * 最长隐藏间隔 + */ + private Integer maxHiddenInterval; + + /** + * 最大连续出现次数 + */ + private Integer maxConsecutiveCount; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop.java b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop.java new file mode 100644 index 0000000..6133270 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 历史数据排行表 + * @TableName history_top + */ +@TableName(value ="history_top") +@Data +public class HistoryTop { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 排行 + */ + private Integer no; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop100.java b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop100.java new file mode 100644 index 0000000..eb17fe4 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/HistoryTop100.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 创建100期数据排行表 + * @TableName history_top_100 + */ +@TableName(value ="history_top_100") +@Data +public class HistoryTop100 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 排行 + */ + private Integer no; + + /** + * 球号 + */ + private Integer ballNumber; + + /** + * 点系数 + */ + private Double pointCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/LotteryDraws.java b/src/main/java/com/xy/xyaicpzs/domain/entity/LotteryDraws.java new file mode 100644 index 0000000..ca9c840 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/LotteryDraws.java @@ -0,0 +1,60 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 彩票开奖信息表 + * @TableName lottery_draws + */ +@TableName(value ="lottery_draws") +@Data +public class LotteryDraws { + /** + * 开奖期号 + */ + @TableId + private Long drawId; + + /** + * 开奖日期 + */ + private Date drawDate; + + /** + * 红1 + */ + private Integer redBall1; + + /** + * 红2 + */ + private Integer redBall2; + + /** + * 红3 + */ + private Integer redBall3; + + /** + * 红4 + */ + private Integer redBall4; + + /** + * 红5 + */ + private Integer redBall5; + + /** + * 红6 + */ + private Integer redBall6; + + /** + * 蓝球 + */ + private Integer blueBall; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/OperationHistory.java b/src/main/java/com/xy/xyaicpzs/domain/entity/OperationHistory.java new file mode 100644 index 0000000..0539183 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/OperationHistory.java @@ -0,0 +1,56 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 操作历史记录表 + * @TableName operation_history + */ +@TableName(value ="operation_history") +@Data +public class OperationHistory { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 操作用户ID + */ + private Long userId; + + /** + * 操作类型(批量生成会员码/获取可用会员码/Excel导入等) + */ + private String operationType; + + /** + * 操作模块(会员码管理/Excel导入管理等) + */ + private Integer operationModule; + + /** + * 操作结果(成功/失败) + */ + private String operationResult; + + /** + * 结果消息 + */ + private String resultMessage; + + /** + * 操作时间 + */ + private Date operationTime; + + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/PredictRecord.java b/src/main/java/com/xy/xyaicpzs/domain/entity/PredictRecord.java new file mode 100644 index 0000000..25f267f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/PredictRecord.java @@ -0,0 +1,96 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 彩票开奖信息表 + * @TableName predict_record + */ +@TableName(value ="predict_record") +@Data +public class PredictRecord { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 用户ID + */ + private Long userId; + + /** + * 开奖期号 + */ + private Long drawId; + + /** + * 开奖日期 + */ + private Date drawDate; + + /** + * 红1 + */ + private Integer redBall1; + + /** + * 红2 + */ + private Integer redBall2; + + /** + * 红3 + */ + private Integer redBall3; + + /** + * 红4 + */ + private Integer redBall4; + + /** + * 红5 + */ + private Integer redBall5; + + /** + * 红6 + */ + private Integer redBall6; + + /** + * 蓝球 + */ + private Integer blueBall; + + /** + * 预测状态(待开奖/已开奖) + */ + private String predictStatus; + + /** + * 预测结果(未中奖/三等奖/二等奖/一等奖) + */ + private String predictResult; + + /** + * 预测时间 + */ + private Date predictTime; + + /** + * 奖金 + */ + private Long bonus; + + /** + * 类型 + */ + private String type; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T11.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T11.java new file mode 100644 index 0000000..82f2b41 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T11.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t11表(蓝球组红球的面系数) + * @TableName t11 + */ +@TableName(value ="t11") +@Data +public class T11 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 面系数 + */ + private Double faceCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T3.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T3.java new file mode 100644 index 0000000..b805ff3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T3.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t3表(红球组红球的线系数) + * @TableName t3 + */ +@TableName(value ="t3") +@Data +public class T3 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 线系数 + */ + private Double lineCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T4.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T4.java new file mode 100644 index 0000000..f6a9833 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T4.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t4表(蓝球组红球的线系数) + * @TableName t4 + */ +@TableName(value ="t4") +@Data +public class T4 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 线系数 + */ + private Double lineCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T5.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T5.java new file mode 100644 index 0000000..24966e9 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T5.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t5表(蓝球组蓝球的线系数) + * @TableName t5 + */ +@TableName(value ="t5") +@Data +public class T5 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 线系数 + */ + private Double lineCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T6.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T6.java new file mode 100644 index 0000000..685416d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T6.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t6表(红球组蓝球的线系数) + * @TableName t6 + */ +@TableName(value ="t6") +@Data +public class T6 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 线系数 + */ + private Double lineCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T7.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T7.java new file mode 100644 index 0000000..edede85 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T7.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t7表(红球组红球的面系数) + * @TableName t7 + */ +@TableName(value ="t7") +@Data +public class T7 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 面系数 + */ + private Double faceCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/T8.java b/src/main/java/com/xy/xyaicpzs/domain/entity/T8.java new file mode 100644 index 0000000..694e23d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/T8.java @@ -0,0 +1,35 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * t8表(红球组蓝球的面系数) + * @TableName t8 + */ +@TableName(value ="t8") +@Data +public class T8 { + /** + * 唯一标识符 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 主球 + */ + private Integer masterBallNumber; + + /** + * 从球 + */ + private Integer slaveBallNumber; + + /** + * 面系数 + */ + private Double faceCoefficient; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/User.java b/src/main/java/com/xy/xyaicpzs/domain/entity/User.java new file mode 100644 index 0000000..9ff29fc --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/User.java @@ -0,0 +1,86 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 用户 + * @TableName user + */ +@TableName(value ="user") +@Data +public class User { + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 电话 + */ + private String phone; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 性别 + */ + private Integer gender; + + /** + * 用户角色:user / admin + */ + private String userRole; + + /** + * 密码 + */ + private String userPassword; + + /** + * 是否会员:0-非会员,1-会员 + */ + private Integer isVip; + + /** + * 会员到期时间 + */ + private Date vipExpire; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 是否删除 + */ + private Integer isDelete; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/VipCode.java b/src/main/java/com/xy/xyaicpzs/domain/entity/VipCode.java new file mode 100644 index 0000000..40ac723 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/VipCode.java @@ -0,0 +1,72 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 会员码表 + * @TableName vip_code + */ +@TableName(value ="vip_code") +@Data +public class VipCode { + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 会员码 + */ + private String code; + + /** + * 会员有效月数(1/12) + */ + private Integer vipExpireTime; + + /** + * 会员编号 + */ + private Integer vipNumber; + + /** + * 是否使用:0-未使用,1-已使用 + */ + private Integer isUse; + + /** + * 创建的用户id + */ + private Long createdUserId; + + /** + * 创建的用户名称 + */ + private String createdUserName; + + + /** + * 使用的用户id + */ + private Long usedUserId; + + /** + * 使用的用户名称 + */ + private String usedUserName; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/entity/VipExchangeRecord.java b/src/main/java/com/xy/xyaicpzs/domain/entity/VipExchangeRecord.java new file mode 100644 index 0000000..dfd246b --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/entity/VipExchangeRecord.java @@ -0,0 +1,61 @@ +package com.xy.xyaicpzs.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 会员兑换表 + * @TableName vip_exchange_record + */ +@TableName(value ="vip_exchange_record") +@Data +public class VipExchangeRecord { + /** + * 唯一标识符 + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户ID + */ + private Long userId; + + /** + * 月度会员/年度会员 + */ + private String type; + + /** + * 兑换方式 + */ + private Integer exchangeMode; + + /** + * 订单编号 + */ + private Long orderNo; + + /** + * 订单金额 + */ + private Integer orderAmount; + + /** + * 是否兑换(未兑换/已兑换) + */ + private Integer isUse; + + /** + * 兑换时间 + */ + private Date exchangeTime; + + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/BallCombinationAnalysisVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/BallCombinationAnalysisVO.java new file mode 100644 index 0000000..4ea0d95 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/BallCombinationAnalysisVO.java @@ -0,0 +1,39 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 球号组合分析结果VO + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "球号组合分析结果") +public class BallCombinationAnalysisVO { + + @Schema(description = "当前两个球的组合系数") + private Double faceCoefficient; + + @Schema(description = "与主球组合系数最高的球号") + private Integer highestBall; + + @Schema(description = "与主球组合系数最高的值") + private Double highestCoefficient; + + @Schema(description = "与主球组合系数最低的球号") + private Integer lowestBall; + + @Schema(description = "与主球组合系数最低的值") + private Double lowestCoefficient; + + @Schema(description = "与主球组合的所有系数平均值") + private Double averageCoefficient; + + @Schema(description = "最新开奖期号") + private Long latestDrawId; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/BallHitRateVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/BallHitRateVO.java new file mode 100644 index 0000000..ef37e1e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/BallHitRateVO.java @@ -0,0 +1,27 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 球号命中率统计VO + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "球号命中率统计") +public class BallHitRateVO { + + @Schema(description = "命中次数") + private Integer hitCount; + + @Schema(description = "总次数") + private Integer totalCount; + + @Schema(description = "命中率(百分比)") + private Double hitRate; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/BallPersistenceAnalysisVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/BallPersistenceAnalysisVO.java new file mode 100644 index 0000000..1791654 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/BallPersistenceAnalysisVO.java @@ -0,0 +1,39 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 球号持续性分析结果VO + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "球号持续性分析结果") +public class BallPersistenceAnalysisVO { + + @Schema(description = "当前两个球的组合线系数") + private Double lineCoefficient; + + @Schema(description = "与主球组合线系数最高的球号") + private Integer highestBall; + + @Schema(description = "与主球组合线系数最高的值") + private Double highestCoefficient; + + @Schema(description = "与主球组合线系数最低的球号") + private Integer lowestBall; + + @Schema(description = "与主球组合线系数最低的值") + private Double lowestCoefficient; + + @Schema(description = "与主球组合的所有线系数平均值") + private Double averageCoefficient; + + @Schema(description = "最新开奖期号") + private Long latestDrawId; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/PrizeEstimateVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/PrizeEstimateVO.java new file mode 100644 index 0000000..110e702 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/PrizeEstimateVO.java @@ -0,0 +1,47 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 奖金估算VO + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "奖金估算信息") +public class PrizeEstimateVO { + + @Schema(description = "总奖金合计") + private BigDecimal totalPrize; + + @Schema(description = "奖项明细") + private List prizeDetails; + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Schema(description = "奖项明细项") + public static class PrizeDetailItem { + + @Schema(description = "中奖等级,例如:一等奖、二等奖等") + private String prizeLevel; + + @Schema(description = "中奖注数") + private Integer winningCount; + + @Schema(description = "单注奖金(元)") + private BigDecimal singlePrize; + + @Schema(description = "该等级奖金小计(元)") + private BigDecimal subtotal; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/RedBallHitRateVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/RedBallHitRateVO.java new file mode 100644 index 0000000..6843290 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/RedBallHitRateVO.java @@ -0,0 +1,27 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 红球命中率统计VO + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "红球命中率统计") +public class RedBallHitRateVO { + + @Schema(description = "命中总红球数") + private Integer totalHitCount; + + @Schema(description = "总预测红球数") + private Integer totalPredictedCount; + + @Schema(description = "红球命中率(百分比)") + private Double hitRate; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/UserPredictStatVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/UserPredictStatVO.java new file mode 100644 index 0000000..db55705 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/UserPredictStatVO.java @@ -0,0 +1,46 @@ +package com.xy.xyaicpzs.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用户预测统计数据VO + */ +@Data +public class UserPredictStatVO { + + /** + * 用户ID + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long userId; + + /** + * 预测次数(总记录数) + */ + private Long predictCount; + + /** + * 待开奖次数 + */ + private Long pendingCount; + + /** + * 命中次数 + */ + private Long hitCount; + + /** + * 命中率(保留4位小数) + */ + private BigDecimal hitRate; + + /** + * 已开奖次数(总次数 - 待开奖次数) + */ + private Long drawnCount; + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/UserVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/UserVO.java new file mode 100644 index 0000000..2fb6ed4 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/UserVO.java @@ -0,0 +1,78 @@ +package com.xy.xyaicpzs.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户视图(脱敏) + */ +@Data +public class UserVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 用户昵称 + */ + private String userAccount; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 性别 + */ + private Integer gender; + + /** + * 用户角色:user / admin + */ + private String userRole; + + /** + * 用户角色:user / admin + */ + private String phone; + + /** + * 是否会员:0-非会员,1-会员 + */ + private Integer isVip; + + /** + * 会员到期时间 + */ + private Date vipExpire; + + /** + * 状态:0-正常,1-封禁 + */ + private Integer status; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/domain/vo/VipCodeVO.java b/src/main/java/com/xy/xyaicpzs/domain/vo/VipCodeVO.java new file mode 100644 index 0000000..28ed0e0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/domain/vo/VipCodeVO.java @@ -0,0 +1,74 @@ +package com.xy.xyaicpzs.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +/** + * 会员码视图对象 + */ +@Data +@Schema(description = "会员码视图对象") +public class VipCodeVO { + + /** + * 会员码 + */ + @Schema(description = "会员码") + private String code; + + /** + * 会员有效月数(1/12) + */ + @Schema(description = "会员有效月数") + private Integer vipExpireTime; + + /** + * 会员编号(6位数,如100001) + */ + @Schema(description = "会员编号(6位数)") + private Integer vipNumber; + + /** + * 是否使用:0-未使用,1-已使用 + */ + @Schema(description = "是否使用:0-未使用,1-已使用") + private Integer isUse; + + /** + * 创建人ID + */ + @Schema(description = "创建人ID") + private Long createdUserId; + + /** + * 创建人名称 + */ + @Schema(description = "创建人名称") + private String createdUserName; + + /** + * 使用人ID + */ + @Schema(description = "使用人ID") + private Long usedUserId; + + /** + * 使用人名称 + */ + @Schema(description = "使用人名称") + private String usedUserName; + + /** + * 创建时间 + */ + @Schema(description = "创建时间") + private Date createTime; + + /** + * 创建时间 + */ + @Schema(description = "更新时间") + private Date updateTime; +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/exception/BusinessException.java b/src/main/java/com/xy/xyaicpzs/exception/BusinessException.java new file mode 100644 index 0000000..7342547 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/exception/BusinessException.java @@ -0,0 +1,33 @@ +package com.xy.xyaicpzs.exception; + +import com.xy.xyaicpzs.common.ErrorCode; + +/** + * 自定义异常类 + */ +public class BusinessException extends RuntimeException { + + /** + * 错误码 + */ + private final int code; + + public BusinessException(int code, String message) { + super(message); + this.code = code; + } + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.code = errorCode.getCode(); + } + + public BusinessException(ErrorCode errorCode, String message) { + super(message); + this.code = errorCode.getCode(); + } + + public int getCode() { + return code; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java b/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..d6cd857 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/exception/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package com.xy.xyaicpzs.exception; + +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.common.ResultUtils; +import com.xy.xyaicpzs.common.response.ApiResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理器 + */ +//@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + @ExceptionHandler(BusinessException.class) + public ApiResponse businessExceptionHandler(BusinessException e) { + log.error("businessException: " + e.getMessage(), e); + return ResultUtils.error(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(RuntimeException.class) + public ApiResponse runtimeExceptionHandler(RuntimeException e) { + log.error("runtimeException", e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage()); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/mapper/BlueHistory100Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistory100Mapper.java new file mode 100644 index 0000000..e0cc738 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistory100Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.BlueHistory100; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【blue_history_100(蓝球最近100期数据表)】的数据库操作Mapper +* @createDate 2025-06-14 10:40:04 +* @Entity com.xy.xyaicpzs.domain.entity.BlueHistory100 +*/ +public interface BlueHistory100Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryAllMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryAllMapper.java new file mode 100644 index 0000000..04f9d93 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryAllMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryAll; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【blue_history_all(蓝球全部历史数据表)】的数据库操作Mapper +* @createDate 2025-06-14 10:40:07 +* @Entity com.xy.xyaicpzs.domain.entity.BlueHistoryAll +*/ +public interface BlueHistoryAllMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTop100Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTop100Mapper.java new file mode 100644 index 0000000..5da1cc0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTop100Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop100; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【blue_history_top_100(创建蓝球100期数据排行表)】的数据库操作Mapper +* @createDate 2025-06-14 10:40:13 +* @Entity com.xy.xyaicpzs.domain.entity.BlueHistoryTop100 +*/ +public interface BlueHistoryTop100Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTopMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTopMapper.java new file mode 100644 index 0000000..62f2443 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/BlueHistoryTopMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【blue_history_top(蓝球历史数据排行表)】的数据库操作Mapper +* @createDate 2025-06-14 10:40:10 +* @Entity com.xy.xyaicpzs.domain.entity.BlueHistoryTop +*/ +public interface BlueHistoryTopMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/ChatMessageMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/ChatMessageMapper.java new file mode 100644 index 0000000..2badb1c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/ChatMessageMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.ChatMessage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【chat_message(聊天消息表)】的数据库操作Mapper +* @createDate 2025-07-07 17:37:15 +* @Entity com.xy.xyaicpzs.domain.entity.ChatMessage +*/ +public interface ChatMessageMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/History100Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/History100Mapper.java new file mode 100644 index 0000000..1ca452a --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/History100Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.History100; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【history_100(最近100期数据表)】的数据库操作Mapper +* @createDate 2025-06-14 09:48:05 +* @Entity generator.domain.History100 +*/ +public interface History100Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/HistoryAllMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/HistoryAllMapper.java new file mode 100644 index 0000000..3737941 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/HistoryAllMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.HistoryAll; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【history_all(历史数据表)】的数据库操作Mapper +* @createDate 2025-06-14 09:48:10 +* @Entity generator.domain.HistoryAll +*/ +public interface HistoryAllMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/HistoryTop100Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/HistoryTop100Mapper.java new file mode 100644 index 0000000..0be554b --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/HistoryTop100Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.HistoryTop100; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【history_top_100(创建100期数据排行表)】的数据库操作Mapper +* @createDate 2025-06-14 09:48:16 +* @Entity generator.domain.HistoryTop100 +*/ +public interface HistoryTop100Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/HistoryTopMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/HistoryTopMapper.java new file mode 100644 index 0000000..67928a9 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/HistoryTopMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.HistoryTop; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【history_top(历史数据排行表)】的数据库操作Mapper +* @createDate 2025-06-14 09:48:13 +* @Entity generator.domain.HistoryTop +*/ +public interface HistoryTopMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/LotteryDrawsMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/LotteryDrawsMapper.java new file mode 100644 index 0000000..b656f11 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/LotteryDrawsMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.LotteryDraws; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【lottery_draws(彩票开奖信息表)】的数据库操作Mapper +* @createDate 2025-06-14 16:41:29 +* @Entity com.xy.xyaicpzs.domain.entity.LotteryDraws +*/ +public interface LotteryDrawsMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/OperationHistoryMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/OperationHistoryMapper.java new file mode 100644 index 0000000..3f154c6 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/OperationHistoryMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.OperationHistory; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【operation_history(操作历史记录表)】的数据库操作Mapper +* @createDate 2025-06-19 14:51:51 +* @Entity com.xy.xyaicpzs.domain.entity.OperationHistory +*/ +public interface OperationHistoryMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/PredictRecordMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/PredictRecordMapper.java new file mode 100644 index 0000000..6a781e4 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/PredictRecordMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【predict_record(彩票开奖信息表)】的数据库操作Mapper +* @createDate 2025-06-16 13:17:53 +* @Entity com.xy.xyaicpzs.domain.entity.PredictRecord +*/ +public interface PredictRecordMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T11Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T11Mapper.java new file mode 100644 index 0000000..b5c057f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T11Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T11; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t11(t11表(蓝球组红球的面系数))】的数据库操作Mapper +* @createDate 2025-06-14 16:25:23 +* @Entity com.xy.xyaicpzs.domain.entity.T11 +*/ +public interface T11Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T3Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T3Mapper.java new file mode 100644 index 0000000..05cbca6 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T3Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T3; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t3(t3表(红球组红球的线系数))】的数据库操作Mapper +* @createDate 2025-06-14 11:02:50 +* @Entity com.xy.xyaicpzs.domain.entity.T3 +*/ +public interface T3Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T4Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T4Mapper.java new file mode 100644 index 0000000..3fd5795 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T4Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T4; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t4(t4表(蓝球组红球的线系数))】的数据库操作Mapper +* @createDate 2025-06-14 11:45:31 +* @Entity com.xy.xyaicpzs.domain.entity.T4 +*/ +public interface T4Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T5Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T5Mapper.java new file mode 100644 index 0000000..a27b2d2 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T5Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T5; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t5(t5表(蓝球组蓝球的线系数))】的数据库操作Mapper +* @createDate 2025-06-14 12:01:16 +* @Entity com.xy.xyaicpzs.domain.entity.T5 +*/ +public interface T5Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T6Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T6Mapper.java new file mode 100644 index 0000000..e90b630 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T6Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T6; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t6(t6表(红球组蓝球的线系数))】的数据库操作Mapper +* @createDate 2025-06-14 13:19:12 +* @Entity com.xy.xyaicpzs.domain.entity.T6 +*/ +public interface T6Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T7Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T7Mapper.java new file mode 100644 index 0000000..3841c0d --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T7Mapper.java @@ -0,0 +1,21 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T7; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** +* @author XY003 +* @description 针对表【t7(t7表(红球组红球的面系数))】的数据库操作Mapper +* @createDate 2025-06-14 13:30:50 +* @Entity com.xy.xyaicpzs.domain.entity.T7 +*/ +public interface T7Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/T8Mapper.java b/src/main/java/com/xy/xyaicpzs/mapper/T8Mapper.java new file mode 100644 index 0000000..a466238 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/T8Mapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.T8; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【t8(t8表(红球组蓝球的面系数))】的数据库操作Mapper +* @createDate 2025-06-14 16:11:27 +* @Entity com.xy.xyaicpzs.domain.entity.T8 +*/ +public interface T8Mapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/UserMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/UserMapper.java new file mode 100644 index 0000000..930176e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/UserMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.User; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【user(用户)】的数据库操作Mapper +* @createDate 2025-06-15 18:29:28 +* @Entity com.xy.xyaicpzs.domain.entity.User +*/ +public interface UserMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/mapper/VipCodeMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/VipCodeMapper.java new file mode 100644 index 0000000..399f9cd --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/VipCodeMapper.java @@ -0,0 +1,14 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.VipCode; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【vip_code(会员码表)】的数据库操作Mapper +* @createDate 2025-01-15 16:41:29 +* @Entity com.xy.xyaicpzs.domain.entity.VipCode +*/ +public interface VipCodeMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/mapper/VipExchangeRecordMapper.java b/src/main/java/com/xy/xyaicpzs/mapper/VipExchangeRecordMapper.java new file mode 100644 index 0000000..572e8c3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/mapper/VipExchangeRecordMapper.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.mapper; + +import com.xy.xyaicpzs.domain.entity.VipExchangeRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author XY003 +* @description 针对表【vip_exchange_record(会员兑换表)】的数据库操作Mapper +* @createDate 2025-06-19 11:27:10 +* @Entity com.xy.xyaicpzs.domain.entity.VipExchangeRecord +*/ +public interface VipExchangeRecordMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java b/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java new file mode 100644 index 0000000..3d6b863 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/BallAnalysisService.java @@ -0,0 +1,3154 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.xy.xyaicpzs.domain.entity.*; +import com.xy.xyaicpzs.mapper.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; + +import com.xy.xyaicpzs.domain.vo.BallHitRateVO; +import com.xy.xyaicpzs.domain.vo.PrizeEstimateVO; +import com.xy.xyaicpzs.domain.vo.RedBallHitRateVO; + +/** + * 球号分析服务类 + * 实现复杂的球号分析算法 + */ +@Slf4j +@Service +public class BallAnalysisService { + + @Autowired + private T3Mapper t3Mapper; + + @Autowired + private T4Mapper t4Mapper; + + @Autowired + private HistoryTopMapper historyTopMapper; + + @Autowired + private HistoryTop100Mapper historyTop100Mapper; + + @Autowired + private T7Mapper t7Mapper; + + @Autowired + private T5Mapper t5Mapper; + + @Autowired + private T6Mapper t6Mapper; + + @Autowired + private T8Mapper t8Mapper; + + @Autowired + private BlueHistoryTop100Mapper blueHistoryTop100Mapper; + + @Autowired + private BlueHistoryTopMapper blueHistoryTopMapper; + + @Autowired + private PredictRecordMapper predictRecordMapper; + + @Autowired + private LotteryDrawsService lotteryDrawsService; + + /** + * 球号分析算法主方法 + * @param level 高位/中位/低位标识 (H/M/L) + * @param redBalls 6个红球号码 + * @param blueBall 1个蓝球号码 + * @return 分析结果:出现频率最高的前11位数字 + */ + public List analyzeBalls(String level, List redBalls, Integer blueBall) { + log.info("开始球号分析算法,级别:{},红球:{},蓝球:{}", level, redBalls, blueBall); + + // 验证输入参数 + if (redBalls == null || redBalls.size() != 6) { + throw new IllegalArgumentException("红球数量必须为6个"); + } + if (blueBall == null) { + throw new IllegalArgumentException("蓝球不能为空"); + } + if (!Arrays.asList("H", "M", "L").contains(level)) { + throw new IllegalArgumentException("级别必须为H、M或L"); + } + + List allNumbers = new ArrayList<>(); + + // 第一步:处理6个红球,每个红球获取17个数字 + log.info("第一步:处理6个红球,使用{}级别算法", level); + for (int i = 0; i < redBalls.size(); i++) { + Integer redBall = redBalls.get(i); + log.info("处理第{}个红球:{}", i + 1, redBall); + + List ballNumbers = getTop17FromT3(redBall, level); + allNumbers.addAll(ballNumbers); + + log.info("红球{}获取到{}个数字:{}", redBall, ballNumbers.size(), ballNumbers); + } + + // 第二步:从history_top获取前3个球号 + log.info("第二步:从history_top获取前3个球号"); + List top3Numbers = getTop3FromHistoryTop(); + allNumbers.addAll(top3Numbers); + log.info("从history_top获取到{}个数字:{}", top3Numbers.size(), top3Numbers); + + // 第三步:用蓝球从t4表获取17个数字 + log.info("第三步:用蓝球{}从t4表获取17个数字,使用{}级别算法", blueBall, level); + List blueNumbers = getTop17FromT4(blueBall, level); + allNumbers.addAll(blueNumbers); + log.info("蓝球{}获取到{}个数字:{}", blueBall, blueNumbers.size(), blueNumbers); + + log.info("总共收集到{}个数字", allNumbers.size()); + + // 第四步:统计频率并获取前11个 + List result = getTop11ByFrequency(allNumbers); + + log.info("球号分析算法完成,结果:{}", result); + return result; + } + + /** + * 从T3表获取指定主球的17个从球号 + * 根据不同级别使用不同的选择策略 + * @param masterBallNumber 主球号 + * @param level 级别:H-高位,M-中位,L-低位 + */ + private List getTop17FromT3(Integer masterBallNumber, String level) { + log.debug("从T3表查询主球{}的线系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t3List = t3Mapper.selectList(queryWrapper); + + if (t3List.isEmpty()) { + log.warn("T3表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + + switch (level) { + case "H": + // 高位:取前17个(按线系数从大到小排列) + result = getHighLevelBalls(t3List); + break; + case "M": + // 中位:取线系数平均值向上9个球(含),向下8个球,共17个 + result = getMiddleLevelBalls(t3List); + break; + case "L": + // 低位:取最小值向上17个球,含最小值 + result = getLowLevelBalls(t3List); + break; + } + + log.debug("T3表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 从T4表获取指定主球的17个从球号 + * 根据不同级别使用不同的选择策略 + * @param masterBallNumber 主球号 + * @param level 级别:H-高位,M-中位,L-低位 + */ + private List getTop17FromT4(Integer masterBallNumber, String level) { + log.debug("从T4表查询主球{}的线系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t4List = t4Mapper.selectList(queryWrapper); + + if (t4List.isEmpty()) { + log.warn("T4表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + + switch (level) { + case "H": + // 高位:取前17个(按线系数从大到小排列) + result = getHighLevelBallsFromT4(t4List); + break; + case "M": + // 中位:取线系数平均值向上9个球(含),向下8个球,共17个 + result = getMiddleLevelBallsFromT4(t4List); + break; + case "L": + // 低位:取最小值向上17个球,含最小值 + result = getLowLevelBallsFromT4(t4List); + break; + } + + log.debug("T4表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 高位算法:从T3表取前17个(按线系数从大到小排列) + */ + private List getHighLevelBalls(List t3List) { + if (t3List.size() < 17) { + log.warn("T3表数据不足17条,实际{}条", t3List.size()); + return t3List.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前16个 + List result = new ArrayList<>(); + for (int i = 0; i < 16; i++) { + result.add(t3List.get(i).getSlaveBallNumber()); + } + + // 处理第17个位置:检查是否有相同的线系数 + Double targetCoefficient = t3List.get(16).getLineCoefficient(); + List candidatesFor17th = new ArrayList<>(); + + // 找出所有线系数等于第17个位置线系数的记录 + for (int i = 16; i < t3List.size(); i++) { + if (t3List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor17th.add(t3List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor17th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor17th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第17位有{}个相同线系数的候选:{}", candidatesFor17th.size(), + candidatesFor17th.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor17th.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + return result; + } + + /** + * 中位算法:从T3表取线系数平均值向上9个球(含),向下8个球,共17个 + */ + private List getMiddleLevelBalls(List t3List) { + if (t3List.size() < 17) { + log.warn("T3表数据不足17条,实际{}条", t3List.size()); + return t3List.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 计算线系数平均值 + double avgCoefficient = t3List.stream() + .mapToDouble(T3::getLineCoefficient) + .average() + .orElse(0.0); + + log.debug("T3表线系数平均值:{}", avgCoefficient); + + // 找到最接近平均值的位置 + int avgIndex = -1; + double minDiff = Double.MAX_VALUE; + for (int i = 0; i < t3List.size(); i++) { + double diff = Math.abs(t3List.get(i).getLineCoefficient() - avgCoefficient); + if (diff < minDiff) { + minDiff = diff; + avgIndex = i; + } + } + + log.debug("最接近平均值的位置:{},线系数:{}", avgIndex, t3List.get(avgIndex).getLineCoefficient()); + + // 向上9个(含当前),向下8个,共17个 + int startIndex = Math.max(0, avgIndex - 8); + int endIndex = Math.min(t3List.size() - 1, avgIndex + 8); + + // 确保总共17个数字 + while (endIndex - startIndex + 1 < 17 && (startIndex > 0 || endIndex < t3List.size() - 1)) { + if (startIndex > 0) { + startIndex--; + } + if (endIndex < t3List.size() - 1 && endIndex - startIndex + 1 < 17) { + endIndex++; + } + } + + List result = new ArrayList<>(); + for (int i = startIndex; i <= endIndex && result.size() < 17; i++) { + result.add(t3List.get(i).getSlaveBallNumber()); + } + + log.debug("中位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 低位算法:从T3表取最小值向上17个球,含最小值 + */ + private List getLowLevelBalls(List t3List) { + if (t3List.size() < 17) { + log.warn("T3表数据不足17条,实际{}条", t3List.size()); + return t3List.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 从最后17个开始(最小的线系数) + int startIndex = Math.max(0, t3List.size() - 17); + List candidates = new ArrayList<>(); + + for (int i = startIndex; i < t3List.size(); i++) { + candidates.add(t3List.get(i).getSlaveBallNumber()); + } + + // 处理第一个位置(最大线系数)的相同值情况 + if (candidates.size() >= 17) { + Double firstCoefficient = t3List.get(startIndex).getLineCoefficient(); + List candidatesForFirst = new ArrayList<>(); + + // 找出所有线系数等于第一个位置线系数的记录 + for (int i = 0; i < t3List.size(); i++) { + if (t3List.get(i).getLineCoefficient().equals(firstCoefficient)) { + candidatesForFirst.add(t3List.get(i)); + } + } + + if (candidatesForFirst.size() > 1) { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第一位有{}个相同线系数的候选:{}", candidatesForFirst.size(), + candidatesForFirst.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesForFirst.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()) + ); + + // 替换第一个位置 + candidates.set(0, bestBall); + } + } + + log.debug("低位算法选择范围:[{}, {}],共{}个球", startIndex, t3List.size() - 1, candidates.size()); + return candidates.subList(0, Math.min(17, candidates.size())); + } + + /** + * 高位算法:从T4表取前17个(按线系数从大到小排列) + */ + private List getHighLevelBallsFromT4(List t4List) { + if (t4List.size() < 17) { + log.warn("T4表数据不足17条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前16个 + List result = new ArrayList<>(); + for (int i = 0; i < 16; i++) { + result.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理第17个位置:检查是否有相同的线系数 + Double targetCoefficient = t4List.get(16).getLineCoefficient(); + List candidatesFor17th = new ArrayList<>(); + + // 找出所有线系数等于第17个位置线系数的记录 + for (int i = 16; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor17th.add(t4List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor17th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor17th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第17位有{}个相同线系数的候选:{}", candidatesFor17th.size(), + candidatesFor17th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor17th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + return result; + } + + /** + * 中位算法:从T4表取线系数平均值向上9个球(含),向下8个球,共17个 + */ + private List getMiddleLevelBallsFromT4(List t4List) { + if (t4List.size() < 17) { + log.warn("T4表数据不足17条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 计算线系数平均值 + double avgCoefficient = t4List.stream() + .mapToDouble(T4::getLineCoefficient) + .average() + .orElse(0.0); + + log.debug("T4表线系数平均值:{}", avgCoefficient); + + // 找到最接近平均值的位置 + int avgIndex = -1; + double minDiff = Double.MAX_VALUE; + for (int i = 0; i < t4List.size(); i++) { + double diff = Math.abs(t4List.get(i).getLineCoefficient() - avgCoefficient); + if (diff < minDiff) { + minDiff = diff; + avgIndex = i; + } + } + + log.debug("最接近平均值的位置:{},线系数:{}", avgIndex, t4List.get(avgIndex).getLineCoefficient()); + + // 向上9个(含当前),向下8个,共17个 + int startIndex = Math.max(0, avgIndex - 8); + int endIndex = Math.min(t4List.size() - 1, avgIndex + 8); + + // 确保总共17个数字 + while (endIndex - startIndex + 1 < 17 && (startIndex > 0 || endIndex < t4List.size() - 1)) { + if (startIndex > 0) { + startIndex--; + } + if (endIndex < t4List.size() - 1 && endIndex - startIndex + 1 < 17) { + endIndex++; + } + } + + List result = new ArrayList<>(); + for (int i = startIndex; i <= endIndex && result.size() < 17; i++) { + result.add(t4List.get(i).getSlaveBallNumber()); + } + + log.debug("中位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 低位算法:从T4表取线系数最小值向上第4-14个球的10个球号 + */ + private List getLowLevelBallsFromT4(List t4List) { + if (t4List.size() < 14) { + log.warn("T4表数据不足14条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 从最后14个开始,取第4-14个(即倒数第11到倒数第1个) + int startIndex = Math.max(0, t4List.size() - 11); + int endIndex = t4List.size() - 1; + + List candidates = new ArrayList<>(); + for (int i = startIndex; i <= endIndex; i++) { + candidates.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理边界位置的相同线系数情况 + List result = handleT4BoundaryConflictsFor10(t4List, candidates, startIndex, endIndex); + + log.debug("T4低位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 处理T4表边界位置的线系数冲突(10个球版本) + */ + private List handleT4BoundaryConflictsFor10(List t4List, List candidates, + int startIndex, int endIndex) { + List result = new ArrayList<>(candidates); + + if (result.size() >= 10) { + // 检查第1个位置(最大线系数)的冲突 + Double firstCoefficient = t4List.get(startIndex).getLineCoefficient(); + List candidatesForFirst = new ArrayList<>(); + + for (int i = 0; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(firstCoefficient)) { + candidatesForFirst.add(t4List.get(i)); + } + } + + if (candidatesForFirst.size() > 1) { + log.debug("第1位有{}个相同线系数的候选:{}", candidatesForFirst.size(), + candidatesForFirst.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesForFirst.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.set(0, bestBall); + } + + // 检查第10个位置(最小线系数)的冲突 + Double lastCoefficient = t4List.get(endIndex).getLineCoefficient(); + List candidatesForLast = new ArrayList<>(); + + for (int i = 0; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(lastCoefficient)) { + candidatesForLast.add(t4List.get(i)); + } + } + + if (candidatesForLast.size() > 1) { + log.debug("第10位有{}个相同线系数的候选:{}", candidatesForLast.size(), + candidatesForLast.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesForLast.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.set(result.size() - 1, bestBall); + } + } + + return result.subList(0, Math.min(10, result.size())); + } + + /** + * 从history_top表获取前3个球号(按点系数排行) + * 如果点系数相同,通过history_top_100表比较 + */ + private List getTop3FromHistoryTop() { + log.debug("从history_top表获取前3个球号"); + + // 查询前3个排行的数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("no").last("LIMIT 3"); + + List topList = historyTopMapper.selectList(queryWrapper); + + if (topList.size() < 3) { + log.warn("history_top表数据不足3条,实际{}条", topList.size()); + return topList.stream().map(HistoryTop::getBallNumber).collect(Collectors.toList()); + } + + List result = new ArrayList<>(); + + // 处理每个位置,检查是否有相同点系数的情况 + for (int i = 0; i < 3; i++) { + HistoryTop current = topList.get(i); + + // 查找所有具有相同排行的记录 + QueryWrapper sameRankQuery = new QueryWrapper<>(); + sameRankQuery.eq("no", current.getNo()); + List sameRankList = historyTopMapper.selectList(sameRankQuery); + + if (sameRankList.size() == 1) { + // 只有一个,直接添加 + result.add(current.getBallNumber()); + } else { + // 有多个相同排行,通过history_top_100表比较点系数 + log.debug("排行{}有{}个相同的球号:{}", current.getNo(), sameRankList.size(), + sameRankList.stream().map(HistoryTop::getBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + sameRankList.stream().map(HistoryTop::getBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + } + + log.debug("history_top表最终选择的3个球号:{}", result); + return result; + } + + /** + * 从候选球号中选择history_top_100表中点系数最大的球号 + */ + private Integer selectBestBallFromHistoryTop100(List candidates) { + if (candidates.isEmpty()) { + throw new IllegalArgumentException("候选球号列表不能为空"); + } + + if (candidates.size() == 1) { + return candidates.get(0); + } + + log.debug("从history_top_100表中比较候选球号:{}", candidates); + + // 查询这些球号在history_top_100表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidates) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = historyTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("候选球号{}在history_top_100表中未找到数据,返回第一个", candidates); + return candidates.get(0); + } + + Integer bestBall = top100List.get(0).getBallNumber(); + log.debug("从候选{}中选择最佳球号:{}(点系数:{})", candidates, bestBall, top100List.get(0).getPointCoefficient()); + + return bestBall; + } + + /** + * 统计数字出现频率,返回频率最高的前11个数字 + * 如果频次相同的球号超过11个,使用T3表线系数进行二次筛选 + */ + private List getTop11ByFrequency(List allNumbers) { + log.debug("统计{}个数字的出现频率", allNumbers.size()); + + // 统计频率 + Map frequencyMap = new HashMap<>(); + for (Integer number : allNumbers) { + frequencyMap.put(number, frequencyMap.getOrDefault(number, 0) + 1); + } + + log.debug("数字频率统计:{}", frequencyMap); + + // 按频率分组 + Map> frequencyGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : frequencyMap.entrySet()) { + Integer frequency = entry.getValue(); + Integer ballNumber = entry.getKey(); + + frequencyGroups.computeIfAbsent(frequency, k -> new ArrayList<>()).add(ballNumber); + } + + log.debug("按频率分组:{}", frequencyGroups); + + List result = new ArrayList<>(); + + // 按频率从高到低处理 + for (Map.Entry> group : frequencyGroups.entrySet()) { + Integer frequency = group.getKey(); + List balls = group.getValue(); + + // 对同频率的球号按数字升序排序 + Collections.sort(balls); + + log.info("频率{}的球号:{}", frequency, balls); + + // 检查加入这组球号后是否会超过11个 + if (result.size() + balls.size() <= 11) { + // 不会超过11个,直接添加所有球号 + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过11个,需要用T3表的线系数进行二次筛选 + int remainingSlots = 11 - result.size(); + log.info("需要从{}个频率相同的球号中选择{}个,使用T3表线系数进行筛选", balls.size(), remainingSlots); + + List selectedBalls = selectBallsByT3LineCoefficient(balls, remainingSlots); + result.addAll(selectedBalls); + + log.info("通过T3表线系数筛选完成,最终选择:{}", selectedBalls); + break; // 已经达到11个,结束 + } + + // 如果已经有11个,结束 + if (result.size() >= 11) { + break; + } + } + + log.info("频率统计最终结果(共{}个):{}", result.size(), result); + + // 打印详细的频率信息 + for (int i = 0; i < result.size(); i++) { + Integer ballNumber = result.get(i); + Integer frequency = frequencyMap.get(ballNumber); + log.info("第{}位:数字{},出现{}次", i + 1, ballNumber, frequency); + } + + return result; + } + + /** + * 根据T3表的线系数总和选择球号,支持多级筛选 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 选择的球号列表 + */ + private List selectBallsByT3LineCoefficient(List candidateBalls, int selectCount) { + log.info("开始根据T3表线系数总和选择球号,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 第一级:计算每个球号作为主球时的线系数总和 + Map lineCoefficientSumMap = new HashMap<>(); + + for (Integer ballNumber : candidateBalls) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", ballNumber); + + List t3List = t3Mapper.selectList(queryWrapper); + + double sum = t3List.stream() + .mapToDouble(T3::getLineCoefficient) + .sum(); + + lineCoefficientSumMap.put(ballNumber, sum); + log.debug("球号{}作为主球的线系数总和:{}", ballNumber, sum); + } + + // 按线系数总和分组 + Map> lineCoefficientGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : lineCoefficientSumMap.entrySet()) { + Double sum = entry.getValue(); + Integer ballNumber = entry.getKey(); + lineCoefficientGroups.computeIfAbsent(sum, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("T3表线系数总和分组:{}", lineCoefficientGroups); + + List result = new ArrayList<>(); + + // 按线系数总和从高到低处理 + for (Map.Entry> group : lineCoefficientGroups.entrySet()) { + Double lineSum = group.getKey(); + List balls = group.getValue(); + + log.info("线系数总和{}的球号:{}", lineSum, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,需要进一步筛选 + int remainingSlots = selectCount - result.size(); + log.info("需要从{}个线系数总和相同的球号中选择{}个,开始多级筛选", balls.size(), remainingSlots); + + List selectedBalls = selectBallsByMultiLevelFiltering(balls, remainingSlots); + result.addAll(selectedBalls); + + log.info("通过多级筛选完成,最终选择:{}", selectedBalls); + break; // 已经达到selectCount个,结束 + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + log.info("T3表线系数筛选最终结果(共{}个):{}", result.size(), result); + + // 打印详细的线系数信息 + for (int i = 0; i < result.size(); i++) { + Integer ballNumber = result.get(i); + Double sum = lineCoefficientSumMap.get(ballNumber); + log.info("第{}位:球号{},线系数总和:{}", i + 1, ballNumber, sum); + } + + return result; + } + + /** + * 多级筛选球号:history_top_100 -> history_top -> 随机选择 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 选择的球号列表 + */ + private List selectBallsByMultiLevelFiltering(List candidateBalls, int selectCount) { + log.info("开始多级筛选,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 第二级:使用history_top_100表的排名进行筛选 + List filteredByTop100 = selectBallsByHistoryTop100Ranking(candidateBalls, selectCount); + + if (filteredByTop100.size() == selectCount) { + log.info("通过history_top_100表筛选成功,结果:{}", filteredByTop100); + return filteredByTop100; + } + + // 第三级:使用history_top表的点系数进行筛选 + log.info("history_top_100表筛选后仍有{}个球号,继续使用history_top表筛选", filteredByTop100.size()); + List filteredByTop = selectBallsByHistoryTopPointCoefficient(filteredByTop100, selectCount); + + if (filteredByTop.size() == selectCount) { + log.info("通过history_top表筛选成功,结果:{}", filteredByTop); + return filteredByTop; + } + + // 第四级:随机选择 + log.info("history_top表筛选后仍有{}个球号,进行随机选择", filteredByTop.size()); + List finalResult = selectBallsRandomly(filteredByTop, selectCount); + + log.info("随机选择完成,最终结果:{}", finalResult); + return finalResult; + } + + /** + * 根据history_top_100表的排名筛选球号 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 筛选后的球号列表 + */ + private List selectBallsByHistoryTop100Ranking(List candidateBalls, int selectCount) { + log.info("使用history_top_100表排名筛选球号,候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在history_top_100表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = historyTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("候选球号{}在history_top_100表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new LinkedHashMap<>(); + for (HistoryTop100 item : top100List) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("history_top_100表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的球号:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个球号:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在history_top_100表中的球号 + List notInTop100 = new ArrayList<>(candidateBalls); + notInTop100.removeAll(result); + if (!notInTop100.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInTop100); + int addCount = Math.min(remainingSlots, notInTop100.size()); + result.addAll(notInTop100.subList(0, addCount)); + log.info("添加不在history_top_100表中的{}个球号:{}", addCount, notInTop100.subList(0, addCount)); + } + + log.info("history_top_100表筛选结果:{}", result); + return result; + } + + /** + * 根据history_top表的点系数筛选球号 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 筛选后的球号列表 + */ + private List selectBallsByHistoryTopPointCoefficient(List candidateBalls, int selectCount) { + log.info("使用history_top表点系数筛选球号,候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在history_top表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List historyTopList = historyTopMapper.selectList(queryWrapper); + + if (historyTopList.isEmpty()) { + log.warn("候选球号{}在history_top表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new LinkedHashMap<>(); + for (HistoryTop item : historyTopList) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("history_top表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的球号:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个球号:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在history_top表中的球号 + List notInHistoryTop = new ArrayList<>(candidateBalls); + notInHistoryTop.removeAll(result); + if (!notInHistoryTop.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInHistoryTop); + int addCount = Math.min(remainingSlots, notInHistoryTop.size()); + result.addAll(notInHistoryTop.subList(0, addCount)); + log.info("添加不在history_top表中的{}个球号:{}", addCount, notInHistoryTop.subList(0, addCount)); + } + + log.info("history_top表筛选结果:{}", result); + return result; + } + + /** + * 随机选择球号 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 随机选择的球号列表 + */ + private List selectBallsRandomly(List candidateBalls, int selectCount) { + log.info("随机选择球号,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 创建候选球号的副本并打乱顺序 + List shuffledBalls = new ArrayList<>(candidateBalls); + Collections.shuffle(shuffledBalls, new Random(System.currentTimeMillis())); + + // 选择前selectCount个 + List result = shuffledBalls.subList(0, selectCount); + + // 按球号升序排序结果 + Collections.sort(result); + + log.info("随机选择结果:{}", result); + return result; + } + + /** + * 跟随球号分析算法 + * @param level 高位/中位/低位标识 (H/M/L) + * @param firstThreeRedBalls 前3个红球号码(独立的) + * @param lastSixRedBalls 后6个红球号码(独立的) + * @param blueBall 1个蓝球号码 + * @return 分析结果:出现频率最高的前8位数字 + */ + public List fallowBallAnalysis(String level, List firstThreeRedBalls, + List lastSixRedBalls, Integer blueBall) { + log.info("开始跟随球号分析算法,级别:{},前3个红球:{},后6个红球:{},蓝球:{}", + level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 验证输入参数 + if (firstThreeRedBalls == null || firstThreeRedBalls.size() != 3) { + throw new IllegalArgumentException("前3个红球数量必须为3个"); + } + if (lastSixRedBalls == null || lastSixRedBalls.size() != 6) { + throw new IllegalArgumentException("后6个红球数量必须为6个"); + } + if (blueBall == null) { + throw new IllegalArgumentException("蓝球不能为空"); + } + if (!Arrays.asList("H", "M", "L").contains(level)) { + throw new IllegalArgumentException("级别必须为H、M或L"); + } + + // 验证球号范围和重复性 + validateBallNumbers(firstThreeRedBalls, lastSixRedBalls, blueBall); + + List allNumbers = new ArrayList<>(); + + // 第一步:处理第1个红球,从T7表获取10个数字 + log.info("第一步:处理第1个红球{},从T7表获取10个数字,使用{}级别算法", firstThreeRedBalls.get(0), level); + List firstRedBallNumbers = getTop10FromT7(firstThreeRedBalls.get(0), level); + allNumbers.addAll(firstRedBallNumbers); + log.info("第1个红球{}获取到{}个数字:{}", firstThreeRedBalls.get(0), firstRedBallNumbers.size(), firstRedBallNumbers); + + // 第二步:处理后6个红球,每个红球从T3表获取26个数字 + log.info("第二步:处理后6个红球,每个红球从T3表获取26个数字"); + for (int i = 0; i < lastSixRedBalls.size(); i++) { + Integer redBall = lastSixRedBalls.get(i); + log.info("处理第{}个红球:{}", i + 1, redBall); + + List ballNumbers = getTop26FromT3(redBall); + allNumbers.addAll(ballNumbers); + + log.info("红球{}获取到{}个数字:{}", redBall, ballNumbers.size(), ballNumbers); + } + + // 第三步:从history_top_100获取前3个球号 + log.info("第三步:从history_top_100获取前3个球号"); + List top3Numbers = getTop3FromHistoryTop100(); + allNumbers.addAll(top3Numbers); + log.info("从history_top_100获取到{}个数字:{}", top3Numbers.size(), top3Numbers); + + // 第四步:取出前3个红球号码的后两个 + log.info("第四步:取出前3个红球号码的后两个"); + List lastTwoOfFirstThree = Arrays.asList(firstThreeRedBalls.get(1), firstThreeRedBalls.get(2)); + allNumbers.addAll(lastTwoOfFirstThree); + log.info("前3个红球的后两个:{}", lastTwoOfFirstThree); + + // 第五步:用上期蓝球从T5表获取12个蓝球号码 + log.info("第五步:用上期蓝球{}从T5表获取12个蓝球号码", blueBall); + List blueNumbers = getTop12FromT5(blueBall); + allNumbers.addAll(blueNumbers); + log.info("蓝球{}获取到{}个数字:{}", blueBall, blueNumbers.size(), blueNumbers); + + log.info("总共收集到{}个数字", allNumbers.size()); + + // 第六步:统计频率并获取前8个 + List result = getTop8ByFrequency(allNumbers); + + log.info("跟随球号分析算法完成,结果:{}", result); + return result; + } + + /** + * 验证球号的有效性和唯一性 + */ + private void validateBallNumbers(List firstThreeRedBalls, List lastSixRedBalls, Integer blueBall) { + // 验证红球范围 + for (Integer ball : firstThreeRedBalls) { + if (ball == null || ball < 1 || ball > 33) { + throw new IllegalArgumentException("前3个红球号码必须在1-33范围内"); + } + } + for (Integer ball : lastSixRedBalls) { + if (ball == null || ball < 1 || ball > 33) { + throw new IllegalArgumentException("后6个红球号码必须在1-33范围内"); + } + } + + // 验证蓝球范围 + if (blueBall < 1 || blueBall > 16) { + throw new IllegalArgumentException("蓝球号码必须在1-16范围内"); + } + + // 验证前3个红球不重复 + Set firstThreeSet = new HashSet<>(firstThreeRedBalls); + if (firstThreeSet.size() != 3) { + throw new IllegalArgumentException("前3个红球号码不能重复"); + } + + // 验证后6个红球不重复 + Set lastSixSet = new HashSet<>(lastSixRedBalls); + if (lastSixSet.size() != 6) { + throw new IllegalArgumentException("后6个红球号码不能重复"); + } + + log.debug("球号验证通过"); + } + + /** + * 从T7表获取指定主球的10个从球号 + * 根据不同级别使用不同的选择策略 + * @param masterBallNumber 主球号 + * @param level 级别:H-高位,M-中位,L-低位 + */ + private List getTop10FromT7(Integer masterBallNumber, String level) { + log.debug("从T7表查询主球{}的面系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按面系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("faceCoefficient") + .orderByAsc("slaveBallNumber"); // 面系数相同时按从球号升序 + + List t7List = t7Mapper.selectList(queryWrapper); + + if (t7List.isEmpty()) { + log.warn("T7表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + + switch (level) { + case "H": + // 高位:取面系数最大的前10个 + result = getHighLevelBallsFromT7(t7List); + break; + case "M": + // 中位:取面系数平均值向上6个向下4个的10个球号 + result = getMiddleLevelBallsFromT7(t7List); + break; + case "L": + // 低位:取面系数最小值向上第3-13个球共10个球号 + result = getLowLevelBallsFromT7(t7List); + break; + } + + log.debug("T7表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 高位算法:从T7表取面系数最大的前10个 + */ + private List getHighLevelBallsFromT7(List t7List) { + if (t7List.size() < 10) { + log.warn("T7表数据不足10条,实际{}条", t7List.size()); + return t7List.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前9个 + List result = new ArrayList<>(); + for (int i = 0; i < 9; i++) { + result.add(t7List.get(i).getSlaveBallNumber()); + } + + // 处理第10个位置:检查是否有相同的面系数 + Double targetCoefficient = t7List.get(9).getFaceCoefficient(); + List candidatesFor10th = new ArrayList<>(); + + // 找出所有面系数等于第10个位置面系数的记录 + for (int i = 9; i < t7List.size(); i++) { + if (t7List.get(i).getFaceCoefficient().equals(targetCoefficient)) { + candidatesFor10th.add(t7List.get(i)); + } else { + break; // 面系数不同,停止查找 + } + } + + if (candidatesFor10th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor10th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第10位有{}个相同面系数的候选:{}", candidatesFor10th.size(), + candidatesFor10th.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor10th.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T7高位算法最终选择的10个球:{}", result); + return result; + } + + /** + * 中位算法:从T7表取面系数平均值向上6个向下4个的10个球号 + */ + private List getMiddleLevelBallsFromT7(List t7List) { + if (t7List.size() < 10) { + log.warn("T7表数据不足10条,实际{}条", t7List.size()); + return t7List.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 计算面系数平均值 + double avgCoefficient = t7List.stream() + .mapToDouble(T7::getFaceCoefficient) + .average() + .orElse(0.0); + + log.debug("T7表面系数平均值:{}", avgCoefficient); + + // 找到最接近平均值的位置 + int avgIndex = 0; + double minDiff = Double.MAX_VALUE; + for (int i = 0; i < t7List.size(); i++) { + double diff = Math.abs(t7List.get(i).getFaceCoefficient() - avgCoefficient); + if (diff < minDiff) { + minDiff = diff; + avgIndex = i; + } + } + + log.debug("最接近平均值的位置:{},面系数:{}", avgIndex, t7List.get(avgIndex).getFaceCoefficient()); + + // 向上6个(含当前),向下4个,共10个 + int startIndex = Math.max(0, avgIndex - 4); + int endIndex = Math.min(t7List.size() - 1, avgIndex + 5); + + // 确保总共10个数字 + while (endIndex - startIndex + 1 < 10 && (startIndex > 0 || endIndex < t7List.size() - 1)) { + if (startIndex > 0) { + startIndex--; + } + if (endIndex < t7List.size() - 1 && endIndex - startIndex + 1 < 10) { + endIndex++; + } + } + + List candidates = new ArrayList<>(); + for (int i = startIndex; i <= endIndex && candidates.size() < 10; i++) { + candidates.add(t7List.get(i).getSlaveBallNumber()); + } + + // 处理边界位置的相同面系数情况 + List result = handleT7BoundaryConflicts(t7List, candidates, startIndex, endIndex); + + log.debug("T7中位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 低位算法:从T7表取面系数最小值向上第3-13个球共10个球号 + */ + private List getLowLevelBallsFromT7(List t7List) { + if (t7List.size() < 13) { + log.warn("T7表数据不足13条,实际{}条", t7List.size()); + return t7List.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 从最后13个开始,取第3-13个(即倒数第11到倒数第1个) + int startIndex = Math.max(0, t7List.size() - 11); + int endIndex = t7List.size() - 1; + + List candidates = new ArrayList<>(); + for (int i = startIndex; i <= endIndex; i++) { + candidates.add(t7List.get(i).getSlaveBallNumber()); + } + + // 处理边界位置的相同面系数情况 + List result = handleT7BoundaryConflicts(t7List, candidates, startIndex, endIndex); + + log.debug("T7低位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 处理T7表边界位置的面系数冲突 + */ + private List handleT7BoundaryConflicts(List t7List, List candidates, + int startIndex, int endIndex) { + List result = new ArrayList<>(candidates); + + if (result.size() >= 10) { + // 检查第1个位置(最大面系数)的冲突 + Double firstCoefficient = t7List.get(startIndex).getFaceCoefficient(); + List candidatesForFirst = new ArrayList<>(); + + for (int i = 0; i < t7List.size(); i++) { + if (t7List.get(i).getFaceCoefficient().equals(firstCoefficient)) { + candidatesForFirst.add(t7List.get(i)); + } + } + + if (candidatesForFirst.size() > 1) { + log.debug("第1位有{}个相同面系数的候选:{}", candidatesForFirst.size(), + candidatesForFirst.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesForFirst.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.set(0, bestBall); + } + + // 检查第10个位置(最小面系数)的冲突 + Double lastCoefficient = t7List.get(endIndex).getFaceCoefficient(); + List candidatesForLast = new ArrayList<>(); + + for (int i = 0; i < t7List.size(); i++) { + if (t7List.get(i).getFaceCoefficient().equals(lastCoefficient)) { + candidatesForLast.add(t7List.get(i)); + } + } + + if (candidatesForLast.size() > 1) { + log.debug("第10位有{}个相同面系数的候选:{}", candidatesForLast.size(), + candidatesForLast.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesForLast.stream().map(T7::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.set(result.size() - 1, bestBall); + } + } + + return result.subList(0, Math.min(10, result.size())); + } + + /** + * 从T3表获取指定主球的26个从球号(按线系数从大到小排列) + */ + private List getTop26FromT3(Integer masterBallNumber) { + log.debug("从T3表查询主球{}的线系数数据,取前26个", masterBallNumber); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t3List = t3Mapper.selectList(queryWrapper); + + if (t3List.isEmpty()) { + log.warn("T3表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + if (t3List.size() < 26) { + log.warn("T3表数据不足26条,实际{}条", t3List.size()); + return t3List.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前25个 + List result = new ArrayList<>(); + for (int i = 0; i < 25; i++) { + result.add(t3List.get(i).getSlaveBallNumber()); + } + + // 处理第26个位置:检查是否有相同的线系数 + Double targetCoefficient = t3List.get(25).getLineCoefficient(); + List candidatesFor26th = new ArrayList<>(); + + // 找出所有线系数等于第26个位置线系数的记录 + for (int i = 25; i < t3List.size(); i++) { + if (t3List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor26th.add(t3List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor26th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor26th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第26位有{}个相同线系数的候选:{}", candidatesFor26th.size(), + candidatesFor26th.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor26th.stream().map(T3::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T3表主球{}最终选择的26个从球:{}", masterBallNumber, result); + return result; + } + + /** + * 从history_top_100表获取前3个球号(按点系数排序) + */ + private List getTop3FromHistoryTop100() { + log.debug("从history_top_100表获取前3个球号"); + + // 查询前3个点系数最高的球号 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = historyTop100Mapper.selectList(queryWrapper); + + if (top100List.size() < 3) { + log.warn("history_top_100表数据不足3条,实际{}条", top100List.size()); + } + + List result = top100List.stream() + .map(HistoryTop100::getBallNumber) + .collect(Collectors.toList()); + + log.debug("history_top_100表前3个球号:{}", result); + return result; + } + + /** + * 从T4表获取指定主球的10个从球号 + * 根据不同级别使用不同的选择策略 + * @param masterBallNumber 主球号 + * @param level 级别:H-高位,M-中位,L-低位 + */ + private List getTop10FromT4(Integer masterBallNumber, String level) { + log.debug("从T4表查询主球{}的线系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t4List = t4Mapper.selectList(queryWrapper); + + if (t4List.isEmpty()) { + log.warn("T4表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + + switch (level) { + case "H": + // 高位:取线系数最大的前10个 + result = getHighLevelBallsFromT4For10(t4List); + break; + case "M": + // 中位:取线系数平均值向上6个向下4个的10个球号 + result = getMiddleLevelBallsFromT4For10(t4List); + break; + case "L": + // 低位:取线系数最小值向上第4-14个球的10个球号 + result = getLowLevelBallsFromT4For10(t4List); + break; + } + + log.debug("T4表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 高位算法:从T4表取线系数最大的前10个 + */ + private List getHighLevelBallsFromT4For10(List t4List) { + if (t4List.size() < 10) { + log.warn("T4表数据不足10条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前9个 + List result = new ArrayList<>(); + for (int i = 0; i < 9; i++) { + result.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理第10个位置:检查是否有相同的线系数 + Double targetCoefficient = t4List.get(9).getLineCoefficient(); + List candidatesFor10th = new ArrayList<>(); + + // 找出所有线系数等于第10个位置线系数的记录 + for (int i = 9; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor10th.add(t4List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor10th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor10th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第10位有{}个相同线系数的候选:{}", candidatesFor10th.size(), + candidatesFor10th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor10th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T4高位算法最终选择的10个球:{}", result); + return result; + } + + /** + * 中位算法:从T4表取线系数平均值向上6个向下4个的10个球号 + */ + private List getMiddleLevelBallsFromT4For10(List t4List) { + if (t4List.size() < 10) { + log.warn("T4表数据不足10条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 计算线系数平均值 + double avgCoefficient = t4List.stream() + .mapToDouble(T4::getLineCoefficient) + .average() + .orElse(0.0); + + log.debug("T4表线系数平均值:{}", avgCoefficient); + + // 找到最接近平均值的位置 + int avgIndex = 0; + double minDiff = Double.MAX_VALUE; + for (int i = 0; i < t4List.size(); i++) { + double diff = Math.abs(t4List.get(i).getLineCoefficient() - avgCoefficient); + if (diff < minDiff) { + minDiff = diff; + avgIndex = i; + } + } + + log.debug("最接近平均值的位置:{},线系数:{}", avgIndex, t4List.get(avgIndex).getLineCoefficient()); + + // 向上6个(含当前),向下4个,共10个 + int startIndex = Math.max(0, avgIndex - 4); + int endIndex = Math.min(t4List.size() - 1, avgIndex + 5); + + // 确保总共10个数字 + while (endIndex - startIndex + 1 < 10 && (startIndex > 0 || endIndex < t4List.size() - 1)) { + if (startIndex > 0) { + startIndex--; + } + if (endIndex < t4List.size() - 1 && endIndex - startIndex + 1 < 10) { + endIndex++; + } + } + + List candidates = new ArrayList<>(); + for (int i = startIndex; i <= endIndex && candidates.size() < 10; i++) { + candidates.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理边界位置的相同线系数情况 + List result = handleT4BoundaryConflictsFor10(t4List, candidates, startIndex, endIndex); + + log.debug("T4中位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 低位算法:从T4表取线系数最小值向上第4-14个球的10个球号 + */ + private List getLowLevelBallsFromT4For10(List t4List) { + if (t4List.size() < 14) { + log.warn("T4表数据不足14条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 从最后14个开始,取第4-14个(即倒数第11到倒数第1个) + int startIndex = Math.max(0, t4List.size() - 11); + int endIndex = t4List.size() - 1; + + List candidates = new ArrayList<>(); + for (int i = startIndex; i <= endIndex; i++) { + candidates.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理边界位置的相同线系数情况 + List result = handleT4BoundaryConflictsFor10(t4List, candidates, startIndex, endIndex); + + log.debug("T4低位算法选择范围:[{}, {}],共{}个球", startIndex, endIndex, result.size()); + return result; + } + + /** + * 统计数字出现频率,返回频率最高的前8个数字 + * 如果频次相同的球号超过8个,使用T7表面系数进行二次筛选 + */ + private List getTop8ByFrequency(List allNumbers) { + log.debug("统计{}个数字的出现频率", allNumbers.size()); + + // 统计频率 + Map frequencyMap = new HashMap<>(); + for (Integer number : allNumbers) { + frequencyMap.put(number, frequencyMap.getOrDefault(number, 0) + 1); + } + + log.debug("数字频率统计:{}", frequencyMap); + + // 按频率分组 + Map> frequencyGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : frequencyMap.entrySet()) { + Integer frequency = entry.getValue(); + Integer ballNumber = entry.getKey(); + + frequencyGroups.computeIfAbsent(frequency, k -> new ArrayList<>()).add(ballNumber); + } + + log.debug("按频率分组:{}", frequencyGroups); + + List result = new ArrayList<>(); + + // 按频率从高到低处理 + for (Map.Entry> group : frequencyGroups.entrySet()) { + Integer frequency = group.getKey(); + List balls = group.getValue(); + + // 对同频率的球号按数字升序排序 + Collections.sort(balls); + + log.info("频率{}的球号:{}", frequency, balls); + + // 检查加入这组球号后是否会超过8个 + if (result.size() + balls.size() <= 8) { + // 不会超过8个,直接添加所有球号 + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过8个,需要用T7表的面系数进行二次筛选 + int remainingSlots = 8 - result.size(); + log.info("需要从{}个频率相同的球号中选择{}个,使用T7表面系数进行筛选", balls.size(), remainingSlots); + + List selectedBalls = selectBallsByT7FaceCoefficient(balls, remainingSlots); + result.addAll(selectedBalls); + + log.info("通过T7表面系数筛选完成,最终选择:{}", selectedBalls); + break; // 已经达到8个,结束 + } + + // 如果已经有8个,结束 + if (result.size() >= 8) { + break; + } + } + + log.info("频率统计最终结果(共{}个):{}", result.size(), result); + + // 打印详细的频率信息 + for (int i = 0; i < result.size(); i++) { + Integer ballNumber = result.get(i); + Integer frequency = frequencyMap.get(ballNumber); + log.info("第{}位:数字{},出现{}次", i + 1, ballNumber, frequency); + } + + return result; + } + + /** + * 根据T7表的面系数总和选择球号,支持多级筛选 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 选择的球号列表 + */ + private List selectBallsByT7FaceCoefficient(List candidateBalls, int selectCount) { + log.info("开始根据T7表面系数总和选择球号,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 第一级:计算每个球号作为主球时的面系数总和 + Map faceCoefficientSumMap = new HashMap<>(); + + for (Integer ballNumber : candidateBalls) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", ballNumber); + + List t7List = t7Mapper.selectList(queryWrapper); + + double sum = t7List.stream() + .mapToDouble(T7::getFaceCoefficient) + .sum(); + + faceCoefficientSumMap.put(ballNumber, sum); + log.debug("球号{}作为主球的面系数总和:{}", ballNumber, sum); + } + + // 按面系数总和分组 + Map> faceCoefficientGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : faceCoefficientSumMap.entrySet()) { + Double sum = entry.getValue(); + Integer ballNumber = entry.getKey(); + faceCoefficientGroups.computeIfAbsent(sum, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("T7表面系数总和分组:{}", faceCoefficientGroups); + + List result = new ArrayList<>(); + + // 按面系数总和从高到低处理 + for (Map.Entry> group : faceCoefficientGroups.entrySet()) { + Double faceSum = group.getKey(); + List balls = group.getValue(); + + log.info("面系数总和{}的球号:{}", faceSum, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,需要进一步筛选 + int remainingSlots = selectCount - result.size(); + log.info("需要从{}个面系数总和相同的球号中选择{}个,开始多级筛选", balls.size(), remainingSlots); + + List selectedBalls = selectBallsByMultiLevelFilteringFor8(balls, remainingSlots); + result.addAll(selectedBalls); + + log.info("通过多级筛选完成,最终选择:{}", selectedBalls); + break; // 已经达到selectCount个,结束 + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + log.info("T7表面系数筛选最终结果(共{}个):{}", result.size(), result); + + // 打印详细的面系数信息 + for (int i = 0; i < result.size(); i++) { + Integer ballNumber = result.get(i); + Double sum = faceCoefficientSumMap.get(ballNumber); + log.info("第{}位:球号{},面系数总和:{}", i + 1, ballNumber, sum); + } + + return result; + } + + /** + * 多级筛选球号(8个球版本):history_top_100 -> history_top -> 随机选择 + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 选择的球号列表 + */ + private List selectBallsByMultiLevelFilteringFor8(List candidateBalls, int selectCount) { + log.info("开始多级筛选(8个球版本),候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 第二级:使用history_top_100表的排名进行筛选 + List filteredByTop100 = selectBallsByHistoryTop100RankingFor8(candidateBalls, selectCount); + + if (filteredByTop100.size() == selectCount) { + log.info("通过history_top_100表筛选成功,结果:{}", filteredByTop100); + return filteredByTop100; + } + + // 第三级:使用history_top表的点系数进行筛选 + log.info("history_top_100表筛选后仍有{}个球号,继续使用history_top表筛选", filteredByTop100.size()); + List filteredByTop = selectBallsByHistoryTopPointCoefficientFor8(filteredByTop100, selectCount); + + if (filteredByTop.size() == selectCount) { + log.info("通过history_top表筛选成功,结果:{}", filteredByTop); + return filteredByTop; + } + + // 第四级:随机选择 + log.info("history_top表筛选后仍有{}个球号,进行随机选择", filteredByTop.size()); + List finalResult = selectBallsRandomlyFor8(filteredByTop, selectCount); + + log.info("随机选择完成,最终结果:{}", finalResult); + return finalResult; + } + + /** + * 根据history_top_100表的排名筛选球号(8个球版本) + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 筛选后的球号列表 + */ + private List selectBallsByHistoryTop100RankingFor8(List candidateBalls, int selectCount) { + log.info("使用history_top_100表排名筛选球号(8个球版本),候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在history_top_100表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = historyTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("候选球号{}在history_top_100表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new LinkedHashMap<>(); + for (HistoryTop100 item : top100List) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("history_top_100表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的球号:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个球号:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在history_top_100表中的球号 + List notInTop100 = new ArrayList<>(candidateBalls); + notInTop100.removeAll(result); + if (!notInTop100.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInTop100); + int addCount = Math.min(remainingSlots, notInTop100.size()); + result.addAll(notInTop100.subList(0, addCount)); + log.info("添加不在history_top_100表中的{}个球号:{}", addCount, notInTop100.subList(0, addCount)); + } + + log.info("history_top_100表筛选结果:{}", result); + return result; + } + + /** + * 根据history_top表的点系数筛选球号(8个球版本) + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 筛选后的球号列表 + */ + private List selectBallsByHistoryTopPointCoefficientFor8(List candidateBalls, int selectCount) { + log.info("使用history_top表点系数筛选球号(8个球版本),候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在history_top表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List historyTopList = historyTopMapper.selectList(queryWrapper); + + if (historyTopList.isEmpty()) { + log.warn("候选球号{}在history_top表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new LinkedHashMap<>(); + for (HistoryTop item : historyTopList) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("history_top表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的球号:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个球号,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个球号:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在history_top表中的球号 + List notInHistoryTop = new ArrayList<>(candidateBalls); + notInHistoryTop.removeAll(result); + if (!notInHistoryTop.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInHistoryTop); + int addCount = Math.min(remainingSlots, notInHistoryTop.size()); + result.addAll(notInHistoryTop.subList(0, addCount)); + log.info("添加不在history_top表中的{}个球号:{}", addCount, notInHistoryTop.subList(0, addCount)); + } + + log.info("history_top表筛选结果:{}", result); + return result; + } + + /** + * 随机选择球号(8个球版本) + * @param candidateBalls 候选球号列表 + * @param selectCount 需要选择的数量 + * @return 随机选择的球号列表 + */ + private List selectBallsRandomlyFor8(List candidateBalls, int selectCount) { + log.info("随机选择球号(8个球版本),候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选球号数量不超过需要选择的数量,直接返回所有候选球号"); + return new ArrayList<>(candidateBalls); + } + + // 创建候选球号的副本并打乱顺序 + List shuffledBalls = new ArrayList<>(candidateBalls); + Collections.shuffle(shuffledBalls, new Random(System.currentTimeMillis())); + + // 选择前selectCount个 + List result = shuffledBalls.subList(0, selectCount); + + // 按球号升序排序结果 + Collections.sort(result); + + log.info("随机选择结果:{}", result); + return result; + } + + /** + * 蓝球分析算法主方法 + * @param level 高位/中位/低位标识 (H/M/L) + * @param predictedRedBalls 6个预测的红球号码 + * @param predictedBlueBalls 2个预测的蓝球号码 + * @param lastRedBalls 6个上期红球号码 + * @param lastBlueBall 1个上期蓝球号码 + * @return 分析结果:出现频率最高的前4个蓝球号码 + */ + public List blueBallAnalysis(String level, List predictedRedBalls, + List predictedBlueBalls, List lastRedBalls, + Integer lastBlueBall) { + log.info("开始蓝球分析算法,级别:{},预测红球:{},预测蓝球:{},上期红球:{},上期蓝球:{}", + level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + // 验证输入参数 + validateBlueBallAnalysisParams(level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + List allNumbers = new ArrayList<>(); + + // 第一步:处理上期6个红球,每个红球从T6表获取12个蓝球号码 + log.info("第一步:处理上期6个红球,从T6表获取蓝球号码"); + for (int i = 0; i < lastRedBalls.size(); i++) { + Integer redBall = lastRedBalls.get(i); + log.info("处理第{}个上期红球:{}", i + 1, redBall); + + List ballNumbers = getTop12FromT6(redBall); + allNumbers.addAll(ballNumbers); + + log.info("上期红球{}从T6表获取到{}个蓝球号码:{}", redBall, ballNumbers.size(), ballNumbers); + } + + // 第二步:处理预测的6个红球,每个红球从T8表获取5个蓝球号码 + log.info("第二步:处理预测的6个红球,从T8表获取蓝球号码,使用{}级别算法", level); + for (int i = 0; i < predictedRedBalls.size(); i++) { + Integer redBall = predictedRedBalls.get(i); + log.info("处理第{}个预测红球:{}", i + 1, redBall); + + List ballNumbers = getSimpleTop5FromT8ByLevel(redBall, level); + allNumbers.addAll(ballNumbers); + + log.info("预测红球{}从T8表获取到{}个蓝球号码:{}", redBall, ballNumbers.size(), ballNumbers); + } + + // 第三步:从blue_history_top_100获取前2个蓝球号码 + log.info("第三步:从blue_history_top_100获取前2个蓝球号码"); + List top2BlueNumbers = getTop2FromBlueHistoryTop100(); + allNumbers.addAll(top2BlueNumbers); + log.info("从blue_history_top_100获取到{}个蓝球号码:{}", top2BlueNumbers.size(), top2BlueNumbers); + + // 第四步:添加预测的2个蓝球号码 + log.info("第四步:添加预测的2个蓝球号码:{}", predictedBlueBalls); + allNumbers.addAll(predictedBlueBalls); + + // 第五步:用上期蓝球从T5表获取5个蓝球号码 + log.info("第五步:用上期蓝球{}从T5表获取5个蓝球号码,使用{}级别算法", lastBlueBall, level); + List t5Numbers = getSimpleTop5FromT5ByLevel(lastBlueBall, level); + allNumbers.addAll(t5Numbers); + log.info("上期蓝球{}从T5表获取到{}个蓝球号码:{}", lastBlueBall, t5Numbers.size(), t5Numbers); + + log.info("总共收集到{}个蓝球号码", allNumbers.size()); + + // 第六步:统计频率并获取前4个 + List result = getSimpleTop4ByFrequency(allNumbers); + + log.info("蓝球分析算法完成,结果:{}", result); + return result; + } + + /** + * 验证蓝球分析算法的输入参数 + */ + private void validateBlueBallAnalysisParams(String level, List predictedRedBalls, + List predictedBlueBalls, List lastRedBalls, + Integer lastBlueBall) { + // 验证级别 + if (!Arrays.asList("H", "M", "L").contains(level)) { + throw new IllegalArgumentException("级别必须为H、M或L"); + } + + // 验证预测红球 + if (predictedRedBalls == null || predictedRedBalls.size() != 6) { + throw new IllegalArgumentException("预测红球数量必须为6个"); + } + for (Integer ball : predictedRedBalls) { + if (ball == null || ball < 1 || ball > 33) { + throw new IllegalArgumentException("预测红球号码必须在1-33范围内,实际:" + ball); + } + } + if (predictedRedBalls.stream().distinct().count() != predictedRedBalls.size()) { + throw new IllegalArgumentException("预测红球号码不能重复"); + } + + // 验证预测蓝球 + if (predictedBlueBalls == null || predictedBlueBalls.size() != 2) { + throw new IllegalArgumentException("预测蓝球数量必须为2个"); + } + for (Integer ball : predictedBlueBalls) { + if (ball == null || ball < 1 || ball > 16) { + throw new IllegalArgumentException("预测蓝球号码必须在1-16范围内,实际:" + ball); + } + } + if (predictedBlueBalls.stream().distinct().count() != predictedBlueBalls.size()) { + throw new IllegalArgumentException("预测蓝球号码不能重复"); + } + + // 验证上期红球 + if (lastRedBalls == null || lastRedBalls.size() != 6) { + throw new IllegalArgumentException("上期红球数量必须为6个"); + } + for (Integer ball : lastRedBalls) { + if (ball == null || ball < 1 || ball > 33) { + throw new IllegalArgumentException("上期红球号码必须在1-33范围内,实际:" + ball); + } + } + if (lastRedBalls.stream().distinct().count() != lastRedBalls.size()) { + throw new IllegalArgumentException("上期红球号码不能重复"); + } + + // 验证上期蓝球 + if (lastBlueBall == null || lastBlueBall < 1 || lastBlueBall > 16) { + throw new IllegalArgumentException("上期蓝球号码必须在1-16范围内,实际:" + lastBlueBall); + } + + log.debug("蓝球分析算法参数验证通过"); + } + + /** + * 从T6表获取指定红球对应的12个蓝球号码(线系数最大的12个) + * @param masterBallNumber 主球号(红球) + * @return 12个蓝球号码列表 + */ + private List getTop12FromT6(Integer masterBallNumber) { + log.debug("从T6表查询主球{}的线系数数据", masterBallNumber); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t6List = t6Mapper.selectList(queryWrapper); + + if (t6List.isEmpty()) { + log.warn("T6表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + if (t6List.size() < 12) { + log.warn("T6表数据不足12条,实际{}条", t6List.size()); + return t6List.stream().map(T6::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前11个 + List result = new ArrayList<>(); + for (int i = 0; i < 11; i++) { + result.add(t6List.get(i).getSlaveBallNumber()); + } + + // 处理第12个位置:检查是否有相同的线系数 + Double targetCoefficient = t6List.get(11).getLineCoefficient(); + List candidatesFor12th = new ArrayList<>(); + + // 找出所有线系数等于第12个位置线系数的记录 + for (int i = 11; i < t6List.size(); i++) { + if (t6List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor12th.add(t6List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor12th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor12th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过blue_history_top_100表的点系数排序 + log.debug("第12位有{}个相同线系数的候选:{}", candidatesFor12th.size(), + candidatesFor12th.stream().map(T6::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromBlueHistoryTop100( + candidatesFor12th.stream().map(T6::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T6表主球{}最终选择的{}个从球:{}", masterBallNumber, result.size(), result); + return result; + } + + /** + * 从blue_history_top_100表中选择点系数最高的球号 + * @param candidates 候选球号列表 + * @return 点系数最高的球号 + */ + private Integer selectBestBallFromBlueHistoryTop100(List candidates) { + log.debug("从blue_history_top_100表中选择最佳球号,候选:{}", candidates); + + if (candidates.isEmpty()) { + throw new IllegalArgumentException("候选球号列表不能为空"); + } + + if (candidates.size() == 1) { + return candidates.get(0); + } + + // 查询这些球号在blue_history_top_100表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidates) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = blueHistoryTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("候选球号{}在blue_history_top_100表中未找到数据,返回最小球号", candidates); + return Collections.min(candidates); + } + + // 返回点系数最高的球号 + Integer bestBall = top100List.get(0).getBallNumber(); + log.debug("选择的最佳球号:{},点系数:{}", bestBall, top100List.get(0).getPointCoefficient()); + + return bestBall; + } + + /** + * 从T8表获取指定红球对应的5个蓝球号码(简化版本) + * @param masterBallNumber 主球号(红球) + * @param level 级别:H-高位,M-中位,L-低位 + * @return 5个蓝球号码列表 + */ + private List getSimpleTop5FromT8ByLevel(Integer masterBallNumber, String level) { + log.debug("从T8表查询主球{}的面系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按面系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("faceCoefficient") + .orderByAsc("slaveBallNumber"); // 面系数相同时按从球号升序 + + List t8List = t8Mapper.selectList(queryWrapper); + + if (t8List.isEmpty()) { + log.warn("T8表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + int size = t8List.size(); + + switch (level) { + case "H": + // 高位:取面系数最大的5个 + for (int i = 0; i < Math.min(5, size); i++) { + result.add(t8List.get(i).getSlaveBallNumber()); + } + break; + case "M": + // 中位:取中间的5个 + int start = Math.max(0, (size - 5) / 2); + for (int i = start; i < Math.min(start + 5, size); i++) { + result.add(t8List.get(i).getSlaveBallNumber()); + } + break; + case "L": + // 低位:取最后5个(面系数最小的) + int startLow = Math.max(0, size - 5); + for (int i = startLow; i < size; i++) { + result.add(t8List.get(i).getSlaveBallNumber()); + } + break; + } + + log.debug("T8表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 从blue_history_top_100表获取点系数最高的前2个蓝球号码 + * 如果第2个点系数不唯一,使用blue_history_top表进行二级筛选 + * @return 前2个蓝球号码列表 + */ + private List getTop2FromBlueHistoryTop100() { + log.debug("从blue_history_top_100表获取前2个蓝球号码"); + + // 查询所有数据,按点系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = blueHistoryTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("blue_history_top_100表中没有数据"); + return new ArrayList<>(); + } + + if (top100List.size() == 1) { + List result = Arrays.asList(top100List.get(0).getBallNumber()); + log.debug("blue_history_top_100表只有1条数据:{}", result); + return result; + } + + List result = new ArrayList<>(); + + // 第1个直接取点系数最高的 + result.add(top100List.get(0).getBallNumber()); + log.debug("第1个蓝球号码:{},点系数:{}", top100List.get(0).getBallNumber(), top100List.get(0).getPointCoefficient()); + + // 处理第2个位置:检查是否有相同的点系数 + Double targetCoefficient = top100List.get(1).getPointCoefficient(); + List candidatesFor2nd = new ArrayList<>(); + + // 找出所有点系数等于第2个位置点系数的记录 + for (int i = 1; i < top100List.size(); i++) { + if (top100List.get(i).getPointCoefficient().equals(targetCoefficient)) { + candidatesFor2nd.add(top100List.get(i)); + } else { + break; // 点系数不同,停止查找 + } + } + + if (candidatesFor2nd.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor2nd.get(0).getBallNumber()); + log.debug("第2个蓝球号码:{},点系数:{}", candidatesFor2nd.get(0).getBallNumber(), candidatesFor2nd.get(0).getPointCoefficient()); + } else { + // 有多个候选,通过blue_history_top表的点系数排序 + log.debug("第2位有{}个相同点系数的候选:{}", candidatesFor2nd.size(), + candidatesFor2nd.stream().map(BlueHistoryTop100::getBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromBlueHistoryTop( + candidatesFor2nd.stream().map(BlueHistoryTop100::getBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + log.debug("通过blue_history_top表筛选的第2个蓝球号码:{}", bestBall); + } + + log.debug("从blue_history_top_100表最终获取到{}个蓝球号码:{}", result.size(), result); + return result; + } + + /** + * 从T5表获取指定蓝球对应的5个蓝球号码(简化版本) + * @param masterBallNumber 主球号(蓝球) + * @param level 级别:H-高位,M-中位,L-低位 + * @return 5个蓝球号码列表 + */ + private List getSimpleTop5FromT5ByLevel(Integer masterBallNumber, String level) { + log.debug("从T5表查询主球{}的线系数数据,级别:{}", masterBallNumber, level); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t5List = t5Mapper.selectList(queryWrapper); + + if (t5List.isEmpty()) { + log.warn("T5表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + List result = new ArrayList<>(); + int size = t5List.size(); + + switch (level) { + case "H": + // 高位:取线系数最大的5个 + for (int i = 0; i < Math.min(5, size); i++) { + result.add(t5List.get(i).getSlaveBallNumber()); + } + break; + case "M": + // 中位:取中间的5个 + int start = Math.max(0, (size - 5) / 2); + for (int i = start; i < Math.min(start + 5, size); i++) { + result.add(t5List.get(i).getSlaveBallNumber()); + } + break; + case "L": + // 低位:取最后5个(线系数最小的) + int startLow = Math.max(0, size - 5); + for (int i = startLow; i < size; i++) { + result.add(t5List.get(i).getSlaveBallNumber()); + } + break; + } + + log.debug("T5表主球{}{}级别最终选择的{}个从球:{}", masterBallNumber, level, result.size(), result); + return result; + } + + /** + * 统计数字出现频率,返回频率最高的前4个蓝球号码 + * 如果频次相同的球号超过4个,使用多级筛选机制 + */ + private List getSimpleTop4ByFrequency(List allNumbers) { + log.debug("统计{}个蓝球号码的出现频率", allNumbers.size()); + + // 统计频率 + Map frequencyMap = new HashMap<>(); + for (Integer number : allNumbers) { + frequencyMap.put(number, frequencyMap.getOrDefault(number, 0) + 1); + } + + log.debug("蓝球号码频率统计:{}", frequencyMap); + + // 按频率分组 + Map> frequencyGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : frequencyMap.entrySet()) { + Integer frequency = entry.getValue(); + Integer ballNumber = entry.getKey(); + + frequencyGroups.computeIfAbsent(frequency, k -> new ArrayList<>()).add(ballNumber); + } + + log.debug("按频率分组:{}", frequencyGroups); + + List result = new ArrayList<>(); + + // 按频率从高到低处理 + for (Map.Entry> group : frequencyGroups.entrySet()) { + Integer frequency = group.getKey(); + List balls = group.getValue(); + + // 对同频率的球号按数字升序排序 + Collections.sort(balls); + + log.info("频率{}的蓝球号码:{}", frequency, balls); + + // 检查加入这组球号后是否会超过4个 + if (result.size() + balls.size() <= 4) { + // 不会超过4个,直接添加所有球号 + result.addAll(balls); + log.info("直接添加{}个蓝球号码,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过4个,需要用多级筛选机制 + int remainingSlots = 4 - result.size(); + log.info("需要从{}个频率相同的蓝球号码中选择{}个,使用多级筛选机制", balls.size(), remainingSlots); + + List selectedBalls = selectBallsByMultiLevelFilteringForBlue4(balls, remainingSlots); + result.addAll(selectedBalls); + + log.info("通过多级筛选完成,最终选择:{}", selectedBalls); + break; // 已经达到4个,结束 + } + + // 如果已经有4个,结束 + if (result.size() >= 4) { + break; + } + } + + log.info("频率统计最终结果(共{}个):{}", result.size(), result); + + // 打印详细的频率信息 + for (int i = 0; i < result.size(); i++) { + Integer ballNumber = result.get(i); + Integer frequency = frequencyMap.get(ballNumber); + log.info("第{}位:蓝球号码{},出现{}次", i + 1, ballNumber, frequency); + } + + return result; + } + + /** + * 从blue_history_top表中选择点系数最高的球号 + * @param candidates 候选球号列表 + * @return 点系数最高的球号 + */ + private Integer selectBestBallFromBlueHistoryTop(List candidates) { + log.debug("从blue_history_top表中选择最佳球号,候选:{}", candidates); + + if (candidates.isEmpty()) { + throw new IllegalArgumentException("候选球号列表不能为空"); + } + + if (candidates.size() == 1) { + return candidates.get(0); + } + + // 查询这些球号在blue_history_top表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidates) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List historyTopList = blueHistoryTopMapper.selectList(queryWrapper); + + if (historyTopList.isEmpty()) { + log.warn("候选球号{}在blue_history_top表中未找到数据,返回最小球号", candidates); + return Collections.min(candidates); + } + + // 返回点系数最高的球号 + Integer bestBall = historyTopList.get(0).getBallNumber(); + log.debug("选择的最佳球号:{},点系数:{}", bestBall, historyTopList.get(0).getPointCoefficient()); + + return bestBall; + } + + /** + * 四级筛选蓝球号码:T8面系数 -> blue_history_top_100排名 -> blue_history_top点系数 -> 随机选择 + * @param candidateBalls 候选蓝球号码列表 + * @param selectCount 需要选择的数量 + * @return 选择的蓝球号码列表 + */ + private List selectBallsByMultiLevelFilteringForBlue4(List candidateBalls, int selectCount) { + log.info("开始四级筛选蓝球号码,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选蓝球号码数量不超过需要选择的数量,直接返回所有候选蓝球号码"); + return new ArrayList<>(candidateBalls); + } + + // 第一级:使用T8表的面系数总和进行筛选 + List filteredByT8 = selectBallsByT8FaceCoefficientSumForBlue4(candidateBalls, selectCount); + + if (filteredByT8.size() == selectCount) { + log.info("通过T8表面系数筛选成功,结果:{}", filteredByT8); + return filteredByT8; + } + + // 第二级:使用blue_history_top_100表的排名进行筛选 + log.info("T8表筛选后仍有{}个蓝球号码,继续使用blue_history_top_100表筛选", filteredByT8.size()); + List filteredByTop100 = selectBallsByBlueHistoryTop100RankingForBlue4(filteredByT8, selectCount); + + if (filteredByTop100.size() == selectCount) { + log.info("通过blue_history_top_100表筛选成功,结果:{}", filteredByTop100); + return filteredByTop100; + } + + // 第三级:使用blue_history_top表的点系数进行筛选 + log.info("blue_history_top_100表筛选后仍有{}个蓝球号码,继续使用blue_history_top表筛选", filteredByTop100.size()); + List filteredByTop = selectBallsByBlueHistoryTopPointCoefficientForBlue4(filteredByTop100, selectCount); + + if (filteredByTop.size() == selectCount) { + log.info("通过blue_history_top表筛选成功,结果:{}", filteredByTop); + return filteredByTop; + } + + // 第四级:随机选择 + log.info("blue_history_top表筛选后仍有{}个蓝球号码,进行随机选择", filteredByTop.size()); + List finalResult = selectBallsRandomlyForBlue4(filteredByTop, selectCount); + + log.info("随机选择完成,最终结果:{}", finalResult); + return finalResult; + } + + /** + * 根据T8表的面系数总和选择蓝球号码(第一级筛选) + * @param candidateBalls 候选蓝球号码列表 + * @param selectCount 需要选择的数量 + * @return 选择的蓝球号码列表 + */ + private List selectBallsByT8FaceCoefficientSumForBlue4(List candidateBalls, int selectCount) { + log.info("开始根据T8表面系数总和选择蓝球号码,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选蓝球号码数量不超过需要选择的数量,直接返回所有候选蓝球号码"); + return new ArrayList<>(candidateBalls); + } + + // 计算每个蓝球号码作为主球时的面系数总和 + Map faceCoefficientSumMap = new HashMap<>(); + + for (Integer ballNumber : candidateBalls) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", ballNumber); + + List t8List = t8Mapper.selectList(queryWrapper); + + double sum = t8List.stream() + .mapToDouble(T8::getFaceCoefficient) + .sum(); + + faceCoefficientSumMap.put(ballNumber, sum); + log.debug("蓝球号码{}作为主球的面系数总和:{}", ballNumber, sum); + } + + // 按面系数总和分组 + Map> faceCoefficientGroups = new TreeMap<>(Collections.reverseOrder()); + for (Map.Entry entry : faceCoefficientSumMap.entrySet()) { + Double sum = entry.getValue(); + Integer ballNumber = entry.getKey(); + faceCoefficientGroups.computeIfAbsent(sum, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("T8表面系数总和分组:{}", faceCoefficientGroups); + + List result = new ArrayList<>(); + + // 按面系数总和从高到低处理 + for (Map.Entry> group : faceCoefficientGroups.entrySet()) { + Double faceSum = group.getKey(); + List balls = group.getValue(); + + log.info("面系数总和{}的蓝球号码:{}", faceSum, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个蓝球号码,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个蓝球号码:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + log.info("T8表面系数筛选结果:{}", result); + return result; + } + + /** + * 根据blue_history_top_100表的点系数选择蓝球号码(第二级筛选) + * @param candidateBalls 候选蓝球号码列表 + * @param selectCount 需要选择的数量 + * @return 选择的蓝球号码列表 + */ + private List selectBallsByBlueHistoryTop100RankingForBlue4(List candidateBalls, int selectCount) { + log.info("使用blue_history_top_100表点系数筛选蓝球号码,候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在blue_history_top_100表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List top100List = blueHistoryTop100Mapper.selectList(queryWrapper); + + if (top100List.isEmpty()) { + log.warn("候选球号{}在blue_history_top_100表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new TreeMap<>(Collections.reverseOrder()); + for (BlueHistoryTop100 item : top100List) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("blue_history_top_100表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的蓝球号码:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个蓝球号码,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个蓝球号码:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在blue_history_top_100表中的球号 + List notInTop100 = new ArrayList<>(candidateBalls); + notInTop100.removeAll(result); + if (!notInTop100.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInTop100); + int addCount = Math.min(remainingSlots, notInTop100.size()); + result.addAll(notInTop100.subList(0, addCount)); + log.info("添加不在blue_history_top_100表中的{}个蓝球号码:{}", addCount, notInTop100.subList(0, addCount)); + } + + log.info("blue_history_top_100表筛选结果:{}", result); + return result; + } + + /** + * 根据blue_history_top表的点系数选择蓝球号码(第三级筛选) + * @param candidateBalls 候选蓝球号码列表 + * @param selectCount 需要选择的数量 + * @return 选择的蓝球号码列表 + */ + private List selectBallsByBlueHistoryTopPointCoefficientForBlue4(List candidateBalls, int selectCount) { + log.info("使用blue_history_top表点系数筛选蓝球号码,候选:{},需要选择:{}", candidateBalls, selectCount); + + // 查询这些球号在blue_history_top表中的点系数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("ballNumber", candidateBalls) + .orderByDesc("pointCoefficient") + .orderByAsc("ballNumber"); // 点系数相同时按球号升序 + + List historyTopList = blueHistoryTopMapper.selectList(queryWrapper); + + if (historyTopList.isEmpty()) { + log.warn("候选球号{}在blue_history_top表中未找到数据,按球号升序返回", candidateBalls); + Collections.sort(candidateBalls); + return candidateBalls.subList(0, Math.min(selectCount, candidateBalls.size())); + } + + // 按点系数分组 + Map> pointCoefficientGroups = new TreeMap<>(Collections.reverseOrder()); + for (BlueHistoryTop item : historyTopList) { + Double pointCoefficient = item.getPointCoefficient(); + Integer ballNumber = item.getBallNumber(); + pointCoefficientGroups.computeIfAbsent(pointCoefficient, k -> new ArrayList<>()).add(ballNumber); + } + + log.info("blue_history_top表点系数分组:{}", pointCoefficientGroups); + + List result = new ArrayList<>(); + + // 按点系数从高到低处理 + for (Map.Entry> group : pointCoefficientGroups.entrySet()) { + Double pointCoefficient = group.getKey(); + List balls = group.getValue(); + + log.info("点系数{}的蓝球号码:{}", pointCoefficient, balls); + + // 检查加入这组球号后是否会超过selectCount个 + if (result.size() + balls.size() <= selectCount) { + // 不会超过,直接添加所有球号(按球号升序排序) + Collections.sort(balls); + result.addAll(balls); + log.info("直接添加{}个蓝球号码,当前总数:{}", balls.size(), result.size()); + } else { + // 会超过,按球号升序选择需要的数量 + int remainingSlots = selectCount - result.size(); + Collections.sort(balls); + result.addAll(balls.subList(0, remainingSlots)); + log.info("选择前{}个蓝球号码:{}", remainingSlots, balls.subList(0, remainingSlots)); + break; + } + + // 如果已经有selectCount个,结束 + if (result.size() >= selectCount) { + break; + } + } + + // 处理不在blue_history_top表中的球号 + List notInHistoryTop = new ArrayList<>(candidateBalls); + notInHistoryTop.removeAll(result); + if (!notInHistoryTop.isEmpty() && result.size() < selectCount) { + int remainingSlots = selectCount - result.size(); + Collections.sort(notInHistoryTop); + int addCount = Math.min(remainingSlots, notInHistoryTop.size()); + result.addAll(notInHistoryTop.subList(0, addCount)); + log.info("添加不在blue_history_top表中的{}个蓝球号码:{}", addCount, notInHistoryTop.subList(0, addCount)); + } + + log.info("blue_history_top表筛选结果:{}", result); + return result; + } + + /** + * 随机选择蓝球号码(第四级筛选) + * @param candidateBalls 候选蓝球号码列表 + * @param selectCount 需要选择的数量 + * @return 随机选择的蓝球号码列表 + */ + private List selectBallsRandomlyForBlue4(List candidateBalls, int selectCount) { + log.info("随机选择蓝球号码,候选:{},需要选择:{}", candidateBalls, selectCount); + + if (candidateBalls.size() <= selectCount) { + log.info("候选蓝球号码数量不超过需要选择的数量,直接返回所有候选蓝球号码"); + return new ArrayList<>(candidateBalls); + } + + // 创建候选球号的副本并打乱顺序 + List shuffledBalls = new ArrayList<>(candidateBalls); + Collections.shuffle(shuffledBalls, new Random(System.currentTimeMillis())); + + // 选择前selectCount个 + List result = shuffledBalls.subList(0, selectCount); + + // 按球号升序排序结果 + Collections.sort(result); + + log.info("随机选择结果:{}", result); + return result; + } + + /** + * 首球命中率统计 + * @param userId 用户ID + * @return 首球命中率统计信息 + */ + public BallHitRateVO getFirstBallHitRate(Long userId) { + log.info("开始统计用户{}的首球命中率", userId); + + // 查询用户的所有预测记录(除了"待开奖"状态的) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId) + .ne("predictStatus", "待开奖"); + + List predictRecords = predictRecordMapper.selectList(queryWrapper); + + // 总预测次数 + int totalCount = predictRecords.size(); + + // 统计首球命中次数 + int hitCount = 0; + + for (PredictRecord record : predictRecords) { + // 获取该预测记录对应的开奖信息 + LotteryDraws draw = lotteryDrawsService.getByDrawId(record.getDrawId()); + + if (draw != null && record.getRedBall1() != null) { + Integer predictedFirstBall = record.getRedBall1(); + List drawnRedBalls = Arrays.asList( + draw.getRedBall1(), + draw.getRedBall2(), + draw.getRedBall3(), + draw.getRedBall4(), + draw.getRedBall5(), + draw.getRedBall6() + ); + // 比较预测的第一个红球是否在开奖的六个红球中 + if (drawnRedBalls.contains(predictedFirstBall)) { + hitCount++; + } + } + } + + // 计算命中率 + double hitRate = totalCount > 0 ? (double) hitCount / totalCount * 100 : 0; + + BallHitRateVO result = BallHitRateVO.builder() + .hitCount(hitCount) + .totalCount(totalCount) + .hitRate(hitRate) + .build(); + + log.info("用户{}的首球命中率统计结果:命中{}次,总计{}次,命中率{}%", + userId, hitCount, totalCount, String.format("%.2f", hitRate)); + return result; + } + + /** + * 蓝球命中率统计 + * @param userId 用户ID + * @return 蓝球命中率统计信息 + */ + public BallHitRateVO getBlueBallHitRate(Long userId) { + log.info("开始统计用户{}的蓝球命中率", userId); + + // 查询用户的所有预测记录(除了"待开奖"状态的) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId) + .ne("predictStatus", "待开奖"); + + List predictRecords = predictRecordMapper.selectList(queryWrapper); + + // 总预测次数 + int totalCount = predictRecords.size(); + + // 统计蓝球命中次数 + int hitCount = 0; + + for (PredictRecord record : predictRecords) { + // 获取该预测记录对应的开奖信息 + LotteryDraws draw = lotteryDrawsService.getByDrawId(record.getDrawId()); + + if (draw != null && record.getBlueBall() != null) { + // 比较预测的蓝球与开奖的蓝球是否相等 + if (record.getBlueBall().equals(draw.getBlueBall())) { + hitCount++; + } + } + } + + // 计算命中率 + double hitRate = totalCount > 0 ? (double) hitCount / totalCount * 100 : 0; + + BallHitRateVO result = BallHitRateVO.builder() + .hitCount(hitCount) + .totalCount(totalCount) + .hitRate(hitRate) + .build(); + + log.info("用户{}的蓝球命中率统计结果:命中{}次,总计{}次,命中率{}%", + userId, hitCount, totalCount, String.format("%.2f", hitRate)); + return result; + } + + /** + * 奖金统计 + * @param userId 用户ID + * @param predictId 预测记录ID,如果为null则统计所有记录 + * @return 奖金统计信息 + */ + public PrizeEstimateVO getPrizeStatistics(Long userId, Long predictId) { + log.info("开始为用户{}进行奖金统计,predictId={}", userId, predictId); + + // 查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId); + // 排除待开奖状态 + queryWrapper.ne("predictStatus", "待开奖"); + // 如果指定了预测记录ID,则只查询该记录 + if (predictId != null) { + queryWrapper.eq("id", predictId); + } + + // 查询用户的预测记录 + List records = predictRecordMapper.selectList(queryWrapper); + + // 按中奖等级分组统计 + Map countByPrizeLevel = new HashMap<>(); + Map totalBonusByPrizeLevel = new HashMap<>(); + + // 初始化所有等级 + String[] prizeLevels = {"一等奖", "二等奖", "三等奖", "四等奖", "五等奖", "六等奖", "未中奖"}; + for (String level : prizeLevels) { + countByPrizeLevel.put(level, 0); + totalBonusByPrizeLevel.put(level, BigDecimal.ZERO); + } + + // 统计各等级数量和奖金 + for (PredictRecord record : records) { + String prizeLevel = record.getPredictResult(); + if (prizeLevel == null) { + prizeLevel = "未中奖"; + } + + // 更新计数 + countByPrizeLevel.put(prizeLevel, countByPrizeLevel.getOrDefault(prizeLevel, 0) + 1); + + // 累计奖金 + if (record.getBonus() != null) { + BigDecimal bonus = new BigDecimal(record.getBonus().toString()); + totalBonusByPrizeLevel.put(prizeLevel, + totalBonusByPrizeLevel.getOrDefault(prizeLevel, BigDecimal.ZERO).add(bonus)); + } + } + + // 构建返回结果 + List prizeDetails = new ArrayList<>(); + + // 按顺序添加各等级的统计结果(从高到低) + for (String level : prizeLevels) { + // 跳过没有记录的等级 + if (countByPrizeLevel.get(level) <= 0) { + continue; + } + + int count = countByPrizeLevel.get(level); + BigDecimal totalBonus = totalBonusByPrizeLevel.get(level); + BigDecimal singlePrize = BigDecimal.ZERO; + if (count > 0) { + singlePrize = totalBonus.divide(new BigDecimal(count), 2, RoundingMode.HALF_UP); + } + + prizeDetails.add(PrizeEstimateVO.PrizeDetailItem.builder() + .prizeLevel(level) + .winningCount(count) + .singlePrize(singlePrize) + .subtotal(totalBonus) + .build()); + } + + // 计算总奖金 + BigDecimal totalPrize = prizeDetails.stream() + .map(PrizeEstimateVO.PrizeDetailItem::getSubtotal) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + PrizeEstimateVO result = PrizeEstimateVO.builder() + .totalPrize(totalPrize) + .prizeDetails(prizeDetails) + .build(); + + log.info("用户{}的奖金统计结果:总奖金{},各等级明细:{}", + userId, totalPrize, prizeDetails); + return result; + } + + /** + * 红球命中率统计 + * @param userId 用户ID + * @return 红球命中率统计信息 + */ + public RedBallHitRateVO getRedBallHitRate(Long userId) { + log.info("开始统计用户{}的红球命中率", userId); + + // 查询用户的所有预测记录(除了"待开奖"状态的) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId) + .ne("predictStatus", "待开奖"); + + List predictRecords = predictRecordMapper.selectList(queryWrapper); + + int totalHitCount = 0; + int totalRecords = predictRecords.size(); + + for (PredictRecord record : predictRecords) { + // 获取该预测记录对应的开奖信息 + LotteryDraws draw = lotteryDrawsService.getByDrawId(record.getDrawId()); + + if (draw != null) { + List predictedRedBalls = Arrays.asList( + record.getRedBall1(), + record.getRedBall2(), + record.getRedBall3(), + record.getRedBall4(), + record.getRedBall5(), + record.getRedBall6() + ); + + List drawnRedBalls = Arrays.asList( + draw.getRedBall1(), + draw.getRedBall2(), + draw.getRedBall3(), + draw.getRedBall4(), + draw.getRedBall5(), + draw.getRedBall6() + ); + + // 计算当前记录命中的红球数 + for (Integer predictedBall : predictedRedBalls) { + if (predictedBall != null && drawnRedBalls.contains(predictedBall)) { + totalHitCount++; + } + } + } + } + + int totalPredictedCount = totalRecords * 6; + double hitRate = (totalPredictedCount > 0) ? ((double) totalHitCount / totalPredictedCount) * 100 : 0; + + RedBallHitRateVO result = RedBallHitRateVO.builder() + .totalHitCount(totalHitCount) + .totalPredictedCount(totalPredictedCount) + .hitRate(hitRate) + .build(); + + log.info("用户{}的红球命中率统计结果:命中总数{},预测总数{},命中率{}%", + userId, totalHitCount, totalPredictedCount, String.format("%.2f", hitRate)); + + return result; + } + + /** + * 从T4表获取指定主球的26个从球号,取线系数最大值向下26个数字 + * @param masterBallNumber 主球号 + */ + private List getTop26FromT4(Integer masterBallNumber) { + log.debug("从T4表查询主球{}的线系数数据,取前26个", masterBallNumber); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t4List = t4Mapper.selectList(queryWrapper); + + if (t4List.isEmpty()) { + log.warn("T4表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + if (t4List.size() < 26) { + log.warn("T4表数据不足26条,实际{}条", t4List.size()); + return t4List.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前25个 + List result = new ArrayList<>(); + for (int i = 0; i < 25; i++) { + result.add(t4List.get(i).getSlaveBallNumber()); + } + + // 处理第26个位置:检查是否有相同的线系数 + Double targetCoefficient = t4List.get(25).getLineCoefficient(); + List candidatesFor26th = new ArrayList<>(); + + // 找出所有线系数等于第26个位置线系数的记录 + for (int i = 25; i < t4List.size(); i++) { + if (t4List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor26th.add(t4List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor26th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor26th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过history_top_100表的点系数排序 + log.debug("第26位有{}个相同线系数的候选:{}", candidatesFor26th.size(), + candidatesFor26th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromHistoryTop100( + candidatesFor26th.stream().map(T4::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T4表主球{}最终选择的26个从球:{}", masterBallNumber, result); + return result; + } + + /** + * 从T5表获取指定主球的12个从球号,取线系数最大值向下12个数字 + * @param masterBallNumber 主球号 + */ + private List getTop12FromT5(Integer masterBallNumber) { + log.debug("从T5表查询主球{}的线系数数据,取前12个", masterBallNumber); + + // 查询指定主球的所有数据,按线系数降序排列 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("masterBallNumber", masterBallNumber) + .orderByDesc("lineCoefficient") + .orderByAsc("slaveBallNumber"); // 线系数相同时按从球号升序 + + List t5List = t5Mapper.selectList(queryWrapper); + + if (t5List.isEmpty()) { + log.warn("T5表中主球{}没有数据", masterBallNumber); + return new ArrayList<>(); + } + + if (t5List.size() < 12) { + log.warn("T5表数据不足12条,实际{}条", t5List.size()); + return t5List.stream().map(T5::getSlaveBallNumber).collect(Collectors.toList()); + } + + // 获取前11个 + List result = new ArrayList<>(); + for (int i = 0; i < 11; i++) { + result.add(t5List.get(i).getSlaveBallNumber()); + } + + // 处理第12个位置:检查是否有相同的线系数 + Double targetCoefficient = t5List.get(11).getLineCoefficient(); + List candidatesFor12th = new ArrayList<>(); + + // 找出所有线系数等于第12个位置线系数的记录 + for (int i = 11; i < t5List.size(); i++) { + if (t5List.get(i).getLineCoefficient().equals(targetCoefficient)) { + candidatesFor12th.add(t5List.get(i)); + } else { + break; // 线系数不同,停止查找 + } + } + + if (candidatesFor12th.size() == 1) { + // 只有一个候选,直接添加 + result.add(candidatesFor12th.get(0).getSlaveBallNumber()); + } else { + // 有多个候选,通过blue_history_top_100表的点系数排序 + log.debug("第12位有{}个相同线系数的候选:{}", candidatesFor12th.size(), + candidatesFor12th.stream().map(T5::getSlaveBallNumber).collect(Collectors.toList())); + + Integer bestBall = selectBestBallFromBlueHistoryTop100( + candidatesFor12th.stream().map(T5::getSlaveBallNumber).collect(Collectors.toList()) + ); + result.add(bestBall); + } + + log.debug("T5表主球{}最终选择的{}个从球:{}", masterBallNumber, result.size(), result); + return result; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/BlueHistory100Service.java b/src/main/java/com/xy/xyaicpzs/service/BlueHistory100Service.java new file mode 100644 index 0000000..278eaa4 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/BlueHistory100Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.BlueHistory100; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【blue_history_100(蓝球最近100期数据表)】的数据库操作Service +* @createDate 2025-06-14 10:40:04 +*/ +public interface BlueHistory100Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/BlueHistoryAllService.java b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryAllService.java new file mode 100644 index 0000000..39ba6a7 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryAllService.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryAll; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【blue_history_all(蓝球全部历史数据表)】的数据库操作Service +* @createDate 2025-06-14 10:40:07 +*/ +public interface BlueHistoryAllService extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTop100Service.java b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTop100Service.java new file mode 100644 index 0000000..0b273b9 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTop100Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop100; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【blue_history_top_100(创建蓝球100期数据排行表)】的数据库操作Service +* @createDate 2025-06-14 10:40:13 +*/ +public interface BlueHistoryTop100Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTopService.java b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTopService.java new file mode 100644 index 0000000..e62d0ce --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/BlueHistoryTopService.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【blue_history_top(蓝球历史数据排行表)】的数据库操作Service +* @createDate 2025-06-14 10:40:10 +*/ +public interface BlueHistoryTopService extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/ChatMessageService.java b/src/main/java/com/xy/xyaicpzs/service/ChatMessageService.java new file mode 100644 index 0000000..7a5aaff --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/ChatMessageService.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.ChatMessage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【chat_message(聊天消息表)】的数据库操作Service +* @createDate 2025-07-07 17:37:15 +*/ +public interface ChatMessageService extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/CozeAuthService.java b/src/main/java/com/xy/xyaicpzs/service/CozeAuthService.java new file mode 100644 index 0000000..43e888f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/CozeAuthService.java @@ -0,0 +1,84 @@ +package com.xy.xyaicpzs.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +/** + * Coze认证服务 + * 提供通过JWT获取访问令牌的功能 + */ +@Service +public class CozeAuthService { + + private static final Logger logger = LoggerFactory.getLogger(CozeAuthService.class); + private static final String COZE_TOKEN_URL = "https://api.coze.cn/api/permission/oauth2/token"; + private static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private ObjectMapper objectMapper; + + /** + * 通过JWT获取访问令牌 + * + * @param jwt JWT令牌 + * @param durationSeconds 令牌有效期(秒) + * @return 包含访问令牌和过期时间的Map + */ + public Map getAccessToken(String jwt, Integer durationSeconds) { + try { + // 设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("Authorization", "Bearer " + jwt); + + // 设置请求体 + Map requestBody = new HashMap<>(); + requestBody.put("grant_type", GRANT_TYPE); + if (durationSeconds != null && durationSeconds > 0) { + requestBody.put("duration_seconds", durationSeconds); + } + + // 创建请求实体 + HttpEntity> requestEntity = new HttpEntity<>(requestBody, headers); + + // 发送请求 + ResponseEntity response = restTemplate.postForEntity(COZE_TOKEN_URL, requestEntity, String.class); + + // 解析响应 + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + JsonNode jsonNode = objectMapper.readTree(response.getBody()); + + Map result = new HashMap<>(); + result.put("access_token", jsonNode.get("access_token").asText()); + result.put("expires_in", jsonNode.get("expires_in").asLong()); + + return result; + } else { + throw new RuntimeException("获取访问令牌失败,HTTP状态码:" + response.getStatusCodeValue()); + } + + } catch (JsonProcessingException e) { + logger.error("解析响应JSON失败", e); + throw new RuntimeException("解析响应JSON失败: " + e.getMessage()); + } catch (Exception e) { + logger.error("获取访问令牌失败", e); + throw new RuntimeException("获取访问令牌失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/DataAnalysisService.java b/src/main/java/com/xy/xyaicpzs/service/DataAnalysisService.java new file mode 100644 index 0000000..5dcf545 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/DataAnalysisService.java @@ -0,0 +1,38 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.common.requset.PredictRecordQueryRequest; +import com.xy.xyaicpzs.common.response.PageResponse; +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.xy.xyaicpzs.domain.vo.UserPredictStatVO; + +/** + * 数据分析服务接口 + */ +public interface DataAnalysisService { + + /** + * 获取用户预测统计数据 + * @param userId 用户ID + * @return 用户预测统计数据 + */ + UserPredictStatVO getUserPredictStat(Long userId); + + /** + * 处理待开奖记录,匹配开奖结果 + * @return 处理的记录数量 + */ + int processPendingPredictions(); + + /** + * 按条件查询预测记录 + * @param request 查询条件 + * @return 分页预测记录 + */ + PageResponse queryPredictRecords(PredictRecordQueryRequest request); + + /** + * 获取预测记录总数 + * @return 预测记录总数 + */ + long getTotalPredictCount(); +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/ExcelImportService.java b/src/main/java/com/xy/xyaicpzs/service/ExcelImportService.java new file mode 100644 index 0000000..b5fd6a0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/ExcelImportService.java @@ -0,0 +1,249 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.util.ExcelDataImporter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; + +/** + * Excel导入服务类 + */ +@Slf4j +@Service +public class ExcelImportService { + + @Autowired + private ExcelDataImporter excelDataImporter; + + /** + * 导入Excel文件数据 + * @param file 上传的Excel文件 + * @return 导入结果消息 + */ + public String importExcelFile(MultipartFile file) { + if (file.isEmpty()) { + return "文件为空,请选择有效的Excel文件"; + } + + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".xlsx")) { + return "请上传.xlsx格式的Excel文件"; + } + + try { + // 创建临时文件 + File tempFile = File.createTempFile("import_", ".xlsx"); + file.transferTo(tempFile); + + // 执行数据导入 + excelDataImporter.importExcelData(tempFile.getAbsolutePath()); + + // 删除临时文件 + tempFile.delete(); + + return "数据导入成功"; + + } catch (IOException e) { + log.error("文件处理失败:{}", e.getMessage(), e); + return "文件处理失败:" + e.getMessage(); + } catch (Exception e) { + log.error("数据导入失败:{}", e.getMessage(), e); + return "数据导入失败:" + e.getMessage(); + } + } + + /** + * 导入指定路径的Excel文件 + * @param filePath 文件路径 + * @return 导入结果消息 + */ + public String importExcelFileByPath(String filePath) { + try { + File file = new File(filePath); + if (!file.exists()) { + return "文件不存在:" + filePath; + } + + if (!filePath.toLowerCase().endsWith(".xlsx")) { + return "请提供.xlsx格式的Excel文件路径"; + } + + // 执行数据导入 + excelDataImporter.importExcelData(filePath); + + return "数据导入成功"; + + } catch (Exception e) { + log.error("数据导入失败:{}", e.getMessage(), e); + return "数据导入失败:" + e.getMessage(); + } + } + + /** + * 获取Excel导入信息说明 + * @return 导入信息说明 + */ + public String getImportInfo() { + StringBuilder info = new StringBuilder(); + info.append("=== Excel数据导入说明 ===\n"); + info.append("支持的工作表:\n"); + info.append("1. T1工作表 - 红球数据(4个表:history_all, history_100, history_top, history_top_100)\n"); + info.append("2. T2工作表 - 蓝球数据(4个表:blue_history_all, blue_history_100, blue_history_top, blue_history_top_100)\n"); + info.append("3. T3工作表 - 红球线系数数据(1个表:t3,33×33=1089条记录)\n"); + info.append("4. T4工作表 - 蓝球组红球线系数数据(1个表:t4,16×33=528条记录)\n"); + info.append("5. T5工作表 - 蓝球组蓝球线系数数据(1个表:t5,16×16=256条记录)\n"); + info.append("6. T6工作表 - 红球组蓝球线系数数据(1个表:t6,33×16=528条记录)\n"); + info.append("7. T7工作表 - 红球组红球面系数数据(1个表:t7,33×33=1089条记录)\n"); + info.append("8. T8工作表 - 红球组蓝球面系数数据(1个表:t8,33×16=528条记录)\n"); + info.append("9. T10工作表 - 彩票开奖信息数据(1个表:lottery_draws,历史开奖记录)\n"); + info.append("10. T11工作表 - 蓝球组红球面系数数据(1个表:t11,16×33=528条记录)\n"); + info.append("\n数据结构:\n"); + info.append("- T1/T2:标准表格结构,按列映射到对应字段\n"); + info.append("- T3:每三列为一组,红球1-33号,线系数在C、F、I、L...列\n"); + info.append("- T4:每三列为一组,蓝球1-16号,红球1-33号,线系数在C、F、I、L...列\n"); + info.append("- T5:每三列为一组,蓝球1-16号,蓝球1-16号,线系数在C、F、I、L...列\n"); + info.append("- T6:每三列为一组,红球1-33号,蓝球1-16号,线系数在C、F、I、L...列\n"); + info.append("- T7:每三列为一组,红球1-33号,红球1-33号,面系数在C、F、I、L...列\n"); + info.append("- T8:每三列为一组,红球1-33号,蓝球1-16号,面系数在C、F、I、L...列\n"); + info.append("- T10:标准表格结构,A列开奖期号,B列开奖日期,C-H列红球1-6,I列蓝球\n"); + info.append("- T11:每三列为一组,蓝球1-16号,红球1-33号,面系数在C、F、I、L...列\n"); + info.append("\n导入特性:\n"); + info.append("- 自动清空现有数据\n"); + info.append("- 数值自动保留两位小数\n"); + info.append("- 完善的错误处理和日志记录\n"); + info.append("- 支持.xlsx和.xls格式\n"); + return info.toString(); + } + + /** + * 导入指定路径的开奖数据Excel文件 + * @param filePath 文件路径 + * @return 导入结果消息 + */ + public String importLotteryDrawsByPath(String filePath) { + try { + File file = new File(filePath); + if (!file.exists()) { + return "文件不存在:" + filePath; + } + + if (!filePath.toLowerCase().endsWith(".xlsx")) { + return "请提供.xlsx格式的Excel文件路径"; + } + + // 执行开奖数据导入 + excelDataImporter.importLotteryDrawsData(filePath); + + return "开奖数据导入成功"; + + } catch (Exception e) { + log.error("开奖数据导入失败:{}", e.getMessage(), e); + return "开奖数据导入失败:" + e.getMessage(); + } + } + + /** + * 导入上传的开奖数据Excel文件 + * @param file 上传的Excel文件 + * @return 导入结果消息 + */ + public String importLotteryDrawsFile(MultipartFile file) { + if (file.isEmpty()) { + return "文件为空,请选择有效的Excel文件"; + } + + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".xlsx")) { + return "请上传.xlsx格式的Excel文件"; + } + + try { + // 创建临时文件 + File tempFile = File.createTempFile("lottery_import_", ".xlsx"); + file.transferTo(tempFile); + + // 执行开奖数据导入 + excelDataImporter.importLotteryDrawsData(tempFile.getAbsolutePath()); + + // 删除临时文件 + tempFile.delete(); + + return "开奖数据导入成功"; + + } catch (IOException e) { + log.error("文件处理失败:{}", e.getMessage(), e); + return "文件处理失败:" + e.getMessage(); + } catch (Exception e) { + log.error("开奖数据导入失败:{}", e.getMessage(), e); + return "开奖数据导入失败:" + e.getMessage(); + } + } + + /** + * 追加导入指定路径的开奖数据Excel文件(不清空现有数据) + * @param filePath 文件路径 + * @return 导入结果消息 + */ + public String appendLotteryDrawsByPath(String filePath) { + try { + File file = new File(filePath); + if (!file.exists()) { + return "文件不存在:" + filePath; + } + + if (!filePath.toLowerCase().endsWith(".xlsx")) { + return "请提供.xlsx格式的Excel文件路径"; + } + + // 执行开奖数据追加导入 + excelDataImporter.appendLotteryDrawsData(filePath); + + return "开奖数据追加导入成功"; + + } catch (Exception e) { + log.error("开奖数据追加导入失败:{}", e.getMessage(), e); + return "开奖数据追加导入失败:" + e.getMessage(); + } + } + + /** + * 追加导入上传的开奖数据Excel文件(不清空现有数据) + * @param file 上传的Excel文件 + * @return 导入结果消息 + */ + public String appendLotteryDrawsFile(MultipartFile file) { + if (file.isEmpty()) { + return "文件为空,请选择有效的Excel文件"; + } + + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".xlsx")) { + return "请上传.xlsx格式的Excel文件"; + } + + try { + // 创建临时文件 + File tempFile = File.createTempFile("lottery_append_", ".xlsx"); + file.transferTo(tempFile); + + // 执行开奖数据追加导入 + excelDataImporter.appendLotteryDrawsData(tempFile.getAbsolutePath()); + + // 删除临时文件 + tempFile.delete(); + + return "开奖数据追加导入成功"; + + } catch (IOException e) { + log.error("文件处理失败:{}", e.getMessage(), e); + return "文件处理失败:" + e.getMessage(); + } catch (Exception e) { + log.error("开奖数据追加导入失败:{}", e.getMessage(), e); + return "开奖数据追加导入失败:" + e.getMessage(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/History100Service.java b/src/main/java/com/xy/xyaicpzs/service/History100Service.java new file mode 100644 index 0000000..481cabc --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/History100Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.History100; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【history_100(最近100期数据表)】的数据库操作Service +* @createDate 2025-06-14 09:48:05 +*/ +public interface History100Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/HistoryAllService.java b/src/main/java/com/xy/xyaicpzs/service/HistoryAllService.java new file mode 100644 index 0000000..0dafcef --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/HistoryAllService.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.HistoryAll; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【history_all(历史数据表)】的数据库操作Service +* @createDate 2025-06-14 09:48:10 +*/ +public interface HistoryAllService extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/HistoryTop100Service.java b/src/main/java/com/xy/xyaicpzs/service/HistoryTop100Service.java new file mode 100644 index 0000000..d5bb701 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/HistoryTop100Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.HistoryTop100; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【history_top_100(创建100期数据排行表)】的数据库操作Service +* @createDate 2025-06-14 09:48:16 +*/ +public interface HistoryTop100Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/HistoryTopService.java b/src/main/java/com/xy/xyaicpzs/service/HistoryTopService.java new file mode 100644 index 0000000..b2fc82c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/HistoryTopService.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.HistoryTop; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【history_top(历史数据排行表)】的数据库操作Service +* @createDate 2025-06-14 09:48:13 +*/ +public interface HistoryTopService extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/LotteryDrawsService.java b/src/main/java/com/xy/xyaicpzs/service/LotteryDrawsService.java new file mode 100644 index 0000000..512a9ad --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/LotteryDrawsService.java @@ -0,0 +1,47 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.LotteryDraws; + +import java.util.Date; +import java.util.List; + +/** +* @author XY003 +* @description 针对表【lottery_draws(彩票开奖信息表)】的数据库操作Service +* @createDate 2025-06-14 16:41:29 +*/ +public interface LotteryDrawsService extends IService { + + /** + * 获取近期开奖信息 + * @param limit 获取条数,默认15条 + * @return 开奖信息列表,按开奖期号倒序排列 + */ + List getRecentDraws(Integer limit); + + /** + * 根据期号精准查询开奖信息 + * @param drawId 开奖期号 + * @return 开奖信息 + */ + LotteryDraws getByDrawId(Long drawId); + + /** + * 根据日期范围查询开奖信息 + * @param startDate 开始日期 + * @param endDate 结束日期 + * @return 开奖信息列表,按开奖期号倒序排列 + */ + List getByDateRange(Date startDate, Date endDate); + + /** + * 综合查询开奖信息 + * @param drawId 开奖期号(可选) + * @param startDate 开始日期(可选) + * @param endDate 结束日期(可选) + * @return 开奖信息列表 + */ + List queryDraws(Long drawId, Date startDate, Date endDate); + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/OperationHistoryService.java b/src/main/java/com/xy/xyaicpzs/service/OperationHistoryService.java new file mode 100644 index 0000000..4ccbec0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/OperationHistoryService.java @@ -0,0 +1,41 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.OperationHistory; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** +* @author XY003 +* @description 针对表【operation_history(操作历史记录表)】的数据库操作Service +* @createDate 2025-06-19 14:51:51 +*/ +public interface OperationHistoryService extends IService { + + /** + * 记录操作历史 + * @param userId 操作用户ID + * @param operationType 操作类型 + * @param operationModule 操作模块(0-会员码管理/1-Excel导入管理等) + * @param operationResult 操作结果(成功/失败) + * @param resultMessage 结果消息 + */ + void recordOperation(Long userId, String operationType, Integer operationModule, + String operationResult, String resultMessage); + + /** + * 根据用户ID和操作模块获取操作历史列表 + * @param userId 用户ID + * @param operationModule 操作模块(0-会员码管理/1-Excel导入管理等) + * @return 操作历史列表,按操作时间倒序排列 + */ + List getOperationHistoryByUserIdAndModule(Long userId, Integer operationModule); + + /** + * 根据操作模块获取操作历史列表 + * @param operationModule 操作模块(0-会员码管理/1-Excel导入管理等) + * @return 操作历史列表,按操作时间倒序排列 + */ + List getOperationHistoryByModule(Integer operationModule); + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/PredictRecordService.java b/src/main/java/com/xy/xyaicpzs/service/PredictRecordService.java new file mode 100644 index 0000000..0a356a1 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/PredictRecordService.java @@ -0,0 +1,50 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.Date; +import java.util.List; + +/** +* @author XY003 +* @description 针对表【predict_record(彩票开奖信息表)】的数据库操作Service +* @createDate 2025-06-16 13:17:53 +*/ +public interface PredictRecordService extends IService { + + /** + * 创建预测记录 + * @param userId 用户ID + * @param drawId 开奖期号 + * @param drawDate 开奖日期 + * @param redBalls 6个红球号码 + * @param blueBall 蓝球号码 + * @return 创建的预测记录 + */ + PredictRecord createPredictRecord(Long userId, Long drawId, Date drawDate, List redBalls, Integer blueBall); + + /** + * 根据用户ID获取所有预测记录 + * @param userId 用户ID + * @return 用户的所有预测记录列表,按预测时间倒序排列 + */ + List getPredictRecordsByUserId(Long userId); + + /** + * 根据用户ID分页获取预测记录 + * @param userId 用户ID + * @param page 页码,从1开始 + * @param size 每页大小 + * @return 用户的预测记录列表,按预测时间倒序排列 + */ + List getPredictRecordsByUserIdWithPaging(Long userId, Integer page, Integer size); + + /** + * 根据用户ID获取预测记录总数 + * @param userId 用户ID + * @return 用户的预测记录总数 + */ + Long getPredictRecordsCountByUserId(Long userId); + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/SmsService.java b/src/main/java/com/xy/xyaicpzs/service/SmsService.java new file mode 100644 index 0000000..5c49320 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/SmsService.java @@ -0,0 +1,25 @@ +package com.xy.xyaicpzs.service; + +/** + * 短信服务接口 + */ +public interface SmsService { + + /** + * 发送短信验证码 + * + * @param phoneNumber 手机号码 + * @return 发送是否成功 + * @throws Exception 发送异常 + */ + boolean sendVerificationCode(String phoneNumber) throws Exception; + + /** + * 验证短信验证码 + * + * @param phoneNumber 手机号码 + * @param code 验证码 + * @return 验证是否通过 + */ + boolean verifyCode(String phoneNumber, String code); +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/T11Service.java b/src/main/java/com/xy/xyaicpzs/service/T11Service.java new file mode 100644 index 0000000..7619054 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T11Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.T11; + +/** +* @author XY003 +* @description 针对表【t11(t11表(蓝球组红球的面系数))】的数据库操作Service +* @createDate 2025-06-14 16:25:23 +*/ +public interface T11Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T3Service.java b/src/main/java/com/xy/xyaicpzs/service/T3Service.java new file mode 100644 index 0000000..5d24cdd --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T3Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.T3; + +/** +* @author XY003 +* @description 针对表【t3(t3表(红球组红球的线系数))】的数据库操作Service +* @createDate 2025-06-14 11:02:50 +*/ +public interface T3Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T4Service.java b/src/main/java/com/xy/xyaicpzs/service/T4Service.java new file mode 100644 index 0000000..ddd0019 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T4Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.T4; + +/** +* @author XY003 +* @description 针对表【t4(t4表(蓝球组红球的线系数))】的数据库操作Service +* @createDate 2025-06-14 11:45:31 +*/ +public interface T4Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T5Service.java b/src/main/java/com/xy/xyaicpzs/service/T5Service.java new file mode 100644 index 0000000..37a5078 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T5Service.java @@ -0,0 +1,14 @@ +package com.xy.xyaicpzs.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.T5; + +/** +* @author XY003 +* @description 针对表【t5(t5表(蓝球组蓝球的线系数))】的数据库操作Service +* @createDate 2025-06-14 12:01:16 +*/ +public interface T5Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T6Service.java b/src/main/java/com/xy/xyaicpzs/service/T6Service.java new file mode 100644 index 0000000..8c4eef5 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T6Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.T6; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【t6(t6表(红球组蓝球的线系数))】的数据库操作Service +* @createDate 2025-06-14 13:19:12 +*/ +public interface T6Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T7Service.java b/src/main/java/com/xy/xyaicpzs/service/T7Service.java new file mode 100644 index 0000000..5f72460 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T7Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.T7; + +/** +* @author XY003 +* @description 针对表【t7(t7表(红球组红球的面系数))】的数据库操作Service +* @createDate 2025-06-14 13:30:50 +*/ +public interface T7Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/T8Service.java b/src/main/java/com/xy/xyaicpzs/service/T8Service.java new file mode 100644 index 0000000..4138022 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/T8Service.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.T8; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author XY003 +* @description 针对表【t8(t8表(红球组蓝球的面系数))】的数据库操作Service +* @createDate 2025-06-14 16:11:27 +*/ +public interface T8Service extends IService { + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/UserService.java b/src/main/java/com/xy/xyaicpzs/service/UserService.java new file mode 100644 index 0000000..798828e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/UserService.java @@ -0,0 +1,99 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.dto.user.UserPhoneLoginRequest; +import com.xy.xyaicpzs.domain.dto.user.UserPhoneRegisterRequest; +import com.xy.xyaicpzs.domain.entity.User; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * 用户服务 +*/ +public interface UserService extends IService { + + /** + * 用户注册 + * + * @param userAccount 用户账户 + * @param userPassword 用户密码 + * @param checkPassword 校验密码 + * @return 新用户 id + */ + long userRegister(String userAccount, String userName, String userPassword, String checkPassword); + + /** + * 用户登录 + * + * @param userAccount 用户账户 + * @param userPassword 用户密码 + * @param request + * @return 脱敏后的用户信息 + */ + User userLogin(String userAccount, String userPassword, HttpServletRequest request); + + /** + * 获取当前登录用户 + * + * @param request + * @return + */ + User getLoginUser(HttpServletRequest request); + + /** + * 用户注销 + * + * @param request + * @return + */ + boolean userLogout(HttpServletRequest request); + + /** + * 获取脱敏的用户信息 + * + * @param originUser + * @return + */ + User getSafetyUser(User originUser); + + /** + * 是否为管理员 + * + * @param request + * @return + */ + boolean isAdmin(HttpServletRequest request); + + /** + * 是否为管理员 + * + * @param user + * @return + */ + boolean isAdmin(User user); + + /** + * 手机号注册 + * + * @param userPhoneRegisterRequest 手机号注册请求 + * @return 新用户 id + */ + long userPhoneRegister(UserPhoneRegisterRequest userPhoneRegisterRequest); + + /** + * 手机号登录 + * + * @param userPhoneLoginRequest 手机号登录请求 + * @param request HTTP请求 + * @return 脱敏后的用户信息 + */ + User userPhoneLogin(UserPhoneLoginRequest userPhoneLoginRequest, HttpServletRequest request); + + /** + * 加密用户密码 + * + * @param password 原始密码 + * @return 加密后的密码 + */ + String encryptPassword(String password); +} diff --git a/src/main/java/com/xy/xyaicpzs/service/VipCodeService.java b/src/main/java/com/xy/xyaicpzs/service/VipCodeService.java new file mode 100644 index 0000000..e4ed167 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/VipCodeService.java @@ -0,0 +1,40 @@ +package com.xy.xyaicpzs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.xy.xyaicpzs.domain.entity.VipCode; + +/** +* @author XY003 +* @description 针对表【vip_code(会员码表)】的数据库操作Service +* @createDate 2025-01-15 16:41:29 +*/ +public interface VipCodeService extends IService { + + /** + * 激活会员码 + * @param userId 用户ID + * @param code 会员码 + * @return 是否激活成功 + */ + boolean activateVipCode(Long userId, String code); + + /** + * 批量生成会员码 + * @param numCodes 生成数量 + * @param vipExpireTime 会员有效月数 + * @param createdUserId 创建人ID + * @param createdUserName 创建人名称 + * @return 生成成功的数量 + */ + int generateVipCodes(int numCodes, int vipExpireTime, Long createdUserId, String createdUserName); + + /** + * 获取一个可用的会员码 + * @param vipExpireTime 会员有效月数(1或12) + * @param createdUserId 创建人ID + * @param createdUserName 创建人名称 + * @return 可用的会员码,如果没有则返回null + */ + String getAvailableVipCode(int vipExpireTime, Long createdUserId, String createdUserName); + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/VipExchangeRecordService.java b/src/main/java/com/xy/xyaicpzs/service/VipExchangeRecordService.java new file mode 100644 index 0000000..20a8e3c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/VipExchangeRecordService.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.service; + +import com.xy.xyaicpzs.domain.entity.VipExchangeRecord; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** +* @author XY003 +* @description 针对表【vip_exchange_record(会员兑换表)】的数据库操作Service +* @createDate 2025-06-19 11:27:10 +*/ +public interface VipExchangeRecordService extends IService { + + /** + * 根据用户ID获取所有兑换记录 + * @param userId 用户ID + * @return 用户的所有兑换记录列表,按兑换时间倒序排列 + */ + List getExchangeRecordsByUserId(Long userId); + +} diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistory100ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistory100ServiceImpl.java new file mode 100644 index 0000000..84e35f8 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistory100ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.BlueHistory100; +import com.xy.xyaicpzs.mapper.BlueHistory100Mapper; +import com.xy.xyaicpzs.service.BlueHistory100Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【blue_history_100(蓝球最近100期历史数据表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class BlueHistory100ServiceImpl extends ServiceImpl + implements BlueHistory100Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryAllServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryAllServiceImpl.java new file mode 100644 index 0000000..5292b3a --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryAllServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.BlueHistoryAll; +import com.xy.xyaicpzs.mapper.BlueHistoryAllMapper; +import com.xy.xyaicpzs.service.BlueHistoryAllService; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【blue_history_all(蓝球历史数据表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class BlueHistoryAllServiceImpl extends ServiceImpl + implements BlueHistoryAllService{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTop100ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTop100ServiceImpl.java new file mode 100644 index 0000000..6d29967 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTop100ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop100; +import com.xy.xyaicpzs.mapper.BlueHistoryTop100Mapper; +import com.xy.xyaicpzs.service.BlueHistoryTop100Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【blue_history_top_100(蓝球100期数据排行表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class BlueHistoryTop100ServiceImpl extends ServiceImpl + implements BlueHistoryTop100Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTopServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTopServiceImpl.java new file mode 100644 index 0000000..5a8529f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/BlueHistoryTopServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop; +import com.xy.xyaicpzs.mapper.BlueHistoryTopMapper; +import com.xy.xyaicpzs.service.BlueHistoryTopService; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【blue_history_top(蓝球历史数据排行表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class BlueHistoryTopServiceImpl extends ServiceImpl + implements BlueHistoryTopService{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/ChatMessageServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/ChatMessageServiceImpl.java new file mode 100644 index 0000000..62b901e --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/ChatMessageServiceImpl.java @@ -0,0 +1,22 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.ChatMessage; +import com.xy.xyaicpzs.service.ChatMessageService; +import com.xy.xyaicpzs.mapper.ChatMessageMapper; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【chat_message(聊天消息表)】的数据库操作Service实现 +* @createDate 2025-07-07 17:37:15 +*/ +@Service +public class ChatMessageServiceImpl extends ServiceImpl + implements ChatMessageService{ + +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/DataAnalysisServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/DataAnalysisServiceImpl.java new file mode 100644 index 0000000..4ce210a --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/DataAnalysisServiceImpl.java @@ -0,0 +1,217 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.xy.xyaicpzs.common.requset.PredictRecordQueryRequest; +import com.xy.xyaicpzs.common.response.PageResponse; +import com.xy.xyaicpzs.domain.entity.LotteryDraws; +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.xy.xyaicpzs.domain.vo.UserPredictStatVO; +import com.xy.xyaicpzs.mapper.LotteryDrawsMapper; +import com.xy.xyaicpzs.mapper.PredictRecordMapper; +import com.xy.xyaicpzs.service.DataAnalysisService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +/** + * 数据分析服务实现类 + */ +@Service +public class DataAnalysisServiceImpl implements DataAnalysisService { + + @Autowired + private PredictRecordMapper predictRecordMapper; + + @Autowired + private LotteryDrawsMapper lotteryDrawsMapper; + + @Override + public UserPredictStatVO getUserPredictStat(Long userId) { + UserPredictStatVO statVO = new UserPredictStatVO(); + + // 查询用户的所有预测记录 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId); + List predictRecords = predictRecordMapper.selectList(queryWrapper); + + if (predictRecords == null || predictRecords.isEmpty()) { + statVO.setUserId(userId); + statVO.setPredictCount(0L); + statVO.setHitCount(0L); + statVO.setPendingCount(0L); + statVO.setDrawnCount(0L); + statVO.setHitRate(java.math.BigDecimal.ZERO); + return statVO; + } + + // 统计数据 + long totalPredicts = predictRecords.size(); + long hitCount = 0L; + long pendingCount = 0L; + long drawnCount = 0L; + + for (PredictRecord record : predictRecords) { + if ("待开奖".equals(record.getPredictStatus())) { + pendingCount++; + } else if ("已中奖".equals(record.getPredictStatus())) { + hitCount++; + drawnCount++; + } else if ("未中奖".equals(record.getPredictStatus())) { + drawnCount++; + } + } + + // 计算命中率 + java.math.BigDecimal hitRate = drawnCount > 0 ? + java.math.BigDecimal.valueOf(hitCount).divide(java.math.BigDecimal.valueOf(drawnCount), 4, java.math.RoundingMode.HALF_UP) : + java.math.BigDecimal.ZERO; + + statVO.setUserId(userId); + statVO.setPredictCount(totalPredicts); + statVO.setHitCount(hitCount); + statVO.setPendingCount(pendingCount); + statVO.setDrawnCount(drawnCount); + statVO.setHitRate(hitRate); + + return statVO; + } + + @Override + public int processPendingPredictions() { + // 查询所有待开奖的预测记录 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("predictStatus", "待开奖"); + List pendingRecords = predictRecordMapper.selectList(queryWrapper); + + int processedCount = 0; + + for (PredictRecord record : pendingRecords) { + // 查询对应期号的开奖结果 + LotteryDraws draws = lotteryDrawsMapper.selectById(record.getDrawId()); + if (draws != null) { + // 比较预测号码与开奖号码,计算中奖结果 + String result = calculatePredictResult(record, draws); + long bonus = calculateBonus(result); + if(result.equals("未中奖")){ + record.setPredictStatus("未中奖"); + }else{ + record.setPredictStatus("已中奖"); + } + + // 更新预测记录 + + record.setPredictResult(result); + record.setBonus(bonus); + predictRecordMapper.updateById(record); + + processedCount++; + } + } + + return processedCount; + } + + @Override + public PageResponse queryPredictRecords(PredictRecordQueryRequest request) { + // 构建查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 添加用户ID筛选条件 + if (request.getUserId() != null) { + queryWrapper.eq("userId", request.getUserId()); + } + + // 添加预测状态筛选条件 + if (StringUtils.hasText(request.getPredictStatus())) { + queryWrapper.eq("predictStatus", request.getPredictStatus()); + } + + // 按预测时间降序排序 + queryWrapper.orderByDesc("predictTime"); + + // 执行分页查询 + Page page = new Page<>(request.getCurrent(), request.getPageSize()); + Page resultPage = predictRecordMapper.selectPage(page, queryWrapper); + + // 构建分页响应对象 + return PageResponse.of( + resultPage.getRecords(), + resultPage.getTotal(), + (int) resultPage.getCurrent(), + (int) resultPage.getSize() + ); + } + + @Override + public long getTotalPredictCount() { + // 获取全部预测记录数量 + return predictRecordMapper.selectCount(null); + } + + /** + * 计算预测结果 + */ + private String calculatePredictResult(PredictRecord record, LotteryDraws draws) { + // 比较红球 + int redMatches = 0; + Integer[] predictReds = {record.getRedBall1(), record.getRedBall2(), record.getRedBall3(), + record.getRedBall4(), record.getRedBall5(), record.getRedBall6()}; + Integer[] drawReds = {draws.getRedBall1(), draws.getRedBall2(), draws.getRedBall3(), + draws.getRedBall4(), draws.getRedBall5(), draws.getRedBall6()}; + + for (Integer predictRed : predictReds) { + for (Integer drawRed : drawReds) { + if (predictRed != null && predictRed.equals(drawRed)) { + redMatches++; + break; + } + } + } + + // 比较蓝球 + boolean blueMatch = record.getBlueBall() != null && + record.getBlueBall().equals(draws.getBlueBall()); + + // 根据中奖规则判断奖项 + if (redMatches == 6 && blueMatch) { + return "一等奖"; + } else if (redMatches == 6) { + return "二等奖"; + } else if (redMatches == 5 && blueMatch) { + return "三等奖"; + } else if ((redMatches == 5) || (redMatches == 4 && blueMatch)) { + return "四等奖"; + } else if ((redMatches == 4) || (redMatches == 3 && blueMatch)) { + return "五等奖"; + } else if (blueMatch && (redMatches == 0 || redMatches == 1 || redMatches == 2)) { + return "六等奖"; + } else { + return "未中奖"; + } + } + + /** + * 计算奖金 + */ + private long calculateBonus(String result) { + switch (result) { + case "一等奖": + return 5000000L; // 500万 + case "二等奖": + return 1000000L; // 100万 + case "三等奖": + return 3000L; // 3000元 + case "四等奖": + return 200L; // 200元 + case "五等奖": + return 10L; // 10元 + case "六等奖": + return 5L; // 5元 + default: + return 0L; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/History100ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/History100ServiceImpl.java new file mode 100644 index 0000000..41f3860 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/History100ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.History100; +import com.xy.xyaicpzs.mapper.History100Mapper; +import com.xy.xyaicpzs.service.History100Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【history_100(最近100期历史数据表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class History100ServiceImpl extends ServiceImpl + implements History100Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/HistoryAllServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryAllServiceImpl.java new file mode 100644 index 0000000..e319f24 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryAllServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.HistoryAll; +import com.xy.xyaicpzs.mapper.HistoryAllMapper; +import com.xy.xyaicpzs.service.HistoryAllService; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【history_all(历史数据表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class HistoryAllServiceImpl extends ServiceImpl + implements HistoryAllService{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTop100ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTop100ServiceImpl.java new file mode 100644 index 0000000..6a219d6 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTop100ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.HistoryTop100; +import com.xy.xyaicpzs.mapper.HistoryTop100Mapper; +import com.xy.xyaicpzs.service.HistoryTop100Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【history_top_100(100期数据排行表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class HistoryTop100ServiceImpl extends ServiceImpl + implements HistoryTop100Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTopServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTopServiceImpl.java new file mode 100644 index 0000000..48594f3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/HistoryTopServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.HistoryTop; +import com.xy.xyaicpzs.mapper.HistoryTopMapper; +import com.xy.xyaicpzs.service.HistoryTopService; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【history_top(历史数据排行表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class HistoryTopServiceImpl extends ServiceImpl + implements HistoryTopService{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/LotteryDrawsServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/LotteryDrawsServiceImpl.java new file mode 100644 index 0000000..c460dfb --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/LotteryDrawsServiceImpl.java @@ -0,0 +1,65 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.LotteryDraws; +import com.xy.xyaicpzs.mapper.LotteryDrawsMapper; +import com.xy.xyaicpzs.service.LotteryDrawsService; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** +* @author XY003 +* @description 针对表【lottery_draws(开奖结果表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class LotteryDrawsServiceImpl extends ServiceImpl + implements LotteryDrawsService{ + + @Override + public List getRecentDraws(Integer limit) { + if (limit == null || limit <= 0) { + limit = 15; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("drawId").last("LIMIT " + limit); + return list(queryWrapper); + } + + @Override + public LotteryDraws getByDrawId(Long drawId) { + return getById(drawId); + } + + @Override + public List getByDateRange(Date startDate, Date endDate) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (startDate != null) { + queryWrapper.ge("drawDate", startDate); + } + if (endDate != null) { + queryWrapper.le("drawDate", endDate); + } + queryWrapper.orderByDesc("drawId"); + return list(queryWrapper); + } + + @Override + public List queryDraws(Long drawId, Date startDate, Date endDate) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (drawId != null) { + queryWrapper.eq("drawId", drawId); + } + if (startDate != null) { + queryWrapper.ge("drawDate", startDate); + } + if (endDate != null) { + queryWrapper.le("drawDate", endDate); + } + queryWrapper.orderByDesc("drawId"); + return list(queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/OperationHistoryServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/OperationHistoryServiceImpl.java new file mode 100644 index 0000000..3353709 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/OperationHistoryServiceImpl.java @@ -0,0 +1,67 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.OperationHistory; +import com.xy.xyaicpzs.service.OperationHistoryService; +import com.xy.xyaicpzs.mapper.OperationHistoryMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** +* @author XY003 +* @description 针对表【operation_history(操作历史记录表)】的数据库操作Service实现 +* @createDate 2025-06-19 14:51:51 +*/ +@Service +@Slf4j +public class OperationHistoryServiceImpl extends ServiceImpl + implements OperationHistoryService{ + + @Override + public void recordOperation(Long userId, String operationType, Integer operationModule, + String operationResult, String resultMessage) { + try { + OperationHistory operationHistory = new OperationHistory(); + operationHistory.setUserId(userId); + operationHistory.setOperationType(operationType); + operationHistory.setOperationModule(operationModule); + operationHistory.setOperationResult(operationResult); + operationHistory.setResultMessage(resultMessage); + operationHistory.setOperationTime(new Date()); + operationHistory.setUpdateTime(new Date()); + + save(operationHistory); + + log.info("操作历史记录成功 - 用户ID: {}, 操作类型: {}, 操作模块: {}, 操作结果: {}", + userId, operationType, operationModule, operationResult); + } catch (Exception e) { + log.error("记录操作历史失败 - 用户ID: {}, 操作类型: {}, 错误信息: {}", + userId, operationType, e.getMessage(), e); + } + } + + @Override + public List getOperationHistoryByUserIdAndModule(Long userId, Integer operationModule) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId) + .eq("operationModule", operationModule) + .orderByDesc("operationTime"); + return list(queryWrapper); + } + + @Override + public List getOperationHistoryByModule(Integer operationModule) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("operationModule", operationModule) + .orderByDesc("operationTime"); + return list(queryWrapper); + } +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/PredictRecordServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/PredictRecordServiceImpl.java new file mode 100644 index 0000000..a684d83 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/PredictRecordServiceImpl.java @@ -0,0 +1,77 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.PredictRecord; +import com.xy.xyaicpzs.mapper.PredictRecordMapper; +import com.xy.xyaicpzs.service.PredictRecordService; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** +* @author XY003 +* @description 针对表【predict_record(彩票开奖信息表)】的数据库操作Service实现 +* @createDate 2025-06-16 13:17:53 +*/ +@Service +public class PredictRecordServiceImpl extends ServiceImpl + implements PredictRecordService{ + + @Override + public PredictRecord createPredictRecord(Long userId, Long drawId, Date drawDate, List redBalls, Integer blueBall) { + PredictRecord predictRecord = new PredictRecord(); + predictRecord.setUserId(userId); + predictRecord.setDrawId(drawId); + predictRecord.setDrawDate(drawDate); + predictRecord.setPredictTime(new Date()); + + // 设置红球号码 + if (redBalls != null && redBalls.size() >= 6) { + predictRecord.setRedBall1(redBalls.get(0)); + predictRecord.setRedBall2(redBalls.get(1)); + predictRecord.setRedBall3(redBalls.get(2)); + predictRecord.setRedBall4(redBalls.get(3)); + predictRecord.setRedBall5(redBalls.get(4)); + predictRecord.setRedBall6(redBalls.get(5)); + } + + // 设置蓝球号码 + if (blueBall != null) { + predictRecord.setBlueBall(blueBall); + } + + // 默认状态为待开奖 + predictRecord.setPredictStatus("待开奖"); + + save(predictRecord); + return predictRecord; + } + + @Override + public List getPredictRecordsByUserId(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId).orderByDesc("predictTime"); + return list(queryWrapper); + } + + @Override + public List getPredictRecordsByUserIdWithPaging(Long userId, Integer page, Integer size) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId).orderByDesc("predictTime"); + + // 计算偏移量 + int offset = (page - 1) * size; + queryWrapper.last("LIMIT " + offset + ", " + size); + + return list(queryWrapper); + } + + @Override + public Long getPredictRecordsCountByUserId(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId); + return count(queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/SmsServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/SmsServiceImpl.java new file mode 100644 index 0000000..5ba5f74 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/SmsServiceImpl.java @@ -0,0 +1,153 @@ +package com.xy.xyaicpzs.service.impl; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.tea.TeaException; +import com.aliyun.teautil.models.RuntimeOptions; +import com.xy.xyaicpzs.service.SmsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * 短信服务实现类 + */ +@Service +public class SmsServiceImpl implements SmsService { + + private static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class); + + @Value("${aliyun.sms.sign-name:西安精彩数据服务社}") + private String signName; + + @Value("${aliyun.sms.template-code:SMS_489840017}") + private String templateCode; + + @Value("${aliyun.sms.access-key-id}") + private String accessKeyId; + + @Value("${aliyun.sms.access-key-secret}") + private String accessKeySecret; + + @Autowired + private RedisTemplate redisTemplate; + + // 短信验证码Redis前缀 + private static final String SMS_CODE_PREFIX = "sms:code:"; + // 短信发送次数Redis前缀 + private static final String SMS_COUNT_PREFIX = "sms:count:"; + // 短信验证码有效期(分钟) + private static final long SMS_CODE_EXPIRE = 5; + // 每天最大发送次数 + private static final int MAX_SMS_COUNT_PER_DAY = 10; + + /** + * 创建阿里云短信客户端 + */ + private Client createSmsClient() throws Exception { + // 从配置文件中获取阿里云AccessKey配置 + com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); + config.accessKeyId = accessKeyId; + config.accessKeySecret = accessKeySecret; + config.endpoint = "dysmsapi.aliyuncs.com"; + return new Client(config); + } + + /** + * 生成6位随机数字验证码 + */ + private String generateVerificationCode() { + Random random = new Random(); + StringBuilder code = new StringBuilder(); + for (int i = 0; i < 6; i++) { + code.append(random.nextInt(10)); + } + return code.toString(); + } + + /** + * 获取当天结束时间的剩余秒数 + */ + private long getSecondsUntilEndOfDay() { + LocalDateTime now = LocalDateTime.now(); + LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59); + Duration duration = Duration.between(now, endOfDay); + return duration.getSeconds(); + } + + @Override + public boolean sendVerificationCode(String phoneNumber) throws Exception { + // 检查当天发送次数是否达到上限 + String countKey = SMS_COUNT_PREFIX + phoneNumber + ":" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + Integer count = (Integer) redisTemplate.opsForValue().get(countKey); + + if (count != null && count >= MAX_SMS_COUNT_PER_DAY) { + logger.warn("手机号{}今日短信发送次数已达上限: {}", phoneNumber, MAX_SMS_COUNT_PER_DAY); + return false; + } + + // 生成6位随机验证码 + String verificationCode = generateVerificationCode(); + + // 构建短信请求 + Client client = createSmsClient(); + SendSmsRequest sendSmsRequest = new SendSmsRequest() + .setSignName(signName) + .setTemplateCode(templateCode) + .setPhoneNumbers(phoneNumber) + .setTemplateParam("{\"code\":\"" + verificationCode + "\"}"); + + RuntimeOptions runtime = new RuntimeOptions(); + try { + // 发送短信 + client.sendSmsWithOptions(sendSmsRequest, runtime); + logger.info("短信验证码发送成功,手机号: {}", phoneNumber); + + // 将验证码保存到Redis,设置过期时间 + String codeKey = SMS_CODE_PREFIX + phoneNumber; + redisTemplate.opsForValue().set(codeKey, verificationCode, SMS_CODE_EXPIRE, TimeUnit.MINUTES); + + // 增加当天发送次数,并设置过期时间为当天结束 + if (count == null) { + count = 0; + } + redisTemplate.opsForValue().set(countKey, count + 1, getSecondsUntilEndOfDay(), TimeUnit.SECONDS); + + return true; + } catch (TeaException error) { + logger.error("短信发送失败, 手机号: {}, 错误信息: {}, 诊断信息: {}", + phoneNumber, error.getMessage(), error.getData().get("Recommend")); + return false; + } catch (Exception error) { + logger.error("短信发送异常, 手机号: {}", phoneNumber, error); + return false; + } + } + + @Override + public boolean verifyCode(String phoneNumber, String code) { + if (phoneNumber == null || code == null) { + return false; + } + + String codeKey = SMS_CODE_PREFIX + phoneNumber; + String savedCode = (String) redisTemplate.opsForValue().get(codeKey); + + if (savedCode != null && savedCode.equals(code)) { + // 验证成功后删除验证码 + redisTemplate.delete(codeKey); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T11ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T11ServiceImpl.java new file mode 100644 index 0000000..c6a7e5c --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T11ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T11; +import com.xy.xyaicpzs.mapper.T11Mapper; +import com.xy.xyaicpzs.service.T11Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t11(蓝球组蓝球面系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T11ServiceImpl extends ServiceImpl + implements T11Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T3ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T3ServiceImpl.java new file mode 100644 index 0000000..0e57ef0 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T3ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T3; +import com.xy.xyaicpzs.mapper.T3Mapper; +import com.xy.xyaicpzs.service.T3Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t3(红球线系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T3ServiceImpl extends ServiceImpl + implements T3Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T4ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T4ServiceImpl.java new file mode 100644 index 0000000..631e6e7 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T4ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T4; +import com.xy.xyaicpzs.mapper.T4Mapper; +import com.xy.xyaicpzs.service.T4Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t4(蓝球组红球线系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T4ServiceImpl extends ServiceImpl + implements T4Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T5ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T5ServiceImpl.java new file mode 100644 index 0000000..0910d26 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T5ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T5; +import com.xy.xyaicpzs.mapper.T5Mapper; +import com.xy.xyaicpzs.service.T5Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t5(蓝球组蓝球线系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T5ServiceImpl extends ServiceImpl + implements T5Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T6ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T6ServiceImpl.java new file mode 100644 index 0000000..d67fb30 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T6ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T6; +import com.xy.xyaicpzs.mapper.T6Mapper; +import com.xy.xyaicpzs.service.T6Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t6(红球组蓝球线系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T6ServiceImpl extends ServiceImpl + implements T6Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T7ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T7ServiceImpl.java new file mode 100644 index 0000000..57c4106 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T7ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T7; +import com.xy.xyaicpzs.mapper.T7Mapper; +import com.xy.xyaicpzs.service.T7Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t7(红球组红球面系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T7ServiceImpl extends ServiceImpl + implements T7Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/T8ServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/T8ServiceImpl.java new file mode 100644 index 0000000..0b55f98 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/T8ServiceImpl.java @@ -0,0 +1,18 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.T8; +import com.xy.xyaicpzs.mapper.T8Mapper; +import com.xy.xyaicpzs.service.T8Service; +import org.springframework.stereotype.Service; + +/** +* @author XY003 +* @description 针对表【t8(红球组蓝球面系数表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +public class T8ServiceImpl extends ServiceImpl + implements T8Service{ + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/UserServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..45f779f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/UserServiceImpl.java @@ -0,0 +1,332 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.common.ErrorCode; +import com.xy.xyaicpzs.constant.UserConstant; +import com.xy.xyaicpzs.domain.dto.user.UserPhoneLoginRequest; +import com.xy.xyaicpzs.domain.dto.user.UserPhoneRegisterRequest; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.exception.BusinessException; +import com.xy.xyaicpzs.mapper.UserMapper; +import com.xy.xyaicpzs.service.SmsService; +import com.xy.xyaicpzs.service.UserService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.DigestUtils; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** +* @author XY003 +* @description 针对表【user(用户表)】的数据库操作Service实现 +* @createDate 2025-06-14 09:48:10 +*/ +@Service +@Slf4j +public class UserServiceImpl extends ServiceImpl + implements UserService{ + + /** + * 盐值,混淆密码 + */ + private static final String SALT = "xy"; + + @Autowired + private SmsService smsService; + + @Override + public long userRegister(String userAccount, String userName, String userPassword, String checkPassword) { + // 1. 校验 + if (StringUtils.isAnyBlank(userAccount, userName, userPassword, checkPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); + } + if (userAccount.length() < 4) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短"); + } + if (userName.length() > 40) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名过长"); + } + if (userPassword.length() < 8 || checkPassword.length() < 8) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短"); + } + + // 密码和校验密码相同 + if (!userPassword.equals(checkPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致"); + } + + synchronized (userAccount.intern()) { + // 账户不能重复 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userAccount", userAccount); + long count = this.baseMapper.selectCount(queryWrapper); + if (count > 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复"); + } + + // 2. 加密 + String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); + + // 3. 插入数据 + User user = new User(); + user.setUserAccount(userAccount); + user.setUserName(userName); + user.setUserPassword(encryptPassword); + user.setCreateTime(new Date()); + user.setUpdateTime(new Date()); + // 设置为VIP用户,有效期10天 + user.setIsVip(1); + Date vipExpireDate = new Date(System.currentTimeMillis() + 10L * 24 * 60 * 60 * 1000); + user.setVipExpire(vipExpireDate); + boolean saveResult = this.save(user); + if (!saveResult) { + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误"); + } + return user.getId(); + } + } + + @Override + public User userLogin(String userAccount, String userPassword, HttpServletRequest request) { + // 1. 校验 + if (StringUtils.isAnyBlank(userAccount, userPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); + } + if (userAccount.length() < 4) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误"); + } + if (userPassword.length() < 8) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误"); + } + + // 2. 加密 + String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); + + // 查询用户是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userAccount", userAccount); + queryWrapper.eq("userPassword", encryptPassword); + User user = this.baseMapper.selectOne(queryWrapper); + + // 用户不存在 + if (user == null) { + log.info("user login failed, userAccount cannot match userPassword"); + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误"); + } + + // 3. 记录用户的登录态 + request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user); + return getSafetyUser(user); + } + + /** + * 获取当前登录用户 + * + * @param request + * @return + */ + @Override + public User getLoginUser(HttpServletRequest request) { + // 先判断是否已登录 + Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE); + User currentUser = (User) userObj; + if (currentUser == null || currentUser.getId() == null) { + throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); + } + // 从数据库查询(追求性能的话可以注释,直接走缓存) + long userId = currentUser.getId(); + currentUser = this.getById(userId); + if (currentUser == null) { + throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); + } + return currentUser; + } + + /** + * 用户注销 + * + * @param request + */ + @Override + public boolean userLogout(HttpServletRequest request) { + if (request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE) == null) { + throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录"); + } + // 移除登录态 + request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE); + return true; + } + + @Override + public User getSafetyUser(User originUser) { + if (originUser == null) { + return null; + } + User safetyUser = new User(); + safetyUser.setId(originUser.getId()); + safetyUser.setUserName(originUser.getUserName()); + safetyUser.setUserAccount(originUser.getUserAccount()); + safetyUser.setUserAvatar(originUser.getUserAvatar()); + safetyUser.setUserRole(originUser.getUserRole()); + safetyUser.setCreateTime(originUser.getCreateTime()); + safetyUser.setUpdateTime(originUser.getUpdateTime()); + return safetyUser; + } + + @Override + public boolean isAdmin(HttpServletRequest request) { + // 仅管理员可查询 + Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE); + User user = (User) userObj; + return isAdmin(user); + } + + @Override + public boolean isAdmin(User user) { + return user != null && (UserConstant.ADMIN_ROLE.equals(user.getUserRole()) + || UserConstant.SUPER_ADMIN_ROLE.equals(user.getUserRole())); + } + + @Override + public long userPhoneRegister(UserPhoneRegisterRequest userPhoneRegisterRequest) { + if (userPhoneRegisterRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空"); + } + + String userAccount = userPhoneRegisterRequest.getUserAccount(); + String userPassword = userPhoneRegisterRequest.getUserPassword(); + String checkPassword = userPhoneRegisterRequest.getCheckPassword(); + String phone = userPhoneRegisterRequest.getPhone(); + String code = userPhoneRegisterRequest.getCode(); + String userName = userPhoneRegisterRequest.getUserName(); + + // 1. 校验 + if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword, phone, code)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); + } + // 用户名可以为空,如果为空则默认使用账号 + if (StringUtils.isBlank(userName)) { + userName = userAccount; + } + if (userAccount.length() < 4) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短"); + } + if (userPassword.length() < 8 || checkPassword.length() < 8) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短"); + } + + // 密码和校验密码相同 + if (!userPassword.equals(checkPassword)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致"); + } + + // 验证手机号格式 + String phoneRegex = "^1[3-9]\\d{9}$"; + if (!phone.matches(phoneRegex)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式错误"); + } + + // 验证短信验证码 + boolean isCodeValid = smsService.verifyCode(phone, code); + if (!isCodeValid) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误或已过期"); + } + + synchronized (userAccount.intern()) { + // 账户不能重复 + QueryWrapper accountQueryWrapper = new QueryWrapper<>(); + accountQueryWrapper.eq("userAccount", userAccount); + long accountCount = this.baseMapper.selectCount(accountQueryWrapper); + if (accountCount > 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号已存在"); + } + + // 手机号不能重复 + QueryWrapper phoneQueryWrapper = new QueryWrapper<>(); + phoneQueryWrapper.eq("phone", phone); + long phoneCount = this.baseMapper.selectCount(phoneQueryWrapper); + if (phoneCount > 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号已注册"); + } + + // 2. 加密 + String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); + + // 3. 插入数据 + User user = new User(); + user.setUserAccount(userAccount); + user.setUserPassword(encryptPassword); + user.setPhone(phone); + // 设置用户名 + user.setUserName(userName); + user.setCreateTime(new Date()); + user.setUpdateTime(new Date()); + // 设置为VIP用户,有效期10天 + user.setIsVip(0); + Date vipExpireDate = new Date(System.currentTimeMillis() + 10L * 24 * 60 * 60 * 1000); + user.setVipExpire(vipExpireDate); + + boolean saveResult = this.save(user); + if (!saveResult) { + throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误"); + } + return user.getId(); + } + } + + @Override + public User userPhoneLogin(UserPhoneLoginRequest userPhoneLoginRequest, HttpServletRequest request) { + if (userPhoneLoginRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空"); + } + + String phone = userPhoneLoginRequest.getPhone(); + String code = userPhoneLoginRequest.getCode(); + + // 1. 校验参数 + if (StringUtils.isAnyBlank(phone, code)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); + } + + // 验证手机号格式 + String phoneRegex = "^1[3-9]\\d{9}$"; + if (!phone.matches(phoneRegex)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式错误"); + } + + // 验证短信验证码 + boolean isCodeValid = smsService.verifyCode(phone, code); + if (!isCodeValid) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误或已过期"); + } + + // 查询用户是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("phone", phone); + User user = this.baseMapper.selectOne(queryWrapper); + + // 用户不存在 + if (user == null) { + log.info("user login failed, phone number not registered"); + throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号未注册"); + } + + // 3. 记录用户的登录态 + request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user); + return getSafetyUser(user); + } + + @Override + public String encryptPassword(String password) { + if (StringUtils.isBlank(password)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不能为空"); + } + return DigestUtils.md5DigestAsHex((SALT + password).getBytes()); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/VipCodeServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/VipCodeServiceImpl.java new file mode 100644 index 0000000..ed5c68f --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/VipCodeServiceImpl.java @@ -0,0 +1,273 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.User; +import com.xy.xyaicpzs.domain.entity.VipCode; +import com.xy.xyaicpzs.domain.entity.VipExchangeRecord; +import com.xy.xyaicpzs.mapper.UserMapper; +import com.xy.xyaicpzs.mapper.VipCodeMapper; +import com.xy.xyaicpzs.service.VipCodeService; +import com.xy.xyaicpzs.service.VipExchangeRecordService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; +import java.util.UUID; + +/** + * @author XY003 + * @description 针对表【vip_code(会员码表)】的数据库操作Service实现 + * @createDate 2025-01-15 16:41:29 + */ +@Slf4j +@Service +public class VipCodeServiceImpl extends ServiceImpl implements VipCodeService { + + @Autowired + private VipCodeMapper vipCodeMapper; + + @Autowired + private UserMapper userMapper; + + @Autowired + private VipExchangeRecordService vipExchangeRecordService; + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean activateVipCode(Long userId, String code) { + log.info("开始激活会员码,用户ID:{},会员码:{}", userId, code); + + // 1. 校验参数 + if (userId == null || code == null || code.trim().isEmpty()) { + throw new IllegalArgumentException("用户ID和会员码不能为空"); + } + + // 2. 查询会员码信息 + QueryWrapper vipCodeQuery = new QueryWrapper<>(); + vipCodeQuery.eq("code", code); + VipCode vipCode = vipCodeMapper.selectOne(vipCodeQuery); + + if (vipCode == null) { + throw new IllegalArgumentException("会员码不存在"); + } + + if (vipCode.getIsUse() == 1) { + throw new IllegalArgumentException("会员码已被使用"); + } + + // 3. 查询用户信息 + User user = userMapper.selectById(userId); + if (user == null) { + throw new IllegalArgumentException("用户不存在"); + } + + // 4. 根据会员码的vipExpireTime判断会员类型 + String memberType; + int orderAmount; + if (vipCode.getVipExpireTime() == 1) { + memberType = "月度会员"; + orderAmount = 10; + } else if (vipCode.getVipExpireTime() == 12) { + memberType = "年度会员"; + orderAmount = 100; + } else { + throw new IllegalArgumentException("无效的会员有效期:" + vipCode.getVipExpireTime()); + } + + // 5. 先在vip_exchange_record表插入兑换记录 + VipExchangeRecord exchangeRecord = new VipExchangeRecord(); + exchangeRecord.setUserId(userId); + exchangeRecord.setType(memberType); + exchangeRecord.setExchangeMode(1); // 1表示会员码兑换 + //生成随机16位订单号 + exchangeRecord.setOrderNo(generateOrderNumber()); + exchangeRecord.setOrderAmount(orderAmount); + exchangeRecord.setIsUse(1); // 1表示已兑换 + exchangeRecord.setExchangeTime(new Date()); + exchangeRecord.setUpdateTime(new Date()); + + boolean recordSaved = vipExchangeRecordService.save(exchangeRecord); + if (!recordSaved) { + log.error("保存兑换记录失败,用户ID:{},会员码:{}", userId, code); + throw new RuntimeException("保存兑换记录失败"); + } + + log.info("成功插入兑换记录,用户ID:{},会员类型:{}", userId, memberType); + + // 6. 计算新的会员到期时间 + Date newVipExpire = calculateNewVipExpire(user.getVipExpire(), vipCode.getVipExpireTime()); + + // 7. 更新用户会员状态 + User updateUser = new User(); + updateUser.setId(userId); + updateUser.setIsVip(1); // 设置为会员 + updateUser.setVipExpire(newVipExpire); + updateUser.setUpdateTime(new Date()); + + int userUpdateResult = userMapper.updateById(updateUser); + if (userUpdateResult == 0) { + log.error("更新用户会员状态失败,用户ID:{}", userId); + throw new RuntimeException("更新用户会员状态失败"); + } + + // 8. 标记会员码为已使用,并记录使用人信息和使用时间 + Date now = new Date(); + VipCode updateVipCode = new VipCode(); + updateVipCode.setId(vipCode.getId()); + updateVipCode.setIsUse(1); + updateVipCode.setUpdateTime(now); + // 添加使用人ID、使用人名称 + updateVipCode.setUsedUserId(userId); + updateVipCode.setUsedUserName(user.getUserName()); + + int vipCodeUpdateResult = vipCodeMapper.updateById(updateVipCode); + if (vipCodeUpdateResult == 0) { + log.error("更新会员码状态失败,会员码:{}", code); + throw new RuntimeException("更新会员码状态失败"); + } + + log.info("会员码激活成功,用户ID:{},会员类型:{},新的到期时间:{}", userId, memberType, newVipExpire); + return true; + } + + /** + * 计算新的会员到期时间 + * @param currentVipExpire 当前会员到期时间 + * @param vipExpireTime 会员有效月数 + * @return 新的会员到期时间 + */ + private Date calculateNewVipExpire(Date currentVipExpire, int vipExpireTime) { + LocalDate baseDate; + + // 如果当前已经是会员且未过期,则从当前到期时间开始延长 + if (currentVipExpire != null) { + LocalDate currentExpireDate = currentVipExpire.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + LocalDate today = LocalDate.now(); + + if (currentExpireDate.isAfter(today)) { + // 当前会员未过期,从到期时间开始延长 + baseDate = currentExpireDate; + } else { + // 当前会员已过期,从今天开始计算 + baseDate = today; + } + } else { + // 从未开通过会员,从今天开始计算 + baseDate = LocalDate.now(); + } + + // 增加对应的月数 + LocalDate newExpireDate = baseDate.plusMonths(vipExpireTime); + + return Date.from(newExpireDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } + + @Override + public int generateVipCodes(int numCodes, int vipExpireTime, Long createdUserId, String createdUserName) { + log.info("开始生成会员码,数量:{},有效月数:{},创建人ID:{}", numCodes, vipExpireTime, createdUserId); + + if (numCodes <= 0) { + throw new IllegalArgumentException("生成数量必须大于0"); + } + + if (vipExpireTime != 1 && vipExpireTime != 12) { + throw new IllegalArgumentException("会员有效月数只能是1或12"); + } + + if (numCodes > 1000) { + throw new IllegalArgumentException("单次生成数量不能超过1000"); + } + + // 获取当前最大的vipNumber + Integer maxVipNumber = 100000; // 默认从100001开始(6位数) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("vipNumber").last("LIMIT 1"); + VipCode maxVipCode = vipCodeMapper.selectOne(queryWrapper); + if (maxVipCode != null && maxVipCode.getVipNumber() != null) { + maxVipNumber = Math.max(maxVipNumber, maxVipCode.getVipNumber()); + } + + int successCount = 0; + Date now = new Date(); + + for (int i = 0; i < numCodes; i++) { + try { + VipCode vipCode = new VipCode(); + vipCode.setCode(generateUniqueCode()); + vipCode.setVipExpireTime(vipExpireTime); + + // 设置会员编号,从最大值+1开始,确保是6位数 + int nextVipNumber = maxVipNumber + i + 1; + vipCode.setVipNumber(nextVipNumber); + + vipCode.setIsUse(0); // 0表示未使用 + vipCode.setCreatedUserId(createdUserId); // 设置创建人ID + vipCode.setCreatedUserName(createdUserName); // 设置创建人名称 + vipCode.setCreateTime(now); +/* vipCode.setUpdateTime(now);*/ + + int result = vipCodeMapper.insert(vipCode); + if (result > 0) { + successCount++; + } + } catch (Exception e) { + log.error("生成第{}个会员码失败:{}", i + 1, e.getMessage()); + } + } + + log.info("会员码生成完成,请求生成:{}个,实际成功:{}个", numCodes, successCount); + return successCount; + } + + @Override + public String getAvailableVipCode(int vipExpireTime, Long createdUserId, String createdUserName) { + log.info("查找可用会员码,有效月数:{},创建人ID:{}", vipExpireTime, createdUserId); + + if (vipExpireTime != 1 && vipExpireTime != 12) { + throw new IllegalArgumentException("会员有效月数只能是1或12"); + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("vipExpireTime", vipExpireTime) + .eq("isUse", 0) + .orderByAsc("createTime") + .last("LIMIT 1"); + + VipCode vipCode = vipCodeMapper.selectOne(queryWrapper); + + if (vipCode != null) { + log.info("找到可用会员码:{}", vipCode.getCode()); + return vipCode.getCode(); + } else { + log.warn("没有找到有效月数为{}的可用会员码", vipExpireTime); + return null; + } + } + + /** + * 生成唯一的会员码 + * @return 会员码字符串 + */ + private String generateUniqueCode() { + // 生成16位的随机字符串作为会员码 + String uuid = UUID.randomUUID().toString().replace("-", ""); + return uuid.substring(0, 16).toUpperCase(); + } + + /** + * 生成16位随机订单号 + * @return 16位订单号 + */ + private Long generateOrderNumber() { + // 生成16位随机数字订单号 + // 方法1: 时间戳 + 随机数组合(推荐,避免重复) + long timestamp = System.currentTimeMillis() % 1000000L; // 取6位时间戳 + long random = (long) (Math.random() * 9000000000L) + 1000000000L; // 10位随机数 + return Long.parseLong(String.valueOf(timestamp) + String.valueOf(random)); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/service/impl/VipExchangeRecordServiceImpl.java b/src/main/java/com/xy/xyaicpzs/service/impl/VipExchangeRecordServiceImpl.java new file mode 100644 index 0000000..6f8d6a3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/service/impl/VipExchangeRecordServiceImpl.java @@ -0,0 +1,32 @@ +package com.xy.xyaicpzs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.xy.xyaicpzs.domain.entity.VipExchangeRecord; +import com.xy.xyaicpzs.service.VipExchangeRecordService; +import com.xy.xyaicpzs.mapper.VipExchangeRecordMapper; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** +* @author XY003 +* @description 针对表【vip_exchange_record(会员兑换表)】的数据库操作Service实现 +* @createDate 2025-06-19 11:27:10 +*/ +@Service +public class VipExchangeRecordServiceImpl extends ServiceImpl + implements VipExchangeRecordService{ + + @Override + public List getExchangeRecordsByUserId(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId) + .orderByDesc("exchangeTime"); + return list(queryWrapper); + } +} + + + + diff --git a/src/main/java/com/xy/xyaicpzs/task/PredictResultTask.java b/src/main/java/com/xy/xyaicpzs/task/PredictResultTask.java new file mode 100644 index 0000000..7b16505 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/task/PredictResultTask.java @@ -0,0 +1,44 @@ +package com.xy.xyaicpzs.task; + +import com.xy.xyaicpzs.service.DataAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * 预测结果处理定时任务 + */ +@Slf4j +@Component +public class PredictResultTask { + + @Autowired + private DataAnalysisService dataAnalysisService; + + /** + * 每5分钟执行一次预测结果匹配 + * cron表达式:秒 分 时 日 月 周 + * 0 0/5 * * * ? 表示每5分钟执行一次 + */ + @Scheduled(cron = "0 0/1 * * * ?") + public void processPendingPredictions() { + try { + log.info("=== 开始执行预测结果匹配定时任务 ==="); + + long startTime = System.currentTimeMillis(); + + // 调用服务处理待开奖记录 + int processedCount = dataAnalysisService.processPendingPredictions(); + + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + + log.info("=== 预测结果匹配定时任务执行完成 === 处理记录数:{},耗时:{}ms", processedCount, duration); + + } catch (Exception e) { + log.error("预测结果匹配定时任务执行失败:{}", e.getMessage(), e); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java b/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java new file mode 100644 index 0000000..db7fa85 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/util/ExcelDataImporter.java @@ -0,0 +1,1737 @@ +package com.xy.xyaicpzs.util; + +import com.xy.xyaicpzs.domain.entity.History100; +import com.xy.xyaicpzs.domain.entity.HistoryAll; +import com.xy.xyaicpzs.domain.entity.HistoryTop; +import com.xy.xyaicpzs.domain.entity.HistoryTop100; +import com.xy.xyaicpzs.domain.entity.BlueHistory100; +import com.xy.xyaicpzs.domain.entity.BlueHistoryAll; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop; +import com.xy.xyaicpzs.domain.entity.BlueHistoryTop100; +import com.xy.xyaicpzs.domain.entity.T3; +import com.xy.xyaicpzs.domain.entity.T4; +import com.xy.xyaicpzs.domain.entity.T5; +import com.xy.xyaicpzs.domain.entity.T6; +import com.xy.xyaicpzs.domain.entity.T7; +import com.xy.xyaicpzs.domain.entity.T8; +import com.xy.xyaicpzs.domain.entity.T11; +import com.xy.xyaicpzs.domain.entity.LotteryDraws; +import com.xy.xyaicpzs.mapper.History100Mapper; +import com.xy.xyaicpzs.mapper.HistoryAllMapper; +import com.xy.xyaicpzs.mapper.HistoryTop100Mapper; +import com.xy.xyaicpzs.mapper.HistoryTopMapper; +import com.xy.xyaicpzs.mapper.BlueHistory100Mapper; +import com.xy.xyaicpzs.mapper.BlueHistoryAllMapper; +import com.xy.xyaicpzs.mapper.BlueHistoryTop100Mapper; +import com.xy.xyaicpzs.mapper.BlueHistoryTopMapper; +import com.xy.xyaicpzs.mapper.T3Mapper; +import com.xy.xyaicpzs.mapper.T4Mapper; +import com.xy.xyaicpzs.mapper.T5Mapper; +import com.xy.xyaicpzs.mapper.T6Mapper; +import com.xy.xyaicpzs.mapper.T7Mapper; +import com.xy.xyaicpzs.mapper.T8Mapper; +import com.xy.xyaicpzs.mapper.T11Mapper; +import com.xy.xyaicpzs.mapper.LotteryDrawsMapper; +import com.xy.xyaicpzs.service.T3Service; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; + +/** + * Excel数据导入工具类 + * 用于读取T1 sheet的数据并插入到四个数据库表中 + */ +@Slf4j +@Component +public class ExcelDataImporter { + + @Autowired + private HistoryAllMapper historyAllMapper; + + @Autowired + private History100Mapper history100Mapper; + + @Autowired + private HistoryTopMapper historyTopMapper; + + @Autowired + private HistoryTop100Mapper historyTop100Mapper; + + @Autowired + private BlueHistoryAllMapper blueHistoryAllMapper; + + @Autowired + private BlueHistory100Mapper blueHistory100Mapper; + + @Autowired + private BlueHistoryTopMapper blueHistoryTopMapper; + + @Autowired + private BlueHistoryTop100Mapper blueHistoryTop100Mapper; + + @Autowired + private T3Mapper t3Mapper; + + @Autowired + private T4Mapper t4Mapper; + + @Autowired + private T5Mapper t5Mapper; + + @Autowired + private T6Mapper t6Mapper; + + @Autowired + private T7Mapper t7Mapper; + + @Autowired + private T8Mapper t8Mapper; + + @Autowired + private T11Mapper t11Mapper; + + @Autowired + private LotteryDrawsMapper lotteryDrawsMapper; + + @Autowired + private T3Service t3Service; + + /** + * 导入Excel数据到数据库 + * @param filePath Excel文件路径 + */ + public void importExcelData(String filePath) { + try (FileInputStream fis = new FileInputStream(filePath); + XSSFWorkbook workbook = new XSSFWorkbook(fis)) { + + // 清空现有数据 + clearExistingData(); + + // 处理T1 sheet(红球数据) + Sheet t1Sheet = workbook.getSheet("T1"); + if (t1Sheet != null) { + int lastRowNum = t1Sheet.getLastRowNum(); + log.info("开始导入T1数据(红球),共{}行", lastRowNum); + + // 读取数据并插入到各个表 + importHistoryAllData(t1Sheet, lastRowNum); + importHistory100Data(t1Sheet, lastRowNum); + importHistoryTopData(t1Sheet, lastRowNum); + importHistoryTop100Data(t1Sheet, lastRowNum); + + log.info("T1数据(红球)导入完成"); + } else { + log.warn("未找到T1工作表"); + } + + // 处理T2 sheet(蓝球数据) + Sheet t2Sheet = workbook.getSheet("T2"); + if (t2Sheet != null) { + int lastRowNum = t2Sheet.getLastRowNum(); + log.info("开始导入T2数据(蓝球),共{}行", lastRowNum); + + // 读取数据并插入到蓝球相关表 + importBlueHistoryAllData(t2Sheet, lastRowNum); + importBlueHistory100Data(t2Sheet, lastRowNum); + importBlueHistoryTopData(t2Sheet, lastRowNum); + importBlueHistoryTop100Data(t2Sheet, lastRowNum); + + log.info("T2数据(蓝球)导入完成"); + } else { + log.warn("未找到T2工作表"); + } + + // 处理T3 sheet(红球线系数数据) + Sheet t3Sheet = workbook.getSheet("T3"); + if (t3Sheet != null) { + log.info("开始导入T3数据(红球线系数)"); + List dataList = readT3DataFromSheet(t3Sheet); + if (!dataList.isEmpty()) { + // clearExistingData() is called at the beginning, so we just save. + t3Service.saveBatch(dataList); + log.info("成功导入{}条T3数据(红球线系数)", dataList.size()); + } else { + log.warn("未找到有效的T3数据"); + } + log.info("T3数据(红球线系数)导入完成"); + } else { + log.warn("未找到T3工作表"); + } + + // 处理T4 sheet(蓝球组红球线系数数据) + Sheet t4Sheet = workbook.getSheet("T4"); + if (t4Sheet != null) { + log.info("开始导入T4数据(蓝球组红球线系数)"); + + // 读取T4数据并插入到t4表 + importT4Data(t4Sheet); + + log.info("T4数据(蓝球组红球线系数)导入完成"); + } else { + log.warn("未找到T4工作表"); + } + + // 处理T5 sheet(蓝球组蓝球线系数数据) + Sheet t5Sheet = workbook.getSheet("T5"); + if (t5Sheet != null) { + log.info("开始导入T5数据(蓝球组蓝球线系数)"); + + // 读取T5数据并插入到t5表 + importT5Data(t5Sheet); + + log.info("T5数据(蓝球组蓝球线系数)导入完成"); + } else { + log.warn("未找到T5工作表"); + } + + // 处理T6 sheet(红球组蓝球线系数数据) + Sheet t6Sheet = workbook.getSheet("T6"); + if (t6Sheet != null) { + log.info("开始导入T6数据(红球组蓝球线系数)"); + + // 读取T6数据并插入到t6表 + importT6Data(t6Sheet); + + log.info("T6数据(红球组蓝球线系数)导入完成"); + } else { + log.warn("未找到T6工作表"); + } + + // 处理T7 sheet(红球组红球面系数数据) + Sheet t7Sheet = workbook.getSheet("T7"); + if (t7Sheet != null) { + log.info("开始导入T7数据(红球组红球面系数)"); + + // 读取T7数据并插入到t7表 + importT7Data(t7Sheet); + + log.info("T7数据(红球组红球面系数)导入完成"); + } else { + log.warn("未找到T7工作表"); + } + + // 处理T8 sheet(红球组蓝球面系数数据) + Sheet t8Sheet = workbook.getSheet("T8"); + if (t8Sheet != null) { + log.info("开始导入T8数据(红球组蓝球面系数)"); + + // 读取T8数据并插入到t8表 + importT8Data(t8Sheet); + + log.info("T8数据(红球组蓝球面系数)导入完成"); + } else { + log.warn("未找到T8工作表"); + } + +// // 处理T10 sheet(彩票开奖信息数据) +// Sheet t10Sheet = workbook.getSheet("T10"); +// if (t10Sheet != null) { +// log.info("开始导入T10数据(彩票开奖信息)"); +// +// // 读取T10数据并插入到lottery_draws表 +// importT10Data(t10Sheet); +// +// log.info("T10数据(彩票开奖信息)导入完成"); +// } else { +// log.warn("未找到T10工作表"); +// } + + // 处理T11 sheet(蓝球组红球面系数数据) + Sheet t11Sheet = workbook.getSheet("T11"); + if (t11Sheet != null) { + log.info("开始导入T11数据(蓝球组红球面系数)"); + + // 读取T11数据并插入到t11表 + importT11Data(t11Sheet); + + log.info("T11数据(蓝球组红球面系数)导入完成"); + } else { + log.warn("未找到T11工作表"); + } + + log.info("数据导入完成"); + + } catch (IOException e) { + log.error("读取Excel文件失败:{}", e.getMessage(), e); + throw new RuntimeException("Excel文件读取失败", e); + } + } + + /** + * 导入Excel的开奖数据到数据库 + * @param filePath Excel文件路径 + */ + public void importLotteryDrawsData(String filePath) { + try (FileInputStream fis = new FileInputStream(filePath); + XSSFWorkbook workbook = new XSSFWorkbook(fis)) { + // 清空现有数据 + clearLotteryDrawsData(); + + // 处理T10 sheet(彩票开奖信息数据) + Sheet t10Sheet = workbook.getSheet("T10"); + if (t10Sheet != null) { + log.info("开始导入T10数据(彩票开奖信息)"); + + // 读取T10数据并插入到lottery_draws表 + importT10Data(t10Sheet); + + log.info("T10数据(彩票开奖信息)导入完成"); + } else { + log.warn("未找到T10工作表"); + } + + log.info("数据导入完成"); + } catch (IOException e) { + log.error("读取Excel文件失败:{}", e.getMessage(), e); + throw new RuntimeException("Excel文件读取失败", e); + } + } + + /** + * 追加导入Excel的开奖数据到数据库(不清空现有数据) + * @param filePath Excel文件路径 + */ + public void appendLotteryDrawsData(String filePath) { + try (FileInputStream fis = new FileInputStream(filePath); + XSSFWorkbook workbook = new XSSFWorkbook(fis)) { + + // 处理T10 sheet(彩票开奖信息数据) + Sheet t10Sheet = workbook.getSheet("T10"); + if (t10Sheet != null) { + log.info("开始追加导入T10数据(彩票开奖信息)"); + + // 读取T10数据并追加到lottery_draws表 + appendT10Data(t10Sheet); + + log.info("T10数据(彩票开奖信息)追加导入完成"); + } else { + log.warn("未找到T10工作表"); + } + + log.info("追加数据导入完成"); + } catch (IOException e) { + log.error("读取Excel文件失败:{}", e.getMessage(), e); + throw new RuntimeException("Excel文件读取失败", e); + } + } + + /** + * 清空现有数据 + */ + private void clearExistingData() { + log.info("清空现有数据..."); + // 使用MyBatis-Plus的delete方法清空表 + // 清空红球数据表 + historyAllMapper.delete(null); + history100Mapper.delete(null); + historyTopMapper.delete(null); + historyTop100Mapper.delete(null); + + // 清空蓝球数据表 + blueHistoryAllMapper.delete(null); + blueHistory100Mapper.delete(null); + blueHistoryTopMapper.delete(null); + blueHistoryTop100Mapper.delete(null); + + // 清空T3数据表 + t3Mapper.delete(null); + + // 清空T4数据表 + t4Mapper.delete(null); + + // 清空T5数据表 + t5Mapper.delete(null); + + // 清空T6数据表 + t6Mapper.delete(null); + + // 清空T7数据表 + t7Mapper.delete(null); + + // 清空T8数据表 + t8Mapper.delete(null); + + // 清空T10数据表 + lotteryDrawsMapper.delete(null); + + // 清空T11数据表 + t11Mapper.delete(null); + } + + /** + * 清空现有开奖数据 + */ + private void clearLotteryDrawsData() { + log.info("清空现有开奖数据..."); + // 使用MyBatis-Plus的delete方法清空表 + // 清空T10数据表 + lotteryDrawsMapper.delete(null); + } + + /** + * 导入全部历史数据 (列A-G) + */ + private void importHistoryAllData(Sheet sheet, int lastRowNum) { + log.info("开始导入全部历史数据..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + HistoryAll entity = new HistoryAll(); + + // 列A: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(0))); + + // 列B: 出现频次 + entity.setFrequencyCount(getCellIntegerValue(row.getCell(1))); + + // 列C: 出现频率百分比 + entity.setFrequencyPercentage(getCellNumericValue(row.getCell(2))); + + // 列D: 平均隐现期 + entity.setAverageInterval(getCellNumericValue(row.getCell(3))); + + // 列E: 最长隐现期 + entity.setMaxHiddenInterval(getCellIntegerValue(row.getCell(4))); + + // 列F: 最多连出期 + entity.setMaxConsecutiveCount(getCellIntegerValue(row.getCell(5))); + + // 列G: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(6))); + + if (entity.getBallNumber() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(historyAllMapper::insert); + log.info("成功导入{}条全部历史数据", dataList.size()); + } + } + + /** + * 导入最近100期数据 (列H-L) + */ + private void importHistory100Data(Sheet sheet, int lastRowNum) { + log.info("开始导入最近100期数据..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + History100 entity = new History100(); + + // 使用第一列的球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(0))); + + // 列H: 出现频次 + entity.setFrequencyCount(getCellIntegerValue(row.getCell(8))); + + // 列J: 平均隐现期 + entity.setAverageInterval(getCellNumericValue(row.getCell(9))); + + // 列K: 当前隐现期 + entity.setNowInterval(getCellIntegerValue(row.getCell(10))); + + // 列L: 最多连出期 + entity.setMaxConsecutiveCount(getCellIntegerValue(row.getCell(11))); + + // 列M: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(12))); + + if (entity.getBallNumber() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(history100Mapper::insert); + log.info("成功导入{}条最近100期数据", dataList.size()); + } + } + + /** + * 导入历史数据排行 (列N-P) + */ + private void importHistoryTopData(Sheet sheet, int lastRowNum) { + log.info("开始导入历史数据排行..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + HistoryTop entity = new HistoryTop(); + + // 列N: 排行 + entity.setNo(getCellIntegerValue(row.getCell(14))); + + // 列O: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(15))); + + // 列P: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(16))); + + if (entity.getBallNumber() != null && entity.getNo() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(historyTopMapper::insert); + log.info("成功导入{}条历史数据排行", dataList.size()); + } + } + + /** + * 导入100期数据排行 (列Q-S) + */ + private void importHistoryTop100Data(Sheet sheet, int lastRowNum) { + log.info("开始导入100期数据排行..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + HistoryTop100 entity = new HistoryTop100(); + + // 列Q: 排行 + entity.setNo(getCellIntegerValue(row.getCell(18))); + + // 列R: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(19))); + + // 列S: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(20))); + + if (entity.getBallNumber() != null && entity.getNo() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(historyTop100Mapper::insert); + log.info("成功导入{}条100期数据排行", dataList.size()); + } + } + + /** + * 获取单元格的数值(保留两位小数) + */ + private Double getCellNumericValue(Cell cell) { + if (cell == null) return null; + + try { + double value = 0.0; + switch (cell.getCellType()) { + case NUMERIC: + value = cell.getNumericCellValue(); + break; + case STRING: + String strValue = cell.getStringCellValue().trim(); + if (strValue.isEmpty()) { + return null; + } + try { + value = Double.parseDouble(strValue); + } catch (NumberFormatException e) { + log.warn("无法解析单元格数值:{}", strValue); + return null; + } + break; + case FORMULA: + try { + value = cell.getNumericCellValue(); + } catch (Exception e) { + log.warn("无法获取公式单元格的数值:{}", e.getMessage()); + return null; + } + break; + case BLANK: + return null; + default: + log.warn("不支持的单元格类型:{}", cell.getCellType()); + return null; + } + + // 保留两位小数 + return roundToTwoDecimalPlaces(value); + + } catch (Exception e) { + log.warn("读取单元格数据失败:{}", e.getMessage()); + return null; + } + } + + /** + * 获取单元格的整数值 + */ + private Integer getCellIntegerValue(Cell cell) { + Double numericValue = getCellNumericValue(cell); + return numericValue != null ? numericValue.intValue() : null; + } + + /** + * 将数值保留两位小数 + * @param value 原始数值 + * @return 保留两位小数的数值 + */ + private Double roundToTwoDecimalPlaces(double value) { + if (Double.isNaN(value) || Double.isInfinite(value)) { + return null; + } + + try { + BigDecimal bd = new BigDecimal(Double.toString(value)); + return bd.setScale(2, RoundingMode.HALF_UP).doubleValue(); + } catch (Exception e) { + log.warn("数值格式化失败:{}", value); + return value; + } + } + + // ==================== 蓝球数据导入方法 ==================== + + /** + * 导入蓝球全部历史数据 (列A-G) + */ + private void importBlueHistoryAllData(Sheet sheet, int lastRowNum) { + log.info("开始导入蓝球全部历史数据..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + BlueHistoryAll entity = new BlueHistoryAll(); + + // 列A: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(0))); + + // 列B: 出现频次 + entity.setFrequencyCount(getCellIntegerValue(row.getCell(1))); + + // 列C: 出现频率百分比 + entity.setFrequencyPercentage(getCellNumericValue(row.getCell(2))); + + // 列D: 平均隐现期 + entity.setAverageInterval(getCellNumericValue(row.getCell(3))); + + // 列E: 最长隐现期 + entity.setMaxHiddenInterval(getCellIntegerValue(row.getCell(4))); + + // 列F: 最多连出期 + entity.setMaxConsecutiveCount(getCellIntegerValue(row.getCell(5))); + + // 列G: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(6))); + + if (entity.getBallNumber() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(blueHistoryAllMapper::insert); + log.info("成功导入{}条蓝球全部历史数据", dataList.size()); + } + } + + /** + * 导入蓝球最近100期数据 (列H-M) + */ + private void importBlueHistory100Data(Sheet sheet, int lastRowNum) { + log.info("开始导入蓝球最近100期数据..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + BlueHistory100 entity = new BlueHistory100(); + + // 使用第一列的球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(0))); + + // 列H: 出现频次 + entity.setFrequencyCount(getCellIntegerValue(row.getCell(8))); + + // 列J: 平均隐现期 + entity.setAverageInterval(getCellNumericValue(row.getCell(9))); + + // 列K: 当前隐现期 + entity.setNowInterval(getCellIntegerValue(row.getCell(10))); + + // 列L: 最多连出期 + entity.setMaxConsecutiveCount(getCellIntegerValue(row.getCell(11))); + + // 列M: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(12))); + + if (entity.getBallNumber() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(blueHistory100Mapper::insert); + log.info("成功导入{}条蓝球最近100期数据", dataList.size()); + } + } + + /** + * 导入蓝球历史数据排行 (列N-P) + */ + private void importBlueHistoryTopData(Sheet sheet, int lastRowNum) { + log.info("开始导入蓝球历史数据排行..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + BlueHistoryTop entity = new BlueHistoryTop(); + + // 列N: 排行 + entity.setNo(getCellIntegerValue(row.getCell(14))); + + // 列O: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(15))); + + // 列P: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(16))); + + if (entity.getBallNumber() != null && entity.getNo() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(blueHistoryTopMapper::insert); + log.info("成功导入{}条蓝球历史数据排行", dataList.size()); + } + } + + /** + * 导入蓝球100期数据排行 (列Q-S) + */ + private void importBlueHistoryTop100Data(Sheet sheet, int lastRowNum) { + log.info("开始导入蓝球100期数据排行..."); + List dataList = new ArrayList<>(); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + BlueHistoryTop100 entity = new BlueHistoryTop100(); + + // 列Q: 排行 + entity.setNo(getCellIntegerValue(row.getCell(18))); + + // 列R: 球号 + entity.setBallNumber(getCellIntegerValue(row.getCell(19))); + + // 列S: 点系数 + entity.setPointCoefficient(getCellNumericValue(row.getCell(20))); + + if (entity.getBallNumber() != null && entity.getNo() != null) { + dataList.add(entity); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(blueHistoryTop100Mapper::insert); + log.info("成功导入{}条蓝球100期数据排行", dataList.size()); + } + } + + // ==================== T3数据导入方法 ==================== + + /** + * 导入T3数据(红球线系数) + * 数据结构:每三列为一组,每组有33行数据 + * 从球号固定为1-33(行号),线系数在C、F、I、L...列 + */ + private void importT3Data(Sheet sheet) { + log.info("开始导入T3数据(红球线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有33行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); + + // 遍历每组数据 + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主球号从1开始 + int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); + + // 遍历33行数据(跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 33; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T3 entity = new T3(); + entity.setMasterBallNumber(masterBallNumber); + + // 从球号固定为行号(1-33) + Integer slaveBallNumber = i; + + // 线系数(从对应组的第二列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(lineCoefficient); + dataList.add(entity); + } else { + log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t3Mapper::insert); + log.info("成功导入{}条T3数据(红球线系数)", dataList.size()); + } else { + log.warn("未找到有效的T3数据"); + } + } + + // ==================== T4数据导入方法 ==================== + + /** + * 导入T4数据(蓝球组红球的线系数) + * 数据结构:每三列为一组,每组有33行数据 + * 蓝球号码范围:1-16(主球) + * 红球号码范围:1-33(从球,对应行号) + * 线系数在C、F、I、L...列 + */ + private void importT4Data(Sheet sheet) { + log.info("开始导入T4数据(蓝球组红球的线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有33行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 蓝球号码范围是1-16,所以最多16组 + groupCount = Math.min(groupCount, 16); + + log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); + + // 遍历每组数据(蓝球1-16号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 蓝球号从1开始 + int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(蓝球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); + + // 遍历33行数据(红球1-33号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 33; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T4 entity = new T4(); + entity.setMasterBallNumber(masterBallNumber); // 蓝球号 + + // 从球号固定为行号(红球1-33) + Integer slaveBallNumber = i; + + // 线系数(从对应组的第三列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t4Mapper::insert); + log.info("成功导入{}条T4数据(蓝球组红球的线系数)", dataList.size()); + log.info("预期数据量:16个蓝球 × 33个红球 = 528条记录"); + } else { + log.warn("未找到有效的T4数据"); + } + } + + // ==================== T5数据导入方法 ==================== + + /** + * 导入T5数据(蓝球组蓝球的线系数) + * 数据结构:每三列为一组,每组有16行数据 + * 蓝球号码范围:1-16(主球和从球都是) + * 线系数在C、F、I、L...列 + */ + private void importT5Data(Sheet sheet) { + log.info("开始导入T5数据(蓝球组蓝球的线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 蓝球号码范围是1-16,所以最多16组 + groupCount = Math.min(groupCount, 16); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(蓝球1-16号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主蓝球号从1开始 + int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主蓝球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T5 entity = new T5(); + entity.setMasterBallNumber(masterBallNumber); // 主蓝球号 + + // 从球号固定为行号(从蓝球1-16) + Integer slaveBallNumber = i; + + // 线系数(从对应组的第三列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t5Mapper::insert); + log.info("成功导入{}条T5数据(蓝球组蓝球的线系数)", dataList.size()); + log.info("预期数据量:16个蓝球 × 16个蓝球 = 256条记录"); + } else { + log.warn("未找到有效的T5数据"); + } + } + + // ==================== T6数据导入方法 ==================== + + /** + * 导入T6数据(红球组蓝球的线系数) + * 数据结构:每三列为一组,每组有16行数据 + * 红球号码范围:1-33(主球) + * 蓝球号码范围:1-16(从球) + * 线系数在C、F、I、L...列 + */ + private void importT6Data(Sheet sheet) { + log.info("开始导入T6数据(红球组蓝球的线系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 红球号码范围是1-33,所以最多33组 + groupCount = Math.min(groupCount, 33); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(红球1-33号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主红球号从1开始 + int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主红球{}号),线系数列位置:{}", group + 1, masterBallNumber, lineCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T6 entity = new T6(); + entity.setMasterBallNumber(masterBallNumber); // 主红球号 + + // 从球号固定为行号(从蓝球1-16) + Integer slaveBallNumber = i; + + // 线系数(从对应组的第三列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(roundToTwoDecimalPlaces(lineCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行线系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t6Mapper::insert); + log.info("成功导入{}条T6数据(红球组蓝球的线系数)", dataList.size()); + log.info("预期数据量:33个红球 × 16个蓝球 = 528条记录"); + } else { + log.warn("未找到有效的T6数据"); + } + } + + // ==================== T7数据导入方法 ==================== + + /** + * 导入T7数据(红球组红球的面系数) + * 数据结构:每三列为一组,每组有33行数据,但需要排除自己和自己组合的情况 + * 红球号码范围:1-33(主球和从球都是) + * 面系数在C、F、I、L...列 + * 特殊处理:1号只能与2-33组合,2号只能与1,3-33组合,以此类推 + */ + private void importT7Data(Sheet sheet) { + log.info("开始导入T7数据(红球组红球的面系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有33行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 红球号码范围是1-33,所以最多33组 + groupCount = Math.min(groupCount, 33); + + log.info("检测到{}组数据,共{}列,数据行数{},预期33行数据", groupCount, totalCols, lastRowNum); + + // 遍历每组数据(红球1-33号作为主球) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主红球号从1开始 + int ballNumberCol = group * 3 + 1; // 球号列:1,4,7,10...(B,E,H,K列) + int faceCoefCol = group * 3 + 2; // 面系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主红球{}号),球号列:{},面系数列:{}", group + 1, masterBallNumber, ballNumberCol, faceCoefCol); + + int validDataCount = 0; // 统计这组有效数据数量 + int skippedDiagonal = 0; // 统计跳过的对角线数量 + int emptyBallNumber = 0; // 统计球号为空的数量 + int emptyCoefficient = 0; // 统计面系数为空的数量 + + // 遍历所有数据行(跳过标题行) + // 需要读取到最后一行数据,确保包含33号球 + for (int rowIndex = 1; rowIndex <= lastRowNum; rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + continue; + } + + // 从Excel中读取球号(从球号列读取) + Integer slaveBallNumber = getCellIntegerValue(row.getCell(ballNumberCol)); + if (slaveBallNumber == null) { + emptyBallNumber++; + continue; // 如果球号为空,跳过这行 + } + + // 不排除对角线,读取到什么就插入什么 + // if (masterBallNumber == slaveBallNumber) { + // skippedDiagonal++; + // log.debug("跳过对角线组合:主球{},从球{}", masterBallNumber, slaveBallNumber); + // continue; + // } + + // 面系数(从对应组的面系数列读取) + Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); + + if (faceCoefficient != null) { + T7 entity = new T7(); + entity.setMasterBallNumber(masterBallNumber); // 主红球号 + entity.setSlaveBallNumber(slaveBallNumber); // 从红球号 + entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); + dataList.add(entity); + validDataCount++; + + // 特别记录1号组33号球的数据 + if (masterBallNumber == 1 && slaveBallNumber == 33) { + log.info("★ 重要数据:主球1,从球33,Excel行{},面系数{}", rowIndex + 1, faceCoefficient); + } + + log.debug("添加T7数据:主球{},从球{},Excel行{},面系数{}", + masterBallNumber, slaveBallNumber, rowIndex + 1, faceCoefficient); + } else { + emptyCoefficient++; + log.debug("第{}组第{}行面系数为空,球号{},跳过", group + 1, rowIndex + 1, slaveBallNumber); + } + } + + // 统计这组的处理结果 + log.info("第{}组统计:有效数据{}条,跳过对角线{}条,球号为空{}条,面系数为空{}条", + group + 1, validDataCount, skippedDiagonal, emptyBallNumber, emptyCoefficient); + + if (validDataCount != 33) { + log.warn("第{}组数据异常:应该有33条有效数据,实际{}条", group + 1, validDataCount); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t7Mapper::insert); + log.info("成功导入{}条T7数据(红球组红球的面系数)", dataList.size()); + log.info("预期数据量:33个红球 × 32个红球(排除自己) = 1056条记录"); + + // 验证关键数据点 + boolean found1_33 = dataList.stream().anyMatch(t7 -> + t7.getMasterBallNumber() == 1 && t7.getSlaveBallNumber() == 33); + if (found1_33) { + T7 record1_33 = dataList.stream() + .filter(t7 -> t7.getMasterBallNumber() == 1 && t7.getSlaveBallNumber() == 33) + .findFirst().orElse(null); + log.info("验证成功:找到(1,33)记录,面系数={}", record1_33.getFaceCoefficient()); + } else { + log.warn("验证失败:未找到(1,33)记录"); + } + + // 统计每组的记录数(应该都是32条,排除对角线) + for (int master = 1; master <= Math.min(groupCount, 5); master++) { + final int masterNum = master; + long count = dataList.stream().filter(t7 -> t7.getMasterBallNumber() == masterNum).count(); + log.info("主球{}号记录数:{}(应该是32)", masterNum, count); + } + + // 验证对角线数据不存在 + long diagonalCount = dataList.stream() + .filter(t7 -> t7.getMasterBallNumber().equals(t7.getSlaveBallNumber())) + .count(); + log.info("对角线记录数:{}(应该是0)", diagonalCount); + + // 验证从球号范围 + Set slaveBallNumbers = dataList.stream() + .map(T7::getSlaveBallNumber) + .collect(java.util.stream.Collectors.toSet()); + log.info("从球号范围:{}到{},总数:{}(应该是1到33)", + slaveBallNumbers.stream().min(Integer::compareTo).orElse(0), + slaveBallNumbers.stream().max(Integer::compareTo).orElse(0), + slaveBallNumbers.size()); + + // 验证是否包含33号球 + boolean has33 = slaveBallNumbers.contains(33); + log.info("是否包含33号球:{}(应该是true)", has33); + + // 详细分析缺失的球号 + List missingSlaves = new ArrayList<>(); + for (int i = 1; i <= 33; i++) { + if (!slaveBallNumbers.contains(i)) { + missingSlaves.add(i); + } + } + if (!missingSlaves.isEmpty()) { + log.warn("缺失的从球号:{}", missingSlaves); + } + + // 统计每个主球的记录数,找出缺失的组合 + for (int master = 1; master <= 33; master++) { + final int masterNum = master; + long count = dataList.stream().filter(t7 -> t7.getMasterBallNumber() == masterNum).count(); + if (count != 33) { + log.warn("主球{}号记录数异常:{}(应该是33)", masterNum, count); + + // 找出这个主球缺失的从球号 + Set existingSlaves = dataList.stream() + .filter(t7 -> t7.getMasterBallNumber() == masterNum) + .map(T7::getSlaveBallNumber) + .collect(java.util.stream.Collectors.toSet()); + + List missingForThisMaster = new ArrayList<>(); + for (int slave = 1; slave <= 33; slave++) { + if (!existingSlaves.contains(slave)) { + missingForThisMaster.add(slave); + } + } + if (!missingForThisMaster.isEmpty()) { + log.warn("主球{}号缺失的从球号:{}", masterNum, missingForThisMaster); + } + } + } + + // 验证总记录数 + log.info("实际记录数:{},预期记录数:{}(33×33=1089),差异:{}", + dataList.size(), 33 * 33, (33 * 33) - dataList.size()); + } else { + log.warn("未找到有效的T7数据"); + } + } + + // ==================== T8数据导入方法 ==================== + + /** + * 导入T8数据(红球组蓝球的面系数) + * 数据结构:每三列为一组,每组有16行数据 + * 红球号码范围:1-33(主球) + * 蓝球号码范围:1-16(从球) + * 面系数在C、F、I、L...列 + */ + private void importT8Data(Sheet sheet) { + log.info("开始导入T8数据(红球组蓝球的面系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有16行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 红球号码范围是1-33,所以最多33组 + groupCount = Math.min(groupCount, 33); + + log.info("检测到{}组数据,共{}列,预期16行数据", groupCount, totalCols); + + // 遍历每组数据(红球1-33号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主红球号从1开始 + int faceCoefCol = group * 3 + 2; // 面系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主红球{}号),面系数列位置:{}", group + 1, masterBallNumber, faceCoefCol); + + // 遍历16行数据(从蓝球1-16号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 16; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T8 entity = new T8(); + entity.setMasterBallNumber(masterBallNumber); // 主红球号 + + // 从球号固定为行号(从蓝球1-16) + Integer slaveBallNumber = i; + + // 面系数(从对应组的第三列读取) + Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); + + if (faceCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行面系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t8Mapper::insert); + log.info("成功导入{}条T8数据(红球组蓝球的面系数)", dataList.size()); + log.info("预期数据量:33个红球 × 16个蓝球 = 528条记录"); + } else { + log.warn("未找到有效的T8数据"); + } + } + + // ==================== T11数据导入方法 ==================== + + /** + * 导入T11数据(蓝球组红球的面系数) + * 数据结构:每三列为一组,每组有33行数据 + * 蓝球号码范围:1-16(主球) + * 红球号码范围:1-33(从球) + * 面系数在C、F、I、L...列 + */ + private void importT11Data(Sheet sheet) { + log.info("开始导入T11数据(蓝球组红球的面系数)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行,应该有33行数据 + int lastRowNum = sheet.getLastRowNum(); + + // 计算组数,每组占用3列,从A列开始 + int totalCols = 0; + if (lastRowNum > 0) { + Row firstDataRow = sheet.getRow(1); + if (firstDataRow != null) { + totalCols = firstDataRow.getLastCellNum(); + } + } + + int groupCount = totalCols / 3; // 每组3列 + // 蓝球号码范围是1-16,所以最多16组 + groupCount = Math.min(groupCount, 16); + + log.info("检测到{}组数据,共{}列,预期33行数据", groupCount, totalCols); + + // 遍历每组数据(蓝球1-16号) + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 蓝球号从1开始 + int faceCoefCol = group * 3 + 2; // 面系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(蓝球{}号),面系数列位置:{}", group + 1, masterBallNumber, faceCoefCol); + + // 遍历33行数据(红球1-33号,跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 33; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T11 entity = new T11(); + entity.setMasterBallNumber(masterBallNumber); // 蓝球号 + + // 从球号固定为行号(红球1-33) + Integer slaveBallNumber = i; + + // 面系数(从对应组的第三列读取) + Double faceCoefficient = getCellNumericValue(row.getCell(faceCoefCol)); + + if (faceCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setFaceCoefficient(roundToTwoDecimalPlaces(faceCoefficient)); + dataList.add(entity); + } else { + log.warn("第{}组第{}行面系数为空,跳过", group + 1, i); + } + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(t11Mapper::insert); + log.info("成功导入{}条T11数据(蓝球组红球的面系数)", dataList.size()); + log.info("预期数据量:16个蓝球 × 33个红球 = 528条记录"); + } else { + log.warn("未找到有效的T11数据"); + } + } + + // ==================== T10数据导入方法 ==================== + + /** + * 导入T10数据(彩票开奖信息) + * 数据结构:标准表格结构 + * A列:开奖期号,B列:开奖日期 + * C-H列:红球1-6,I列:蓝球 + */ + private void importT10Data(Sheet sheet) { + log.info("开始导入T10数据(彩票开奖信息)..."); + List dataList = new ArrayList<>(); + + // 获取数据行数,跳过标题行 + int lastRowNum = sheet.getLastRowNum(); + log.info("T10工作表共{}行数据(包含标题行)", lastRowNum + 1); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + LotteryDraws entity = new LotteryDraws(); + + // A列: 开奖期号 + Long drawId = getCellLongValue(row.getCell(0)); + if (drawId == null) { + log.warn("第{}行开奖期号为空,跳过", i + 1); + continue; + } + entity.setDrawId(drawId); + + // B列: 开奖日期 + Date drawDate = getCellDateValue(row.getCell(1)); + if (drawDate == null) { + log.warn("第{}行开奖日期为空,跳过", i + 1); + continue; + } + entity.setDrawDate(drawDate); + + // C列: 红球1 + entity.setRedBall1(getCellIntegerValue(row.getCell(2))); + + // D列: 红球2 + entity.setRedBall2(getCellIntegerValue(row.getCell(3))); + + // E列: 红球3 + entity.setRedBall3(getCellIntegerValue(row.getCell(4))); + + // F列: 红球4 + entity.setRedBall4(getCellIntegerValue(row.getCell(5))); + + // G列: 红球5 + entity.setRedBall5(getCellIntegerValue(row.getCell(6))); + + // H列: 红球6 + entity.setRedBall6(getCellIntegerValue(row.getCell(7))); + + // I列: 蓝球 + entity.setBlueBall(getCellIntegerValue(row.getCell(8))); + + // 验证必要字段 + if (entity.getRedBall1() != null && entity.getRedBall2() != null && + entity.getRedBall3() != null && entity.getRedBall4() != null && + entity.getRedBall5() != null && entity.getRedBall6() != null && + entity.getBlueBall() != null) { + dataList.add(entity); + log.debug("添加开奖记录:期号{},日期{},红球{}-{}-{}-{}-{}-{},蓝球{}", + entity.getDrawId(), entity.getDrawDate(), + entity.getRedBall1(), entity.getRedBall2(), entity.getRedBall3(), + entity.getRedBall4(), entity.getRedBall5(), entity.getRedBall6(), + entity.getBlueBall()); + } else { + log.warn("第{}行数据不完整,跳过", i + 1); + } + } + + // 批量插入 + if (!dataList.isEmpty()) { + dataList.forEach(lotteryDrawsMapper::insert); + log.info("成功导入{}条T10数据(彩票开奖信息)", dataList.size()); + } else { + log.warn("未找到有效的T10数据"); + } + } + + /** + * 获取单元格的Long值 + */ + private Long getCellLongValue(Cell cell) { + if (cell == null) return null; + + try { + switch (cell.getCellType()) { + case NUMERIC: + return (long) cell.getNumericCellValue(); + case STRING: + String strValue = cell.getStringCellValue().trim(); + if (strValue.isEmpty()) return null; + return Long.parseLong(strValue); + case FORMULA: + return (long) cell.getNumericCellValue(); + case BLANK: + return null; + default: + log.warn("不支持的单元格类型:{}", cell.getCellType()); + return null; + } + } catch (Exception e) { + log.warn("读取Long值失败:{}", e.getMessage()); + return null; + } + } + + /** + * 获取单元格的Date值 + */ + private Date getCellDateValue(Cell cell) { + if (cell == null) return null; + + try { + switch (cell.getCellType()) { + case NUMERIC: + if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue(); + } else { + // 如果是数字,尝试转换为日期 + return org.apache.poi.ss.usermodel.DateUtil.getJavaDate(cell.getNumericCellValue()); + } + case STRING: + String strValue = cell.getStringCellValue().trim(); + if (strValue.isEmpty()) return null; + // 尝试解析字符串日期,支持多种格式 + return parseStringToDate(strValue); + case FORMULA: + if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue(); + } else { + return org.apache.poi.ss.usermodel.DateUtil.getJavaDate(cell.getNumericCellValue()); + } + case BLANK: + return null; + default: + log.warn("不支持的日期单元格类型:{}", cell.getCellType()); + return null; + } + } catch (Exception e) { + log.warn("读取Date值失败:{}", e.getMessage()); + return null; + } + } + + /** + * 解析字符串为日期 + */ + private Date parseStringToDate(String dateStr) { + try { + // 支持多种日期格式 + java.text.SimpleDateFormat[] formats = { + new java.text.SimpleDateFormat("yyyy-MM-dd"), + new java.text.SimpleDateFormat("yyyy/MM/dd"), + new java.text.SimpleDateFormat("yyyy-M-d"), + new java.text.SimpleDateFormat("yyyy/M/d") + }; + + for (java.text.SimpleDateFormat format : formats) { + try { + return format.parse(dateStr); + } catch (java.text.ParseException ignored) { + // 继续尝试下一种格式 + } + } + + log.warn("无法解析日期字符串:{}", dateStr); + return null; + } catch (Exception e) { + log.warn("解析日期字符串失败:{}", e.getMessage()); + return null; + } + } + + /** + * 追加导入T10数据(彩票开奖信息),检查重复数据 + * 数据结构:标准表格结构 + * A列:开奖期号,B列:开奖日期 + * C-H列:红球1-6,I列:蓝球 + */ + private void appendT10Data(Sheet sheet) { + log.info("开始追加导入T10数据(彩票开奖信息)..."); + List dataList = new ArrayList<>(); + int duplicateCount = 0; + int newCount = 0; + + // 获取数据行数,跳过标题行 + int lastRowNum = sheet.getLastRowNum(); + log.info("T10工作表共{}行数据(包含标题行)", lastRowNum + 1); + + for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行 + Row row = sheet.getRow(i); + if (row == null) continue; + + LotteryDraws entity = new LotteryDraws(); + + // A列: 开奖期号 + Long drawId = getCellLongValue(row.getCell(0)); + if (drawId == null) { + log.warn("第{}行开奖期号为空,跳过", i + 1); + continue; + } + entity.setDrawId(drawId); + + // 检查该期号是否已存在 + LotteryDraws existingRecord = lotteryDrawsMapper.selectById(drawId); + if (existingRecord != null) { + duplicateCount++; + log.debug("开奖期号{}已存在,跳过", drawId); + continue; + } + + // B列: 开奖日期 + Date drawDate = getCellDateValue(row.getCell(1)); + if (drawDate == null) { + log.warn("第{}行开奖日期为空,跳过", i + 1); + continue; + } + entity.setDrawDate(drawDate); + + // C列: 红球1 + entity.setRedBall1(getCellIntegerValue(row.getCell(2))); + + // D列: 红球2 + entity.setRedBall2(getCellIntegerValue(row.getCell(3))); + + // E列: 红球3 + entity.setRedBall3(getCellIntegerValue(row.getCell(4))); + + // F列: 红球4 + entity.setRedBall4(getCellIntegerValue(row.getCell(5))); + + // G列: 红球5 + entity.setRedBall5(getCellIntegerValue(row.getCell(6))); + + // H列: 红球6 + entity.setRedBall6(getCellIntegerValue(row.getCell(7))); + + // I列: 蓝球 + entity.setBlueBall(getCellIntegerValue(row.getCell(8))); + + // 验证必要字段 + if (entity.getRedBall1() != null && entity.getRedBall2() != null && + entity.getRedBall3() != null && entity.getRedBall4() != null && + entity.getRedBall5() != null && entity.getRedBall6() != null && + entity.getBlueBall() != null) { + dataList.add(entity); + newCount++; + log.debug("添加新开奖记录:期号{},日期{},红球{}-{}-{}-{}-{}-{},蓝球{}", + entity.getDrawId(), entity.getDrawDate(), + entity.getRedBall1(), entity.getRedBall2(), entity.getRedBall3(), + entity.getRedBall4(), entity.getRedBall5(), entity.getRedBall6(), + entity.getBlueBall()); + } else { + log.warn("第{}行数据不完整,跳过", i + 1); + } + } + + // 批量插入新数据 + if (!dataList.isEmpty()) { + dataList.forEach(lotteryDrawsMapper::insert); + log.info("成功追加导入{}条新的T10数据(彩票开奖信息)", dataList.size()); + } else { + log.info("没有新的T10数据需要导入"); + } + + log.info("追加导入统计:新增{}条,跳过重复{}条", newCount, duplicateCount); + } + + /** + * 读取并保存T3表数据 + * @param filePath 文件路径 + * @throws IOException IO异常 + */ + public void readAndSaveT3Data(String filePath) throws IOException { + log.info("开始读取并保存T3表数据,文件路径: {}", filePath); + try (InputStream inputStream = new FileInputStream(filePath)) { + readAndSaveT3Data(inputStream); + } + } + + public void readAndSaveT3Data(InputStream inputStream) throws IOException { + log.info("开始读取并保存T3表数据..."); + List dataList; + try (Workbook workbook = new XSSFWorkbook(inputStream)) { + Sheet sheet = workbook.getSheet("T3"); + if (sheet == null) { + log.warn("在提供的文件中未找到T3工作表"); + return; + } + dataList = readT3DataFromSheet(sheet); + } + + if (!dataList.isEmpty()) { + // 清空T3表 + t3Service.remove(null); + log.info("已清空T3表"); + t3Service.saveBatch(dataList); + log.info("成功保存 {} 条T3数据", dataList.size()); + } else { + log.warn("没有读取到T3数据"); + } + } + + private List readT3DataFromSheet(Sheet sheet) { + List dataList = new ArrayList<>(); + + int lastRowNum = sheet.getLastRowNum(); + int groupCount = 33; // T3表有33组数据 + + // 遍历每组数据 + for (int group = 0; group < groupCount; group++) { + int masterBallNumber = group + 1; // 主球号从1开始 + int slaveBallCol = group * 3 + 1; // 从球号列:1,4,7,10...(B,E,H,K列) + int lineCoefCol = group * 3 + 2; // 线系数列:2,5,8,11...(C,F,I,L列) + + log.info("处理第{}组数据(主球{}号),从球号列: {}, 线系数列: {}", group + 1, masterBallNumber, slaveBallCol, lineCoefCol); + + // 遍历33行数据(跳过标题行) + for (int i = 1; i <= lastRowNum && i <= 33; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + T3 entity = new T3(); + entity.setMasterBallNumber(masterBallNumber); + + // 从对应组的第一列读取从球号 + Double slaveBallDouble = getCellNumericValue(row.getCell(slaveBallCol)); + Integer slaveBallNumber = (slaveBallDouble != null) ? slaveBallDouble.intValue() : null; + + // 线系数(从对应组的第二列读取) + Double lineCoefficient = getCellNumericValue(row.getCell(lineCoefCol)); + + if (slaveBallNumber != null && lineCoefficient != null) { + entity.setSlaveBallNumber(slaveBallNumber); + entity.setLineCoefficient(lineCoefficient); + dataList.add(entity); + } else { + log.warn("第{}组第{}行从球号或线系数为空,跳过", group + 1, i); + } + } + } + return dataList; + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/util/ExcelTestRunner.java b/src/main/java/com/xy/xyaicpzs/util/ExcelTestRunner.java new file mode 100644 index 0000000..bdc81b7 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/util/ExcelTestRunner.java @@ -0,0 +1,48 @@ +package com.xy.xyaicpzs.util; + +import com.xy.xyaicpzs.service.ExcelImportService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * Excel导入测试运行器 + * 可以在应用启动时自动执行Excel导入(需要手动启用) + */ +@Slf4j +@Component +public class ExcelTestRunner implements CommandLineRunner { + + @Autowired + private ExcelImportService excelImportService; + + @Override + public void run(String... args) throws Exception { + // 默认不执行,如果需要在启动时自动导入,请取消注释以下代码 + /* + log.info("开始执行Excel数据导入测试..."); + try { + // 请根据实际情况修改文件路径 + String filePath = "kaifa1.xlsx"; + String result = excelImportService.importExcelFileByPath(filePath); + log.info("导入结果:{}", result); + } catch (Exception e) { + log.error("导入失败:{}", e.getMessage(), e); + } + */ + } + + /** + * 手动执行导入的方法 + */ + public void manualImport(String filePath) { + log.info("手动执行Excel数据导入,文件路径:{}", filePath); + try { + String result = excelImportService.importExcelFileByPath(filePath); + log.info("导入结果:{}", result); + } catch (Exception e) { + log.error("导入失败:{}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/util/JwtUtil.java b/src/main/java/com/xy/xyaicpzs/util/JwtUtil.java new file mode 100644 index 0000000..c8739d3 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/util/JwtUtil.java @@ -0,0 +1,140 @@ +package com.xy.xyaicpzs.util; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.time.Instant; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * JWT工具类,用于生成和验证JWT令牌 + */ +@Component +public class JwtUtil { + + private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class); + + private static final String COZE_APP_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" + + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7ZkUY3DNf0wf0\n" + + "K4MX9oytqYl2HFfZ8O5qZvN/MaLcyojzios97DZba9kj0ZBkhQNAZe5IZkBZ1Vud\n" + + "sQu3sxXHW1YEazDqMDEm8x8QspCXniiNUb9RX3kk+vxIczqXhn/xxAIcR1jnq2Pr\n" + + "Pt0j8kKr9FjhS1xuKEzBhU2YGJfMzN/ARqr7Q9zw5ONYjU8s6ejkUw240m/TvyMl\n" + + "eSBNkqLfWM8o7CMPCcvAnvGw7n7lpxQ8EQV4J5rfjl02cW5wZHLEtOEGlcQsx1KF\n" + + "gukcRkpGi6M7ifAENtqUrqZXghq7BlVRDDk3gXLP++fyOklL57eyhdKaY/bIlsXn\n" + + "N9WQc/YJAgMBAAECggEAEvH8Y06DrRjXEYLCno4Q28+rc3LbGM/oMn6U+FNqzRp2\n" + + "rPRhLlHujuCA08OwbtEZqo2DgPNBZzOQLwmCj0A+H+jmcczqZYqYtYDXr6b1wjY9\n" + + "kEfm6RGXXDs5fROVJVN2JNl1gyldXhJwKAyza5pmzh6GS8SEJCjT1a6l0Q4PbqdN\n" + + "XIKJzwXKZO0LCqlA3mQV5liEDe5XQM3ygkdYgLFvl+lUHws9TfCxpvKgn87b3OmT\n" + + "9k9bbWN1TOfP64Fhdwho2hoH0G7jiYjvm1fUuMxX0cYjIAmcuwokj9l/aTBBzc8+\n" + + "XT1zGxZ1ewSd0Xuc9+Xn+lKCScgSkbpzMZcQ5Eka3wKBgQDgrXIpI59V1U5jYiNn\n" + + "WX0G+8/UyraNxzv3rl+cJX43bvAN9KYgCq6qnJBdFDPF3Z9jEIU3LE06fz1gxrN4\n" + + "NbdM2GpnBQJ/wkMM5EG+0Zec01n5PZdES6NWbA5AZlRmsAxE71L2OOwbj0gVnyAj\n" + + "w5f9m44YaL2ZWpLbY93XKmEWzwKBgQDVhmbqdDjEl7xxt2H7xvJjCoSPLGruMfIH\n" + + "94o7xAIYCyjnNc4aTyQawo+cfzq+wjtRbZEvz4S6CtfrNfJHlgrLEF1V4WaaKHcN\n" + + "V43IdC18H4/8F502D4SZCwvhdmXdYjOcBbGZD3w5HZOBuH4RYcspplsj4Ot+w2Lz\n" + + "YQy8kHXbpwKBgHYZleWcDPggTLke7/82YesW2FNBTx5NeO8joKxCZQscbGDZla1I\n" + + "EDIsZBIZOXGrokl/eJbc2aeDFK9XIyVwDu7830lRr9OaOIaBQTHdmDVeP3As+ON0\n" + + "YuJdoEwnvfvQVFKz/kbg+vMtqLV81HcYLD+p0dJw1CDVJFbgMs8UPr6vAoGBAK+2\n" + + "MXzgdVK6dzWxLi3OMurz3dAgQkKP0VdjCltSWlLE5D0YVunplJF86Edln8cY+U1x\n" + + "99c7U0Lx52tE8oKcY3dlmRkyKofTotzU3vVFPaT2KDvQhuvU604x++3my77ZsBTF\n" + + "zrdhOd2ajCdk1kGhk1lL75Zf4gtn6EbV53BJBOPjAoGASVU6chk0zAEg7c9xOjCd\n" + + "uFlGeNqfiTJGL6aHHaaJN3EhCeWc36l4NGJ/JwWCm0ETydzYAtcUaj2biUAlEm0Q\n" + + "s1Vgl2ulxkpw32IclM0oND1VdJfwZRzcl4OO9jyF+993icaY+dAtZ9U37Jk9QazY\n" + + "L+Cmvmq59YO4yS9+WeBEGV8=\n" + + "-----END PRIVATE KEY-----"; + + private static final String COZE_APP_ID = "1102723433113"; + private static final String COZE_APP_FINGERPRINT = "WNHPUWKXL_PDNeynptov7GsiwW1eqgPP-2OfCIFlEc0"; + private static final String COZE_API_ENDPOINT = "api.coze.cn"; + + /** + * 生成JWT令牌 + * + * @param expireSeconds 过期时间(秒) + * @param sessionName 会话名称(可选) + * @param deviceId 设备ID(可选) + * @return JWT令牌字符串 + */ + public String generateToken(int expireSeconds, String sessionName, String deviceId) { + try { + // 当前时间戳(秒) + long currentTimeSeconds = Instant.now().getEpochSecond(); + + // 构建Header + Map headers = new HashMap<>(); + headers.put("alg", "RS256"); // 固定为RS256 + headers.put("typ", "JWT"); // 固定为JWT + headers.put("kid", COZE_APP_FINGERPRINT); // OAuth应用的公钥指纹 + + // 构建Payload + Map claims = new HashMap<>(); + claims.put("iss", COZE_APP_ID); // OAuth应用的ID + claims.put("aud", COZE_API_ENDPOINT); // 扣子API的Endpoint + claims.put("iat", currentTimeSeconds); // JWT开始生效的时间 + claims.put("exp", currentTimeSeconds + expireSeconds); // JWT过期的时间 + claims.put("jti", UUID.randomUUID().toString()); // 随机字符串,防止重放攻击 + + // 可选参数 + if (sessionName != null && !sessionName.isEmpty()) { + claims.put("session_name", sessionName); + } + + // 如果提供了设备ID,则添加设备信息 + if (deviceId != null && !deviceId.isEmpty()) { + Map sessionContext = new HashMap<>(); + Map deviceInfo = new HashMap<>(); + deviceInfo.put("device_id", deviceId); + sessionContext.put("device_info", deviceInfo); + claims.put("session_context", sessionContext); + } + + // 从私钥字符串中获取PrivateKey对象 + PrivateKey privateKey = getPrivateKeyFromString(COZE_APP_PRIVATE_KEY); + + // 生成JWT + return Jwts.builder() + .setHeader(headers) + .setClaims(claims) + .signWith(privateKey, SignatureAlgorithm.RS256) + .compact(); + } catch (Exception e) { + logger.error("JWT生成失败", e); + throw new RuntimeException("JWT生成失败: " + e.getMessage()); + } + } + + /** + * 从字符串中获取PrivateKey对象 + * + * @param privateKeyStr 私钥字符串(PEM格式) + * @return PrivateKey对象 + */ + private PrivateKey getPrivateKeyFromString(String privateKeyStr) throws Exception { + // 去除PEM格式的头尾和换行符 + String privateKeyPEM = privateKeyStr + .replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replaceAll("\\s", ""); + + // Base64解码 + byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyPEM); + + // 生成PKCS8EncodedKeySpec对象 + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); + + // 获取KeyFactory实例 + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + // 生成PrivateKey对象 + return keyFactory.generatePrivate(keySpec); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/util/SpeechRecognizerDemo.java b/src/main/java/com/xy/xyaicpzs/util/SpeechRecognizerDemo.java new file mode 100644 index 0000000..2be8814 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/util/SpeechRecognizerDemo.java @@ -0,0 +1,231 @@ +package com.xy.xyaicpzs.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.concurrent.CompletableFuture; + +import com.alibaba.nls.client.AccessToken; +import com.alibaba.nls.client.protocol.InputFormatEnum; +import com.alibaba.nls.client.protocol.NlsClient; +import com.alibaba.nls.client.protocol.SampleRateEnum; +import com.alibaba.nls.client.protocol.asr.SpeechRecognizer; +import com.alibaba.nls.client.protocol.asr.SpeechRecognizerListener; +import com.alibaba.nls.client.protocol.asr.SpeechRecognizerResponse; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * 语音识别服务类 + * 可以将语音文件转换为文本 + */ +@Service +public class SpeechRecognizerDemo { + private static final Logger logger = LoggerFactory.getLogger(SpeechRecognizerDemo.class); + private String appKey; + private NlsClient client; + + @Value("${aliyun.speech.app-key:}") + private String nLsAppKey; + + @Value("${aliyun.speech.access-key-id}") + private String accessKeyId; + + @Value("${aliyun.speech.access-key-secret}") + private String accessKeySecret; + + @Value("${aliyun.speech.gateway-url}") + private String gatewayUrl; + + public SpeechRecognizerDemo() { + } + + @PostConstruct + public void initialize() { + this.appKey = nLsAppKey; + AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret); + try { + accessToken.apply(); + logger.info("get token: " + accessToken.getToken() + ", expire time: " + accessToken.getExpireTime()); + if(gatewayUrl.isEmpty()) { + client = new NlsClient(accessToken.getToken()); + } else { + client = new NlsClient(gatewayUrl, accessToken.getToken()); + } + } catch (IOException e) { + logger.error("初始化语音识别客户端失败", e); + } + } + + public SpeechRecognizerDemo(String appKey, String id, String secret, String url) { + this.appKey = appKey; + //应用全局创建一个NlsClient实例,默认服务地址为阿里云线上服务地址。 + //获取Token,实际使用时注意在accessToken.getExpireTime()过期前再次获取。 + AccessToken accessToken = new AccessToken(id, secret); + try { + accessToken.apply(); + System.out.println("get token: " + accessToken.getToken() + ", expire time: " + accessToken.getExpireTime()); + if(url.isEmpty()) { + client = new NlsClient(accessToken.getToken()); + } else { + client = new NlsClient(url, accessToken.getToken()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 获取语音识别监听器 + */ + private static SpeechRecognizerListener getRecognizerListener(CompletableFuture resultFuture) { + SpeechRecognizerListener listener = new SpeechRecognizerListener() { + // 最终识别结果 + private String finalResult = ""; + + //识别出中间结果。仅当setEnableIntermediateResult为true时,才会返回该消息。 + @Override + public void onRecognitionResultChanged(SpeechRecognizerResponse response) { + //getName是获取事件名称,getStatus是获取状态码,getRecognizedText是语音识别文本。 + logger.info("name: " + response.getName() + ", status: " + response.getStatus() + ", result: " + response.getRecognizedText()); + } + + //识别完毕 + @Override + public void onRecognitionCompleted(SpeechRecognizerResponse response) { + //getName是获取事件名称,getStatus是获取状态码,getRecognizedText是语音识别文本。 + logger.info("name: " + response.getName() + ", status: " + response.getStatus() + ", result: " + response.getRecognizedText()); + finalResult = response.getRecognizedText(); + resultFuture.complete(finalResult); + } + + @Override + public void onStarted(SpeechRecognizerResponse response) { + logger.info("task_id: " + response.getTaskId() + " started"); + } + + @Override + public void onFail(SpeechRecognizerResponse response) { + //task_id是调用方和服务端通信的唯一标识,当遇到问题时,需要提供此task_id。 + logger.error("task_id: " + response.getTaskId() + ", status: " + response.getStatus() + ", status_text: " + response.getStatusText()); + resultFuture.completeExceptionally(new RuntimeException("语音识别失败: " + response.getStatusText())); + } + }; + return listener; + } + + //根据二进制数据大小计算对应的同等语音长度 + //sampleRate仅支持8000或16000。 + public static int getSleepDelta(int dataSize, int sampleRate) { + // 仅支持16位采样。 + int sampleBytes = 16; + // 仅支持单通道。 + int soundChannel = 1; + return (dataSize * 10 * 8000) / (160 * sampleRate); + } + + /** + * 将语音文件转换为文本 + * @param filepath 语音文件路径 + * @param sampleRate 采样率 + * @return 识别出的文本 + */ + public String speechToText(String filepath, int sampleRate) { + CompletableFuture resultFuture = new CompletableFuture<>(); + + try { + process(filepath, sampleRate, resultFuture); + // 等待异步结果完成 + return resultFuture.get(); + } catch (Exception e) { + logger.error("语音识别失败", e); + return "语音识别失败: " + e.getMessage(); + } + } + + private void process(String filepath, int sampleRate, CompletableFuture resultFuture) { + SpeechRecognizer recognizer = null; + try { + SpeechRecognizerListener listener = getRecognizerListener(resultFuture); + recognizer = new SpeechRecognizer(client, listener); + recognizer.setAppKey(appKey); + //设置音频编码格式。如果是OPUS文件,请设置为InputFormatEnum.OPUS。 + recognizer.setFormat(InputFormatEnum.PCM); + //设置音频采样率 + if(sampleRate == 16000) { + recognizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K); + } else if(sampleRate == 8000) { + recognizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_8K); + } + //设置是否返回中间识别结果 + recognizer.setEnableIntermediateResult(true); + //设置是否打开语音检测(即vad) + recognizer.addCustomedParam("enable_voice_detection",true); + //此方法将以上参数设置序列化为JSON发送给服务端,并等待服务端确认。 + long now = System.currentTimeMillis(); + recognizer.start(); + logger.info("ASR start latency : " + (System.currentTimeMillis() - now) + " ms"); + File file = new File(filepath); + FileInputStream fis = new FileInputStream(file); + byte[] b = new byte[3200]; + int len; + while ((len = fis.read(b)) > 0) { + logger.debug("send data pack length: " + len); + recognizer.send(b, len); + //本案例用读取本地文件的形式模拟实时获取语音流,因为读取速度较快,这里需要设置sleep时长。 + // 如果实时获取语音则无需设置sleep时长,如果是8k采样率语音第二个参数设置为8000。 + int deltaSleep = getSleepDelta(len, sampleRate); + Thread.sleep(deltaSleep); + } + //通知服务端语音数据发送完毕,等待服务端处理完成。 + now = System.currentTimeMillis(); + //计算实际延迟,调用stop返回之后一般即是识别结果返回时间。 + logger.info("ASR wait for complete"); + recognizer.stop(); + logger.info("ASR stop latency : " + (System.currentTimeMillis() - now) + " ms"); + fis.close(); + } catch (Exception e) { + logger.error("语音识别处理异常", e); + resultFuture.completeExceptionally(e); + } finally { + //关闭连接 + if (null != recognizer) { + recognizer.close(); + } + } + } + + public void process(String filepath, int sampleRate) { + CompletableFuture resultFuture = new CompletableFuture<>(); + process(filepath, sampleRate, resultFuture); + } + + public void shutdown() { + if (client != null) { + client.shutdown(); + } + } + + public static void main(String[] args) throws Exception { + // 这个main方法用于独立测试,实际应用中不会使用 + SpeechRecognizerDemo demo = new SpeechRecognizerDemo(); + // 手动设置参数进行测试 + demo.appKey = System.getenv().getOrDefault("NLS_APP_KEY", ""); + String id = System.getenv().getOrDefault("ALIYUN_AK_ID", ""); + String secret = System.getenv().getOrDefault("ALIYUN_AK_SECRET", ""); + String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", "wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1"); + + // 初始化客户端 + AccessToken accessToken = new AccessToken(id, secret); + accessToken.apply(); + demo.client = new NlsClient(url, accessToken.getToken()); + + //转换为接口调用方式 + String result = demo.speechToText("D:\\code\\xy-ai-cpzs\\nls-sample-16k.wav", 16000); + System.out.println("语音识别结果: " + result); + demo.shutdown(); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..c21ab00 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,75 @@ +spring: + application: + name: xy-ai-cpzs + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/cpzs + username: root + password: root +# datasource: +# driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://47.117.22.239:3306/cpzs +# username: cpzs_root +# password: cpzs_123456 + data: + redis: + host: localhost + port: 6379 + database: 0 +# data: +# redis: +# host: 47.117.22.239 +# port: 6379 +# database: 0 +# password: cpzs_123456 +server: + port: 8123 + servlet: + context-path: /api + session: + timeout: 86400 +# springdoc-openapi +springdoc: + swagger-ui: + path: /swagger-ui.html + tags-sorter: alpha + operations-sorter: alpha + api-docs: + path: /v3/api-docs + group-configs: + - group: 'default' + paths-to-match: '/**' + packages-to-scan: com.xy.xyaicpzs.controller +# knife4j +knife4j: + enable: true + setting: + language: zh_cn +mybatis-plus: + configuration: + # MyBatis ?? + map-underscore-to-camel-case: false + # ?????????? + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + global-config: + db-config: + logic-delete-field: isDelete # ???????????? + logic-delete-value: 1 # ?????????? 1? + logic-not-delete-value: 0 # ?????????? 0? + +# DashScope API配置 +dashscope: + api-key: sk-2ca3c5503a594147bffb0a8be73a125a + +# 阿里云语音识别服务配置 +aliyun: + speech: + app-key: scUTVRDNy1LVzsYz + access-key-id: LTAI5tR18rXPYazi3y8kAuep + access-key-secret: KZ1aKZOupilVc332SXE1g1DfKsqHPu + gateway-url: wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1 + sms: + sign-name: 西安精彩数据服务社 + template-code: SMS_489840017 + access-key-id: LTAI5tR18rXPYazi3y8kAuep + access-key-secret: KZ1aKZOupilVc332SXE1g1DfKsqHPu \ No newline at end of file diff --git a/src/main/resources/generator/mapper/BlueHistory100Mapper.xml b/src/main/resources/generator/mapper/BlueHistory100Mapper.xml new file mode 100644 index 0000000..c5d79dc --- /dev/null +++ b/src/main/resources/generator/mapper/BlueHistory100Mapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + id,ballNumber,frequencyCount,averageInterval,nowInterval,maxConsecutiveCount, + pointCoefficient + + diff --git a/src/main/resources/generator/mapper/BlueHistoryAllMapper.xml b/src/main/resources/generator/mapper/BlueHistoryAllMapper.xml new file mode 100644 index 0000000..d307cda --- /dev/null +++ b/src/main/resources/generator/mapper/BlueHistoryAllMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + id,ballNumber,frequencyCount,frequencyPercentage,averageInterval,maxHiddenInterval, + maxConsecutiveCount,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/BlueHistoryTop100Mapper.xml b/src/main/resources/generator/mapper/BlueHistoryTop100Mapper.xml new file mode 100644 index 0000000..e1dc984 --- /dev/null +++ b/src/main/resources/generator/mapper/BlueHistoryTop100Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,no,ballNumber,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/BlueHistoryTopMapper.xml b/src/main/resources/generator/mapper/BlueHistoryTopMapper.xml new file mode 100644 index 0000000..bc33554 --- /dev/null +++ b/src/main/resources/generator/mapper/BlueHistoryTopMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,no,ballNumber,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/ChatMessageMapper.xml b/src/main/resources/generator/mapper/ChatMessageMapper.xml new file mode 100644 index 0000000..df9fdfd --- /dev/null +++ b/src/main/resources/generator/mapper/ChatMessageMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + id,conversationId,studentId,messageType,content,createTime, + updateTime,isDelete + + diff --git a/src/main/resources/generator/mapper/History100Mapper.xml b/src/main/resources/generator/mapper/History100Mapper.xml new file mode 100644 index 0000000..4b6dcf7 --- /dev/null +++ b/src/main/resources/generator/mapper/History100Mapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + id,ballNumber,frequencyCount,averageInterval,nowInterval,maxConsecutiveCount, + pointCoefficient + + diff --git a/src/main/resources/generator/mapper/HistoryAllMapper.xml b/src/main/resources/generator/mapper/HistoryAllMapper.xml new file mode 100644 index 0000000..42abea0 --- /dev/null +++ b/src/main/resources/generator/mapper/HistoryAllMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + id,ballNumber,frequencyCount,frequencyPercentage,averageInterval,maxHiddenInterval, + maxConsecutiveCount,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/HistoryTop100Mapper.xml b/src/main/resources/generator/mapper/HistoryTop100Mapper.xml new file mode 100644 index 0000000..de06ff6 --- /dev/null +++ b/src/main/resources/generator/mapper/HistoryTop100Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,no,ballNumber,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/HistoryTopMapper.xml b/src/main/resources/generator/mapper/HistoryTopMapper.xml new file mode 100644 index 0000000..b9a5296 --- /dev/null +++ b/src/main/resources/generator/mapper/HistoryTopMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,no,ballNumber,pointCoefficient + + diff --git a/src/main/resources/generator/mapper/LotteryDrawsMapper.xml b/src/main/resources/generator/mapper/LotteryDrawsMapper.xml new file mode 100644 index 0000000..7ff8e2a --- /dev/null +++ b/src/main/resources/generator/mapper/LotteryDrawsMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + drawId,drawDate,redBall1,redBall2,redBall3,redBall4, + redBall5,redBall6,blueBall + + diff --git a/src/main/resources/generator/mapper/OperationHistoryMapper.xml b/src/main/resources/generator/mapper/OperationHistoryMapper.xml new file mode 100644 index 0000000..fd1da29 --- /dev/null +++ b/src/main/resources/generator/mapper/OperationHistoryMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + id,userId,operationType,operationModule,operationResult,resultMessage, + operationTime,updateTime + + diff --git a/src/main/resources/generator/mapper/PredictRecordMapper.xml b/src/main/resources/generator/mapper/PredictRecordMapper.xml new file mode 100644 index 0000000..818ef7e --- /dev/null +++ b/src/main/resources/generator/mapper/PredictRecordMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id,userId,drawId,drawDate,redBall1,redBall2, + redBall3,redBall4,redBall5,redBall6,blueBall, + predictStatus,predictResult,predictTime,bonus,type + + diff --git a/src/main/resources/generator/mapper/T11Mapper.xml b/src/main/resources/generator/mapper/T11Mapper.xml new file mode 100644 index 0000000..3a01e2c --- /dev/null +++ b/src/main/resources/generator/mapper/T11Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,faceCoefficient + + diff --git a/src/main/resources/generator/mapper/T3Mapper.xml b/src/main/resources/generator/mapper/T3Mapper.xml new file mode 100644 index 0000000..8b15c33 --- /dev/null +++ b/src/main/resources/generator/mapper/T3Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,lineCoefficient + + diff --git a/src/main/resources/generator/mapper/T4Mapper.xml b/src/main/resources/generator/mapper/T4Mapper.xml new file mode 100644 index 0000000..60f9f16 --- /dev/null +++ b/src/main/resources/generator/mapper/T4Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,lineCoefficient + + diff --git a/src/main/resources/generator/mapper/T5Mapper.xml b/src/main/resources/generator/mapper/T5Mapper.xml new file mode 100644 index 0000000..d6af954 --- /dev/null +++ b/src/main/resources/generator/mapper/T5Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,lineCoefficient + + diff --git a/src/main/resources/generator/mapper/T6Mapper.xml b/src/main/resources/generator/mapper/T6Mapper.xml new file mode 100644 index 0000000..6aa4cd3 --- /dev/null +++ b/src/main/resources/generator/mapper/T6Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,lineCoefficient + + diff --git a/src/main/resources/generator/mapper/T7Mapper.xml b/src/main/resources/generator/mapper/T7Mapper.xml new file mode 100644 index 0000000..1800877 --- /dev/null +++ b/src/main/resources/generator/mapper/T7Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,faceCoefficient + + diff --git a/src/main/resources/generator/mapper/T8Mapper.xml b/src/main/resources/generator/mapper/T8Mapper.xml new file mode 100644 index 0000000..6307f14 --- /dev/null +++ b/src/main/resources/generator/mapper/T8Mapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + id,masterBallNumber,slaveBallNumber,faceCoefficient + + diff --git a/src/main/resources/generator/mapper/UserMapper.xml b/src/main/resources/generator/mapper/UserMapper.xml new file mode 100644 index 0000000..667f48a --- /dev/null +++ b/src/main/resources/generator/mapper/UserMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + id,userName,userAccount,phone,userAvatar,gender,userRole, + userPassword,isVip,vipExpire,status,createTime,updateTime, + isDelete + + diff --git a/src/main/resources/generator/mapper/VipCodeMapper.xml b/src/main/resources/generator/mapper/VipCodeMapper.xml new file mode 100644 index 0000000..49ebd62 --- /dev/null +++ b/src/main/resources/generator/mapper/VipCodeMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + id,code,vipExpireTime, + vipNumber,isUse,createdUserId,createdUserName + usedUserId,usedUserName,createTime,updateTime + + + \ No newline at end of file diff --git a/src/main/resources/generator/mapper/VipExchangeRecordMapper.xml b/src/main/resources/generator/mapper/VipExchangeRecordMapper.xml new file mode 100644 index 0000000..b34f08b --- /dev/null +++ b/src/main/resources/generator/mapper/VipExchangeRecordMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + id,userId,type,exchangeMode,orderNo,orderAmount, + isUse,exchangeTime,updateTime + + diff --git a/src/main/resources/private_key.pem b/src/main/resources/private_key.pem new file mode 100644 index 0000000..ee03bdb --- /dev/null +++ b/src/main/resources/private_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCZ1yKyaaWauaTX +7UhYFQsbZ87oHIHRdb74FPv3qtwpFFCVcNNKbK9uI2IrrrSUmVpExn89r1wT7KkW +pkohlI2EysBLuRlFAe2mr/2UGJD1VwHIla3GVgOEnIlnvFCLGFHDbEQB32XUmGuJ +7Q5aB+4p8pXtEOatv0wtp09g6nAF5i/YXgD9F/L9ejHN7UDAZV7XI5316bEg5suC +HZM40eEM+060A1oTM4byn7DocW5JUfktozIe61VUKFWXsI8dSXv9cMuia9e1sde3 +T+M2ykBkUX/XKUpLCOejZR2tlBnF4JdtYcydRtzT/9GzU4roz6i83OVD9dHKqwAz +NUar6Qr1AgMBAAECggEABynJjjmq8fYAII7GU4BNV1jBfV+AcEv1g7CEcqnkck7l +bq6azrMaBbyaNbL+6mbBRC+4R9tvuTzH5cuslXzeNxHyxhkyaEXDTAOTVjnrnATn +CsY6GctdAr0q4mdAxS1GzLJF8Llh0OD1AZkwayLwj8hMJgZSBhfreI+7EOXxp+Xs +u76AVuI8OwpXeRjs+dkoMGYIRasBcUL4PLZlWFd5EHuEx5PvI+yCAbLY2oQEViqX +hSnmrdybrjbp0cBh3cvSh4UqTCfuHcH82KAh2+u+vlSkPEAl5mkiXKXvVKXrrkIf +TUDFnv20hTMJwyggd0BuWQjusm/1hjUxVNZ2TppEuQKBgQDQYDtJxBX287VqKiDe +JN2QTYVDIwBmqD4YhoR9OxtLFEUmSGVVVGWzD9DoB2SUkV1lheOiYc3N89w1p6dy +K3wxzNLVKNKvsUw1k8QsX61BSk7xyzDYgcg19EmowcISV1eU2Xa/9p4Wgsh3chad +sNwjUlRFWo3BRX4CbmBLrMnirQKBgQC9ABwqS7AsoTpCyi4R6NTvL/vLflU+AU26 +AeK5KOzgyr1H1h6pLvCQeCVSG64H/W/frIXPDeYtooHhyePpW475OHABgfYVpnjy +j0qaKobqeNns2HNGqxWF+WG3lFmgAd014zW3Q1N6SQEFvxOdNC9QImKPiTZng9mp +05YLDJuaaQKBgHRNsenLQ0Mx5Yja+LtksjHPwtilGZ0yvG3t7tcC/YnbR3lFoSGO +WLEn278WGUJ/HDUFFPfWRQt11+wuplwn/0rAetC011tuxw2Ea1MlF8vAUO3OLnY5 +gejzb4V8l/iqvVx8QDaGzNfdqUxZ5lufkk84rYaEM2izg9CRkLfMOmaFAoGAHbQy +uQMEQT9lpLGZ4/6v2Je1/xlv1DroOF+rfmZMNFgov22LjBNwg4QeeXUYOPE/7+tx +bEVG880ilJXiV/6nzcts7w+52VU8lQKoOuqMIbW0qmCqXWTuEQxMq0mJfHhOh/WZ +r5/JMuLeYkTRlFdrSDDfRKfQARzbzLEQV9Q3cGECgYB/xL4h2CyBroQFNlu/PuP3 +AqO8Aexj42EAzfB6whb6UbyrFF94cNxdxBiLVMEw3cDHidpc8OwAksM8DPrrpKBJ +ARC0Tishf9DimuFjA0aamLu9jIxm+kNrvY51mmyqdAl/BS2UJN4hYk9Y4bR/bt8E +llF8Ty61JhMnJgiFqt4Yog== +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java b/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java new file mode 100644 index 0000000..170ffa5 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/BallAnalysisFrequencyTest.java @@ -0,0 +1,173 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.mapper.T7Mapper; +import com.xy.xyaicpzs.service.BallAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +/** + * 球号分析算法频次筛选测试 + * 验证当频次相同的球号超过11个时,使用T3表线系数进行二次筛选的功能 + */ +@Slf4j +@SpringBootTest +public class BallAnalysisFrequencyTest { + + @Autowired + private BallAnalysisService ballAnalysisService; + + /** + * 测试高位算法的频次筛选功能 + */ + @Test + public void testHighLevelFrequencySelection() { + log.info("=== 测试高位算法的频次筛选功能 ==="); + + // 输入参数 + String level = "H"; + List redBalls = Arrays.asList(7, 24, 27, 21, 10, 5); + Integer blueBall = 16; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("高位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + } + + /** + * 测试中位算法的频次筛选功能 + */ + @Test + public void testMiddleLevelFrequencySelection() { + log.info("=== 测试中位算法的频次筛选功能 ==="); + + // 输入参数 + String level = "M"; + List redBalls = Arrays.asList(2, 9, 14, 20, 25, 32); + Integer blueBall = 12; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("中位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + } + + /** + * 测试低位算法的频次筛选功能 + */ + @Test + public void testLowLevelFrequencySelection() { + log.info("=== 测试低位算法的频次筛选功能 ==="); + + // 输入参数 + String level = "L"; + List redBalls = Arrays.asList(3, 7, 11, 17, 22, 29); + Integer blueBall = 8; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("低位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + } + + /** + * 测试用户提供的示例场景 + * 模拟频次相同导致超过11个球号的情况 + */ + @Test + public void testUserExampleScenario() { + log.info("=== 测试用户示例场景 ==="); + log.info("模拟场景:"); + log.info("26出现了8次 - 直接选择"); + log.info("17出现了7次 - 直接选择"); + log.info("14出现了7次 - 直接选择"); + log.info("7出现了6次 - 直接选择"); + log.info("3出现了6次 - 直接选择"); + log.info("20出现了6次 - 直接选择"); + log.info("2,9,1,22,32,13出现了5次 - 需要T3表线系数筛选"); + + // 使用特定的红球和蓝球组合来模拟这种情况 + String level = "H"; + List redBalls = Arrays.asList(26, 17, 14, 7, 3, 20); + Integer blueBall = 2; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("示例场景结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("频次筛选测试完成!"); + } + + /** + * 测试边界情况:恰好11个球号 + */ + @Test + public void testExactly11Balls() { + log.info("=== 测试边界情况:恰好11个球号 ==="); + + String level = "M"; + List redBalls = Arrays.asList(5, 10, 15, 18, 24, 30); + Integer blueBall = 6; + + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + log.info("边界情况结果:{}", result); + assert result.size() == 11 : "结果应该包含11个球号"; + } + + /** + * 测试极端情况:验证T3表线系数筛选的稳定性 + */ + @Test + public void testT3LineCoefficientStability() { + log.info("=== 测试T3表线系数筛选的稳定性 ==="); + + String level = "H"; + List redBalls = Arrays.asList(1, 2, 3, 4, 5, 6); + Integer blueBall = 1; + + // 多次执行同样的分析,结果应该一致 + List result1 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + List result2 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + log.info("第一次结果:{}", result1); + log.info("第二次结果:{}", result2); + + assert result1.equals(result2) : "相同输入应该产生相同输出"; + log.info("T3表线系数筛选稳定性测试通过!"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java b/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java new file mode 100644 index 0000000..3123fba --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/BallAnalysisMultiLevelFilteringTest.java @@ -0,0 +1,232 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.BallAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +/** + * 球号分析多级筛选测试 + * 测试analyzeBalls方法的多级筛选功能 + */ +@Slf4j +@SpringBootTest +public class BallAnalysisMultiLevelFilteringTest { + + @Autowired + private BallAnalysisService ballAnalysisService; + + /** + * 测试高位算法的多级筛选 + */ + @Test + public void testHighLevelMultiLevelFiltering() { + log.info("=== 测试高位算法的多级筛选 ==="); + + // 输入参数 + String level = "H"; + List redBalls = Arrays.asList(1, 5, 12, 18, 25, 33); + Integer blueBall = 8; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("高位算法多级筛选结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("高位算法多级筛选测试通过!"); + } + + /** + * 测试中位算法的多级筛选 + */ + @Test + public void testMiddleLevelMultiLevelFiltering() { + log.info("=== 测试中位算法的多级筛选 ==="); + + // 输入参数 + String level = "M"; + List redBalls = Arrays.asList(2, 8, 15, 22, 28, 31); + Integer blueBall = 12; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("中位算法多级筛选结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("中位算法多级筛选测试通过!"); + } + + /** + * 测试低位算法的多级筛选 + */ + @Test + public void testLowLevelMultiLevelFiltering() { + log.info("=== 测试低位算法的多级筛选 ==="); + + // 输入参数 + String level = "L"; + List redBalls = Arrays.asList(3, 9, 16, 23, 29, 32); + Integer blueBall = 4; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("低位算法多级筛选结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("低位算法多级筛选测试通过!"); + } + + /** + * 测试可能触发多级筛选的特殊情况 + * 使用容易产生频率冲突的球号组合 + */ + @Test + public void testSpecialCaseForMultiLevelFiltering() { + log.info("=== 测试可能触发多级筛选的特殊情况 ==="); + + // 输入参数 - 使用一些常见的球号,可能会产生更多的频率冲突 + String level = "H"; + List redBalls = Arrays.asList(7, 14, 21, 28, 1, 8); + Integer blueBall = 16; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("特殊情况多级筛选结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("特殊情况多级筛选测试通过!"); + } + + /** + * 测试多次运行的一致性 + * 验证随机选择部分的稳定性 + */ + @Test + public void testConsistencyOfMultipleRuns() { + log.info("=== 测试多次运行的一致性 ==="); + + // 输入参数 + String level = "M"; + List redBalls = Arrays.asList(6, 13, 20, 27, 2, 9); + Integer blueBall = 11; + + // 执行多次分析 + List result1 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + List result2 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + List result3 = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("第1次结果:{}", result1); + log.info("第2次结果:{}", result2); + log.info("第3次结果:{}", result3); + + // 断言 - 每次结果都应该是11个不重复的球号 + assert result1.size() == 11 : "第1次结果应该包含11个球号"; + assert result2.size() == 11 : "第2次结果应该包含11个球号"; + assert result3.size() == 11 : "第3次结果应该包含11个球号"; + + assert result1.stream().distinct().count() == result1.size() : "第1次结果不应该有重复的球号"; + assert result2.stream().distinct().count() == result2.size() : "第2次结果不应该有重复的球号"; + assert result3.stream().distinct().count() == result3.size() : "第3次结果不应该有重复的球号"; + + // 注意:由于有随机选择的部分,结果可能不完全相同,但大部分应该是相同的 + log.info("多次运行一致性测试通过!"); + } + + /** + * 测试边界情况:所有球号频率都不同 + */ + @Test + public void testBoundaryCase_AllDifferentFrequencies() { + log.info("=== 测试边界情况:所有球号频率都不同 ==="); + + // 输入参数 - 使用差异较大的球号,减少频率冲突 + String level = "H"; + List redBalls = Arrays.asList(1, 11, 22, 33, 5, 15); + Integer blueBall = 1; + + // 执行分析 + List result = ballAnalysisService.analyzeBalls(level, redBalls, blueBall); + + // 验证结果 + log.info("边界情况结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 11 : "结果应该包含11个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("边界情况测试通过!"); + } + + /** + * 测试三种级别算法的对比 + */ + @Test + public void testAllLevelsComparison() { + log.info("=== 测试三种级别算法的对比 ==="); + + // 输入参数 + List redBalls = Arrays.asList(4, 10, 17, 24, 30, 6); + Integer blueBall = 14; + + // 执行三种级别的分析 + List resultH = ballAnalysisService.analyzeBalls("H", redBalls, blueBall); + List resultM = ballAnalysisService.analyzeBalls("M", redBalls, blueBall); + List resultL = ballAnalysisService.analyzeBalls("L", redBalls, blueBall); + + // 验证结果 + log.info("高位算法结果:{}", resultH); + log.info("中位算法结果:{}", resultM); + log.info("低位算法结果:{}", resultL); + + // 断言 + assert resultH.size() == 11 : "高位算法结果应该包含11个球号"; + assert resultM.size() == 11 : "中位算法结果应该包含11个球号"; + assert resultL.size() == 11 : "低位算法结果应该包含11个球号"; + + assert resultH.stream().distinct().count() == resultH.size() : "高位算法结果不应该有重复的球号"; + assert resultM.stream().distinct().count() == resultM.size() : "中位算法结果不应该有重复的球号"; + assert resultL.stream().distinct().count() == resultL.size() : "低位算法结果不应该有重复的球号"; + + // 分析结果差异 + log.info("高位与中位的交集:{}", resultH.stream().filter(resultM::contains).collect(java.util.stream.Collectors.toList())); + log.info("高位与低位的交集:{}", resultH.stream().filter(resultL::contains).collect(java.util.stream.Collectors.toList())); + log.info("中位与低位的交集:{}", resultM.stream().filter(resultL::contains).collect(java.util.stream.Collectors.toList())); + + log.info("三种级别算法对比测试通过!"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java b/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java new file mode 100644 index 0000000..71f5c1a --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/BlueBallAnalysisTest.java @@ -0,0 +1,204 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.BallAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +/** + * 蓝球分析算法测试类 + */ +@Slf4j +@SpringBootTest +public class BlueBallAnalysisTest { + + @Autowired + private BallAnalysisService ballAnalysisService; + + @Test + public void testBlueBallAnalysisHigh() { + log.info("=== 测试蓝球分析算法 - 高位算法 ==="); + + // 测试数据26 20 18 32 10 14 + String level = "H"; + List predictedRedBalls = Arrays.asList(26, 20, 18, 32, 10, 14); // 6个预测红球 + List predictedBlueBalls = Arrays.asList(5, 8); // 2个预测蓝球 + List lastRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5); // 6个上期红球 + Integer lastBlueBall = 16; // 1个上期蓝球 + + log.info("输入参数:"); + log.info("级别:{}", level); + log.info("预测红球:{}", predictedRedBalls); + log.info("预测蓝球:{}", predictedBlueBalls); + log.info("上期红球:{}", lastRedBalls); + log.info("上期蓝球:{}", lastBlueBall); + + List result = ballAnalysisService.blueBallAnalysis( + level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + log.info("高位算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为空"; + assert result.size() <= 4 : "结果数量不能超过4个"; + log.info("高位算法测试通过"); + } + + @Test + public void testBlueBallAnalysisMiddle() { + log.info("=== 测试蓝球分析算法 - 中位算法 ==="); + + // 测试数据 + String level = "M"; + List predictedRedBalls = Arrays.asList(3, 9, 14, 21, 27, 32); // 6个预测红球 + List predictedBlueBalls = Arrays.asList(5, 11); // 2个预测蓝球 + List lastRedBalls = Arrays.asList(4, 10, 16, 22, 29, 30); // 6个上期红球 + Integer lastBlueBall = 7; // 1个上期蓝球 + + log.info("输入参数:"); + log.info("级别:{}", level); + log.info("预测红球:{}", predictedRedBalls); + log.info("预测蓝球:{}", predictedBlueBalls); + log.info("上期红球:{}", lastRedBalls); + log.info("上期蓝球:{}", lastBlueBall); + + List result = ballAnalysisService.blueBallAnalysis( + level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + log.info("中位算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为空"; + assert result.size() <= 4 : "结果数量不能超过4个"; + log.info("中位算法测试通过"); + } + + @Test + public void testBlueBallAnalysisLow() { + log.info("=== 测试蓝球分析算法 - 低位算法 ==="); + + // 测试数据 + String level = "L"; + List predictedRedBalls = Arrays.asList(6, 11, 17, 23, 26, 33); // 6个预测红球 + List predictedBlueBalls = Arrays.asList(2, 14); // 2个预测蓝球 + List lastRedBalls = Arrays.asList(1, 8, 13, 19, 24, 32); // 6个上期红球 + Integer lastBlueBall = 16; // 1个上期蓝球 + + log.info("输入参数:"); + log.info("级别:{}", level); + log.info("预测红球:{}", predictedRedBalls); + log.info("预测蓝球:{}", predictedBlueBalls); + log.info("上期红球:{}", lastRedBalls); + log.info("上期蓝球:{}", lastBlueBall); + + List result = ballAnalysisService.blueBallAnalysis( + level, predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + + log.info("低位算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为空"; + assert result.size() <= 4 : "结果数量不能超过4个"; + log.info("低位算法测试通过"); + } + + @Test + public void testBlueBallAnalysisAllLevels() { + log.info("=== 测试蓝球分析算法 - 三种级别对比 ==="); + + // 相同的测试数据 + List predictedRedBalls = Arrays.asList(7, 12, 18, 24, 29, 33); // 6个预测红球 + List predictedBlueBalls = Arrays.asList(4, 9); // 2个预测蓝球 + List lastRedBalls = Arrays.asList(3, 8, 14, 20, 25, 31); // 6个上期红球 + Integer lastBlueBall = 6; // 1个上期蓝球 + + log.info("使用相同输入测试三种级别算法:"); + log.info("预测红球:{}", predictedRedBalls); + log.info("预测蓝球:{}", predictedBlueBalls); + log.info("上期红球:{}", lastRedBalls); + log.info("上期蓝球:{}", lastBlueBall); + + // 高位算法 + List highResult = ballAnalysisService.blueBallAnalysis( + "H", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + log.info("高位算法结果:{}", highResult); + + // 中位算法 + List middleResult = ballAnalysisService.blueBallAnalysis( + "M", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + log.info("中位算法结果:{}", middleResult); + + // 低位算法 + List lowResult = ballAnalysisService.blueBallAnalysis( + "L", predictedRedBalls, predictedBlueBalls, lastRedBalls, lastBlueBall); + log.info("低位算法结果:{}", lowResult); + + // 验证结果 + assert highResult != null && highResult.size() <= 4 : "高位算法结果异常"; + assert middleResult != null && middleResult.size() <= 4 : "中位算法结果异常"; + assert lowResult != null && lowResult.size() <= 4 : "低位算法结果异常"; + + log.info("三种级别算法对比测试通过"); + } + + @Test + public void testBlueBallAnalysisParameterValidation() { + log.info("=== 测试蓝球分析算法 - 参数验证 ==="); + + // 测试无效级别 + try { + ballAnalysisService.blueBallAnalysis( + "X", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1, 2), + Arrays.asList(7, 8, 9, 10, 11, 12), 1); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("无效级别测试通过:{}", e.getMessage()); + } + + // 测试预测红球数量错误 + try { + ballAnalysisService.blueBallAnalysis( + "H", Arrays.asList(1, 2, 3, 4, 5), Arrays.asList(1, 2), + Arrays.asList(7, 8, 9, 10, 11, 12), 1); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("预测红球数量错误测试通过:{}", e.getMessage()); + } + + // 测试预测蓝球数量错误 + try { + ballAnalysisService.blueBallAnalysis( + "H", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1), + Arrays.asList(7, 8, 9, 10, 11, 12), 1); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("预测蓝球数量错误测试通过:{}", e.getMessage()); + } + + // 测试红球号码超出范围 + try { + ballAnalysisService.blueBallAnalysis( + "H", Arrays.asList(1, 2, 3, 4, 5, 34), Arrays.asList(1, 2), + Arrays.asList(7, 8, 9, 10, 11, 12), 1); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("红球号码超出范围测试通过:{}", e.getMessage()); + } + + // 测试蓝球号码超出范围 + try { + ballAnalysisService.blueBallAnalysis( + "H", Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(1, 17), + Arrays.asList(7, 8, 9, 10, 11, 12), 1); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("蓝球号码超出范围测试通过:{}", e.getMessage()); + } + + log.info("参数验证测试全部通过"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java b/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java new file mode 100644 index 0000000..8358e76 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/DecimalPrecisionTest.java @@ -0,0 +1,77 @@ +package com.xy.xyaicpzs; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 小数精度处理测试类 + */ +@SpringBootTest +public class DecimalPrecisionTest { + + /** + * 测试小数位数处理方法 + */ + @Test + public void testDecimalPrecision() { + System.out.println("=== 小数位数处理测试 ==="); + + // 测试数据 + double[] testValues = { + 123.456789, // 多位小数 + 12.1, // 一位小数 + 5.0, // 整数 + 0.999, // 四舍五入测试 + 0.001, // 小数点后多位 + 99.999 // 进位测试 + }; + + for (double value : testValues) { + Double result = roundToTwoDecimalPlaces(value); + System.out.printf("原值:%f → 结果:%.2f%n", value, result); + } + } + + /** + * 将数值保留两位小数的辅助方法(与ExcelDataImporter中的方法相同) + */ + private Double roundToTwoDecimalPlaces(double value) { + if (Double.isNaN(value) || Double.isInfinite(value)) { + return null; + } + + try { + BigDecimal bd = new BigDecimal(Double.toString(value)); + return bd.setScale(2, RoundingMode.HALF_UP).doubleValue(); + } catch (Exception e) { + System.err.println("数值格式化失败:" + value); + return value; + } + } + + /** + * 测试边界情况 + */ + @Test + public void testEdgeCases() { + System.out.println("=== 边界情况测试 ==="); + + // 测试特殊值 + double[] edgeCases = { + Double.NaN, + Double.POSITIVE_INFINITY, + Double.NEGATIVE_INFINITY, + 0.0, + -0.0, + -123.456 + }; + + for (double value : edgeCases) { + Double result = roundToTwoDecimalPlaces(value); + System.out.printf("特殊值:%f → 结果:%s%n", value, result); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java b/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java new file mode 100644 index 0000000..6906e9a --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/ExcelImportTest.java @@ -0,0 +1,63 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.ExcelImportService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * Excel导入功能测试类 + */ +@SpringBootTest +public class ExcelImportTest { + + @Autowired + private ExcelImportService excelImportService; + + /** + * 测试通过文件路径导入Excel数据 + * 需要将kaifa1.xlsx文件放在项目根目录下 + * 现在会同时导入T1(红球)和T2(蓝球)的数据 + */ + @Test + public void testImportExcelByPath() { + // 假设Excel文件在项目根目录下 + String filePath = "kaifa1.xlsx"; + + try { + String result = excelImportService.importExcelFileByPath(filePath); + System.out.println("导入结果:" + result); + System.out.println("注意:系统会自动导入T1(红球)、T2(蓝球)、T3(红球线系数)、T4(蓝球组红球线系数)、T5(蓝球组蓝球线系数)、T6(红球组蓝球线系数)和T7(红球组红球面系数)七个工作表的数据"); + } catch (Exception e) { + System.err.println("导入失败:" + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 测试导入绝对路径的Excel文件 + * 请根据实际情况修改文件路径 + * 现在会同时导入T1(红球)和T2(蓝球)的数据 + */ + @Test + public void testImportExcelByAbsolutePath() { + // 请根据实际情况修改文件路径 + String filePath = "D:/code/xy-ai-cpzs/kaifa1.xlsx"; + + try { + String result = excelImportService.importExcelFileByPath(filePath); + System.out.println("导入结果:" + result); + System.out.println("数据导入详情:"); + System.out.println("- T1工作表 → 红球数据表(history_all, history_100, history_top, history_top_100)"); + System.out.println("- T2工作表 → 蓝球数据表(blue_history_all, blue_history_100, blue_history_top, blue_history_top_100)"); + System.out.println("- T3工作表 → 红球线系数表(t3,33×33=1089条记录)"); + System.out.println("- T4工作表 → 蓝球组红球线系数表(t4,16×33=528条记录)"); + System.out.println("- T5工作表 → 蓝球组蓝球线系数表(t5,16×16=256条记录)"); + System.out.println("- T6工作表 → 红球组蓝球线系数表(t6,33×16=528条记录)"); + System.out.println("- T7工作表 → 红球组红球面系数表(t7,33×32=1056条记录,排除自己组合)"); + } catch (Exception e) { + System.err.println("导入失败:" + e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java new file mode 100644 index 0000000..8d754c5 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisApiTest.java @@ -0,0 +1,245 @@ +package com.xy.xyaicpzs; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.xy.xyaicpzs.common.requset.FallowBallAnalysisRequest; +import com.xy.xyaicpzs.controller.BallAnalysisController; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; + +import java.util.Arrays; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; + +/** + * 跟随球号分析API接口测试 + * 测试REST API的功能和响应 + */ +@Slf4j +@SpringBootTest +@AutoConfigureMockMvc +public class FallowBallAnalysisApiTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + /** + * 测试表单参数方式的跟随球号分析接口 + */ + @Test + public void testFallowBallAnalysisWithFormParams() throws Exception { + log.info("=== 测试表单参数方式的跟随球号分析接口 ==="); + + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "H") + .param("firstThreeRedBalls", "7,24,27") + .param("lastSixRedBalls", "21,10,5,15,23,28") + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.data.length()").value(8)); + + log.info("表单参数方式测试通过!"); + } + + /** + * 测试JSON请求体方式的跟随球号分析接口 + */ + @Test + public void testFallowBallAnalysisWithJsonBody() throws Exception { + log.info("=== 测试JSON请求体方式的跟随球号分析接口 ==="); + + // 构建请求对象 + FallowBallAnalysisRequest request = + new FallowBallAnalysisRequest(); + request.setLevel("M"); + request.setFirstThreeRedBalls(Arrays.asList(26, 31, 28)); + request.setLastSixRedBalls(Arrays.asList(7, 24, 27, 21, 10, 5)); + request.setBlueBall(16); + + String requestJson = objectMapper.writeValueAsString(request); + log.info("请求JSON: {}", requestJson); + + mockMvc.perform(post("/api/ball-analysis/fallow-json") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.data.length()").value(8)); + + log.info("JSON请求体方式测试通过!"); + } + + /** + * 测试获取算法说明接口 + */ + @Test + public void testGetFallowAlgorithmInfo() throws Exception { + log.info("=== 测试获取算法说明接口 ==="); + + mockMvc.perform(get("/api/ball-analysis/fallow-info")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.data").isString()) + .andExpect(jsonPath("$.data").value(org.hamcrest.Matchers.containsString("跟随球号分析算法说明"))); + + log.info("获取算法说明接口测试通过!"); + } + + /** + * 测试不同级别的算法 + */ + @Test + public void testAllLevelsWithJsonBody() throws Exception { + log.info("=== 测试不同级别的算法 ==="); + + String[] levels = {"H", "M", "L"}; + + for (String level : levels) { + log.info("测试{}级别算法", level); + + // 构建请求对象 + FallowBallAnalysisRequest request = + new FallowBallAnalysisRequest(); + request.setLevel(level); + request.setFirstThreeRedBalls(Arrays.asList(1, 15, 23)); + request.setLastSixRedBalls(Arrays.asList(28, 31, 33, 2, 8, 12)); + request.setBlueBall(8); + + String requestJson = objectMapper.writeValueAsString(request); + + mockMvc.perform(post("/api/ball-analysis/fallow-json") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.data.length()").value(8)); + + log.info("{}级别算法测试通过!", level); + } + } + + /** + * 测试参数验证 - 错误的级别 + */ + @Test + public void testInvalidLevel() throws Exception { + log.info("=== 测试参数验证 - 错误的级别 ==="); + + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "X") // 错误的级别 + .param("firstThreeRedBalls", "7,24,27") + .param("lastSixRedBalls", "21,10,5,15,23,28") + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("级别必须为H、M或L"))); + + log.info("错误级别参数验证测试通过!"); + } + + /** + * 测试参数验证 - 前3个红球数量错误 + */ + @Test + public void testInvalidFirstThreeRedBalls() throws Exception { + log.info("=== 测试参数验证 - 前3个红球数量错误 ==="); + + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "H") + .param("firstThreeRedBalls", "7,24") // 只有2个球,应该是3个 + .param("lastSixRedBalls", "21,10,5,15,23,28") + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("前3个红球数量必须为3个"))); + + log.info("前3个红球数量错误参数验证测试通过!"); + } + + /** + * 测试参数验证 - 后6个红球数量错误 + */ + @Test + public void testInvalidLastSixRedBalls() throws Exception { + log.info("=== 测试参数验证 - 后6个红球数量错误 ==="); + + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "H") + .param("firstThreeRedBalls", "7,24,27") + .param("lastSixRedBalls", "21,10,5,15,23") // 只有5个球,应该是6个 + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("后6个红球数量必须为6个"))); + + log.info("后6个红球数量错误参数验证测试通过!"); + } + + /** + * 测试参数验证 - 红球号码超出范围 + */ + @Test + public void testRedBallOutOfRange() throws Exception { + log.info("=== 测试参数验证 - 红球号码超出范围 ==="); + + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "H") + .param("firstThreeRedBalls", "7,24,35") // 35超出范围 + .param("lastSixRedBalls", "21,10,5,15,23,28") + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("前3个红球号码必须在1-33范围内"))); + + log.info("红球号码超出范围参数验证测试通过!"); + } + + /** + * 测试边界情况 - 前3个红球和后6个红球有重叠 + */ + @Test + public void testOverlappingRedBalls() throws Exception { + log.info("=== 测试边界情况 - 前3个红球和后6个红球有重叠 ==="); + + // 前3个红球和后6个红球有重叠是允许的 + mockMvc.perform(post("/api/ball-analysis/fallow") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("level", "H") + .param("firstThreeRedBalls", "7,24,27") + .param("lastSixRedBalls", "7,24,5,15,23,28") // 7和24重叠 + .param("blueBall", "16")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.data.length()").value(8)); + + log.info("前3个红球和后6个红球重叠测试通过!"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java new file mode 100644 index 0000000..59d639d --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisMultiLevelFilteringTest.java @@ -0,0 +1,250 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.BallAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +/** + * fallowBallAnalysis方法多级筛选功能测试 + * 测试T7面系数筛选后的多级筛选机制: + * 1. T7面系数总和筛选 + * 2. history_top_100排名筛选 + * 3. history_top点系数筛选 + * 4. 随机选择 + */ +@Slf4j +@SpringBootTest +public class FallowBallAnalysisMultiLevelFilteringTest { + + @Autowired + private BallAnalysisService ballAnalysisService; + + /** + * 测试高级算法的多级筛选 + */ + @Test + public void testHighLevelMultiLevelFiltering() { + log.info("=== 测试fallowBallAnalysis高级算法多级筛选 ==="); + + // 使用可能触发多级筛选的输入 + List firstThreeRedBalls = Arrays.asList(1, 2, 3); + List lastSixRedBalls = Arrays.asList(10, 15, 20, 25, 30, 33); + Integer blueBall = 5; + + List result = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("高级算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); + + // 验证球号范围 + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + + // 验证无重复 + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + log.info("高级算法多级筛选测试通过"); + } + + /** + * 测试中级算法的多级筛选 + */ + @Test + public void testMiddleLevelMultiLevelFiltering() { + log.info("=== 测试fallowBallAnalysis中级算法多级筛选 ==="); + + List firstThreeRedBalls = Arrays.asList(5, 8, 12); + List lastSixRedBalls = Arrays.asList(14, 18, 22, 26, 29, 32); + Integer blueBall = 8; + + List result = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("中级算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); + + // 验证球号范围 + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + + // 验证无重复 + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + log.info("中级算法多级筛选测试通过"); + } + + /** + * 测试低级算法的多级筛选 + */ + @Test + public void testLowLevelMultiLevelFiltering() { + log.info("=== 测试fallowBallAnalysis低级算法多级筛选 ==="); + + List firstThreeRedBalls = Arrays.asList(7, 11, 16); + List lastSixRedBalls = Arrays.asList(19, 21, 24, 27, 31, 33); + Integer blueBall = 12; + + List result = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("低级算法结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); + + // 验证球号范围 + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + + // 验证无重复 + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + log.info("低级算法多级筛选测试通过"); + } + + /** + * 测试可能触发多级筛选的特殊情况 + */ + @Test + public void testSpecialCasesForMultiLevelFiltering() { + log.info("=== 测试fallowBallAnalysis特殊情况多级筛选 ==="); + + // 使用连续数字,可能产生相同的面系数 + List firstThreeRedBalls = Arrays.asList(1, 2, 3); + List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); + Integer blueBall = 1; + + List result = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("特殊情况结果:{}", result); + + // 验证结果 + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号,实际:" + result.size(); + + // 验证球号范围 + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + + // 验证无重复 + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + log.info("特殊情况多级筛选测试通过"); + } + + /** + * 测试多次运行的一致性(在相同输入下) + */ + @Test + public void testConsistencyAcrossMultipleRuns() { + log.info("=== 测试fallowBallAnalysis多次运行一致性 ==="); + + List firstThreeRedBalls = Arrays.asList(6, 13, 17); + List lastSixRedBalls = Arrays.asList(20, 23, 25, 28, 30, 32); + Integer blueBall = 10; + + // 运行多次并比较结果 + List result1 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); + List result2 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); + List result3 = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("第1次结果:{}", result1); + log.info("第2次结果:{}", result2); + log.info("第3次结果:{}", result3); + + // 验证所有结果都有效 + for (List result : Arrays.asList(result1, result2, result3)) { + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + } + + // 注意:由于最后一级是随机选择,结果可能不完全一致 + // 但前面几级的筛选应该是确定性的 + log.info("多次运行一致性测试完成(注意:最后一级随机选择可能导致结果不同)"); + } + + /** + * 测试边界情况 + */ + @Test + public void testBoundaryCases() { + log.info("=== 测试fallowBallAnalysis边界情况 ==="); + + // 测试最小值 + List firstThreeRedBalls = Arrays.asList(1, 2, 3); + List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); + Integer blueBall = 1; + + List result1 = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); + log.info("最小值边界结果:{}", result1); + + // 测试最大值 + List firstThreeRedBalls2 = Arrays.asList(31, 32, 33); + List lastSixRedBalls2 = Arrays.asList(25, 26, 27, 28, 29, 30); + Integer blueBall2 = 16; + + List result2 = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls2, lastSixRedBalls2, blueBall2); + log.info("最大值边界结果:{}", result2); + + // 验证结果 + for (List result : Arrays.asList(result1, result2)) { + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + } + + log.info("边界情况测试通过"); + } + + /** + * 测试三种级别算法的比较 + */ + @Test + public void testComparisonBetweenLevels() { + log.info("=== 测试fallowBallAnalysis三种级别算法比较 ==="); + + List firstThreeRedBalls = Arrays.asList(9, 14, 18); + List lastSixRedBalls = Arrays.asList(21, 24, 26, 29, 31, 33); + Integer blueBall = 7; + + List highResult = ballAnalysisService.fallowBallAnalysis("H", firstThreeRedBalls, lastSixRedBalls, blueBall); + List midResult = ballAnalysisService.fallowBallAnalysis("M", firstThreeRedBalls, lastSixRedBalls, blueBall); + List lowResult = ballAnalysisService.fallowBallAnalysis("L", firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("高级算法结果:{}", highResult); + log.info("中级算法结果:{}", midResult); + log.info("低级算法结果:{}", lowResult); + + // 验证所有结果都有效 + for (List result : Arrays.asList(highResult, midResult, lowResult)) { + assert result != null : "结果不能为null"; + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().distinct().count() == result.size() : "结果不应该有重复球号"; + + for (Integer ball : result) { + assert ball >= 1 && ball <= 33 : "球号应该在1-33范围内,实际:" + ball; + } + } + + log.info("三种级别算法比较测试通过"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java new file mode 100644 index 0000000..2d46d29 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/FallowBallAnalysisTest.java @@ -0,0 +1,291 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.BallAnalysisService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +/** + * 跟随球号分析算法测试 + * 验证fallowBallAnalysis方法的功能 + */ +@Slf4j +@SpringBootTest +public class FallowBallAnalysisTest { + + @Autowired + private BallAnalysisService ballAnalysisService; + + /** + * 测试高位算法的跟随球号分析 + */ + @Test + public void testHighLevelFallowBallAnalysis() { + log.info("=== 测试高位算法的跟随球号分析 ==="); + + // 输入参数 + String level = "H"; + List firstThreeRedBalls = Arrays.asList(26, 31, 28); // 前3个红球(独立的) + List lastSixRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5);; // 后6个红球(独立的) + Integer blueBall = 16; + + // 执行分析 + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 验证结果 + log.info("高位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("高位算法测试通过!"); + } + + /** + * 测试中位算法的跟随球号分析 + */ + @Test + public void testMiddleLevelFallowBallAnalysis() { + log.info("=== 测试中位算法的跟随球号分析 ==="); + + // 输入参数 + String level = "M"; + List firstThreeRedBalls = Arrays.asList(2, 9, 14); // 前3个红球(独立的) + List lastSixRedBalls = Arrays.asList(20, 25, 32, 1, 15, 23); // 后6个红球(独立的) + Integer blueBall = 12; + + // 执行分析 + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 验证结果 + log.info("中位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("中位算法测试通过!"); + } + + /** + * 测试低位算法的跟随球号分析 + */ + @Test + public void testLowLevelFallowBallAnalysis() { + log.info("=== 测试低位算法的跟随球号分析 ==="); + + // 输入参数 + String level = "L"; + List firstThreeRedBalls = Arrays.asList(3, 7, 11); // 前3个红球(独立的) + List lastSixRedBalls = Arrays.asList(17, 22, 29, 4, 8, 13); // 后6个红球(独立的) + Integer blueBall = 8; + + // 执行分析 + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 验证结果 + log.info("低位算法结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("低位算法测试通过!"); + } + + /** + * 测试参数验证功能 + */ + @Test + public void testParameterValidation() { + log.info("=== 测试参数验证功能 ==="); + + String level = "H"; + List validFirstThree = Arrays.asList(1, 2, 3); + List validLastSix = Arrays.asList(4, 5, 6, 7, 8, 9); + Integer validBlueBall = 1; + + // 测试前3个红球数量错误 + try { + ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 2), validLastSix, validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("前3个红球数量验证通过:{}", e.getMessage()); + } + + // 测试后6个红球数量错误 + try { + ballAnalysisService.fallowBallAnalysis(level, validFirstThree, Arrays.asList(1, 2, 3, 4, 5), validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("后6个红球数量验证通过:{}", e.getMessage()); + } + + // 测试红球范围错误 + try { + ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 2, 34), validLastSix, validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("红球范围验证通过:{}", e.getMessage()); + } + + // 测试蓝球范围错误 + try { + ballAnalysisService.fallowBallAnalysis(level, validFirstThree, validLastSix, 17); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("蓝球范围验证通过:{}", e.getMessage()); + } + + // 测试前3个红球重复 + try { + ballAnalysisService.fallowBallAnalysis(level, Arrays.asList(1, 1, 3), validLastSix, validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("前3个红球重复验证通过:{}", e.getMessage()); + } + + // 测试后6个红球重复 + try { + ballAnalysisService.fallowBallAnalysis(level, validFirstThree, Arrays.asList(4, 5, 6, 7, 8, 8), validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("后6个红球重复验证通过:{}", e.getMessage()); + } + + // 测试级别错误 + try { + ballAnalysisService.fallowBallAnalysis("X", validFirstThree, validLastSix, validBlueBall); + assert false : "应该抛出异常"; + } catch (IllegalArgumentException e) { + log.info("级别验证通过:{}", e.getMessage()); + } + + log.info("参数验证测试全部通过!"); + } + + /** + * 测试数据收集的完整性 + */ + @Test + public void testDataCollectionCompleteness() { + log.info("=== 测试数据收集的完整性 ==="); + + String level = "H"; + List firstThreeRedBalls = Arrays.asList(1, 2, 3); + List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); + Integer blueBall = 1; + + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("数据收集完整性测试结果:{}", result); + + // 验证数据收集的逻辑 + // 第1个红球从T7表获取10个数字 + // 后6个红球每个从T3表获取26个数字,共6*26=156个数字 + // history_top_100表获取3个数字 + // 前3个红球的后两个,共2个数字 + // 蓝球从T4表获取10个数字 + // 总计:10 + 156 + 3 + 2 + 10 = 181个数字 + + log.info("预期数据收集:10(T7) + 156(T3) + 3(history_top_100) + 2(前3红球后2个) + 10(T4) = 181个数字"); + log.info("数据收集完整性测试通过!"); + } + + /** + * 测试算法稳定性 + */ + @Test + public void testAlgorithmStability() { + log.info("=== 测试算法稳定性 ==="); + + String level = "M"; + List firstThreeRedBalls = Arrays.asList(5, 10, 15); + List lastSixRedBalls = Arrays.asList(18, 24, 30, 12, 19, 26); + Integer blueBall = 6; + + // 多次执行同样的分析,结果应该一致 + List result1 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + List result2 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + log.info("第一次结果:{}", result1); + log.info("第二次结果:{}", result2); + + assert result1.equals(result2) : "相同输入应该产生相同输出"; + log.info("算法稳定性测试通过!"); + } + + /** + * 测试边界情况 + */ + @Test + public void testBoundaryConditions() { + log.info("=== 测试边界情况 ==="); + + // 测试最小值边界 + String level = "L"; + List firstThreeRedBalls = Arrays.asList(1, 2, 3); + List lastSixRedBalls = Arrays.asList(4, 5, 6, 7, 8, 9); + Integer blueBall = 1; + + List result1 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + log.info("最小值边界测试结果:{}", result1); + + // 测试最大值边界 + firstThreeRedBalls = Arrays.asList(31, 32, 33); + lastSixRedBalls = Arrays.asList(25, 26, 27, 28, 29, 30); + blueBall = 16; + + List result2 = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + log.info("最大值边界测试结果:{}", result2); + + // 验证结果 + assert result1.size() == 8 : "最小值边界结果应该包含8个球号"; + assert result2.size() == 8 : "最大值边界结果应该包含8个球号"; + + log.info("边界情况测试通过!"); + } + + /** + * 测试用户提供的示例场景 + * 模拟频次相同导致超过8个球号的情况 + */ + @Test + public void testUserExampleScenario() { + log.info("=== 测试用户示例场景 ==="); + log.info("模拟场景:"); + log.info("当频次相同的球号超过8个时"); + log.info("使用T7表面系数总和进行二次筛选"); + + // 使用特定的红球和蓝球组合来模拟这种情况 + String level = "H"; + List firstThreeRedBalls = Arrays.asList(26, 31, 28); + List lastSixRedBalls = Arrays.asList(7, 24, 27, 21, 10, 5); + Integer blueBall = 16; + + // 执行分析 + List result = ballAnalysisService.fallowBallAnalysis(level, firstThreeRedBalls, lastSixRedBalls, blueBall); + + // 验证结果 + log.info("示例场景结果:{}", result); + log.info("结果数量:{}", result.size()); + + // 断言 + assert result.size() == 8 : "结果应该包含8个球号"; + assert result.stream().allMatch(ball -> ball >= 1 && ball <= 33) : "所有球号应该在1-33范围内"; + assert result.stream().distinct().count() == result.size() : "不应该有重复的球号"; + + log.info("频次筛选测试完成!"); + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java b/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java new file mode 100644 index 0000000..42e9935 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/GenerateVipCodesTest.java @@ -0,0 +1,126 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.VipCodeService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import jakarta.annotation.Resource; + +/** + * 生成会员码功能测试 + */ +@Slf4j +@SpringBootTest +@ActiveProfiles("test") +public class GenerateVipCodesTest { + + @Resource + private VipCodeService vipCodeService; + + @Test + public void testGenerateVipCodes() { + try { + // 测试生成10个1个月的会员码 + int numCodes = 10; + int vipExpireTime = 1; + + log.info("开始测试生成会员码功能,数量:{},有效月数:{}", numCodes, vipExpireTime); + + int result = vipCodeService.generateVipCodes(numCodes, vipExpireTime); + + log.info("生成会员码测试结果:{}", result); + + } catch (Exception e) { + log.error("生成会员码测试失败:{}", e.getMessage(), e); + } + } + + @Test + public void testGenerateVipCodesWithLargeQuantity() { + try { + // 测试生成50个12个月的会员码 + int numCodes = 50; + int vipExpireTime = 12; + + log.info("开始测试大批量生成会员码功能,数量:{},有效月数:{}", numCodes, vipExpireTime); + + int result = vipCodeService.generateVipCodes(numCodes, vipExpireTime); + + log.info("大批量生成会员码测试结果:{}", result); + + } catch (Exception e) { + log.error("大批量生成会员码测试失败:{}", e.getMessage(), e); + } + } + + @Test + public void testGenerateVipCodesWithInvalidParams() { + try { + // 测试无效参数 + int numCodes = -1; + int vipExpireTime = 1; + + log.info("开始测试无效参数的会员码生成,数量:{},有效月数:{}", numCodes, vipExpireTime); + + vipCodeService.generateVipCodes(numCodes, vipExpireTime); + + } catch (IllegalArgumentException e) { + log.info("预期的异常:{}", e.getMessage()); + } catch (Exception e) { + log.error("意外的异常:{}", e.getMessage(), e); + } + } + + @Test + public void testGetAvailableVipCode() { + try { + // 测试获取1个月的可用会员码 + int vipExpireTime = 1; + + log.info("开始测试获取可用会员码功能,有效月数:{}", vipExpireTime); + + String code = vipCodeService.getAvailableVipCode(vipExpireTime); + + log.info("获取可用会员码测试结果:{}", code); + + } catch (Exception e) { + log.error("获取可用会员码测试失败:{}", e.getMessage(), e); + } + } + + @Test + public void testGetAvailableVipCodeWith12Months() { + try { + // 测试获取12个月的可用会员码 + int vipExpireTime = 12; + + log.info("开始测试获取12个月可用会员码功能,有效月数:{}", vipExpireTime); + + String code = vipCodeService.getAvailableVipCode(vipExpireTime); + + log.info("获取12个月可用会员码测试结果:{}", code); + + } catch (Exception e) { + log.error("获取12个月可用会员码测试失败:{}", e.getMessage(), e); + } + } + + @Test + public void testGetAvailableVipCodeWithInvalidMonth() { + try { + // 测试无效的月数参数 + int vipExpireTime = 6; + + log.info("开始测试无效月数参数的获取可用会员码,有效月数:{}", vipExpireTime); + + vipCodeService.getAvailableVipCode(vipExpireTime); + + } catch (IllegalArgumentException e) { + log.info("预期的异常:{}", e.getMessage()); + } catch (Exception e) { + log.error("意外的异常:{}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/UserControllerTest.java b/src/test/java/com/xy/xyaicpzs/UserControllerTest.java new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/UserControllerTest.java @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java b/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java new file mode 100644 index 0000000..072158c --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/VipCodeActivateTest.java @@ -0,0 +1,76 @@ +package com.xy.xyaicpzs; + +import com.xy.xyaicpzs.service.VipCodeService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import jakarta.annotation.Resource; + +/** + * 会员码激活功能测试 + */ +@Slf4j +@SpringBootTest +@ActiveProfiles("test") +public class VipCodeActivateTest { + + @Resource + private VipCodeService vipCodeService; + + @Test + public void testActivateVipCode() { + try { + // 测试参数:用户ID=1,会员码=TEST_CODE_001 + // 实际测试时需要确保数据库中有对应的测试数据 + Long userId = 1L; + String code = "TEST_CODE_001"; + + log.info("开始测试会员码激活功能,用户ID:{},会员码:{}", userId, code); + + boolean result = vipCodeService.activateVipCode(userId, code); + + log.info("会员码激活测试结果:{}", result); + + } catch (Exception e) { + log.error("会员码激活测试失败:{}", e.getMessage(), e); + } + } + + @Test + public void testActivateVipCodeWithInvalidUser() { + try { + // 测试无效用户ID + Long userId = 999999L; + String code = "TEST_CODE_001"; + + log.info("开始测试无效用户ID的会员码激活,用户ID:{},会员码:{}", userId, code); + + vipCodeService.activateVipCode(userId, code); + + } catch (IllegalArgumentException e) { + log.info("预期的异常:{}", e.getMessage()); + } catch (Exception e) { + log.error("意外的异常:{}", e.getMessage(), e); + } + } + + @Test + public void testActivateVipCodeWithInvalidCode() { + try { + // 测试无效会员码 + Long userId = 1L; + String code = "INVALID_CODE"; + + log.info("开始测试无效会员码的激活,用户ID:{},会员码:{}", userId, code); + + vipCodeService.activateVipCode(userId, code); + + } catch (IllegalArgumentException e) { + log.info("预期的异常:{}", e.getMessage()); + } catch (Exception e) { + log.error("意外的异常:{}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/xy/xyaicpzs/XyAiCpzsApplicationTests.java b/src/test/java/com/xy/xyaicpzs/XyAiCpzsApplicationTests.java new file mode 100644 index 0000000..5fc41f3 --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/XyAiCpzsApplicationTests.java @@ -0,0 +1,13 @@ +package com.xy.xyaicpzs; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class XyAiCpzsApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java b/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java new file mode 100644 index 0000000..2a322fa --- /dev/null +++ b/src/test/java/com/xy/xyaicpzs/mapper/T7MapperTest.java @@ -0,0 +1,15 @@ +package com.xy.xyaicpzs.mapper; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.*; + + +@SpringBootTest +class T7MapperTest { + + @Autowired + private T7Mapper t7Mapper; + +} \ No newline at end of file diff --git a/userController.txt b/userController.txt new file mode 100644 index 0000000..8348b60 --- /dev/null +++ b/userController.txt @@ -0,0 +1,164 @@ +2 签署 JWT +扣子的 JWT 生成方式及部分参数定义沿用业界统一流程规范,但 JWT 中 Header 和 Payload 部分由扣子平台自行定义。 +在 JWT(JSON Web Tokens)的流程中,通常使用私钥来签署(sign)token。JWT 包含三部分,即 Header、Payload 和 signature,其中 header 和 payload 由参数拼接而成,signature 根据指定的签名算法和私钥对 Header 和 Payload 自动计算生成。三部分之间用点(.)分隔。详细的签署方式可参考JWT 官方文档。 +Header 和 Payload +扣子平台对 Header 和 Payload 的定义如下: +Header +Header 部分的参数定义如下: +参数 +类型 +是否必选 +说明 +alg +String +必选 +签名使用的加密算法。固定为 RS256,即非对称加密算法,一种基于 RSA(非对称加密算法)+ SHA256(安全哈希函数)的签名算法,该算法使用私钥进行签名,公钥进行验证。 +typ +String +必选 +固定为 JWT。 +kid +String +必选 +OAuth 应用的公钥指纹,可以在OAuth 应用页面找到这个应用,在操作列单击编辑图标,进入配置页面查看公钥指纹。 + + +Header 示例如下: +{ + "alg": "RS256", // 固定为RS256 + "typ": "JWT", // 固定为 JWT + "kid": "gdehvaDegW....." // OAuth 应用的公钥指纹 +} + +Payload: +Payload 部分的参数定义如下: +参数 +类型 +是否必选 +说明 +iss +String +必选 +OAuth 应用的 ID,可以在OAuth 应用页面查看。 +aud +String +必选 +扣子 API 的 Endpoint,即 api.coze.cn。 +iat +Integer +必选 +JWT 开始生效的时间,Unixtime 时间戳格式,精确到秒。一般为当前时刻。 +exp +Integer +必选 +JWT 过期的时间,Unixtime 时间戳格式,精确到秒。必须晚于 iat。 +jti +String +必选 +随机字符串,用于防止重放攻击。建议长度大于 32 字节。每次签署 JWT 时应指定为不同的字符串。 +session_name +String +可选 +访问令牌的会话标识。目前仅限在会话隔离场景下使用,即将 session_name 指定为用户在业务侧的 UID,以此区分不同业务侧用户的对话历史。 +若未指定 session_name,不同用户的对话历史可能会掺杂在一起。 +会话隔离的详细实现方法请参见如何实现会话隔离。 + +session_context +Object +可选 +会话上下文信息,包含设备相关信息等。 + +session_context.device_info +Object +可选 +用于配置设备相关信息,扣子平台基于该部分信息对设备做用量管控以及账单记录。 +该参数为企业白版白名单功能,需要联系扣子商务经理开通后才能使用。硬件设备用量管控的具体操作可参考硬件设备用量查询和配额管控。 +session_context.device_info.device_id +String +可选 +IoT 等硬件设备 ID,一个设备对应一个唯一的设备号。 +当需要记录设备用量或对设备用量进行管控时,需要填写该参数,否则,无法对设备进行用量管控,用量统计页面对应的设备 ID 将显示为 N/A。 +session_context.device_info.custom_consumer + +String +可选 +自定义维度的实体 ID,你可以根据业务需要进行设置,例如 APP 上的用户名等。 +当需要记录设备用量或对设备用量进行管控,需要填写该参数,否则,无法对设备进行用量管控,用量统计页面对应的自定义 ID 将显示为 N/A。 +device_id 和 custom_consumer 建议选择其中一个即可。 +custom_consumer 参数用于设备用量管控,与对话等 API 传入的 user_id 无关,user_id 主要用于上下文、数据库隔离等场景。 +出于数据隐私及信息安全等方面的考虑,不建议使用业务系统中定义的用户敏感标识(如手机号等)作为 custom_consumer 的值。 + + +Payload 示例如下: +{ + "iss": "310000000002", // OAuth 应用的 ID + "aud": "api.coze.cn", // 扣子 API 的 Endpoint + "iat": 1516239022, // JWT 开始生效的时间,秒级时间戳 + "exp": 1516259022, // JWT 过期时间,秒级时间戳 + "jti": "fhjashjgkhalskj", // 随机字符串,防止重放攻击 + "session_name": "user_2222", //用户在业务侧的 UID + "session_context": { + "device_info": { + "device_id": "1234567890" // IoT 等硬件设备的唯一标识 ID + } + } +} + +示例代码 +你可以直接参考以下示例代码签署 JWT。 +# You must run `pip install PyJWT cryptography` to install the PyJWT and the cryptography packages in order to use this script. + +#!/usr/bin/env python3 +import sys +import time +import uuid + +import jwt + +# 替换为你的实际 Coze App 私钥 +signing_key = ''' +-----BEGIN PRIVATE KEY----- +xxxxxxxxxxxxxxxxxx +-----END PRIVATE KEY----- +''' + +payload = { + 'iat': int(time.time()), + 'exp': int(time.time()) + 600, + "jti": str(uuid.uuid4()), + 'aud': 'api.coze.cn', + 'iss': '1127900106117' # 替换为你的实际 Coze App ID +} + +headers = { + 'kid': '_v0VjcMlLdQc3tRTD3jC5Xz29TUnKQOhtuD5k-gpyf4' # 替换为你的实际 Coze App 公钥指纹 +} + +# Create JWT with headers +encoded_jwt = jwt.encode(payload, signing_key, algorithm='RS256', headers=headers) + +print(f"JWT: {encoded_jwt}") + +最终生成的 JWT 示例如下: +eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InZZd2ZsdFR1OWZBbWtwWFhSdnR5UmREc3RONVMzZWNFcDFqVzB6dVQyRE****.eyJpc3MiOiIzMTAwMDAwMDAwMDIiLCJhdWQiOiJhcGkuY296ZS5jb20iLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTkxNjI1OTAyMiwianRpIjoiZmhqaGFsc2tqZmFkc2pld3F****.CuoiCCF-nHFyGmu2EKlwFoyd3uDyKQ3Drc1CrXQyMVySTzZlZd2M7zKWsziB3AktwbUZiRJlQ1HbghR05CW2YRHwKL4-dlJ4koR3onU7iQAO5DkPCaIxbAuTsQobtCAdkkZTg8gav9EnN1QN_1xq0w8BzuuhS7wCeY8UbaskkTK9GnO4eU9tEINmVw-2CrfB-kNbEHlEDwXfcrb4YPpkw3GhmuPShenNLObfSWS0CqIyakXL8qD5AgXLoB-SejAsRdzloSUInNXENJHfSVMkThxRhJy7yEjX3BmculC54fMKENRfLElBqwJyLLUjeRHsYnaru2ca4W8_yaPJ7F**** + + + + + +3 获取访问令牌 +应用程序调用 通过 JWT 获取 Oauth Access Token API ,请求 Header 中携带 JWT,扣子服务端会在响应中通过 access_token 字段返回访问令牌。 +请求示例如下: +curl --location --request POST 'https://api.coze.cn/api/permission/oauth2/token' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InZZd2ZsdFR1OWZBbWtwWFhSdnR5UmREc3RONVMzZWNFcDFqVzB6dVQyRE****.eyJpc3MiOiIzMTAwMDAwMDAwMDIiLCJhdWQiOiJhcGkuY296ZS5jb20iLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTkxNjI1OTAyMiwianRpIjoiZmhqaGFsc2tqZmFkc2pld3F****.CuoiCCF-nHFyGmu2EKlwFoyd3uDyKQ3Drc1CrXQyMVySTzZlZd2M7zKWsziB3AktwbUZiRJlQ1HbghR05CW2YRHwKL4-dlJ4koR3onU7iQAO5DkPCaIxbAuTsQobtCAdkkZTg8gav9EnN1QN_1xq0w8BzuuhS7wCeY8UbaskkTK9GnO4eU9tEINmVw-2CrfB-kNbEHlEDwXfcrb4YPpkw3GhmuPShenNLObfSWS0CqIyakXL8qD5AgXLoB-SejAsRdzloSUInNXENJHfSVMkThxRhJy7yEjX3BmculC54fMKENRfLElBqwJyLLUjeRHsYnaru2ca4W8_yaPJ7F****' \ +--data '{ + "duration_seconds": 86399, + "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer" +}' + +返回示例如下: +{ + "access_token": "czs_RQOhsc7vmUzK4bNgb7hn4wqOgRBYAO6xvpFHNbnl6RiQJX3cSXSguIhFDzgy****", + "expires_in": 1721135859 +} \ No newline at end of file diff --git a/会员码激活API使用说明.md b/会员码激活API使用说明.md new file mode 100644 index 0000000..c3f0a42 --- /dev/null +++ b/会员码激活API使用说明.md @@ -0,0 +1,355 @@ +# 会员码管理API使用说明 + +## 功能概述 + +会员码管理系统包含两个主要功能: +1. **会员码生成**:管理员可以批量生成会员码,用于分发给用户 +2. **会员码激活**:用户通过输入有效的会员码来延长或激活会员服务 + +系统会校验会员码的有效性,并根据会员码设定的月数来更新用户的会员到期时间。 + +## 接口信息 + +### 1. 批量生成会员码 + +**接口地址:** `POST /vip-code/generate` + +**请求参数:** + +```json +{ + "numCodes": 100, + "vipExpireTime": 12 +} +``` + +**参数说明:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| numCodes | Integer | 是 | 生成数量(1-1000) | +| vipExpireTime | Integer | 是 | 会员有效月数 | + +**响应示例:** + +成功响应: +```json +{ + "code": 0, + "data": 100, + "message": "ok" +} +``` + +失败响应: +```json +{ + "code": 40000, + "data": null, + "message": "生成数量必须大于0" +} +``` + +### 2. 获取可用会员码 + +**接口地址:** `GET /vip-code/available?vipExpireTime=1` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| vipExpireTime | Integer | 是 | 会员有效月数(1或12) | + +**响应示例:** + +成功响应: +```json +{ + "code": 0, + "data": "ABC123DEF456GHI7", + "message": "ok" +} +``` + +失败响应: +```json +{ + "code": 40400, + "data": null, + "message": "没有找到可用的会员码" +} +``` + +### 3. 激活会员码 + +**接口地址:** `POST /user/activate-vip` + +**请求参数:** + +```json +{ + "userId": 1, + "code": "VIP_CODE_123456" +} +``` + +**参数说明:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| userId | Long | 是 | 用户ID | +| code | String | 是 | 会员码 | + +**响应示例:** + +成功响应: +```json +{ + "code": 0, + "data": true, + "message": "ok" +} +``` + +失败响应: +```json +{ + "code": 40000, + "data": null, + "message": "会员码不存在或无效" +} +``` + +## 业务逻辑 + +### 会员码生成流程 + +1. **参数校验** + - 验证生成数量大于0且不超过1000 + - 验证会员有效月数大于0 + +2. **生成唯一会员码** + - 使用随机算法生成16位会员码 + - 检查数据库确保会员码唯一性 + - 重复生成直到达到指定数量 + +3. **会员编号分配** + - 查询当前最大会员编号 + - 从最大编号+1开始连续分配 + +4. **批量插入数据库** + - 使用事务确保数据一致性 + - 批量插入提高性能 + +### 获取可用会员码流程 + +1. **参数校验** + - 验证会员有效月数只能是1或12 + +2. **数据库查询** + - 查询指定月数的未使用会员码 + - 按创建时间升序排列,获取最早的一个 + - 确保返回的会员码处于可用状态 + +3. **结果返回** + - 如果找到可用会员码,返回会员码字符串 + - 如果没有找到,返回错误信息 + +### 会员码激活流程 + +1. **参数校验** + - 验证userId不为空 + - 验证会员码不为空或空字符串 + +2. **用户存在性校验** + - 检查用户ID对应的用户是否存在 + - 不存在则抛出"用户不存在"异常 + +3. **会员码有效性校验** + - 根据会员码查询vip_code表 + - 检查会员码是否存在 + - 检查会员码是否已被使用(isUse字段) + +4. **会员时间计算** + - 获取用户当前的会员到期时间(vipExpire) + - 如果当前时间晚于会员到期时间或会员到期时间为空,则从当前时间开始计算 + - 如果当前时间早于会员到期时间,则从会员到期时间开始计算 + - 添加会员码对应的月数(vipExpireTime字段) + +5. **数据库更新** + - 更新用户表:设置isVip=1,更新vipExpire为新计算的时间 + - 更新会员码表:设置isUse=1,标记为已使用 + +### 数据库表结构 + +**vip_code表:** +- `id`: 主键 +- `code`: 会员码(唯一) +- `vipExpireTime`: 会员有效月数 +- `vipNumber`: 会员编号 +- `isUse`: 是否使用(0-未使用,1-已使用) +- `createTime`: 创建时间 +- `updateTime`: 更新时间 + +**user表:** +- `isVip`: 是否会员(0-非会员,1-会员) +- `vipExpire`: 会员到期时间 + +## 错误码说明 + +| 错误码 | 说明 | +|--------|------| +| 40000 | 参数错误(用户ID为空、会员码为空、用户不存在、会员码无效等) | +| 50000 | 系统错误(数据库操作失败等) | + +## 使用示例 + +### cURL 示例 + +**生成会员码:** +```bash +curl -X POST http://localhost:8080/vip-code/generate \ + -H "Content-Type: application/json" \ + -d '{ + "numCodes": 100, + "vipExpireTime": 12 + }' +``` + +**获取可用会员码:** +```bash +curl -X GET "http://localhost:8080/vip-code/available?vipExpireTime=1" +``` + +**激活会员码:** +```bash +curl -X POST http://localhost:8080/user/activate-vip \ + -H "Content-Type: application/json" \ + -d '{ + "userId": 1, + "code": "VIP_CODE_123456" + }' +``` + +### JavaScript 示例 + +**生成会员码:** +```javascript +const generateVipCodes = async (numCodes, vipExpireTime) => { + try { + const response = await fetch('/vip-code/generate', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + numCodes: numCodes, + vipExpireTime: vipExpireTime + }) + }); + + const result = await response.json(); + if (result.code === 0) { + console.log('会员码生成成功,数量:', result.data); + return result.data; + } else { + console.error('会员码生成失败:', result.message); + return 0; + } + } catch (error) { + console.error('请求失败:', error); + return 0; + } +}; +``` + +**获取可用会员码:** +```javascript +const getAvailableVipCode = async (vipExpireTime) => { + try { + const response = await fetch(`/vip-code/available?vipExpireTime=${vipExpireTime}`, { + method: 'GET' + }); + + const result = await response.json(); + if (result.code === 0) { + console.log('获取可用会员码成功:', result.data); + return result.data; + } else { + console.error('获取可用会员码失败:', result.message); + return null; + } + } catch (error) { + console.error('请求失败:', error); + return null; + } +}; +``` + +**激活会员码:** +```javascript +const activateVipCode = async (userId, code) => { + try { + const response = await fetch('/user/activate-vip', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + userId: userId, + code: code + }) + }); + + const result = await response.json(); + if (result.code === 0) { + console.log('会员码激活成功'); + return true; + } else { + console.error('会员码激活失败:', result.message); + return false; + } + } catch (error) { + console.error('请求失败:', error); + return false; + } +}; +``` + +## 注意事项 + +### 会员码生成 +1. **批量限制**:单次最多生成1000个会员码,避免系统负载过高 +2. **唯一性保证**:系统会检查数据库确保生成的会员码唯一 +3. **事务管理**:使用数据库事务确保批量插入的数据一致性 +4. **性能优化**:使用批量插入提高大量数据的插入性能 + +### 获取可用会员码 +1. **参数限制**:只支持1个月和12个月两种类型的会员码 +2. **优先级策略**:按创建时间升序返回,优先返回最早创建的会员码 +3. **状态检查**:只返回未使用状态的会员码 +4. **库存管理**:如果指定类型的会员码已用完,会返回相应错误信息 + +### 会员码激活 +1. **事务管理**:整个激活过程使用数据库事务,确保数据一致性 +2. **重复使用**:每个会员码只能使用一次,使用后会被标记为已使用 +3. **时间计算**:会员时间会根据用户当前状态智能计算,不会丢失已有的会员时间 +4. **日志记录**:所有操作都有详细的日志记录,便于问题排查 +5. **异常处理**:完善的异常处理机制,提供清晰的错误信息 + +## 测试数据 + +在测试环境中,可以在vip_code表中插入测试数据: + +```sql +INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime) +VALUES (1, 'TEST_CODE_001', 1, 1001, 0, NOW(), NOW()); + +INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime) +VALUES (2, 'TEST_CODE_002', 3, 1002, 0, NOW(), NOW()); + +INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime) +VALUES (3, 'TEST_CODE_003', 12, 1003, 0, NOW(), NOW()); +``` + +这些测试数据分别对应1个月、3个月和12个月的会员时长。 \ No newline at end of file

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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4bf350a --- /dev/null +++ b/pom.xml @@ -0,0 +1,198 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.6 + + + com.xy + xy-ai-cpzs + 0.0.1-SNAPSHOT + xy-ai-cpzs + xy-ai-cpzs + + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-web + + + com.tencentcloudapi + tencentcloud-sdk-java-sms + 3.1.1281 + + + + + com.alibaba.nls + nls-sdk-recognizer + 2.2.1 + + + + + + + + + + + + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + org.glassfish.jaxb + jaxb-runtime + 2.3.1 + + + com.alibaba + dashscope-sdk-java + + 2.20.6 + + + org.springframework.boot + spring-boot-starter-aop + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + 1.18.36 + true + + + cn.hutool + hutool-all + 5.8.37 + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + 4.5.0 + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.12 + + + + com.baomidou + mybatis-plus-jsqlparser + 3.5.12 + + + + com.mysql + mysql-connector-j + + + + org.apache.poi + poi + 5.2.4 + + + org.apache.poi + poi-ooxml + 5.2.4 + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + com.aliyun + dysmsapi20170525 + 2.0.24 + + + com.aliyun + tea-openapi + 0.2.8 + + + com.aliyun + tea-util + 0.2.21 + + + com.aliyun + credentials-java + 0.2.4 + + + com.aliyun + tea + 1.2.7 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/sql/ddl.sql b/sql/ddl.sql new file mode 100644 index 0000000..b303653 --- /dev/null +++ b/sql/ddl.sql @@ -0,0 +1,272 @@ +-- 聊天消息表 +create database if not exists cpzs; + +-- 切换库 +use cpzs; + +-- 创建历史数据表 +CREATE TABLE IF NOT EXISTS `history_all` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + ballNumber INT NULL COMMENT '球号', + frequencyCount INT NULL COMMENT '出现频次', + frequencyPercentage FLOAT NULL COMMENT '出现频率百分比', + averageInterval FLOAT NULL COMMENT '平均隐现期(次)', + maxHiddenInterval INT NULL COMMENT '最长隐现期(次)', + maxConsecutiveCount INT NULL COMMENT '最多连出期(次)', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '全部历史数据表'; + + +-- 创建最近100期数据表 +CREATE TABLE IF NOT EXISTS `history_100` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + ballNumber INT NULL COMMENT '球号', + frequencyCount INT NULL COMMENT '出现频次', + averageInterval FLOAT NULL COMMENT '平均隐现期(次)', + nowInterval INT NULL COMMENT '当前隐现期(次)', + maxConsecutiveCount INT NULL COMMENT '最多连出期(次)', +pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '最近100期数据表'; + +-- 创建历史数据排行表 +CREATE TABLE IF NOT EXISTS `history_top` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + no INT NULL COMMENT '排行', + ballNumber INT NULL COMMENT '球号', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '历史数据排行表'; + +-- 创建100期数据排行表 +CREATE TABLE IF NOT EXISTS `history_top_100` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + no INT NULL COMMENT '排行', + ballNumber INT NULL COMMENT '球号', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '100期数据排行表'; + + +-- 创建蓝球历史数据表 +CREATE TABLE IF NOT EXISTS `blue_history_all` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + ballNumber INT NULL COMMENT '球号', + frequencyCount INT NULL COMMENT '出现频次', + frequencyPercentage FLOAT NULL COMMENT '出现频率百分比', + averageInterval FLOAT NULL COMMENT '平均隐现期(次)', + maxHiddenInterval INT NULL COMMENT '最长隐现期(次)', + maxConsecutiveCount INT NULL COMMENT '最多连出期(次)', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '蓝球全部历史数据表'; + + +-- 创建蓝球最近100期数据表 +CREATE TABLE IF NOT EXISTS `blue_history_100` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + ballNumber INT NULL COMMENT '球号', + frequencyCount INT NULL COMMENT '出现频次', + averageInterval FLOAT NULL COMMENT '平均隐现期(次)', + nowInterval INT NULL COMMENT '当前隐现期(次)', + maxConsecutiveCount INT NULL COMMENT '最多连出期(次)', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '蓝球最近100期数据表'; + +-- 创建蓝球历史数据排行表 +CREATE TABLE IF NOT EXISTS `blue_history_top` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + no INT NULL COMMENT '排行', + ballNumber INT NULL COMMENT '球号', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '蓝球历史数据排行表'; + +-- 创建蓝球100期数据排行表 +CREATE TABLE IF NOT EXISTS `blue_history_top_100` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + no INT NULL COMMENT '排行', + ballNumber INT NULL COMMENT '球号', + pointCoefficient FLOAT NULL COMMENT '点系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '蓝球100期数据排行表'; + +-- 创建t3表(红球组红球的线系数) +CREATE TABLE IF NOT EXISTS `t3` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + lineCoefficient FLOAT NULL COMMENT '线系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't3表(红球组红球的线系数)'; + + +-- 创建t4表(蓝球组红球的线系数) +CREATE TABLE IF NOT EXISTS `t4` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + lineCoefficient FLOAT NULL COMMENT '线系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't4表(蓝球组红球的线系数)'; + +-- 创建t5表(蓝球组蓝球的线系数) +CREATE TABLE IF NOT EXISTS `t5` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + lineCoefficient FLOAT NULL COMMENT '线系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't5表(蓝球组蓝球的线系数)'; + +-- 创建t6表(红球组蓝球的线系数) +CREATE TABLE IF NOT EXISTS `t6` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + lineCoefficient FLOAT NULL COMMENT '线系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't6表(红球组蓝球的线系数)'; + +-- 创建t7表(红球组红球的面系数) +CREATE TABLE IF NOT EXISTS `t7` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + faceCoefficient FLOAT NULL COMMENT '面系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't7表(红球组红球的面系数)'; + +-- 创建t8表(红球组蓝球的面系数) +CREATE TABLE IF NOT EXISTS `t8` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + faceCoefficient FLOAT NULL COMMENT '面系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't8表(红球组蓝球的面系数)'; + +-- 创建t11表(蓝球组红球的面系数) +CREATE TABLE IF NOT EXISTS `t11` ( + id BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + masterBallNumber INT NULL COMMENT '主球', + slaveBallNumber INT NULL COMMENT '从球', + faceCoefficient FLOAT NULL COMMENT '面系数' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = 't11表(蓝球组红球的面系数)'; + +CREATE TABLE IF NOT EXISTS `lottery_draws` ( + `drawId` BIGINT NOT NULL COMMENT '开奖期号' PRIMARY KEY, + `drawDate` DATE NOT NULL COMMENT '开奖日期', + `redBall1` INT NOT NULL COMMENT '红1', + `redBall2` INT NOT NULL COMMENT '红2', + `redBall3` INT NOT NULL COMMENT '红3', + `redBall4` INT NOT NULL COMMENT '红4', + `redBall5` INT NOT NULL COMMENT '红5', + `redBall6` INT NOT NULL COMMENT '红6', + `blueBall` INT NOT NULL COMMENT '蓝球' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '彩票开奖信息表'; + +-- 用户表 +create table if not exists user +( + id bigint auto_increment comment 'id' primary key, + userName varchar(256) null comment '用户昵称', + userAccount varchar(256) not null comment '账号', + phone varchar(11) null comment '手机号', + userAvatar varchar(1024) null comment '用户头像', + gender tinyint null comment '性别', + userRole varchar(256) default 'user' not null comment '用户角色:user / admin', + userPassword varchar(512) not null comment '密码', + isVip int default 0 not null comment '是否会员:0-非会员,1-会员', + vipExpire datetime null comment '会员到期时间', + `status` tinyint DEFAULT '0' COMMENT '状态0正常1不正常', + createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', + updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', + isDelete tinyint default 0 not null comment '是否删除', + constraint uni_userAccount + unique (userAccount) +) comment '用户'; + +CREATE TABLE IF NOT EXISTS `predict_record` ( + `id` BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + `userId` BIGINT NOT NULL COMMENT '用户ID', + `drawId` BIGINT NOT NULL COMMENT '开奖期号' , + `drawDate` DATE NOT NULL COMMENT '开奖日期', + `redBall1` INT NOT NULL COMMENT '红1', + `redBall2` INT NOT NULL COMMENT '红2', + `redBall3` INT NOT NULL COMMENT '红3', + `redBall4` INT NOT NULL COMMENT '红4', + `redBall5` INT NOT NULL COMMENT '红5', + `redBall6` INT NOT NULL COMMENT '红6', + `blueBall` INT NOT NULL COMMENT '蓝球', + `predictStatus` VARCHAR(100) default '待开奖' NOT NULL COMMENT '预测状态(待开奖/已开奖)', + `predictResult` VARCHAR(100) default '待开奖' NOT NULL COMMENT '预测结果(未中奖/三等奖/二等奖/一等奖)', + `predictTime` datetime default CURRENT_TIMESTAMP not null comment '预测时间', + `bonus` BIGINT default 0 NOT NULL COMMENT '奖金' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT = '彩票开奖信息表'; + +CREATE TABLE IF NOT EXISTS `vip_code` ( + `id` BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + `code` varchar(36) NOT NULL COMMENT '会员码', + `vipExpireTime` int not null COMMENT '会员有效月数(1/12)', + `vipNumber` int not NULL COMMENT '会员编号', + `isUse` int NOT NULL COMMENT '是否使用', + createdUserId bigint null comment '创建人', + createdUserName varchar(36) null comment '创建人名称', + usedUserId bigint null comment '使用人', + usedUserName varchar(36) null comment '使用人名称', + `createTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间', + `updateTime` datetime NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `Order_OrderNo_uindex` (`code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员码表'; + +INSERT INTO `vip_code` (`id`, `code`, `vipExpireTime`, `vipNumber`, `isUse`, `createTime`, `updateTime`) VALUES +(1, 'A3B4C5D6E7F8G9H1', 1, '000001', 0, NOW(), NOW()), +(2, 'I2J3K4L5M6N7O8P9', 12, '000002', 0, NOW(), NOW()); + + +CREATE TABLE IF NOT EXISTS `vip_exchange_record` ( + `id` BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + `userId` bigint NOT NULL COMMENT '用户ID', + `type` varchar(36) NOT NULL COMMENT '月度会员/年度会员', + `exchangeMode` int not null COMMENT '兑换方式', + `orderNo` bigint not NULL COMMENT '订单编号', + `orderAmount` int not NULL COMMENT '订单金额', + `isUse` int NOT NULL COMMENT '是否兑换(未兑换/已兑换)', + `exchangeTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '兑换时间', + `updateTime` datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员兑换表'; + +CREATE TABLE IF NOT EXISTS `operation_history` ( + `id` BIGINT AUTO_INCREMENT COMMENT '唯一标识符' PRIMARY KEY, + `userId` BIGINT NOT NULL COMMENT '操作用户ID', + `operationType` VARCHAR(50) NOT NULL COMMENT '操作类型(批量生成会员码/获取可用会员码/Excel导入等)', + `operationModule` INTEGER NOT NULL COMMENT '操作模块(0-会员码管理/1-Excel导入管理等)', + `operationResult` VARCHAR(20) NOT NULL COMMENT '操作结果(成功/失败)', + `resultMessage` TEXT COMMENT '结果消息', + `operationTime` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '操作时间', + `updateTime` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='操作历史记录表'; + + +CREATE TABLE IF NOT EXISTS `chat_message` +( + id BIGINT AUTO_INCREMENT COMMENT 'id' PRIMARY KEY, + `conversationId` varchar(64) NULL COMMENT '会话ID', + `studentId` varchar(64) NULL COMMENT '用户ID,关联用户表', + `messageType` varchar(64) NULL COMMENT '消息类型(如: 用户提问、AI回答)', + `content` varchar(1024) NULL COMMENT '消息内容', + `createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `isDelete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除 0-未删除 1-已删除' +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 COMMENT ='聊天消息表'; + + + diff --git a/src/main/java/com/xy/xyaicpzs/Main.java b/src/main/java/com/xy/xyaicpzs/Main.java new file mode 100644 index 0000000..5cccccd --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/Main.java @@ -0,0 +1,42 @@ +package com.xy.xyaicpzs; + +import com.alibaba.dashscope.app.*; +import com.alibaba.dashscope.exception.ApiException; +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import io.reactivex.Flowable; + +import java.util.Arrays; +import java.util.List; + +public class Main { + + public static void streamCall() throws NoApiKeyException, InputRequiredException { + ApplicationParam param = ApplicationParam.builder() + // 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。 + .apiKey(System.getenv("DASHSCOPE_API_KEY")) + // 替换为实际的应用 ID + .appId("ec08d5b81ca248e8834228c1133e2c78") + .prompt("你是谁") + // 增量输出 + .incrementalOutput(true) + .build(); + Application application = new Application(); + // .streamCall():流式输出内容 + Flowable result = application.streamCall(param); + result.blockingForEach(data -> { + System.out.printf("%s\n", + data.getOutput().getText()); +// System.out.println("session_id: " + data.getOutput().getSessionId()); + }); + } + public static void main(String[] args) { + try { + streamCall(); + } catch (ApiException | NoApiKeyException | InputRequiredException e) { + System.out.printf("Exception: %s", e.getMessage()); + System.out.println("请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code"); + } + System.exit(0); + } +} \ No newline at end of file diff --git a/src/main/java/com/xy/xyaicpzs/Sample.java b/src/main/java/com/xy/xyaicpzs/Sample.java new file mode 100644 index 0000000..07e0534 --- /dev/null +++ b/src/main/java/com/xy/xyaicpzs/Sample.java @@ -0,0 +1,54 @@ +// This file is auto-generated, don't edit it. Thanks. +package com.xy.xyaicpzs; + +import com.aliyun.tea.*; + +public class Sample { + + /** + * description : + *