From 92a139e470e7edc3cc52f7aa58f9131f8ffe4b22 Mon Sep 17 00:00:00 2001 From: Toyas Date: Wed, 18 Mar 2026 10:45:15 +0800 Subject: [PATCH] refactor(project): Reorganize frontend and backend directories --- .gitignore | 68 +- .idea/.cache/.Apifox_Helper/.toolWindow.db | Bin 425984 -> 0 bytes .idea/.gitignore | 10 - .idea/ApifoxUploaderProjectSetting.xml | 18 - .idea/checkstyle-idea.xml | 16 - .idea/codeStyles/Project.xml | 7 - .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/dataSources.xml | 113 - .idea/encodings.xml | 15 - .idea/fastRequest/fastRequestCollection.xml | 23 - .../fastRequestCurrentProjectLocalConfig.xml | 9 - .idea/git_toolbox_prj.xml | 15 - .idea/inspectionProfiles/Project_Default.xml | 5 - .idea/markdown.xml | 6 - .idea/misc.xml | 14 - .idea/vcs.xml | 6 - .../build-and-deploy.bat | 0 .../build-and-deploy.sh | 0 {config => backend/config}/.env.node-01 | 0 {config => backend/config}/.env.node-02 | 0 {config => backend/config}/.env.node-03 | 0 .../config}/mysql/my-master.cnf | 0 {config => backend/config}/mysql/my-slave.cnf | 0 {config => backend/config}/nacos-mysql.sql | 0 .../config}/nginx/conf.d/upstream.conf | 0 {config => backend/config}/nginx/nginx.conf | 0 .../config}/redis/redis-master.conf | 0 .../config}/redis/redis-slave.conf | 0 .../config}/redis/sentinel.conf | 0 .../config}/rocketmq/broker-a.conf | 0 .../config}/rocketmq/broker-b.conf | 0 backend/deploy-ha.sh | 333 + .../docker-compose-node-01.yml | 0 .../docker-compose-node-02.yml | 0 .../docker-compose-node-03.yml | 0 .../docker-compose.yml | 0 pom.xml => backend/pom.xml | 0 {scripts => backend/scripts}/init-debian12.sh | 0 .../sentinel-dashboard}/Dockerfile | 0 {sql => backend/sql}/init.sql | 0 {sql => backend/sql}/nacos-config-init.sql | 0 {sql => backend/sql}/nacos-schema.sql | 0 .../video-admin}/Dockerfile | 0 {video-admin => backend/video-admin}/pom.xml | 0 .../nuaa/video/admin/AdminApplication.java | 0 .../video/admin/annotation/OperationLog.java | 0 .../admin/aspect/OperationLogAspect.java | 0 .../video/admin/config/PasswordConfig.java | 0 .../nuaa/video/admin/config/RedisConfig.java | 0 .../admin/controller/AdminUserController.java | 0 .../admin/controller/AuthController.java | 0 .../controller/ContentManageController.java | 0 .../controller/UserManageController.java | 0 .../video/admin/dto/AdminPermissionDTO.java | 0 .../nuaa/video/admin/dto/AdminRoleDTO.java | 0 .../nuaa/video/admin/dto/AdminUserDTO.java | 0 .../com/nuaa/video/admin/dto/LoginDTO.java | 0 .../nuaa/video/admin/dto/SystemConfigDTO.java | 0 .../video/admin/entity/AdminOperationLog.java | 0 .../video/admin/entity/AdminPermission.java | 0 .../nuaa/video/admin/entity/AdminRole.java | 0 .../admin/entity/AdminRolePermission.java | 0 .../video/admin/entity/AdminSystemConfig.java | 0 .../nuaa/video/admin/entity/AdminUser.java | 0 .../video/admin/entity/AdminUserRole.java | 0 .../video/admin/feign/CommentFeignClient.java | 0 .../CommentFeignClientFallbackFactory.java | 0 .../video/admin/feign/ContentFeignClient.java | 0 .../ContentFeignClientFallbackFactory.java | 0 .../video/admin/feign/UserFeignClient.java | 0 .../feign/UserFeignClientFallbackFactory.java | 0 .../admin/mapper/AdminOperationLogMapper.java | 0 .../admin/mapper/AdminPermissionMapper.java | 0 .../video/admin/mapper/AdminRoleMapper.java | 0 .../mapper/AdminRolePermissionMapper.java | 0 .../admin/mapper/AdminSystemConfigMapper.java | 0 .../video/admin/mapper/AdminUserMapper.java | 0 .../admin/mapper/AdminUserRoleMapper.java | 0 .../admin/security/AdminUserDetails.java | 0 .../security/AdminUserDetailsServiceImpl.java | 0 .../CustomAuthenticationProvider.java | 0 .../security/JwtAuthenticationFilter.java | 0 .../admin/security/JwtTokenProvider.java | 0 .../video/admin/security/SecurityConfig.java | 0 .../video/admin/service/AdminUserService.java | 0 .../nuaa/video/admin/service/AuthService.java | 0 .../video/admin/service/PasswordService.java | 0 .../service/impl/AdminUserInitService.java | 0 .../service/impl/AdminUserServiceImpl.java | 0 .../admin/service/impl/AuthServiceImpl.java | 0 .../service/impl/PasswordServiceImpl.java | 0 .../video/admin/vo/AdminPermissionVO.java | 0 .../com/nuaa/video/admin/vo/AdminRoleVO.java | 0 .../com/nuaa/video/admin/vo/AdminUserVO.java | 0 .../com/nuaa/video/admin/vo/CaptchaVO.java | 0 .../java/com/nuaa/video/admin/vo/LoginVO.java | 0 .../nuaa/video/admin/vo/SystemConfigVO.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../mapper/AdminOperationLogMapper.xml | 0 .../mapper/AdminPermissionMapper.xml | 0 .../main/resources/mapper/AdminRoleMapper.xml | 0 .../mapper/AdminRolePermissionMapper.xml | 0 .../mapper/AdminSystemConfigMapper.xml | 0 .../main/resources/mapper/AdminUserMapper.xml | 0 .../resources/mapper/AdminUserRoleMapper.xml | 0 {video-auth => backend/video-auth}/Dockerfile | 0 {video-auth => backend/video-auth}/pom.xml | 0 .../com/nuaa/video/auth/AuthApplication.java | 0 .../nuaa/video/auth/config/RedisConfig.java | 0 .../video/auth/config/SecurityConfig.java | 0 .../auth/controller/AdminAuthController.java | 0 .../video/auth/controller/AuthController.java | 0 .../com/nuaa/video/auth/dto/LoginDTO.java | 0 .../com/nuaa/video/auth/dto/RegisterDTO.java | 0 .../com/nuaa/video/auth/dto/TokenInfoDTO.java | 0 .../video/auth/entity/AuthPermission.java | 0 .../com/nuaa/video/auth/entity/AuthRole.java | 0 .../video/auth/entity/AuthRolePermission.java | 0 .../com/nuaa/video/auth/entity/AuthUser.java | 0 .../nuaa/video/auth/entity/AuthUserRole.java | 0 .../com/nuaa/video/auth/feign/UserClient.java | 0 .../feign/fallback/UserClientFallback.java | 0 .../auth/filter/JwtAuthenticationFilter.java | 0 .../auth/mapper/AuthPermissionMapper.java | 0 .../video/auth/mapper/AuthRoleMapper.java | 0 .../auth/mapper/AuthRolePermissionMapper.java | 0 .../video/auth/mapper/AuthUserMapper.java | 0 .../video/auth/mapper/AuthUserRoleMapper.java | 0 .../video/auth/service/AuthUserService.java | 0 .../video/auth/service/CaptchaService.java | 0 .../service/impl/AuthUserServiceImpl.java | 0 .../auth/service/impl/CaptchaServiceImpl.java | 0 .../com/nuaa/video/auth/utils/JwtUtils.java | 0 .../com/nuaa/video/auth/utils/RedisUtils.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../resources/mapper/AuthPermissionMapper.xml | 0 .../main/resources/mapper/AuthRoleMapper.xml | 0 .../mapper/AuthRolePermissionMapper.xml | 0 .../main/resources/mapper/AuthUserMapper.xml | 0 .../auth/controller/AuthControllerTest.java | 237 + .../nuaa/video/auth/feign/UserClientTest.java | 64 + .../auth/integration/AuthIntegrationTest.java | 92 + .../auth/service/AuthUserServiceTest.java | 263 + .../src/test/resources/application-test.yml | 46 + .../video-comment}/Dockerfile | 0 .../video-comment}/pom.xml | 0 .../video/comment/CommentApplication.java | 0 .../video/comment/config/SecurityConfig.java | 0 .../controller/AdminCommentController.java | 0 .../comment/controller/CommentController.java | 0 .../comment/controller/ReplyController.java | 0 .../nuaa/video/comment/dto/CommentAddDTO.java | 0 .../video/comment/dto/CommentQueryDTO.java | 0 .../nuaa/video/comment/dto/ReplyAddDTO.java | 0 .../nuaa/video/comment/entity/Comment.java | 0 .../video/comment/entity/CommentLike.java | 0 .../video/comment/entity/CommentReply.java | 0 .../comment/feign/ContentFeignClient.java | 0 .../ContentFeignClientFallbackFactory.java | 0 .../video/comment/feign/UserFeignClient.java | 0 .../feign/UserFeignClientFallbackFactory.java | 0 .../filter/JwtAuthenticationFilter.java | 0 .../comment/mapper/CommentLikeMapper.java | 0 .../video/comment/mapper/CommentMapper.java | 0 .../comment/mapper/CommentReplyMapper.java | 0 .../comment/service/CommentReplyService.java | 0 .../video/comment/service/CommentService.java | 0 .../service/impl/CommentReplyServiceImpl.java | 0 .../service/impl/CommentServiceImpl.java | 0 .../comment/utils/SensitiveWordFilter.java | 0 .../nuaa/video/comment/vo/CommentStatVO.java | 0 .../com/nuaa/video/comment/vo/CommentVO.java | 0 .../com/nuaa/video/comment/vo/ReplyVO.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../resources/mapper/CommentLikeMapper.xml | 0 .../main/resources/mapper/CommentMapper.xml | 0 .../resources/mapper/CommentReplyMapper.xml | 0 .../comment/service/CommentServiceTest.java | 287 + .../src/test/resources/application-test.yml | 41 + .../video-common}/pom.xml | 0 .../nuaa/video/common/config/FeignConfig.java | 0 .../nuaa/video/common/config/MinioConfig.java | 0 .../common/config/MybatisPlusConfig.java | 0 .../config/MybatisPlusMetaObjectHandler.java | 0 .../nuaa/video/common/config/RedisConfig.java | 0 .../nuaa/video/common/config/WebConfig.java | 0 .../common/constants/CommonConstants.java | 0 .../common/constants/SecurityConstants.java | 0 .../common/exception/BusinessException.java | 0 .../exception/GlobalExceptionHandler.java | 0 .../common/model/dto/PageRequestDTO.java | 0 .../video/common/model/entity/BaseEntity.java | 0 .../video/common/model/enums/ResultCode.java | 0 .../nuaa/video/common/model/vo/Result.java | 0 .../nuaa/video/common/utils/DateUtils.java | 0 .../com/nuaa/video/common/utils/JwtUtils.java | 0 .../nuaa/video/common/utils/MinioUtils.java | 0 .../nuaa/video/common/utils/PageUtils.java | 0 .../nuaa/video/common/utils/RedisUtils.java | 0 .../nuaa/video/common/utils/StringUtils.java | 0 .../main/resources/META-INF/spring.factories | 0 .../video/common/test/BaseControllerTest.java | 32 + .../video/common/test/BaseServiceTest.java | 41 + .../video-content}/Dockerfile | 0 .../video-content}/pom.xml | 0 .../video/content/ContentApplication.java | 0 .../video/content/config/FFmpegConfig.java | 0 .../video/content/config/MinioConfig.java | 0 .../video/content/config/RocketConfig.java | 0 .../video/content/config/SecurityConfig.java | 0 .../controller/AdminCategoryController.java | 0 .../controller/AdminVideoController.java | 0 .../controller/CategoryController.java | 0 .../content/controller/DanmakuController.java | 0 .../controller/FavoriteController.java | 0 .../content/controller/TagController.java | 0 .../content/controller/VideoController.java | 0 .../controller/VideoStatController.java | 0 .../nuaa/video/content/dto/DanmakuDTO.java | 0 .../nuaa/video/content/dto/FavoriteDTO.java | 0 .../nuaa/video/content/dto/PlayRecordDTO.java | 0 .../nuaa/video/content/dto/VideoQueryDTO.java | 0 .../video/content/dto/VideoUpdateDTO.java | 0 .../video/content/dto/VideoUploadDTO.java | 0 .../video/content/entity/ContentCategory.java | 0 .../video/content/entity/ContentDanmaku.java | 0 .../nuaa/video/content/entity/ContentTag.java | 0 .../content/entity/ContentUserFavorite.java | 0 .../video/content/entity/ContentVideo.java | 0 .../content/entity/ContentVideoCoin.java | 0 .../content/entity/ContentVideoFavorite.java | 0 .../content/entity/ContentVideoLike.java | 0 .../entity/ContentVideoPlayRecord.java | 0 .../content/entity/ContentVideoReview.java | 0 .../content/entity/ContentVideoStatDaily.java | 0 .../video/content/entity/ContentVideoTag.java | 0 .../content/enums/DanmakuPositionEnum.java | 0 .../video/content/enums/VideoStatusEnum.java | 0 .../video/content/feign/UserFeignClient.java | 0 .../feign/UserFeignClientFallbackFactory.java | 0 .../filter/JwtAuthenticationFilter.java | 0 .../content/mapper/ContentCategoryMapper.java | 0 .../content/mapper/ContentDanmakuMapper.java | 0 .../content/mapper/ContentTagMapper.java | 0 .../mapper/ContentUserFavoriteMapper.java | 0 .../mapper/ContentVideoCoinMapper.java | 0 .../mapper/ContentVideoFavoriteMapper.java | 0 .../mapper/ContentVideoLikeMapper.java | 0 .../content/mapper/ContentVideoMapper.java | 0 .../mapper/ContentVideoPlayRecordMapper.java | 0 .../mapper/ContentVideoReviewMapper.java | 0 .../mapper/ContentVideoStatDailyMapper.java | 0 .../content/mapper/ContentVideoTagMapper.java | 0 .../mq/consumer/VideoMessageConsumer.java | 0 .../mq/producer/VideoMessageProducer.java | 0 .../content/service/CategoryService.java | 0 .../video/content/service/DanmakuService.java | 0 .../content/service/FavoriteService.java | 0 .../video/content/service/TagService.java | 0 .../video/content/service/VideoService.java | 0 .../content/service/VideoStatService.java | 0 .../service/impl/CategoryServiceImpl.java | 0 .../service/impl/DanmakuServiceImpl.java | 0 .../service/impl/FavoriteServiceImpl.java | 0 .../content/service/impl/TagServiceImpl.java | 0 .../service/impl/VideoServiceImpl.java | 0 .../service/impl/VideoStatServiceImpl.java | 0 .../content/task/VideoStatsSyncTask.java | 0 .../video/content/utils/VideoProcessor.java | 0 .../com/nuaa/video/content/vo/CategoryVO.java | 0 .../com/nuaa/video/content/vo/DanmakuVO.java | 0 .../com/nuaa/video/content/vo/FavoriteVO.java | 0 .../java/com/nuaa/video/content/vo/TagVO.java | 0 .../nuaa/video/content/vo/UploadResultVO.java | 0 .../nuaa/video/content/vo/VideoInfoVO.java | 0 .../nuaa/video/content/vo/VideoListVO.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../resources/mapper/ContentDanmakuMapper.xml | 0 .../resources/mapper/ContentTagMapper.xml | 0 .../mapper/ContentUserFavoriteMapper.xml | 0 .../mapper/ContentVideoCoinMapper.xml | 0 .../mapper/ContentVideoFavoriteMapper.xml | 0 .../mapper/ContentVideoLikeMapper.xml | 0 .../resources/mapper/ContentVideoMapper.xml | 0 .../mapper/ContentVideoPlayRecordMapper.xml | 0 .../mapper/ContentVideoReviewMapper.xml | 0 .../mapper/ContentVideoStatDailyMapper.xml | 0 .../mapper/ContentVideoTagMapper.xml | 0 .../content/service/VideoServiceTest.java | 338 + .../src/test/resources/application-test.yml | 48 + .../video-gateway}/Dockerfile | 0 .../video-gateway}/pom.xml | 0 .../video/gateway/GatewayApplication.java | 0 .../nuaa/video/gateway/config/CorsConfig.java | 0 .../gateway/config/DynamicRouteConfig.java | 0 .../gateway/config/GatewayFallbackConfig.java | 0 .../gateway/config/LoadBalancerConfig.java | 0 .../gateway/filter/AuthGlobalFilter.java | 0 .../gateway/filter/RequestLogFilter.java | 0 .../handler/GlobalExceptionHandler.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../src/main/resources/logback-spring.xml | 0 .../video-recommend}/Dockerfile | 0 .../video-recommend}/pom.xml | 0 .../video/recommend/RecommendApplication.java | 0 .../recommend/config/SecurityConfig.java | 0 .../controller/RecommendController.java | 0 .../video/recommend/dto/UserBehaviorDTO.java | 0 .../recommend/entity/RecommendHotVideo.java | 0 .../entity/RecommendUserBehavior.java | 0 .../entity/RecommendUserInterest.java | 0 .../entity/RecommendUserRecommendation.java | 0 .../entity/RecommendVideoSimilarity.java | 0 .../recommend/feign/ContentFeignClient.java | 0 .../ContentFeignClientFallbackFactory.java | 0 .../recommend/feign/UserFeignClient.java | 0 .../feign/UserFeignClientFallbackFactory.java | 0 .../filter/JwtAuthenticationFilter.java | 0 .../mapper/RecommendHotVideoMapper.java | 0 .../mapper/RecommendUserBehaviorMapper.java | 0 .../mapper/RecommendUserInterestMapper.java | 0 .../RecommendUserRecommendationMapper.java | 0 .../RecommendVideoSimilarityMapper.java | 0 .../recommend/service/RecommendService.java | 0 .../service/impl/RecommendServiceImpl.java | 0 .../ContentBasedRecommendStrategy.java | 0 .../strategy/HotRecommendStrategy.java | 0 .../recommend/strategy/RecommendStrategy.java | 0 .../strategy/RecommendStrategyFactory.java | 0 .../recommend/task/HotVideoUpdateTask.java | 0 .../task/VideoSimilarityCalculateTask.java | 0 .../recommend/vo/CategoryInterestVO.java | 0 .../video/recommend/vo/TagInterestVO.java | 0 .../video/recommend/vo/UserInterestVO.java | 0 .../video/recommend/vo/VideoRecommendVO.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../mapper/RecommendHotVideoMapper.xml | 0 .../mapper/RecommendUserBehaviorMapper.xml | 0 .../mapper/RecommendUserInterestMapper.xml | 0 .../RecommendUserRecommendationMapper.xml | 0 .../mapper/RecommendVideoSimilarityMapper.xml | 0 {video-user => backend/video-user}/Dockerfile | 0 {video-user => backend/video-user}/pom.xml | 0 .../com/nuaa/video/user/UserApplication.java | 0 .../nuaa/video/user/config/FeignConfig.java | 0 .../nuaa/video/user/config/MinioConfig.java | 0 .../video/user/config/SecurityConfig.java | 0 .../user/controller/AdminUserController.java | 0 .../user/controller/UserFollowController.java | 0 .../controller/UserMessageController.java | 0 .../UserNotificationController.java | 0 .../controller/UserProfileController.java | 0 .../controller/UserSettingController.java | 0 .../nuaa/video/user/dto/UserMessageDTO.java | 0 .../nuaa/video/user/dto/UserProfileDTO.java | 0 .../nuaa/video/user/dto/UserSettingDTO.java | 0 .../nuaa/video/user/entity/UserFollow.java | 0 .../com/nuaa/video/user/entity/UserInfo.java | 0 .../nuaa/video/user/entity/UserMessage.java | 0 .../video/user/entity/UserNotification.java | 0 .../nuaa/video/user/entity/UserSetting.java | 0 .../nuaa/video/user/entity/UserStatDaily.java | 0 .../video/user/feign/AuthFeignClient.java | 0 .../user/filter/JwtAuthenticationFilter.java | 0 .../video/user/mapper/UserFollowMapper.java | 0 .../video/user/mapper/UserInfoMapper.java | 0 .../video/user/mapper/UserMessageMapper.java | 0 .../user/mapper/UserNotificationMapper.java | 0 .../video/user/mapper/UserSettingMapper.java | 0 .../user/mapper/UserStatDailyMapper.java | 0 .../video/user/service/UserFollowService.java | 0 .../video/user/service/UserInfoService.java | 0 .../user/service/UserMessageService.java | 0 .../user/service/UserNotificationService.java | 0 .../user/service/UserSettingService.java | 0 .../service/impl/UserFollowServiceImpl.java | 0 .../service/impl/UserInfoServiceImpl.java | 0 .../service/impl/UserMessageServiceImpl.java | 0 .../impl/UserNotificationServiceImpl.java | 0 .../service/impl/UserSettingServiceImpl.java | 0 .../com/nuaa/video/user/vo/UserMessageVO.java | 0 .../video/user/vo/UserNotificationVO.java | 0 .../com/nuaa/video/user/vo/UserProfileVO.java | 0 .../src/main/resources/application-prod.yml | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/bootstrap.yml | 0 .../resources/mapper/UserFollowMapper.xml | 0 .../main/resources/mapper/UserInfoMapper.xml | 0 .../resources/mapper/UserMessageMapper.xml | 0 .../mapper/UserNotificationMapper.xml | 0 .../user/service/UserFollowServiceTest.java | 203 + .../user/service/UserInfoServiceTest.java | 219 + .../src/test/resources/application-test.yml | 48 + docs/HA-DEPLOYMENT-GUIDE.md | 339 + docs/frontend-architecture.md | 458 ++ frontend/video-frontend-admin/index.html | 13 + frontend/video-frontend-admin/package.json | 43 + frontend/video-frontend-admin/pnpm-lock.yaml | 3009 ++++++++ frontend/video-frontend-admin/src/App.vue | 14 + .../video-frontend-admin/src/api/admin.ts | 69 + frontend/video-frontend-admin/src/api/auth.ts | 40 + .../video-frontend-admin/src/api/category.ts | 65 + .../video-frontend-admin/src/api/comment.ts | 39 + .../video-frontend-admin/src/api/index.ts | 8 + .../src/api/statistics.ts | 42 + frontend/video-frontend-admin/src/api/user.ts | 47 + .../video-frontend-admin/src/api/video.ts | 50 + .../src/auto-imports.d.ts | 87 + .../video-frontend-admin/src/components.d.ts | 20 + .../src/components/Breadcrumb.vue | 68 + .../src/components/TagsView.vue | 229 + frontend/video-frontend-admin/src/main.ts | 23 + .../video-frontend-admin/src/router/index.ts | 206 + .../video-frontend-admin/src/stores/app.ts | 30 + .../video-frontend-admin/src/stores/index.ts | 3 + .../src/stores/tagsView.ts | 111 + .../video-frontend-admin/src/stores/user.ts | 92 + .../src/styles/index.scss | 140 + .../src/styles/variables.scss | 45 + .../video-frontend-admin/src/types/index.ts | 245 + .../video-frontend-admin/src/utils/format.ts | 92 + .../video-frontend-admin/src/utils/request.ts | 167 + .../src/views/content/category.vue | 170 + .../src/views/content/comment.vue | 124 + .../src/views/content/tag.vue | 142 + .../src/views/dashboard/index.vue | 424 ++ .../src/views/error/404.vue | 54 + .../src/views/layout/index.vue | 301 + .../src/views/login/index.vue | 228 + .../src/views/system/admin.vue | 230 + .../src/views/user/detail.vue | 102 + .../src/views/user/list.vue | 355 + .../src/views/video/detail.vue | 154 + .../src/views/video/list.vue | 185 + .../src/views/video/review.vue | 453 ++ frontend/video-frontend-admin/tsconfig.json | 26 + .../video-frontend-admin/tsconfig.node.json | 13 + frontend/video-frontend-admin/vite.config.ts | 47 + frontend/video-frontend-web/.env | 3 + frontend/video-frontend-web/index.html | 14 + frontend/video-frontend-web/package-lock.json | 6105 +++++++++++++++++ frontend/video-frontend-web/package.json | 45 + frontend/video-frontend-web/pnpm-lock.yaml | 3837 +++++++++++ .../video-frontend-web/public/favicon.svg | 10 + frontend/video-frontend-web/src/App.vue | 14 + frontend/video-frontend-web/src/api/auth.ts | 62 + .../video-frontend-web/src/api/category.ts | 47 + .../video-frontend-web/src/api/comment.ts | 114 + .../video-frontend-web/src/api/danmaku.ts | 28 + .../video-frontend-web/src/api/favorite.ts | 42 + frontend/video-frontend-web/src/api/index.ts | 30 + .../video-frontend-web/src/api/recommend.ts | 52 + frontend/video-frontend-web/src/api/user.ts | 183 + frontend/video-frontend-web/src/api/video.ts | 142 + .../video-frontend-web/src/auto-imports.d.ts | 177 + .../video-frontend-web/src/components.d.ts | 37 + .../src/components/comment/CommentSection.vue | 261 + .../src/components/danmaku/DanmakuList.vue | 120 + .../src/components/layout/AppHeader.vue | 323 + .../src/components/layout/AppTabbar.vue | 41 + .../src/components/video/VideoCard.vue | 162 + .../src/components/video/VideoPlayer.vue | 101 + frontend/video-frontend-web/src/main.ts | 23 + .../video-frontend-web/src/router/index.ts | 189 + frontend/video-frontend-web/src/stores/app.ts | 102 + .../video-frontend-web/src/stores/favorite.ts | 102 + .../video-frontend-web/src/stores/index.ts | 5 + .../video-frontend-web/src/stores/message.ts | 89 + .../video-frontend-web/src/stores/user.ts | 184 + .../video-frontend-web/src/stores/video.ts | 118 + .../video-frontend-web/src/styles/index.scss | 254 + .../video-frontend-web/src/types/index.ts | 339 + .../video-frontend-web/src/utils/index.ts | 199 + .../video-frontend-web/src/utils/request.ts | 132 + .../video-frontend-web/src/utils/storage.ts | 151 + .../src/views/error/404.vue | 38 + .../src/views/favorite/index.vue | 94 + .../src/views/home/category.vue | 146 + .../src/views/home/index.vue | 205 + .../src/views/layout/MainLayout.vue | 47 + .../src/views/login/index.vue | 247 + .../src/views/login/register.vue | 196 + .../src/views/message/detail.vue | 177 + .../src/views/message/index.vue | 112 + .../src/views/message/notifications.vue | 117 + .../src/views/search/index.vue | 130 + .../src/views/upload/index.vue | 203 + .../src/views/user/followers.vue | 114 + .../src/views/user/following.vue | 101 + .../src/views/user/history.vue | 117 + .../src/views/user/my-videos.vue | 147 + .../src/views/user/profile-edit.vue | 147 + .../src/views/user/profile.vue | 222 + .../src/views/user/settings.vue | 68 + .../src/views/user/videos.vue | 95 + .../src/views/video/detail.vue | 424 ++ frontend/video-frontend-web/src/vite-env.d.ts | 16 + frontend/video-frontend-web/tsconfig.json | 31 + .../video-frontend-web/tsconfig.node.json | 13 + frontend/video-frontend-web/vite.config.ts | 57 + src/main/java/com/nuaa/video/App.java | 13 - 513 files changed, 28251 insertions(+), 287 deletions(-) delete mode 100644 .idea/.cache/.Apifox_Helper/.toolWindow.db delete mode 100644 .idea/.gitignore delete mode 100644 .idea/ApifoxUploaderProjectSetting.xml delete mode 100644 .idea/checkstyle-idea.xml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/dataSources.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/fastRequest/fastRequestCollection.xml delete mode 100644 .idea/fastRequest/fastRequestCurrentProjectLocalConfig.xml delete mode 100644 .idea/git_toolbox_prj.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/markdown.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml rename build-and-deploy.bat => backend/build-and-deploy.bat (100%) rename build-and-deploy.sh => backend/build-and-deploy.sh (100%) rename {config => backend/config}/.env.node-01 (100%) rename {config => backend/config}/.env.node-02 (100%) rename {config => backend/config}/.env.node-03 (100%) rename {config => backend/config}/mysql/my-master.cnf (100%) rename {config => backend/config}/mysql/my-slave.cnf (100%) rename {config => backend/config}/nacos-mysql.sql (100%) rename {config => backend/config}/nginx/conf.d/upstream.conf (100%) rename {config => backend/config}/nginx/nginx.conf (100%) rename {config => backend/config}/redis/redis-master.conf (100%) rename {config => backend/config}/redis/redis-slave.conf (100%) rename {config => backend/config}/redis/sentinel.conf (100%) rename {config => backend/config}/rocketmq/broker-a.conf (100%) rename {config => backend/config}/rocketmq/broker-b.conf (100%) create mode 100644 backend/deploy-ha.sh rename docker-compose-node-01.yml => backend/docker-compose-node-01.yml (100%) rename docker-compose-node-02.yml => backend/docker-compose-node-02.yml (100%) rename docker-compose-node-03.yml => backend/docker-compose-node-03.yml (100%) rename docker-compose.yml => backend/docker-compose.yml (100%) rename pom.xml => backend/pom.xml (100%) rename {scripts => backend/scripts}/init-debian12.sh (100%) rename {sentinel-dashboard => backend/sentinel-dashboard}/Dockerfile (100%) rename {sql => backend/sql}/init.sql (100%) rename {sql => backend/sql}/nacos-config-init.sql (100%) rename {sql => backend/sql}/nacos-schema.sql (100%) rename {video-admin => backend/video-admin}/Dockerfile (100%) rename {video-admin => backend/video-admin}/pom.xml (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/AdminApplication.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/annotation/OperationLog.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/aspect/OperationLogAspect.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/config/PasswordConfig.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/config/RedisConfig.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/controller/AdminUserController.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/controller/AuthController.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/controller/ContentManageController.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/controller/UserManageController.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/dto/AdminPermissionDTO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/dto/AdminRoleDTO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/dto/AdminUserDTO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/dto/LoginDTO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/dto/SystemConfigDTO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminOperationLog.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminPermission.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminRole.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminRolePermission.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminSystemConfig.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminUser.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/entity/AdminUserRole.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/CommentFeignClient.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/CommentFeignClientFallbackFactory.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/ContentFeignClient.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/ContentFeignClientFallbackFactory.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/UserFeignClient.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/feign/UserFeignClientFallbackFactory.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminOperationLogMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminPermissionMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminRoleMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminRolePermissionMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminSystemConfigMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminUserMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/mapper/AdminUserRoleMapper.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/AdminUserDetails.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/AdminUserDetailsServiceImpl.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/CustomAuthenticationProvider.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/JwtAuthenticationFilter.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/JwtTokenProvider.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/security/SecurityConfig.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/AdminUserService.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/AuthService.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/PasswordService.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/impl/AdminUserInitService.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/impl/AdminUserServiceImpl.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/impl/AuthServiceImpl.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/service/impl/PasswordServiceImpl.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/AdminPermissionVO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/AdminRoleVO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/AdminUserVO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/CaptchaVO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/LoginVO.java (100%) rename {video-admin => backend/video-admin}/src/main/java/com/nuaa/video/admin/vo/SystemConfigVO.java (100%) rename {video-admin => backend/video-admin}/src/main/resources/application-prod.yml (100%) rename {video-admin => backend/video-admin}/src/main/resources/application.yml (100%) rename {video-admin => backend/video-admin}/src/main/resources/bootstrap.yml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminOperationLogMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminPermissionMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminRoleMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminRolePermissionMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminSystemConfigMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminUserMapper.xml (100%) rename {video-admin => backend/video-admin}/src/main/resources/mapper/AdminUserRoleMapper.xml (100%) rename {video-auth => backend/video-auth}/Dockerfile (100%) rename {video-auth => backend/video-auth}/pom.xml (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/AuthApplication.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/config/RedisConfig.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/config/SecurityConfig.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/controller/AdminAuthController.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/controller/AuthController.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/dto/LoginDTO.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/dto/RegisterDTO.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/dto/TokenInfoDTO.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/entity/AuthPermission.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/entity/AuthRole.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/entity/AuthRolePermission.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/entity/AuthUser.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/entity/AuthUserRole.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/feign/UserClient.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/feign/fallback/UserClientFallback.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/filter/JwtAuthenticationFilter.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/mapper/AuthPermissionMapper.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/mapper/AuthRoleMapper.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/mapper/AuthRolePermissionMapper.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/mapper/AuthUserMapper.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/mapper/AuthUserRoleMapper.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/service/AuthUserService.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/service/CaptchaService.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/service/impl/AuthUserServiceImpl.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/service/impl/CaptchaServiceImpl.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/utils/JwtUtils.java (100%) rename {video-auth => backend/video-auth}/src/main/java/com/nuaa/video/auth/utils/RedisUtils.java (100%) rename {video-auth => backend/video-auth}/src/main/resources/application-prod.yml (100%) rename {video-auth => backend/video-auth}/src/main/resources/application.yml (100%) rename {video-auth => backend/video-auth}/src/main/resources/bootstrap.yml (100%) rename {video-auth => backend/video-auth}/src/main/resources/mapper/AuthPermissionMapper.xml (100%) rename {video-auth => backend/video-auth}/src/main/resources/mapper/AuthRoleMapper.xml (100%) rename {video-auth => backend/video-auth}/src/main/resources/mapper/AuthRolePermissionMapper.xml (100%) rename {video-auth => backend/video-auth}/src/main/resources/mapper/AuthUserMapper.xml (100%) create mode 100644 backend/video-auth/src/test/java/com/nuaa/video/auth/controller/AuthControllerTest.java create mode 100644 backend/video-auth/src/test/java/com/nuaa/video/auth/feign/UserClientTest.java create mode 100644 backend/video-auth/src/test/java/com/nuaa/video/auth/integration/AuthIntegrationTest.java create mode 100644 backend/video-auth/src/test/java/com/nuaa/video/auth/service/AuthUserServiceTest.java create mode 100644 backend/video-auth/src/test/resources/application-test.yml rename {video-comment => backend/video-comment}/Dockerfile (100%) rename {video-comment => backend/video-comment}/pom.xml (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/CommentApplication.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/config/SecurityConfig.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/controller/AdminCommentController.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/controller/CommentController.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/controller/ReplyController.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/dto/CommentAddDTO.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/dto/CommentQueryDTO.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/dto/ReplyAddDTO.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/entity/Comment.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/entity/CommentLike.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/entity/CommentReply.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/feign/ContentFeignClient.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/feign/ContentFeignClientFallbackFactory.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/feign/UserFeignClient.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/feign/UserFeignClientFallbackFactory.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/filter/JwtAuthenticationFilter.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/mapper/CommentLikeMapper.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/mapper/CommentMapper.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/mapper/CommentReplyMapper.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/service/CommentReplyService.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/service/CommentService.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/service/impl/CommentReplyServiceImpl.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/service/impl/CommentServiceImpl.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/utils/SensitiveWordFilter.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/vo/CommentStatVO.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/vo/CommentVO.java (100%) rename {video-comment => backend/video-comment}/src/main/java/com/nuaa/video/comment/vo/ReplyVO.java (100%) rename {video-comment => backend/video-comment}/src/main/resources/application-prod.yml (100%) rename {video-comment => backend/video-comment}/src/main/resources/application.yml (100%) rename {video-comment => backend/video-comment}/src/main/resources/bootstrap.yml (100%) rename {video-comment => backend/video-comment}/src/main/resources/mapper/CommentLikeMapper.xml (100%) rename {video-comment => backend/video-comment}/src/main/resources/mapper/CommentMapper.xml (100%) rename {video-comment => backend/video-comment}/src/main/resources/mapper/CommentReplyMapper.xml (100%) create mode 100644 backend/video-comment/src/test/java/com/nuaa/video/comment/service/CommentServiceTest.java create mode 100644 backend/video-comment/src/test/resources/application-test.yml rename {video-common => backend/video-common}/pom.xml (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/FeignConfig.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/MinioConfig.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/MybatisPlusConfig.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/MybatisPlusMetaObjectHandler.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/RedisConfig.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/config/WebConfig.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/constants/CommonConstants.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/constants/SecurityConstants.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/exception/BusinessException.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/exception/GlobalExceptionHandler.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/model/dto/PageRequestDTO.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/model/entity/BaseEntity.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/model/enums/ResultCode.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/model/vo/Result.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/DateUtils.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/JwtUtils.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/MinioUtils.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/PageUtils.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/RedisUtils.java (100%) rename {video-common => backend/video-common}/src/main/java/com/nuaa/video/common/utils/StringUtils.java (100%) rename {video-common => backend/video-common}/src/main/resources/META-INF/spring.factories (100%) create mode 100644 backend/video-common/src/test/java/com/nuaa/video/common/test/BaseControllerTest.java create mode 100644 backend/video-common/src/test/java/com/nuaa/video/common/test/BaseServiceTest.java rename {video-content => backend/video-content}/Dockerfile (100%) rename {video-content => backend/video-content}/pom.xml (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/ContentApplication.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/config/FFmpegConfig.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/config/MinioConfig.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/config/RocketConfig.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/config/SecurityConfig.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/AdminCategoryController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/AdminVideoController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/CategoryController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/DanmakuController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/FavoriteController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/TagController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/VideoController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/controller/VideoStatController.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/DanmakuDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/FavoriteDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/PlayRecordDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/VideoQueryDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/VideoUpdateDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/dto/VideoUploadDTO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentCategory.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentDanmaku.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentTag.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentUserFavorite.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideo.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoCoin.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoFavorite.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoLike.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoPlayRecord.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoReview.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoStatDaily.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/entity/ContentVideoTag.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/enums/DanmakuPositionEnum.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/enums/VideoStatusEnum.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/feign/UserFeignClient.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/feign/UserFeignClientFallbackFactory.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/filter/JwtAuthenticationFilter.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentCategoryMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentDanmakuMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentTagMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentUserFavoriteMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoCoinMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoFavoriteMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoLikeMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoPlayRecordMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoReviewMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoStatDailyMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mapper/ContentVideoTagMapper.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mq/consumer/VideoMessageConsumer.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/mq/producer/VideoMessageProducer.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/CategoryService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/DanmakuService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/FavoriteService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/TagService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/VideoService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/VideoStatService.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/CategoryServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/DanmakuServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/FavoriteServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/TagServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/VideoServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/service/impl/VideoStatServiceImpl.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/task/VideoStatsSyncTask.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/utils/VideoProcessor.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/CategoryVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/DanmakuVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/FavoriteVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/TagVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/UploadResultVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/VideoInfoVO.java (100%) rename {video-content => backend/video-content}/src/main/java/com/nuaa/video/content/vo/VideoListVO.java (100%) rename {video-content => backend/video-content}/src/main/resources/application-prod.yml (100%) rename {video-content => backend/video-content}/src/main/resources/application.yml (100%) rename {video-content => backend/video-content}/src/main/resources/bootstrap.yml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentDanmakuMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentTagMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentUserFavoriteMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoCoinMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoFavoriteMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoLikeMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoPlayRecordMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoReviewMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoStatDailyMapper.xml (100%) rename {video-content => backend/video-content}/src/main/resources/mapper/ContentVideoTagMapper.xml (100%) create mode 100644 backend/video-content/src/test/java/com/nuaa/video/content/service/VideoServiceTest.java create mode 100644 backend/video-content/src/test/resources/application-test.yml rename {video-gateway => backend/video-gateway}/Dockerfile (100%) rename {video-gateway => backend/video-gateway}/pom.xml (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/GatewayApplication.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/config/CorsConfig.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/config/DynamicRouteConfig.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/config/GatewayFallbackConfig.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/config/LoadBalancerConfig.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/filter/AuthGlobalFilter.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/filter/RequestLogFilter.java (100%) rename {video-gateway => backend/video-gateway}/src/main/java/com/nuaa/video/gateway/handler/GlobalExceptionHandler.java (100%) rename {video-gateway => backend/video-gateway}/src/main/resources/application-prod.yml (100%) rename {video-gateway => backend/video-gateway}/src/main/resources/application.yml (100%) rename {video-gateway => backend/video-gateway}/src/main/resources/bootstrap.yml (100%) rename {video-gateway => backend/video-gateway}/src/main/resources/logback-spring.xml (100%) rename {video-recommend => backend/video-recommend}/Dockerfile (100%) rename {video-recommend => backend/video-recommend}/pom.xml (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/RecommendApplication.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/config/SecurityConfig.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/controller/RecommendController.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/dto/UserBehaviorDTO.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/entity/RecommendHotVideo.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/entity/RecommendUserBehavior.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/entity/RecommendUserInterest.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/entity/RecommendUserRecommendation.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/entity/RecommendVideoSimilarity.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClient.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClientFallbackFactory.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/feign/UserFeignClient.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/feign/UserFeignClientFallbackFactory.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/filter/JwtAuthenticationFilter.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/mapper/RecommendHotVideoMapper.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserBehaviorMapper.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserInterestMapper.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserRecommendationMapper.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/mapper/RecommendVideoSimilarityMapper.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/service/RecommendService.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/service/impl/RecommendServiceImpl.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/strategy/ContentBasedRecommendStrategy.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/strategy/HotRecommendStrategy.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategy.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategyFactory.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/task/HotVideoUpdateTask.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/task/VideoSimilarityCalculateTask.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/vo/CategoryInterestVO.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/vo/TagInterestVO.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/vo/UserInterestVO.java (100%) rename {video-recommend => backend/video-recommend}/src/main/java/com/nuaa/video/recommend/vo/VideoRecommendVO.java (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/application-prod.yml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/application.yml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/bootstrap.yml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/mapper/RecommendHotVideoMapper.xml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/mapper/RecommendUserBehaviorMapper.xml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/mapper/RecommendUserInterestMapper.xml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/mapper/RecommendUserRecommendationMapper.xml (100%) rename {video-recommend => backend/video-recommend}/src/main/resources/mapper/RecommendVideoSimilarityMapper.xml (100%) rename {video-user => backend/video-user}/Dockerfile (100%) rename {video-user => backend/video-user}/pom.xml (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/UserApplication.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/config/FeignConfig.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/config/MinioConfig.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/config/SecurityConfig.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/AdminUserController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/UserFollowController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/UserMessageController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/UserNotificationController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/UserProfileController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/controller/UserSettingController.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/dto/UserMessageDTO.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/dto/UserProfileDTO.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/dto/UserSettingDTO.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserFollow.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserInfo.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserMessage.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserNotification.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserSetting.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/entity/UserStatDaily.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/feign/AuthFeignClient.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/filter/JwtAuthenticationFilter.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserFollowMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserInfoMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserMessageMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserNotificationMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserSettingMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/mapper/UserStatDailyMapper.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/UserFollowService.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/UserInfoService.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/UserMessageService.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/UserNotificationService.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/UserSettingService.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/impl/UserFollowServiceImpl.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/impl/UserInfoServiceImpl.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/impl/UserMessageServiceImpl.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/impl/UserNotificationServiceImpl.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/service/impl/UserSettingServiceImpl.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/vo/UserMessageVO.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/vo/UserNotificationVO.java (100%) rename {video-user => backend/video-user}/src/main/java/com/nuaa/video/user/vo/UserProfileVO.java (100%) rename {video-user => backend/video-user}/src/main/resources/application-prod.yml (100%) rename {video-user => backend/video-user}/src/main/resources/application.yml (100%) rename {video-user => backend/video-user}/src/main/resources/bootstrap.yml (100%) rename {video-user => backend/video-user}/src/main/resources/mapper/UserFollowMapper.xml (100%) rename {video-user => backend/video-user}/src/main/resources/mapper/UserInfoMapper.xml (100%) rename {video-user => backend/video-user}/src/main/resources/mapper/UserMessageMapper.xml (100%) rename {video-user => backend/video-user}/src/main/resources/mapper/UserNotificationMapper.xml (100%) create mode 100644 backend/video-user/src/test/java/com/nuaa/video/user/service/UserFollowServiceTest.java create mode 100644 backend/video-user/src/test/java/com/nuaa/video/user/service/UserInfoServiceTest.java create mode 100644 backend/video-user/src/test/resources/application-test.yml create mode 100644 docs/HA-DEPLOYMENT-GUIDE.md create mode 100644 docs/frontend-architecture.md create mode 100644 frontend/video-frontend-admin/index.html create mode 100644 frontend/video-frontend-admin/package.json create mode 100644 frontend/video-frontend-admin/pnpm-lock.yaml create mode 100644 frontend/video-frontend-admin/src/App.vue create mode 100644 frontend/video-frontend-admin/src/api/admin.ts create mode 100644 frontend/video-frontend-admin/src/api/auth.ts create mode 100644 frontend/video-frontend-admin/src/api/category.ts create mode 100644 frontend/video-frontend-admin/src/api/comment.ts create mode 100644 frontend/video-frontend-admin/src/api/index.ts create mode 100644 frontend/video-frontend-admin/src/api/statistics.ts create mode 100644 frontend/video-frontend-admin/src/api/user.ts create mode 100644 frontend/video-frontend-admin/src/api/video.ts create mode 100644 frontend/video-frontend-admin/src/auto-imports.d.ts create mode 100644 frontend/video-frontend-admin/src/components.d.ts create mode 100644 frontend/video-frontend-admin/src/components/Breadcrumb.vue create mode 100644 frontend/video-frontend-admin/src/components/TagsView.vue create mode 100644 frontend/video-frontend-admin/src/main.ts create mode 100644 frontend/video-frontend-admin/src/router/index.ts create mode 100644 frontend/video-frontend-admin/src/stores/app.ts create mode 100644 frontend/video-frontend-admin/src/stores/index.ts create mode 100644 frontend/video-frontend-admin/src/stores/tagsView.ts create mode 100644 frontend/video-frontend-admin/src/stores/user.ts create mode 100644 frontend/video-frontend-admin/src/styles/index.scss create mode 100644 frontend/video-frontend-admin/src/styles/variables.scss create mode 100644 frontend/video-frontend-admin/src/types/index.ts create mode 100644 frontend/video-frontend-admin/src/utils/format.ts create mode 100644 frontend/video-frontend-admin/src/utils/request.ts create mode 100644 frontend/video-frontend-admin/src/views/content/category.vue create mode 100644 frontend/video-frontend-admin/src/views/content/comment.vue create mode 100644 frontend/video-frontend-admin/src/views/content/tag.vue create mode 100644 frontend/video-frontend-admin/src/views/dashboard/index.vue create mode 100644 frontend/video-frontend-admin/src/views/error/404.vue create mode 100644 frontend/video-frontend-admin/src/views/layout/index.vue create mode 100644 frontend/video-frontend-admin/src/views/login/index.vue create mode 100644 frontend/video-frontend-admin/src/views/system/admin.vue create mode 100644 frontend/video-frontend-admin/src/views/user/detail.vue create mode 100644 frontend/video-frontend-admin/src/views/user/list.vue create mode 100644 frontend/video-frontend-admin/src/views/video/detail.vue create mode 100644 frontend/video-frontend-admin/src/views/video/list.vue create mode 100644 frontend/video-frontend-admin/src/views/video/review.vue create mode 100644 frontend/video-frontend-admin/tsconfig.json create mode 100644 frontend/video-frontend-admin/tsconfig.node.json create mode 100644 frontend/video-frontend-admin/vite.config.ts create mode 100644 frontend/video-frontend-web/.env create mode 100644 frontend/video-frontend-web/index.html create mode 100644 frontend/video-frontend-web/package-lock.json create mode 100644 frontend/video-frontend-web/package.json create mode 100644 frontend/video-frontend-web/pnpm-lock.yaml create mode 100644 frontend/video-frontend-web/public/favicon.svg create mode 100644 frontend/video-frontend-web/src/App.vue create mode 100644 frontend/video-frontend-web/src/api/auth.ts create mode 100644 frontend/video-frontend-web/src/api/category.ts create mode 100644 frontend/video-frontend-web/src/api/comment.ts create mode 100644 frontend/video-frontend-web/src/api/danmaku.ts create mode 100644 frontend/video-frontend-web/src/api/favorite.ts create mode 100644 frontend/video-frontend-web/src/api/index.ts create mode 100644 frontend/video-frontend-web/src/api/recommend.ts create mode 100644 frontend/video-frontend-web/src/api/user.ts create mode 100644 frontend/video-frontend-web/src/api/video.ts create mode 100644 frontend/video-frontend-web/src/auto-imports.d.ts create mode 100644 frontend/video-frontend-web/src/components.d.ts create mode 100644 frontend/video-frontend-web/src/components/comment/CommentSection.vue create mode 100644 frontend/video-frontend-web/src/components/danmaku/DanmakuList.vue create mode 100644 frontend/video-frontend-web/src/components/layout/AppHeader.vue create mode 100644 frontend/video-frontend-web/src/components/layout/AppTabbar.vue create mode 100644 frontend/video-frontend-web/src/components/video/VideoCard.vue create mode 100644 frontend/video-frontend-web/src/components/video/VideoPlayer.vue create mode 100644 frontend/video-frontend-web/src/main.ts create mode 100644 frontend/video-frontend-web/src/router/index.ts create mode 100644 frontend/video-frontend-web/src/stores/app.ts create mode 100644 frontend/video-frontend-web/src/stores/favorite.ts create mode 100644 frontend/video-frontend-web/src/stores/index.ts create mode 100644 frontend/video-frontend-web/src/stores/message.ts create mode 100644 frontend/video-frontend-web/src/stores/user.ts create mode 100644 frontend/video-frontend-web/src/stores/video.ts create mode 100644 frontend/video-frontend-web/src/styles/index.scss create mode 100644 frontend/video-frontend-web/src/types/index.ts create mode 100644 frontend/video-frontend-web/src/utils/index.ts create mode 100644 frontend/video-frontend-web/src/utils/request.ts create mode 100644 frontend/video-frontend-web/src/utils/storage.ts create mode 100644 frontend/video-frontend-web/src/views/error/404.vue create mode 100644 frontend/video-frontend-web/src/views/favorite/index.vue create mode 100644 frontend/video-frontend-web/src/views/home/category.vue create mode 100644 frontend/video-frontend-web/src/views/home/index.vue create mode 100644 frontend/video-frontend-web/src/views/layout/MainLayout.vue create mode 100644 frontend/video-frontend-web/src/views/login/index.vue create mode 100644 frontend/video-frontend-web/src/views/login/register.vue create mode 100644 frontend/video-frontend-web/src/views/message/detail.vue create mode 100644 frontend/video-frontend-web/src/views/message/index.vue create mode 100644 frontend/video-frontend-web/src/views/message/notifications.vue create mode 100644 frontend/video-frontend-web/src/views/search/index.vue create mode 100644 frontend/video-frontend-web/src/views/upload/index.vue create mode 100644 frontend/video-frontend-web/src/views/user/followers.vue create mode 100644 frontend/video-frontend-web/src/views/user/following.vue create mode 100644 frontend/video-frontend-web/src/views/user/history.vue create mode 100644 frontend/video-frontend-web/src/views/user/my-videos.vue create mode 100644 frontend/video-frontend-web/src/views/user/profile-edit.vue create mode 100644 frontend/video-frontend-web/src/views/user/profile.vue create mode 100644 frontend/video-frontend-web/src/views/user/settings.vue create mode 100644 frontend/video-frontend-web/src/views/user/videos.vue create mode 100644 frontend/video-frontend-web/src/views/video/detail.vue create mode 100644 frontend/video-frontend-web/src/vite-env.d.ts create mode 100644 frontend/video-frontend-web/tsconfig.json create mode 100644 frontend/video-frontend-web/tsconfig.node.json create mode 100644 frontend/video-frontend-web/vite.config.ts delete mode 100644 src/main/java/com/nuaa/video/App.java diff --git a/.gitignore b/.gitignore index 5523a78..cabb779 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,56 @@ -target/ +# ========================================== +# 后端 (Java/Maven/Spring Boot) +# ========================================== +**/target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ local/ +# 日志文件 +*.log +**/logs/ +**/log/ + +# ========================================== +# 前端 (Node.js/Vue/React) +# ========================================== +# 依赖目录 (绝对不能提交!) +**/node_modules/ + +# 打包输出目录 +**/dist/ +**/dist-ssr/ +.output/ + +# 环境变量 (保护本地密码和密钥不被泄露) +.env.local +.env.*.local + +# npm / yarn / pnpm 错误日志 +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# ========================================== +# IDE 及编辑器配置 +# ========================================== ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea/ +**/.idea/ *.iws *.iml *.ipr +### VS Code ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + ### Eclipse ### .apt_generated .classpath @@ -28,12 +66,18 @@ local/ /dist/ /nbdist/ /.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ -### VS Code ### -.vscode/ +# ========================================== +# 操作系统生成的文件 +# ========================================== +### macOS ### +.DS_Store +**/.DS_Store +.AppleDouble +.LSOverride -### Mac OS ### -.DS_Store \ No newline at end of file +### Windows ### +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ \ No newline at end of file diff --git a/.idea/.cache/.Apifox_Helper/.toolWindow.db b/.idea/.cache/.Apifox_Helper/.toolWindow.db deleted file mode 100644 index df8a67abe54586c47bc9b7455ffbf19c57e93534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 425984 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�%wq@91KpTT-2hIo64f7M%J|m;x526vt;1z-HGl2s_c>y>Gh!ocY`c(UOGO9|w zqV{_-ir(7g*WfUqoKrI3E!VgB7h&yKX9U*S8pgW7S z+W(V$BY1fQh$f`Ud;*&q>lE-Lixwm&SiIW5O-2cq0GuL#)`1m+gkXIdfVIGyf#C9^ z+P{%ef?4UO6jl4b1tL+2Nta6j28Y=L3@A7Yq>Vfl8Bk)F1Ykg-Mck|XLUWWrss%0s zpoHcu&_U*Y6Eb)J8o|JRP@!XiAYV$C7x)w)^)Dxbs(22PL4#nMD?!=Gm8wW1lE)i}5{MQ- zRtrc@aHi~fQMnad7t9=x*?Fc{`vLhv5N!RCFv*}QkZ>}n3cfD44(9-huPk8?03w(! zfK1@h0ho#yd%#WoNOCEl)2vV%GnBCIc`Rlyz~p|x+Jh*rCzq-KCDeXB83nZg-Fs9C zdBdvrhn%qXdZy==QKzQ4Mkl>ZnHp!h=QZ*%a zUWE=!E(QM#eVo8!!RkVx1)4Gj#SGIRJQwg@)P6X*R25_~xfBpHpop;gfc*s4C8rY- zW57#+hhflbKbVZFB%_iqtOPB}rKmA*4EE*#ul+_cs-lWs`_<$Nt2i{0K~+RR$)F0I z@`Q1w62+a|c_p)2I!ff}=)D4X%zV(d<+5L)_k;D2Be?d-nKa5u7;XAqRWydy`95p?#Z! zU-)wU zlVfAM8yj0Q0)=Z|KIHZtjCMxedF%V$`BdX`Z+-G}A3xX9Zhg;v@A;#j{f_1@-~RYF zy#0+o_Rf!e6qVQhny$y9nfmF;nU|)cs1Ci?lPBul-a@ri5{rJ$r!ffQt-&<&qOz;hIg{2b*+OMI%uz7Nq z9g3N~UJ5r`fm|A3*7gQ4`T&lHfr-clHyL6pVb~4*mRnem0w z))S{^k3KR#``F33nPc(7(qsPYNjsQ6cKp!%;){>WpE~N#oqX|wvnQ>Iyjc)TQ{@XO zG)-2mr_QEH;x%Z#2p`F6%ITQU-z1&~d0MDX8QZ-6;{cD7HcLVa7hYlL&!MM+NRZ4T z*({i7VEKiBGfJ*5Fy%}Iogf=_CD_Vg5QMVQf{c(qB}vQS3_?{p+Ox*!VS!GN8z2?{ zGZCz45C4?C@J&S)p2?mL|hYnkuP z@xxf{<4Zz2a5)-n>QL}>B2J*&Lc32jPUKstDUv6bI!>w4uD9HVr{+XYJBr-J7D8$2 zr4#jNdiuDy7}+>nk7(+Ng>D9!F2mj9r4%f8)yhh?Vv1cF-g09k;bDzPSHr9fqZ=%9 z)PgD6kwFqZ*KDJ=EH~u4)RtgI6h#(rdIX~;B%{QMRF()KJNEjpmK&W4DFecm481Ry zU>EXRsC$G25CUH3inQFh4bI&5G~YdzQ|?cOw%^U2-tkH=YxAw1f3mS~+r%43CK}_L z?-%p^#tW(Wu4+3T%>3~sZ>fvyD|a$8Wc*C`n8ak~0ZB!hJn5f|f~7pm z%jgc-(YVqO_2T~l8?|5oN3jIFFPKO?Y80Cw7`4l+^3f>6j7HDZ_f5I8&^*uYo2f4h zVu=MmT0Xx8>sz%j*c&b6=>mbW_+k+SqXCFo07?On69|GRLyn5# z0lht#akQ{>5WG~(sh!XP;y@{C2({Q1=Qro}Clk=q`p(KOZf?=su+-uf;Gzt|V4q%? zKNGc0YPwhXEQk0U-FB5*8?{fYyne7Tzh$DaF!q{cmDaYhO0cl@?dWQ|)vJ+JYUPvq z=Zy|wGMag#j(pJw@?H{_ zPr&}rD@V)X3W0;m$Gu~T{K3=}A-3~9SuC-#Oi%7n2IP{IZPk%I-Tz?jB7133r0}7* zh!a7Tt3dimA0w1w&`P7{V3hLGJiO1Fu1DVEi>GD}TSt+hd3N8FX&zrN7iM(xxr2{? z`MCeeQgolUxahs|{?;K>n9IT;RJ8(9i;-A-M6+Cxo1jLEa6kZ0GOdsBPNO&lalTrT zyb&UL#KjUpm53e!Ja2R;NC43qDP4NW)jN|nU}J^c81V>-N+NzhqmimY`Uo`v2aRw< zX2vbKCER*ov}lfsj3L=dHy4^; zxk!H8FK!OSg?22zFfb@x^k9yilr!^QoE82?DJ|@uDeY4EB z?@b+We0(AD9$M_qth7vNI?)9KTD2h911&FpcmqmDFKm>EPof7xvk?+6Au=~KxRc!$ z5s>8Sody&|C%V9C5R@KW{)>KK2nR55$YdelC0=>9B@+XRh95LB0s0o`7SL>rNkor} zzr!NZ<ai^7M#fL@E^M|B=9JEppW2ROfSB;nl7pV?bwpcXZF+LEJm&w z{H4Fjec0P%4zxErUR>L)Z*5OLz2vQ`DfR!GubHgvx%Q6jyWQL4UEjTH`_^}E{nX7r zaKr2T`szQ!&A|Eb#;L9N@~{=(ot#lK=^0f8QW^ajMU1*oU+O%B(jr0egCw=IOk(1; zZ~s)2a(X1S+@djAM(!zhk-Z4a!h8tQh|G6{>Y|OZhd~FFsA{3@(}P$zW3frnPLI^5 zyLty?(wgR_Ije=EsOr6^Mq-)1JQ*HQu|c7VrY)dZC?knx7=F43;K$ICtFPoJ8iH{W zxB-&(;4dJqM9>?NHZWH3n9)Fo%#g>dfSE`}Ab==*jN1TH92n^H{KzRWCf*9T{!o(0LCeCec6-!CWE9 zh9Die31rLA1p|ixoK(2f^T~I_m2l4C%|-4)2azK>;3%}=?W4&7#c#*HOUyU)j!5^$ zG+C3#0O%0|8s!^QlFYj6Nr4#6=E0DwZH?H zn8dOVQ>$%hr zqEX+MxMB2$a50*mIl~;6Si-W8$~?ug_C%3-cq+X#?qShfHcjQFXd&q^fI-C4EU;5> zGN5one=mqBbTaAd3M(RP?;|fxP95p%HZ~``U>~dAeY&!jX&+&I0AG*lD+;M}IfD>H zeim>f&|8b{XR%3nzmd`#)E9!UvMiKtePpzuW$!CD>0nYso`X?YC@g?01=UBkne~FOWQ13vv8dl`sfWODUg}6@VfB(VNB*R zxoD}q%z67O#h4UNILv=nk4?8Qj`((cIu9rw5nzgrWaRkhG)s_)>LY5?;6MGihkRu& zFX_&9`;_fqJDJsj$*g+o>6%`q$qY@XF=$i6d4u1CN|!?x!GqMw0YvlSYs`y*1fH6yDA2<_7zIH?aFTIum&{sxLFUU9zJm_yTSRA z8_dB}$ws(o!jqoCU3%*wstD5hKE!<8^X|>?w`EUsNHf)Erw-S{x!F_C zO*!@OgOAS!-SwN&r`a#puA1S-^NnEB#MuOG{6OoGaLEK>;u7uB0>QeV(+Wj-$It`U z)opd~M@mNaeZbZ_8u&FO54JzKa@E{7;)V~JdfV6wyt1S1=M(U}ZAwNM=^0vv6YeTV z>&O(C5Sc9Z`I0Tu?`=Nx$e?Sn<01FUWvgCE<0B1^C)JZDeY*9epi*>ryhy3Rgs1T@ z8tM#0A)sm@=cWcDdD1wVnV#?ak{_CSZq}O$>$zUS-mA9xa+BxYpIqFocwu7KuD{`l z+8y7!{m7;>w;ba?ul{p&2CmM))fu=t16OBY=oz^1;l>AnOrMf2-N$yEo0xcWO`2$k zD(GDYOf;k}=ls&*!t5;G=hGbVk1s6E#4~}nG_x?@rsODK9Of6P`sT;h=es(jC6J;(u0#%JG#V@sCqyuQTl#>{GBz3Yj!HS3q1m|gEY_{m{EZ1`#IC%>4w_`!a2 zIQ(M&&dJQGyj5jZbyWimG-8GVy0WwKa?byJ=llNO|6e-a(m?;(QoL0=R%a)wwXL3n zjb={w!sfQTT4(g?OPQ!ZppPg?V2pnjJ=wkLgymGl_!FM+N%Nu`O>m1mmgy+zUfR+U zhinq9eL>O|l8>0aB7S4Ac4u&M<9Xa4)0ZFw1wJIaHsH?H=#Sg4?wz=T0X~S=N~Fx*w`}0h(;>0Y`l9B%!sViPLYvLsS4`C zeKoT&E%(Ir}+R zGeJ@S03TLz$@6~~+;}Zt$%Cq8z^8cPd54Dj4f})N+*$qH@_V0J-g)NO4>b1wMvnbd zecb?6c`Hs*hwY=oD3|OWeOU1>%*DlG|Ax4AqYV46unbhIcFni1mWrjf%dm5yhwf1? z*7#Sd4LQx#pvj<}`!MLvTK69VC(xk}c$tW?(#jPAS4c~spz9)tj(mR5ZURj2+%>u} zZ?6<4z{OH<$r%h*?b~X3s4oXfQlsaqYOD)gLolCtGp-AW+2gB@fCd~fl#N0Q1$;!I z@exQ}1frTYl9&`Inl7T{s#^xtct21U@K8z&PZ+);ixnuLFKG%QZs<5l2pBq$Qh1~h zk8bfebXX*$XF%!T)H4+c=ROGU*}BjM2t1Xp6`>UqD!*4`&6|ozvmirh42)9gt;F8> zznaA@6V~oaJFl`uSjk(TmzVDrwMg0F?XdV|;`#OUSyqbjYNGcAAXP;WuixwM(MvJ+ zH$B&tAR--%7&%fF4jOUjP~cI5Ly0fq*p||hZJUA@WU&(LX$5Eie%D}PcBxQnM!+W@ zOkhqkw16*%4mSmb0N+sZ^*%H?)qEL?2>x7ZBBzqjh~XQ? z%&fV&kF|RW_$^brg55yunBbyv*d8JN!Nhd)gV%O06Z(IDdFN3jXF=NMb{_iUZGoeS z1J_>tFYXv9k2x0Z0Cdn|=437w)7b%*@%%*?du6OX-SWoQYsY9jpDoWb3iR{+T`BY* z|C7cl@RGPHzka!v=X!PJ8&wYA+-K`tR|eCkKMiGaSZcoQ(bbGG6&VfECIr3oQMauO z=LUu7Q?W9vURXc5cCDe{%i9_AA{(nh*Kpk1s(`?$Z(`r&Q|dL%kYSIn2OA=sqEL8p zl%7R3JtSNNG+Y5OntTu3Lh7k(2|^R2G(+)$N^qeUDlHc!ab|!R6ytZ~*ajpaEWFV0 zfc38$M~d{2ZPF7SNH!mskg2mmz(L?0Z#Kw`C_QoLL%t1Y0S6vR*DgTeL*=l1MVK`o z)C&_DNWv8q`@_-RU@TB@^npz)8SlQn^SvjQciuj_0}tm5J5LNt^vG@dSle0X#|ctN zZUBJ{<|17KSi`}%m`jO%lwKd!>5(V@`5*k{FMsyezxX#l>nS|-f-DGoYlAxjr6}54 zfJ))I;@H%A4fQzISHh!7@|F4c5|GS_6@{><~_VY(S^XOlE^czQh zHFe?Ve*cAcU*7p!=$0{xo@5mLcsPh0*Gpit1enMn`(%@QLBqqtK@SrlC8RW$K~&{= zWJ35q|3`oL;rl;*K`}r+{Mnx|pnmbs|6;Ow+4;dxy)3>iS1)c|&bT31eXMECDQ|G6 z!V^*W{^C&Ce(XTfSEmKB^wpeMUz3~Ldh~RWVBX)@`4O5tuPcG%3&-z%b@?Z604Y<(joO%&@&2aeMTpU3oLxbQYdMj z#DJChkYuPEeoQlh8MLaJU7V``@}#HV2+q0&O}>ojNC*z587t3MXqTaH2Oj=8G_P@o zwqpFY)b8#p?c>;`-3~`snh5E1vm)EW$kMQE8F`5K%*;yO^Kg6aoi0G^uGO`UMc!TZ zzH`B|%9Q29YS@*zPmGzhm7~Y+$BRzjnn-=twZSOVg69jkg~LE~GkuReL-suQ_k^|7F=?EICW=*FB++5S z64{H*$iP61?XKCj!=0Z)$ON~RCd_sW6$b1uGdexY-cRNr5v?bYyx;(V|@R9(V#K>=(=y6SabwD%Ck@u2v478ensmA5L-r5!QPDV>>?pVV_jhDN`ft z(lDf*?5;jvgslmJR)JO_-J;+OQ*cKmw)0xW;iuN& zZ9KjvM51zQhg7h96PQ3bj9xT}(jw^wlo4bmlA9NgriaM;NrD&aX)Kd0AI$|SS5gG% zh@c@tdz0x4ci}9u`v4+qGpz!CMNz0S*(yhj&;FI;&ng%WL(o~0auc4|`~pq$@4mhB zd%z%hwH7m+>oCf};fG~?c)potTElMVH@L5r}e4kkQQ_VFUlVUNYl(4F6v{GDC_+S8WsqYfEW618MNO&R7YqAkHEDWO}Z)OGEJrAIL+lhmJr72bcHwAzB z5UKpU8}x<{*Ng$j_+IS&fz1#849sM|-(n`)l}(>Zvbd$<(6)E%ZzijrY)1v5t4;9T zAMRW!)nJ|(rq8>W-HUo6Sq68GTok#;<{HX2EkX9hBbO_!X%^hk*gAEYQPFY5~pd<`GfL-XHwNCA>#?@E;?k}Jy(Z}O6XARsH#nNZDXwRYk9=c zCX&2A*ijlW+`=m*t#dw^WgjE5fPT*a0glOrD*TrQ(V6T=XSRxV+e&DFQVl+_`7zbFAV1gA+iNXdQ)kb; zcnApx(95lM|rTnHwH?Ail_gI^Ub*-=bR1=@!334XzwH?!=0`Dj* zNCdBpD4}N)MU~VTqxiLYVQXdMigK^Jwz4*8I1ywIl{RJl67_>`EYe*AB}cMsMf4n3 zkp?9sm=FFGVxR1z@Ri|>7t#^s(Ob)IJPlm^6|*kVbU?u{MVS}Zht&2g6k9MNOCefX25v+% z*Vl{3JD>6N+&j1WeFj_QHL-A2<}4rPyZg(T zQBHAtYT8yl%$MJ6kQFboa4D!Qz`Z6f=P2H7$8uU+)0`f8pS85tgU!qG`LXtHa+Rj0 zOUpZ7K6XZ<^Nk#x1F8p3f+D;d(-|pKW<6%x5!&!EiU>ivD0Eh7oeT`l%5AZ>-VV?= z2hsXkyp-re+TnU!I(2V5ul(Aeu~#%1^T#<^c(^!dzW_Ulgc*<+WakyL{lG;AD|w7p z0-(?`ZPAvVxv)}@*K@$8q4nlKoV|AG`ua8Tch>J*IJmA&E}@!nda}kM`shiQRbQFCpe`<$n$a;+f(kMS#Hx^3i;U@T}=5m-e>qv18d|9tkS_CX&@eJ)6W`%Igo3esMQar ziT`=?(wXV;U%j{n@OKTke1gpw%+pa}IW#fRkHmOZM!$hlH0S==T3Rix5Cp3am$X5JY7%J;YQIui;T^UETutF@$hj z`kd&q^$iPqW7O3#IA#qJ)Sa!FU4rL3*6u+tKLUO=_j$q-VPB1+$}!{cp64=W5GcL; zQM6yj0S-EVD}uReOR_S{2&==BAS)yD1;G;@Zmp?}jue|uq(l=}1o#GojzAOE4i>c_ zh$P9uwKd`||4mU%o&%Z(Yow8?lcg+YsBOeWJW~Cg~FAntivVoQ{=@wfl{0D9&^|g zV9le?UiSGh>Dcy=V)u|DKxT{#MT$HcqGYJl$62AHg6KB3kFYolT22k$O+w8BH!h~Pl~7)=wO4~gZHkHRc$Twk#bm&22n@$h zAHREM`R>JhB@~3JOl)8TPcb&|mIZ|JR0EW*NO$*@fat!=N_AqexxRKo>KiGqd8dcT zm0Ri_m()S+d9MRdrf7Rj-0bv4irR@zz&CUd3Bcn%!nEFVp(EnnfrLX!oX;+xZShk) zgY|*1)>h=1fm|~goY?@a^9*XGirRZ8As}?S6x$g#a=)@vG!_;QlBVZ@knm{vfR5^eDsutwJ1U>9t9HNauE=(jW z%$TvJupTVA@5^FsRAj~Ice*fg+L}e}TPm-J#ilfm`KWbGT&fMB%5nJ`d5}sMwI|Y_ z1keqUMe#pB($)I^AN?MWKxlgAR& z&|-XU9S4aV%c4pEX&dhyUx_xGPUy_OtFBGDN-VL*NTRmIUL1KbpVd?Ee`@zWJK3Rj zq7x~ScrmR-PMCOxi3=CrW^`ZDh$$g48m*brvt98+c@tfS{zmlBHDL7mp4Z2wj~>uf zP$rNF8xs!`(bBpPS%M;4fICiVHwB-jt&dG11DL=K#g8h&wH-fbOgK{n*#lv*iKj}Y zuVr8BW3{nxZ=#3c%&o)(gcakq0hQy%?yqN?!koLgi*6MinCC=RcU0REaQ}QmTatIQ zE3NMVYmtMq`;-8oPrydA^=|L^Vz)=fCJ7@8FG(+y)Jy`RSf4E;>d<7*_P|D~4X6r2 zXS^1D#H8KcLFJ>>Zhd|LozUl*nyEy$fLte}X5>FmrG_?WAZ8tRaM7mO;HgL7KxZWE zCJq+HuF5XWxVKBqfL>N)wNvPJwrhj|l_nV5IFK6xl~#TBa>{do=nQMzA^DFLW?=G+ z5#~XIz@m`lLU*%#rC0Otp>t{0DwN6_J*!-_TRKhiATZL}Cb7Eh`Gd3l!EgU9XbK-u zGBK+Po!>j2qjO-munjG^JAuGr7R_LEpvbU<gs**0wrgP2Qe_ z&pA`!+Sc~c+xZ&U=DW~ANh=76qxPX*oWv$oL6ud%u5WB^M1|U8njeze3EirOXTwwr zsanN8gn0+Gg2We<%4Z@4?r_g6FgMZ+r4#`e4qEUzk=;Nk?7dDoU32JFc zlfhubmJN%O-ejDP>46t+>eRmoHH>6%u(yA;&s^&(5kz6X57fZ+A zcj{W(Abf7W6MGd<=z#zB5mou6JXQx9iZ?rkpFATvaMot{~@iddPtH8uc{a|2%b`iUzO7osPNcd1R{(S zq2Gy!>e*tr((rtE4S{DWUG4%rvP*(M=+n-P&IcOC4zeCBhHQ~x2(ffH0mm0>hZ|z* z#xib`R${%d72!Fc66bhm>2nSaefTyGWt`vvOxii*OGkY~Reoy^YsZX$!Pgf9g5~0s ztev!q85}YfW<~2_zmV0$++F%1IiYi8?N8{O&=2y(1dSKd#RNU@TvC%v5vEtvfRG5l{~LZA#cgw8Lo3Zy6b8;SJ`zyrqLfySV+nrsX;IW8&044{^7#a9>o0i z6`qR@b`T*!;nD_ZvmBTJBSJl}#%$cn+7^cq4{l6`sF}iVAbi)D$*0GR2v69J9|?pr zVNrC)rop1K2d(79qn{sVO?~$A?!d;e1eZeCK<|MgWo&_8!j=q z3|b`PSlILf0`(R|ICd%Y@3Q-NI8#H#i@s?(LX=()IWXve|hY&Pg#%t&yV~MpZK>Q|M|y1^|9aO$A^CopTPa` z1a?0CgU>FzN8dbp^vN&d1ER+5kt499WReH~o9J8waU_KenK%+i9|U3Q7Ta*_wK4kM z*dpKjwbu3OwJSHToPYJsi>u$g6K%e-9&NsSy3&-Xf3#6UgS5R~Nm>NA#pBvqr zW6{s6d4IT7Fm}))#I?zijs>N}^eWG=7P9HpE^0wXT*{O3_yX!>6W`UlkG#f>fAi>%xN$MOaU1=Ulom839V0tT!o>9ObqTB_AsH)DIma8< zvaFLI!)j*NQUR8U!}^rIzTy#_(qGZ_F5ms(>J!WFKAPFw?EKpBQ6NpPH6?sY+12|Y zz$85ja%?CN>F}nT$<@JL9|P4#kty}f;&xNWm5Ev0Zt{z2a^3ZK&7P$eNqRv!@RU4n zy2i}z73E%g4q@CUt{%S|F5fLSxpXvoj+glOcd!~IB7t(O^iZr&#$;^zXG|wtVP${2 zwi#ndd|SRC?rhy!Q%XDoX5zD>a5>lKyLoF%Wr$$B@cB}jA6*jZ(;qBArLW;+*mO3} zUsG3#TtAW}J+QP|R{f=M*R|ldnLC*9SWgIHMp)FdmkV&qqie}=nI=L6Ci5g{Z}vLB zvbqMxoo27$K)t*@SbOdIN%89Km5py-Z`ha9X_xsF_Ix9aJ#p6%W0Rm#MtV=|!~FvE zV8OF_r+Lj4p%>GT8+)$h*;+0kJO7XhkEk;u=V5?zg&A4O56j`X&>m(bbc@Mm))P8~ zW#OqnLO?M_oYb&mHpq0Cxirs3YU5h$l=LM{L1u$EM7Y6|sxw4W$mThpzGV+&f)(+QEXKFc^7iqZdPRuyvZN?O=s2p>-R3j;qQqkKHvlIBv~U zXYrE>YQJOXZS#2x{r1F@p7l`0M;~PGzJQJGT~~qok2JV1=NZh%Hc+z)5T;U7h+sOf z@ooyVldUHsce!r{bHc^6g8Pf~C-npNtdmKN11J-!DhAp=)Sxb9BGDgHd9}!biOfa} zYd>N^o0e?ymu<0X6Vw$$LNzl@3F@tHqY3C8!-|=@2S7Ii7ZL*nJ;cQbgLwd|o@FU) z$6g~=rK4(Z(*gkHV+++`BtocC6JplCK)UMz$h~E|@ zw2r6BFCGH9-1=%BPg=VdzXy*ljFf}}i{+!)UBTorVBS8WD!+M%<|8yW-(S6i8PO%sT)AF`%Rec^ zHR*K<5f7w=!Bg@kD6-?wh1s8Kn^sb?b4PQCCzpw^U&>M{6Ot`C?d0t|9xorMUhPDR#Pnv@B`aFQHFY_x!}h?QzGza_y<2-&#R zbBPuTfk>-`jZDcD21Zo7kVKOPl9?o~z+nu8rGc4J5W-lS-N0y0!)re?CDqAUfzt*M z*9K7K;2e89sKoqAk=^3#IfZMCxzW5H=DZUgy8i#@$FCguqWJuufA)X+_5b71CqFUZ zpND@ApTOZ0ID7(ocmnT!{uL^+7mjXGk-af2Ln0sTlSpOdghYU`6*aO{QkcY=faNOo zb!1%Z;-{;*=NLPz!K#1X+FDa+j*U;o4GhadjE|M zprlcD=K1XlE0<1g3_n|a`8v{3w^!EQyn2#&u+ID_zNvEe-7n$P^U4$bjM$b}w{F$7 z%({l*?n^I`J~Eego;iN`II8}4FXZW?AdOsDqlj402w;%Mbd4k;DS-;S=SF6KCUaH? z7>${6ms=?c zS+maf(AceXjjHl)1-?cYDPc2+$QC796jl;PkO-2#k7i-SvDx{DbzL962g+?Crqu+f z^*kF#3L4LYSlP6+*saopGSzNnin?wjFiNB8kxh>xkF!?~XqCZB0CyPySBI-#eClX4 zY9{(!ZICvZdg75@N z1I{he@^-qftODtSn+bqjEK_|Ty?l&LCB1ZcqJVR@(lB7ww%3jow zAQ9fdm=~WaJF%pXXfci3aIsvfzi1tptxC=3Pl{-JMXcUlnF8T?&|{X_2BLQjDyG`7 zusc1X!^w%2l$N6;D`^8nRLhG|$B%InL)S!^b5#qw4r;A21KdvFKf++J0+_tWHAmEk zV?vqI%%7I2lem^0CzuS2Jp4V@NUd1QK#nMbn5SAJ^P z?j}jwrXG0Dh4`m|cg4?CZ?_p-HSoP_OzBCQGcl*fcN=XU2s6+TeAY7|F%$Aa&qI)IZ zWA3`kp!@OVouy;vbog%O=pGTogh*dT9`>O)$Ki0HLJ$LI2^@+1X_=W*qB|w00^Qp* zOWLpm$@!|di4Nkcl2%RNR%icu@l`F7BH1_fqBW0hapHb#u34BkFbv$95Y@0vm{-`i zL$XJ`!Zr!k&GszJg`qlCkxeXQMS5goc%EahTtEK?pmz5br-*YShDZlG%05^Vd5Jpo5YTJ$nrG4n z)b-G+9Gi#jjZ!iPH6!uH9Oo#tOJqD$z_4GpOwVbqF1OY@!}pEZR*cTsGwovh{@-}9 zRO@(VSnD8;qXy)I2aXpB!(yD92`V`F9QZDh6O|jDdm-qT|LpFs{_KzERO?vFX@#Zy zF!|%{!RnPa_O;gWYQ``vs$NqYZ8TJp zj-Z?V_|mr6Zs>7lk%XRqd1m=`{jgpU%bq!FqdUstl-eEjmblS3M8R-4F?8*zb~dEy zsi1ff{M9J+49x3|*i6vevW(DArEJyD{LaaterACI{^rRwYMwcdtxw&k9H}&(dLvFr zJ4Q{uWauEmVoj&*0-_oeF(r?Hm5f6w1Y)Ekv03KW?EJ%05yE9k_f0uEVR_}iX(L3V zU`FUh*dmmFPIcosZJaU%vCSuzPtpJZwFrAD3a!2^Stuxp^NNt);ac`TPN|I=JqDk9 zr)x2rsZLb;s>;h^g|5tDK5UOq8Uw0wNjQE=t1Fy2AgMpJY7xlUb-t7B zBA-!mmw<7xi?oo2rHmh7az@81l~terOR-CL1J8-v{;Ku8z@`Gm$=YoZtxJ97mRli^{eHeS{LV{EBdwPKWB_~QQQ(pk9juwx(F`fOJ)Y>^@0>eXc=~U zD)5rCc2Y=Mvonmo)MNKpuJlZN`VD;U8c2-pVc}Oa-_&95}KmGdv~w9RsLwF`o6d-rc&0JeXiN;}Be1KWcnQYG(&e0_|#*r}|dEGWzF8(!Sbz-%J?J zxzf}2%4g3I*3Nc9;_og^9E=PXxm{%Jy_8lSJTf5LxpYjl1N$n0wzxW2nFiR)HJ&?a z!<_GN>Tjq4>|H~R@xKRPClQDuJaRlJYtgzPq=!%kR8S-@43vwS6`uvR_pyZ0(__*# zk0Z0Ru!exF>%dHyEI| zKgS^er+omS-`e%Q4fH>)>OL1V^xHY~JM7a#lpNTwx|oc^Ag4-9RoJE$M`d!6&|hr5 z&dP1Ew%(2Y<74$|)o1jQ+q(eu9JsKVZc+dF%Cib>PHPA&`0}&mh1+J<{E!_rMBfR* z82bzA5-Gkj^f0r-qB2Jhacs6B`>60!q*mAN+#HCr*ZPF+>ij}^UkQySRX+kw^$WEI;U_)eq$&$pFElPwMdBTQ>*c7oT;PQ*o zPh!Cw!*ZJhyTFo!Ob@NwxSUuaofy=kIP@^3BDb=6&BN%+yFmFfiNS6UET z#U%M0=KwXySy&b{&DBLOC}uZ5IDH;xkuNLY{-y%%_r93}w?I%7k2yb9jBjE+OwbIO zCWL&ZiIkGHz?i)N?(wC1{h;%Zut%MK^g^4FK;v{iG7b#< zCtg5N8QIN*;2}h7@IPbSzy2~C$lo;-^9eX(GTmWBhqO|Vs!35L zwqxXTQJJNHpG2tH8T#yHjd?@Jz``rjRnaz6Bc;>B6TT_Qdb{|^@(TrE=u7gTG_p&u zQ2O%{mQ&9T96un1uhc<^;5oiPekEO|n(T04Fal&#utkL5o>(3Vdto9Dlj&JOOaTK= ztsD0hHdGGmhWsWTG=I_)AxZ;*#o?8bdq@Q&IPAc#AI7`!3lIkovPJFt3p-yJ5(j*V zR|1V&s5L3~g-C5mnNt>~A~yMg1vg3N#DRbPr@#E!PlrvClba#YDyLXI9%?#-_L^v z(^e~pZCT2a%yrY4a3P3+F4f8aHFox(q2gGpeE}r5pS<;ZB8hgt5W&W+UU>; zDZlCVe#_$K*K>4uHm}6ZCkSY{|JkcHEhjtSng)$3zF={~QP`&6n=Ocm4Jo~c4jTDw zA;3r=rkFdIyc=lkzOf>+0{hD~dHC|KZ~QxG1OQ#bDo0Sg+D1yn*+MHDOHI0H(ijOC zx^L(MrjeAzony1}53A|8b%k;4#NuGE(xKUKhYm zTTE~Hrpl{g1sylXIj%hv7(c`+ztSBPs2u>mQiOG*)x2%KbKqRo^Oh%)J^LBAgDvM9 zxy9?8ueJN;S%Cd@wHtg{1N$2}u!q=5xoAH?a3zU{vm|_1L*=~%EgzA;55WG?x_Ik* zx8!Ehp2*X$`X-U%=T zk#@ivlURiLCd}oK!i@vcI8oYKn7_~#Us&2$ z_g}wR@l9ypecKyqz8wmmtT>u&`6g|!G!P|;r9vj3dS@hnd157( zk5pGsu>e>p|Cp;V7;pD4u)g9>)7a0N}w*SO99H zs&eq`*x!3Sm;?s-fZcP6Xzc4**p|R}_xs->!S@kuIroK~r-unX#Ct>R0i+pA=qA`` zQ!Z8JtBQ?c#$kL%Rmh5x_uM;!e*X9WW{8i8F-noIuU4K?@4CDebdn0$J zVgEv(#NG!#dY)zXypp?tGIwG5y&vVvE?TkJlsi0F90?;dY!lFxc9X;*F#rtBzU(%y zw4O*Sj?klROyfy9^rtHRrtD1gORxNfns}2{l=VuxE;g^8Dx#^jpWG0)w#6wlo$sv6 z?Nisbw{M>MHvhSl{oob(#z3le-6BjYbaF-|IW;}!){t8~p&Clg#K&l!>x3K9Jc_Zf zB{6xjEEmBR!!VGuBl?PX`>m_;aGzEl>6e^aQi^K@_ij=?u6U12Zx??Xz0t-B-8DRO zz|$)zKCDs&uUJxJLT z*}(D^EwX$fqrg_HJ$dXfi0N`cm(FuSlbWGAbYHh<&Eb;o(7FJ5+Js#5iz+WF%f}T5 zWl+HZ?dx+fqT0q*<(H;er{{wie0>2LqqJTVHaKi9Tf5?c)sRCygjpya&C}IVdd}{* z{(~o$@19@&@$pbCFn5au2HPbUQK|qsFU1+;7gH0WlNp;>$YZSPEo_0wWb=v(Z{O36 z#>-mLG{@@F!@MqLTrK8D#x8EJ_L}FlK*T9;O}bu4PKn?E9RU+=4t*Xl2M~g3-L{<_ zs%4fIi28z1Q^%~lhsGk%HH7jxGvgwFIVX0U_!fv5g#=g{4APj5sfYsP84R^Gs^;mS zRwSVhXM^@!j1D|HMP21Cf&EIV`V#qtVy5d$nnDkg9#aZ9>Ob_F#<7)<0B2ohKj;}@ z>hHT4!^sXpKDMOya8KlWxCq;& z1Ve8Wjmo(q{o%4xm@|D|nvc6O*_I$`xK_p_$?2D`E9 zc8x0FPerOTuDXaT*r@kGmJsZ`Ag3b%g|>nhvgjgC(A;{lBlR5HPeNRELi7s+yCNeA zt%zM)$dX+`<7rpj6oCUyk{AfBDz~~8Z>S0S9pj2Awg=FM)}ypS0dCA9 zNx9h)5t)=G4_fzJWHt2J%M|!&K_BY?90VeWz=*?oZVa$PoS@u>v>oMTn=dFTVo`v7 zs0mXgqVEJj9LKaAT;9+s@V3h=G&@soCh&^t5rFm0R2V>>%t~GUtesuN2sso zJD(iLT$;K2?bFcXzNxA;Su$-khkehXSw_I{!7U>O^%D~H(nW6w$B)2uqlG2YphT8~ z?@H;V3H*IDO=k|@b^WtI;e%3XA%d66wh4Vr2v@|raYA_?c9(~kGc|!WSU*3kv=p|O zrH~#=rS+3**BbUnWhPvK^6e6*U1KSqJu}AlSjr^0XQ+)RFdIA28K~Eys^&?=yR4>y zfv+r#6DlJPRT%zep?Zy^56ZpNRxDRlZ;ENIF9{K|*oG6DsxAQPz@(F@^3dv}TFY#y zWC==8A7TGsz_Ugv2T6qhsT~ujhge50PZ8@LR;aJfYaYd9utorLRA}yz}8?Jd_cy=x#PUzxTz)ezHa(WFk3MW!gy{nuu0(<{n~#>P z8cHSN9_^KfX!Zw5$A&rQ}9ok_drcmnPhO81*4=YYrXEqOFGEP?x zD6&s`vPHXp>i! zXbx~J;o+Nr&H>E@E()SFoq7g+r}U|!NC)3qwBw5zI@aUuJs88@U`Na^pP z(YJW&qhw+wM@O!^I6~Es%23_}`aUJBCN5{ad3gq5Zndf6sz>*w!$59eF8R60!siA? z87`x=0L2Cc@W2f4mP`^j>T zWN3;sj~hWTb7BemTv}|jBRqDZfJR~N^kLon)#hjglG`x5e>tiZVjJ@{A7p%0r2;dx zl=7GZXZfmGvg)-2o%#M%pNhy9+~ABcP@t_Ud&Y@@wj=Bze3C5s%ILa595Qxc z-6RW3(3RdKayqEnjJEMDXp5LmGz;M;s><;C>}8VIw5DNGn47{kFwxn@JVM4U)C&j+G}GAV?}U*BeSm8@L|P?x zrQXVDg0>>98cLO;@(`JESG>~9rJ8>=gV_fLX^nSZ@kSN><3pVSwF#qyZ{e_qachYKPy1K&gMnOi*B2pBa8_(?h#P}itlCx3-~Eyc z;|)LWCzY?m`H>Tw;X3d{{V<74!xPjtaS8|=S^<0t$S^u*U%wg`THh?_UgPK25ognP z)V_ix*@sJFeSKD0phjh1&z1aJ=eCJx-0tjqh{mZ-*d$x%pm!)2}4*k7KwZo>P zgFgAzG*461Q+(&@iip?bYBoA2EpV-my|K`B4IYhKc?%0_IP|%?^nj3nR6fMe>X8nh z-i3;G7{(l%oqt&OcP!yX(lQatNT8fx>k!)rcGEu+g|5)FvTEb#v{nwDmBIy*40mMS z81nc5L1o4#-Sh2GXpzn##Z3wPm?r!o+G>a|L?{w?)%5Nnyky9IPXRTCNLILbrwb*g zE&DgVr}COu#|T4f^Oz&rSGv|QRXKXxiZ>Dx87tsfpVORI?PmA9(P%t?>_N}C&uE;j zw#~41f6oD@FD&o)$9#>`BG2jsh+$A4rD2*`5MmVT;3i_>1xPHIMqavTocKnJ|+Ufp}qkOKdm({UG3X>KlHD{3KzzhdeX&XkVmCmpFo7-o7dM z&PtI2DnyyZ^0kwzgN=cBZF{is+V+YVY->@NDezpqod%3|jjenx>HW$KFdouYNw>d8 zwIBT>SC}y_g0W9qKi+GOg3c<8BT2|{0!cQi8j!>w1Ryd)?VeE2M2eGNDB@pzNmIbM zf##u$yaLTBX%yjGX!0gp18;^DX&!Iin^GEhaIay!G|hR;lW|;)rOHA5;JY!uM{uC$ zf9dst-mheC3l9doo2vi+*FO6H9y$J(kH7nv^Qpi7c5U)-wY{3&nFE?{@kz0}k z?uJqf-`Ij=`nA>!o_*!!mGiIOdGWRHtiNuB+tKQ)gDZ8n5B=*|o?v)RW9NHM9$S9- z=+2Wzk3MY=vkei2UXp8;YlNYXEf5}|DMq&m{qf3VD5;&LCEw6?mFLfY_fB-l9VDwS zTzhddzv9gaSA0{%H^fz}Zs4h4ZfY`s%qsvax>S3Xw^?@#=LpO50af z-5V86@$vU|N_|P!8`#-=;uytGHKLxrFuXxJQZ0wD!5{_9CNY&FLfgSc?>l6x?3q*E zpgw%!?Vc?L-fXW?-|8v-HC^xK-H$%b4WB%^#SQ;pc*AJSlG>)0NW}qV5<1ptRZMaG zg8CSj-Ce^FP(A}%+j`8_%CN4!_2IP*A3`eEu5J$h)i%+;wR&Y;tR{nL27LWdoYG&@ z^?u)7`z*4qk7@k+!pEX?LTvQ*)hj)MS;m`i+ z=l|#rKYahE_%U7G{P1Ug_VYjZ%U}HSznJXZbbhdU{+e7JpzIo7m#Y`IE@zL?72cY= zwPw5C;7;X{s^Y?n;`VlJlq-NN&8*Sz%AV;dl{`iHMqk>Q^)>#g zlX9I~>NNL4swh1SFMDzocXXH@EK6fv0=a`)1-IT6H9XPS$8>_6Hf^Z1ttRO1BF2sB zi9{To-8Vjbe$Z-gKB8O<_uE&mos`>mu1+vNYI(wq?RD4aV8b&cUI;v7RYDQzMnrN* z^u{_Q0Vtl>>)w zd@dvGxp%t2ablKqcrjy#U*#p0a-?da@>%0zAP;sV!MfV_?c|Wm8DG3y& za1L7->K5b^m6Rx_I$L-b>$O8#vY}1h#Q_0XNU_k3*+W?PqTF9|1`D|@ zFdBhu!L-;juPyEv2Klhpslw^ub>Y0WDd2Tcytd)2oDUG(19&aZ$O>u#f(;(>9yx6X z8cpr@t;ayqP@yS`XQ1iJIhsb)VQt}Cv5$aC=&(od$&jb4_-IOD9l0|_`Y}^b)p=sgAiMmw)dW4}O3s46=Ftm7(jp(%Nz3&Y^@!(ET zCx=o7MGVauB1fFLslr5RQ<|vYv0D6@maH}fe6pz|IHhc=7X+8zVB4;spDhG@UNIB>M3qh?9UidWbE*BMO+6pw^i*wKv33SuMgDVoCUE$fd z)gl!}7@D$cgPyZ6(0o;8gvZ0Cj-mSi=cx8J$+YE;IHl|JihYrl?*`jz>!;NBe|>a@ zOapTC?}od2;|IleHY)rFBmxG(*k`CR0eV`vqNlium;p&P-oA`w&oo01^d7y>27Y%9 zL5;A5jPTUi1-9?1-hpURjFTMD4WLKL03Mr7C-#)IR~5fq_F|aCu=5wnAsNM`H1O2~ zF(driwB<{I4jG@Ie|Et)l_fcLYWR3sO3lgkoHWF{7N)l}{h2-14u1GMM1u-Imt)`2 z0ID1^4#P*2xR|1oezG7~;7W_3@_^(rbp8L4k3MtcsUJT6=b!#RKlSX#w)w~5pTj4R zJ%M*$*=(b}r?#WaNmTzDsy}87Im$=N1PZ*AcIxHj;jBo$-Bq*INH8p36~9zebmO7Y z*zk~F{>6Xv%b)$L-qiQCJGhh$kV;;;iLl-FVD(BvL$g}7$uFT^vl;z(qqc28_TsXVGEl^ON@OF5;IR5hlZ7EYe1Ba^9S z1BMwc{ksty!E-zdfnzsb|=aZvz|ayOo#2In}cY5End3K0duR}l)eYv z-^1kmPjS#_j8MbTms@)y-6fp-RJ`-?FZTozu22DCV5pvZ&p>G~CA>mBnjhJ2(%Lus zonhZ>F%EMtTX|_|ONwvZdh7c7HSu@W?_4;$as7?g)~|cZZBFMCUP2=P>l#KnM9KrO z#B-n@3RRnD>q%=GWOGF~_YE5fJZ){1oqt%~A+7B~UkD&H;Bt$qw-WZVJ?gk@T&381 zc?Xe9ddLEU+^sZVl|aikJs1Be3D*UcJ}$o~@6bw{LNlx%mo~)O=8_6FNZV~Jsj_@t!R$Tyo_nVYFDI6F`V38;$>=o^o2XvQ(TwKP zdWmPkc&Z%T9gmGAz?Uw7+09uiwVvYX&FK;MsrB@Fka@KyKQ`FCxDHmo%trgT&Q9K4 z%dwh%uNZzV8kaG97@T-gAA*)4afM7n!|9uy>~l>OtR8G`Z{0kTz1w!A=JVMEM@JEL z9zXXo#cEcI+H~*cIiKc)=6)Qo31o={xoIrJ_zn>~l)0swCipRosTQriv_25l+KLQs z4K}WA4{}tmm*j_bciD{>@1%j%UBf7!HhO0|JywH+stw!|mSTe7jq2bjmV zyS%ztMoI>!QeqZ3BiJtoED9(^@HY!vI(~)ADRw~FB}oj5tkm{W@=lEUD2}64+A@-9 znxYBG@dZ}H{lPs?ksi=LcCfnOOI$}JzJV%&8LM`ynUbCP44PAT^jIFrOL9mA6YtDWQSfwftzWw|!uNoFpD*p2XsS30=dUi7m8e14TS_IGa*~`KT3xw~`^e9Q; z5TDveS)irB!*vl1Vw)?_T7P)qdo+g?Y}G7EtHY;qKn~t&oE7geQ&X7BWag9)6m)yL z)^!4LUj^c(rn;^aNfS%iWyJ(+1`1Xtf(%Beh}T9$vW1XkQP@4$Twl8(&rFKM)d91H z;tw`tM?y*qZye8~@SP|#FtnBhwMyDAp=FM#Qw?M9GXuG1ZuX45hi{<~eAALKap>rI zIdh@}b5>lPeaB8{0kE)_POV7o7$K=SN?E#?^^$3?gXsm@OhdxO*#Q16Y8qS+i52>X zupx5109Q?a4~95%jr;aLQBs-3ypeVQ9}c0)5z~aJHzbr zIc7V`Tiyy)gEL0wC`SobxdJ*8QFO|$=Atlr4~X3rarb(`2R6h`ZPaWNM2&zn`rz^0 zVQ1u%>B4fyGtySPKD#0(<8&p&9!{|aN_PzwjiWQ8v zfg`ZhU9{b0i`v3Ur;h)1NaQFlcpTGfo0`FU2Ko9pE z4uKTvzPbF9ALOwnBIA%Ss3eCn@UfsnX&^LxOQxoW?2(kcV@=(mTP6rVQXcUPDtX<^ zd5q8N6*_&6CBYh0LDj>I+6z^RmL{XQe+VEJqp_z zvPMRLc{9P-(pvRlHsZ#v7hjGWL#PgPjL{50HOruV4_#i*PaM@}VhU|uo1K41gD`y~ zlqj8{v`kAo;%Ah|JTFS=Gc!|1G=`IlEu{8*I=+T>ieKK=ba) zIcSCk38OedIzXzeUrNQnh%pVY1k@)qG8X}wnGM(^&@7{=dRM3Mm@8Gm*a=h%gxRxz zy|%XfRw1#V&VL^``ZcG>9N?Bl{Q$5+e;ctN!}mP&R-~&mSwpbbYh^TyeEi11ZP~|f zTU>3xY}Zg>t_(|H)5C0Fg{Bo7E~GG0`VhdpBygcrB4>esPSn&E2Q?uVSk%iDD6@0M zlRSW)moju?Pwd6QFG5h?NDNar5E;@G=>{L>89r66q{CS3yX0zf4DB<_4rgoyMQboy z`K;KE&t%s(#ngRJ0NUPt`e^{#C4-s)^m36wCC-SkR+ct%L88BpI+2auusL59v%lEOm|&oPt|Y~KSEbHl_WGKO@9XEP4wNNI=eIC##j(Z<0u z4|&*7&Rb~UGaTKCBV}*+tc2QwC_v37LOd0!0!n#G7lu@(oze-W&t9e|ED)cOv_(`W zM5xVFHW29c`H&@$gHZbXnN-b;>C?HzaQhnuXA`ypz2TN1;n_2o1%_>6rfh{a!%`4E)7XJ&p9*ODcXCV)=POAEIN!kYOQFBYibocIKQHVVxa!YLJfOL(F64k8Yta0VD^U6)cs*?nU3$m0fw-J!L`FE zBvwcxoI0B*&HfxYEq;XxpOB%lsy6ZPgS6o(pUFlP4Q+$|50n*57fs8^HK|`&Xs6O5 zhBJXwI$H$~ST!|a&%?3@Qy4uu(}5>!x&c=sW5b-eX;$SQRHM>?OID2L?IfhuQ@3(J z9!odecxIWvoVc0LD9>RIsI_m*?P)I{uVKFb+s6@=v2#%wvcVT~V77epJ}}dubt$xB z&ku!dhAJZ|Xq$H;YY}mC_JYT2BPd{=Nm5439o+XI3q8OjB=hMgz<|zA=#v2*LZnYn z@r&cuB=CF{Wx8H^KDadrYx)$$!WCsuEtKfT1(q74DY7*li8)Z)ktPsrDe7$ju8UHX zIpE-`CJIlfPVUMeteAe41IB?X2Q`7RJP$eG00E_;>i>^?MVZUa zKP;BI(m`Gg!QFr$i*`Z&12sAcC{~7EWU3Xc+J|UH5@Vi_|KVGr1nmUcypj2VC>rqZ zlwT-dSYMKjz#&#EyycZLu1}Ju8E6J7#3PTc5=C!9Sm)5?e@`}g_5u)lN z)Jm4&1V^+lmyNMhIda^(c`pEi3o8Z*xA;ot+tb7h4x7u0U3&+7-2~G8Z<} zt=_9lD*^IIW89E))UNwANQNXBc8O4Fr?NhXH> zH~Os*YjOn`u1!?FIU3$KtSRr61*?7?4UBbsC16_&oEMy3N zXk*OzaIX-fInER7u|lY^R5`MHg_vftbLu9>>*<-#cMdpU=x*(P?Ki0TzD&*cgxW$3 zB}XE7I5xC1C60qXV2Y6tz9}@}LZu>q?9QIMs^M7$+~ZqPY)gH_guO%gBlU()*ZO6; zHUpP$;$bk<)y2h-%%*RYV-+}yqSEa?4X&>O#G5d_5wawvnO`4)gark-S;s&uQGye;^V@O2p-Ob4oU<8jzcsMBBm$XLH&}mHno(9@`2E-*p;WVU5)y?h;*P=(!YkDPv;3gR!eE-bQ z3r$3sDXqo09fo+bc#cXA6?0u*lH-#Cb%YC(EyOxUgfykAc3>s22!o=cAO+1G-V~0J z$PAKEf=gwhvFRkZQ=z@Q?=<&TP}%RyO=*JjXeVHMK7J|(jfMCH&GgdCA7x}}lbvG@ zSio+)``u?oD!HE-nm~57Jls*S+E??^+O#UUI@}vd;;NI}+FDvi^9U)8!` zZ{$mb2m_OXBY`1#Twy}6cTu+{m#+N7sKd^_RGbx?8{)>`%xKMhHjBztz4P>KeBtvW z%KNDi4>!qvz5L;n8MFNK_er*_@i=B*UK*!5VOV&)T7v!vWI64~k})YW7_2T9kLbv@ zO0JVJd+CPUc>b!y?Om?A>k~6(`Ri!xtGdQdKGF4h;zNJ+5QdNGa22s(J7|^@*pS`| z*x!VzzC9Wt`ZuD;G%bAALdp_>=P1=^%Zox0x*@$hQL}y6#zxc(Xz!!TA!e^6B&h^q zAUASQO4n*)1u*F^m?CFpvwe+la3HxRT?f<57(;Gcis4401n(%B$$ib4HAX?6HS_4p z#%0H1w+N8}oKNPmg=##Y>_yDD4mHkJTZ@c$U$REqs3(Tos4gl*Wu2Y-HtLuE z?C!7r?2mhIqlQ6kf3uOk+bA94j20dJF1j{SAAHq>j`kTERGwJV*~k-L{)}GT5pJcG z)&^V=3LvviYppN@1y{&92xu;-mbA91Qqi{y)yy+nXkVAt!OvSgpNojc}cO5MILpw^iqB5C)+mL#;onFa$hz1>!#9lF=~o^f5xdB z4UZFU5IS@{t2QLGdL^`Lc0H0#Lr4WqnuxZvB)u(bn}gMh!?dIulFZ%)v}AYSS~%XcmtgEE>|lKy5z6CeC!Bgdy|>-GK6uK6{y05V&;J zQd^3!bs>Z63+ho8M0F>LRV1lYI}6m+mo$Y;2QGEo0JVEV z)$Hp!+cxy}oq5&<2|S4Q#kLnJRDOHxQamqgD2<2FDm+Fbe|`v|?y&|DeEXR2Lhb9b z=)wl>fUVX7p3=Kjb+;xHgAT*%F8mU2(AZpB% zT~b5vZe8l^K`SZwY*Dt7s{>4|t`45>UKi?bsj(1rjWNc&ifU(E2 z!;)qkn(&s%V+&Jxak=}x;kqvtg3@GH=vEWb&!98I|N2O(9KIL8pKaFj^~FFq_$z?- z!EY_GW6&+_lwRO3*!dC=qQa9vKsV^@WinvQ=16iDfhFmqM0jK|O8~`}%eUn%JwnG+ zU$Q|l;Hagy)qmL_lvfMAG3ekG7cYLaFKGT`#ucE+H=j#Ar)|p4W!oSkHw+@W#Ze6j zOhw6}%*M75U5!K{&ELLlC|cp=zKXQM!OD*Y^oTPKO@D$ZDSX&@=ajsT-|nns)`q9keBE{;LI39SvTSqTxcTwMR| z6yQIKJsdzi$FiVY5Mc%Ij#;JnB$4XW58oc40s=gNNsB{eAXSddSB44w@?*0EGonFh z9E?_mCLnOwT+(%In4q4(0yYZn?zvM`T`sdxu+=JYcOzdVl);-vlNLi&l1;)Bojxn< zv=U0i5P-yDR*9SI;w^pmW#F%G6VyTF&-KDk+Zv47L8%1oOZ@sPGTyqiHzW~Xd#jis{)uAbgWVcK=p$TRWtP|4PedMwgey}c!|{Bze@D-eWI5O zI(oUCM=#KtVdw|25FL}|eAlxq(lm6Or>+Od+h0uda{HRN)!AURq>q|IlJg-*X+p+F zy$t#SDg%-Vr%!qL=u*1#x#4I1aJE6X&nSPZZaHdAqD z>(*L#`|MJ2-~@orY`#l+_l*%SV~X-1Y)OTSMLZHOBoWY!bfn?HWT2PMuu}?>ar>6E z@Cy}}w+CylHOLFu1Fg-)=8I^;ddFbWz&kUn$7sGl9z-rrn1~@j`lC)nw}XL_Kgro9 zV_{k)gehPhB?d{;7ZL~-xg3n?NB~eQ^WYo;_qy@+;e++stgfJS6Wg2Psqzasyk|pE z4;)tPF+R|}rZ?w!aPZvPy?hcp7X<2G(|G2&Beo7(!YZBT9pGyd!LyPP`yW zlLg^<@h&@4jm3d`NH@NauN+elLJuTO4MG(478*;brXa+E+zSjWwN9%Hr0I?6p3M<` zidemPB@Hz18cKRn&W`3jvIcBLkVN)udcFBy)qdc@Lqm*NG=p^P%V`T2k&TKzD_jay z&u~JF15$|ML8`a`#r&R@f0kks0q2w8AIhilHsumrH%+PQqSznpyMKwEMkB^z&hqY} z`%cU9u6+y7FB<}?Sp&E(#)UqN4<{uZi(@N?jSbKzBpzp&+@<$EswEv%o|(CO@o$3b zuP{9DCtCa zt>AiPQgT%VI}?2z{0kMS?cs~hhqIZxpM>VsQB*m2ET+$ETJvqiDt_?M+}I6Hfaa&k zx@2g6Id8!vvV}4B zFlSqQ%uSJ*O*}IUu|kbQSgBDM37Q0jjo8BEY>PZIkZa~o^Xp5Y-jznCy)9zjgk zrnFZ^`9N+#(O!V99;2BZOH}zHiWsOY;*TDuNZF-hLYO>s>94ff6~J^2oxKGxlG+eG zttRRwHokR~-jUhkM+O?f9#u|#_VQMAfdLF^f0)dX;iN~93yR!0K!6pETUtg;Dq392 z!xz8|=Wrz=nI(KtGr4%3hvlKn>Mz)R>dOH33HF^C3H|we-x;%ip;#ItE@zu5!o;Z) zppQ)pw}nArxS%XzBG+Y)N`I^G!Na`Ul(w)!nqJ6cfz-Z9(@{v7vxcp;{Z?OtuEC;b-OTl$0Fi5GP`CydnBZaF=A<|qI0)n!$hfui7A+8> zv7SXd2}4dKQzZ^muo{gB-+Fqwp~e_WrRd><=+dn10O@f~28XqKEj(J=S^B%r|27^q zD@wyNvoW|@WCgL`Bn%_TK_>>YAVEAbjnHeiz-Dt%B-_EwWF{Mf%ik+8t|pZ9biVPj z{*nj1WKVHH1=LttyD8o*>ZOICi4$RNU_h2`OAnqKh-iC7tllmFTV7g1IpABj8j3QP zM|So)N7zgXc8s6B0d|bii%A+VLbf`EHyj3VWL*rEVz{;m$^oBB44LPj&bljw%ABE(*keY-%X zN}qMrrZNTJ8Q*7GscjF-Aowvc@w@3ioL)9%45%P{TUMp!`kXHU6BGdU4-8t@i3dR& zz}@|uzeV704;PKQ7xP6U5ds=NtVpM2;1mN!`N2(EG+OgA z;}(rvDPq?A`GN7HL~YlAh9?})rK`-qoGT5L*h!cec)9pvLj6Jwrci;&{V3}>8Xj(~ z`Jy#J(=}}N2Ka_S!(8B?Zi8(ZQ4QQ&9GT2Wco90thHCJyioZ;opqavW684yDBq($u z4@UkTHw+6!87_kOKfvdYYkBw*H0Alr1DM3<8keD&0Ql2PWWK#6v@gwNJys5sTbc9! E1L!8(^Z)<= diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 0a8642f..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Zeppelin ignored files -/ZeppelinRemoteNotebooks/ diff --git a/.idea/ApifoxUploaderProjectSetting.xml b/.idea/ApifoxUploaderProjectSetting.xml deleted file mode 100644 index bff5671..0000000 --- a/.idea/ApifoxUploaderProjectSetting.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml deleted file mode 100644 index e9f575b..0000000 --- a/.idea/checkstyle-idea.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - 10.21.3 - JavaOnly - true - - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 919ce1f..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a1..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 4ff5223..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - mysql.8 - true - true - $PROJECT_DIR$/video-comment/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_comment?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-content/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/2 - $ProjectFileDir$ - - - mysql.8 - true - true - $PROJECT_DIR$/video-admin/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_admin?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - mysql.8 - true - true - $PROJECT_DIR$/video-auth/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_auth?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-user/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/1 - $ProjectFileDir$ - - - mysql.8 - true - true - $PROJECT_DIR$/video-recommend/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_recommend?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-recommend/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/4 - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-comment/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/3 - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-auth/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/0 - $ProjectFileDir$ - - - mysql.8 - true - true - $PROJECT_DIR$/video-content/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_content?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - mysql.8 - true - true - $PROJECT_DIR$/video-user/src/main/resources/application.yml - com.mysql.cj.jdbc.Driver - jdbc:mysql://5.180.253.115:3306/video_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai - $ProjectFileDir$ - - - redis - true - true - $PROJECT_DIR$/video-admin/src/main/resources/application.yml - jdbc.RedisDriver - jdbc:redis://5.180.253.115:6379/5 - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 1f87f06..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/fastRequest/fastRequestCollection.xml b/.idea/fastRequest/fastRequestCollection.xml deleted file mode 100644 index a433492..0000000 --- a/.idea/fastRequest/fastRequestCollection.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/fastRequest/fastRequestCurrentProjectLocalConfig.xml b/.idea/fastRequest/fastRequestCurrentProjectLocalConfig.xml deleted file mode 100644 index e03c3b9..0000000 --- a/.idea/fastRequest/fastRequestCurrentProjectLocalConfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml deleted file mode 100644 index 02b915b..0000000 --- a/.idea/git_toolbox_prj.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 8d66637..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml deleted file mode 100644 index f6d2542..0000000 --- a/.idea/markdown.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index df00c07..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/build-and-deploy.bat b/backend/build-and-deploy.bat similarity index 100% rename from build-and-deploy.bat rename to backend/build-and-deploy.bat diff --git a/build-and-deploy.sh b/backend/build-and-deploy.sh similarity index 100% rename from build-and-deploy.sh rename to backend/build-and-deploy.sh diff --git a/config/.env.node-01 b/backend/config/.env.node-01 similarity index 100% rename from config/.env.node-01 rename to backend/config/.env.node-01 diff --git a/config/.env.node-02 b/backend/config/.env.node-02 similarity index 100% rename from config/.env.node-02 rename to backend/config/.env.node-02 diff --git a/config/.env.node-03 b/backend/config/.env.node-03 similarity index 100% rename from config/.env.node-03 rename to backend/config/.env.node-03 diff --git a/config/mysql/my-master.cnf b/backend/config/mysql/my-master.cnf similarity index 100% rename from config/mysql/my-master.cnf rename to backend/config/mysql/my-master.cnf diff --git a/config/mysql/my-slave.cnf b/backend/config/mysql/my-slave.cnf similarity index 100% rename from config/mysql/my-slave.cnf rename to backend/config/mysql/my-slave.cnf diff --git a/config/nacos-mysql.sql b/backend/config/nacos-mysql.sql similarity index 100% rename from config/nacos-mysql.sql rename to backend/config/nacos-mysql.sql diff --git a/config/nginx/conf.d/upstream.conf b/backend/config/nginx/conf.d/upstream.conf similarity index 100% rename from config/nginx/conf.d/upstream.conf rename to backend/config/nginx/conf.d/upstream.conf diff --git a/config/nginx/nginx.conf b/backend/config/nginx/nginx.conf similarity index 100% rename from config/nginx/nginx.conf rename to backend/config/nginx/nginx.conf diff --git a/config/redis/redis-master.conf b/backend/config/redis/redis-master.conf similarity index 100% rename from config/redis/redis-master.conf rename to backend/config/redis/redis-master.conf diff --git a/config/redis/redis-slave.conf b/backend/config/redis/redis-slave.conf similarity index 100% rename from config/redis/redis-slave.conf rename to backend/config/redis/redis-slave.conf diff --git a/config/redis/sentinel.conf b/backend/config/redis/sentinel.conf similarity index 100% rename from config/redis/sentinel.conf rename to backend/config/redis/sentinel.conf diff --git a/config/rocketmq/broker-a.conf b/backend/config/rocketmq/broker-a.conf similarity index 100% rename from config/rocketmq/broker-a.conf rename to backend/config/rocketmq/broker-a.conf diff --git a/config/rocketmq/broker-b.conf b/backend/config/rocketmq/broker-b.conf similarity index 100% rename from config/rocketmq/broker-b.conf rename to backend/config/rocketmq/broker-b.conf diff --git a/backend/deploy-ha.sh b/backend/deploy-ha.sh new file mode 100644 index 0000000..b28a81e --- /dev/null +++ b/backend/deploy-ha.sh @@ -0,0 +1,333 @@ +#!/bin/bash +# ============================================================ +# 高可用集群部署脚本 +# 用法: ./deploy-ha.sh +# node-id: 1, 2, 3 +# action: init, start, stop, restart, status +# ============================================================ + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 日志函数 +log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } +log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } + +# 检查参数 +if [ $# -lt 2 ]; then + echo "用法: $0 " + echo "node-id: 1, 2, 3" + echo "action: init, start, stop, restart, status, mysql-master, mysql-slave, redis-master, redis-slave" + exit 1 +fi + +NODE_ID=$1 +ACTION=$2 +ENV_FILE="config/.env.node-0${NODE_ID}" + +# 检查环境文件 +if [ ! -f "$ENV_FILE" ]; then + log_error "环境文件不存在: $ENV_FILE" + exit 1 +fi + +# 加载环境变量 +log_info "加载环境变量: $ENV_FILE" +export $(grep -v '^#' $ENV_FILE | xargs) + +log_info "==========================================" +log_info "节点ID: $NODE_ID" +log_info "主机IP: $HOST_IP" +log_info "操作: $ACTION" +log_info "==========================================" + +# 初始化函数 +init_node() { + log_step "初始化节点 $NODE_ID..." + + # 创建必要目录 + log_info "创建数据目录..." + mkdir -p data/mysql data/redis data/nacos data/rocketmq data/minio logs/nginx + + # 复制配置文件 + log_info "配置文件准备..." + + # MySQL配置 + if [ "$NODE_ID" == "1" ]; then + cp config/mysql/my-master.cnf config/mysql/my.cnf + log_info "MySQL配置: 主节点" + else + cp config/mysql/my-slave.cnf config/mysql/my.cnf + log_info "MySQL配置: 从节点" + fi + + # Redis配置 + if [ "$NODE_ID" == "1" ]; then + cp config/redis/redis-master.conf config/redis/redis.conf + log_info "Redis配置: 主节点" + else + cp config/redis/redis-slave.conf config/redis/redis.conf + fi + + # RocketMQ Broker配置 + if [ "$NODE_ID" == "2" ]; then + cp config/rocketmq/broker-a.conf config/rocketmq/broker.conf + log_info "RocketMQ配置: Broker-A" + elif [ "$NODE_ID" == "3" ]; then + cp config/rocketmq/broker-b.conf config/rocketmq/broker.conf + log_info "RocketMQ配置: Broker-B" + fi + + # 设置Docker网络 + log_info "创建Docker网络..." + docker network create ha-network 2>/dev/null || true + + log_info "节点初始化完成!" +} + +# 启动基础设施 +start_infrastructure() { + log_step "启动基础设施..." + + # 按顺序启动服务 + log_info "启动MySQL..." + docker compose --env-file $ENV_FILE up -d mysql + sleep 30 + + log_info "等待MySQL就绪..." + until docker exec mysql mysqladmin ping -h localhost -uroot -p${MYSQL_ROOT_PASSWORD} --silent 2>/dev/null; do + log_warn "等待MySQL启动..." + sleep 5 + done + log_info "MySQL已就绪" + + # 初始化数据库 (仅主节点) + if [ "$NODE_ID" == "1" ]; then + log_info "初始化数据库..." + docker exec -i mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} < sql/init.sql 2>/dev/null || true + log_info "数据库初始化完成" + fi + + log_info "启动Redis..." + docker compose --env-file $ENV_FILE up -d redis redis-sentinel + sleep 10 + + log_info "启动Nacos..." + docker compose --env-file $ENV_FILE up -d nacos + sleep 30 + + log_info "等待Nacos就绪..." + until curl -s http://localhost:8848/nacos/v1/console/health/liveness | grep -q "UP" 2>/dev/null; do + log_warn "等待Nacos启动..." + sleep 5 + done + log_info "Nacos已就绪" + + log_info "启动RocketMQ NameServer..." + docker compose --env-file $ENV_FILE up -d rmqnamesrv + sleep 10 + + # Broker仅Node-02和Node-03启动 + if [ "$NODE_ID" != "1" ]; then + log_info "启动RocketMQ Broker..." + docker compose --env-file $ENV_FILE up -d rmqbroker + sleep 10 + fi + + log_info "启动MinIO..." + docker compose --env-file $ENV_FILE up -d minio + sleep 10 + + log_info "启动Sentinel..." + docker compose --env-file $ENV_FILE up -d sentinel + + log_info "基础设施启动完成!" +} + +# 启动微服务 +start_microservices() { + log_step "启动微服务..." + + log_info "启动网关服务..." + docker compose --env-file $ENV_FILE up -d video-gateway + sleep 15 + + log_info "启动认证服务..." + docker compose --env-file $ENV_FILE up -d video-auth + sleep 15 + + log_info "启动用户服务..." + docker compose --env-file $ENV_FILE up -d video-user + sleep 15 + + log_info "启动内容服务..." + docker compose --env-file $ENV_FILE up -d video-content + sleep 15 + + log_info "启动评论服务..." + docker compose --env-file $ENV_FILE up -d video-comment + sleep 15 + + log_info "启动推荐服务..." + docker compose --env-file $ENV_FILE up -d video-recommend + sleep 15 + + log_info "启动管理后台服务..." + docker compose --env-file $ENV_FILE up -d video-admin + + log_info "微服务启动完成!" +} + +# 启动Nginx +start_nginx() { + log_step "启动Nginx负载均衡..." + docker compose --env-file $ENV_FILE up -d nginx + log_info "Nginx启动完成!" +} + +# 停止所有服务 +stop_all() { + log_step "停止所有服务..." + docker compose --env-file $ENV_FILE down + log_info "所有服务已停止" +} + +# 查看状态 +check_status() { + log_step "服务状态检查..." + echo "" + docker compose --env-file $ENV_FILE ps + echo "" + + log_info "检查服务健康状态..." + services=("video-gateway:9000" "video-auth:9001" "video-user:9002" "video-content:9003" "video-comment:9004" "video-recommend:9005" "video-admin:9006") + + for service in "${services[@]}"; do + name=$(echo $service | cut -d':' -f1) + port=$(echo $service | cut -d':' -f2) + if curl -s "http://localhost:$port/actuator/health" | grep -q "UP" 2>/dev/null; then + log_info "$name: ${GREEN}健康${NC}" + else + log_warn "$name: ${YELLOW}未响应${NC}" + fi + done +} + +# 配置MySQL主从复制 +setup_mysql_replication() { + log_step "配置MySQL主从复制..." + + if [ "$NODE_ID" == "1" ]; then + log_info "配置主节点..." + + # 创建复制用户 + docker exec mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} <;" + echo "START SLAVE;" + echo "" + fi +} + +# 配置Redis主从复制 +setup_redis_replication() { + log_step "配置Redis主从复制..." + + if [ "$NODE_ID" != "1" ]; then + log_info "配置从节点连接主节点..." + docker exec redis redis-cli -a ${REDIS_PASSWORD} REPLICAOF 192.168.1.101 6379 + log_info "Redis从节点配置完成" + else + log_info "当前为主节点,无需配置" + fi +} + +# 初始化MinIO +init_minio() { + log_step "初始化MinIO..." + + # 等待MinIO就绪 + until curl -s http://localhost:9000/minio/health/live > /dev/null 2>&1; do + log_warn "等待MinIO启动..." + sleep 5 + done + + log_info "创建存储桶..." + docker run --rm --network ha-network minio/mc < captchaData = new HashMap<>(); + captchaData.put("captchaKey", "key123"); + captchaData.put("captchaImage", "base64ImageData"); + + when(captchaService.generateCaptcha()) + .thenReturn(Result.success(captchaData)); + + // When & Then + mockMvc.perform(get("/auth/captcha")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data.captchaKey").value("key123")); + + verify(captchaService, times(1)).generateCaptcha(); + } + + @Test + @DisplayName("刷新令牌接口 - 成功") + void testRefreshTokenSuccess() throws Exception { + // Given + String refreshToken = "validRefreshToken"; + + TokenInfoDTO tokenInfo = new TokenInfoDTO(); + tokenInfo.setAccessToken("newAccessToken"); + tokenInfo.setRefreshToken("newRefreshToken"); + tokenInfo.setTokenType("Bearer"); + tokenInfo.setExpiresIn(86400L); + + when(authUserService.refreshToken(refreshToken)) + .thenReturn(Result.success(tokenInfo)); + + // When & Then + mockMvc.perform(post("/auth/refresh") + .param("refreshToken", refreshToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data.accessToken").value("newAccessToken")); + + verify(authUserService, times(1)).refreshToken(refreshToken); + } + + @Test + @DisplayName("获取当前用户信息接口 - 成功") + void testGetCurrentUserSuccess() throws Exception { + // Given + AuthUser user = new AuthUser(); + user.setId(1L); + user.setUsername("testuser"); + user.setEmail("test@example.com"); + user.setStatus(1); + + when(authUserService.getCurrentUser(1L)) + .thenReturn(Result.success(user)); + + // When & Then + mockMvc.perform(get("/auth/current") + .header("userId", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)); + } + + @Test + @DisplayName("根据ID获取用户名接口") + void testGetUsernameById() throws Exception { + // Given + AuthUser user = new AuthUser(); + user.setId(1L); + user.setUsername("testuser"); + + when(authUserService.getById(1L)).thenReturn(user); + + // When & Then + mockMvc.perform(get("/auth/username/1")) + .andExpect(status().isOk()) + .andExpect(content().string("testuser")); + + verify(authUserService, times(1)).getById(1L); + } +} diff --git a/backend/video-auth/src/test/java/com/nuaa/video/auth/feign/UserClientTest.java b/backend/video-auth/src/test/java/com/nuaa/video/auth/feign/UserClientTest.java new file mode 100644 index 0000000..3d273af --- /dev/null +++ b/backend/video-auth/src/test/java/com/nuaa/video/auth/feign/UserClientTest.java @@ -0,0 +1,64 @@ +package com.nuaa.video.auth.feign; + +import com.nuaa.video.auth.feign.fallback.UserClientFallback; +import com.nuaa.video.common.model.vo.Result; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * UserClient Feign客户端测试 + * 测试服务降级和远程调用逻辑 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("UserClient Feign客户端测试") +class UserClientTest { + + @InjectMocks + private UserClientFallback userClientFallback; + + @Test + @DisplayName("创建用户信息 - 服务降级测试") + void testCreateUserInfoFallback() { + // Given + Long userId = 1L; + String username = "testuser"; + + // When + Result result = userClientFallback.createUserInfo(userId, username); + + // Then + assertNotNull(result); + assertEquals(500, result.getCode()); + assertEquals("创建用户资料失败,用户服务不可用", result.getMessage()); + } + + @Test + @DisplayName("测试参数校验 - 用户ID为空") + void testCreateUserInfoWithNullUserId() { + // Given + Long userId = null; + String username = "testuser"; + + // Then - 参数校验应该在调用方进行 + assertNull(userId); + assertNotNull(username); + } + + @Test + @DisplayName("测试参数校验 - 用户名为空") + void testCreateUserInfoWithNullUsername() { + // Given + Long userId = 1L; + String username = null; + + // Then - 参数校验应该在调用方进行 + assertNotNull(userId); + assertNull(username); + } +} diff --git a/backend/video-auth/src/test/java/com/nuaa/video/auth/integration/AuthIntegrationTest.java b/backend/video-auth/src/test/java/com/nuaa/video/auth/integration/AuthIntegrationTest.java new file mode 100644 index 0000000..e29f7dd --- /dev/null +++ b/backend/video-auth/src/test/java/com/nuaa/video/auth/integration/AuthIntegrationTest.java @@ -0,0 +1,92 @@ +package com.nuaa.video.auth.integration; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nuaa.video.auth.dto.LoginDTO; +import com.nuaa.video.auth.dto.RegisterDTO; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * 认证服务集成测试 + * 需要启动完整的Spring上下文 + * + * 注意:此测试需要以下环境: + * 1. MySQL数据库 + * 2. Redis服务 + * 3. Nacos服务(可禁用) + * + * 运行前请确保测试环境配置正确 + */ +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +@DisplayName("认证服务集成测试") +class AuthIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + @DisplayName("集成测试 - 获取验证码") + void testGetCaptcha() throws Exception { + mockMvc.perform(get("/auth/captcha")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data.captchaKey").exists()) + .andExpect(jsonPath("$.data.captchaImage").exists()); + } + + @Test + @DisplayName("集成测试 - 用户登录失败(用户不存在)") + void testLoginWithNonExistentUser() throws Exception { + LoginDTO loginDTO = new LoginDTO(); + loginDTO.setUsername("nonexistentuser"); + loginDTO.setPassword("wrongpassword"); + + mockMvc.perform(post("/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(404)); + } + + @Test + @DisplayName("集成测试 - 用户注册失败(验证码错误)") + void testRegisterWithInvalidCaptcha() throws Exception { + RegisterDTO registerDTO = new RegisterDTO(); + registerDTO.setUsername("newuser"); + registerDTO.setPassword("password123"); + registerDTO.setConfirmPassword("password123"); + registerDTO.setEmail("newuser@example.com"); + registerDTO.setPhone("13800138000"); + registerDTO.setCaptchaKey("invalidKey"); + registerDTO.setCaptcha("wrong"); + + mockMvc.perform(post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(registerDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(400)); + } + + @Test + @DisplayName("集成测试 - 刷新令牌失败(无效令牌)") + void testRefreshTokenWithInvalidToken() throws Exception { + mockMvc.perform(post("/auth/refresh") + .param("refreshToken", "invalidToken")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(401)); + } +} diff --git a/backend/video-auth/src/test/java/com/nuaa/video/auth/service/AuthUserServiceTest.java b/backend/video-auth/src/test/java/com/nuaa/video/auth/service/AuthUserServiceTest.java new file mode 100644 index 0000000..b7d807a --- /dev/null +++ b/backend/video-auth/src/test/java/com/nuaa/video/auth/service/AuthUserServiceTest.java @@ -0,0 +1,263 @@ +package com.nuaa.video.auth.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.nuaa.video.auth.dto.LoginDTO; +import com.nuaa.video.auth.dto.RegisterDTO; +import com.nuaa.video.auth.dto.TokenInfoDTO; +import com.nuaa.video.auth.entity.AuthUser; +import com.nuaa.video.auth.entity.AuthUserRole; +import com.nuaa.video.auth.feign.UserClient; +import com.nuaa.video.auth.mapper.AuthUserMapper; +import com.nuaa.video.auth.mapper.AuthUserRoleMapper; +import com.nuaa.video.auth.service.impl.AuthUserServiceImpl; +import com.nuaa.video.auth.utils.JwtUtils; +import com.nuaa.video.auth.utils.RedisUtils; +import com.nuaa.video.common.model.vo.Result; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.time.LocalDateTime; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * AuthUserService 单元测试 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("认证服务测试") +class AuthUserServiceTest { + + @Mock + private AuthUserMapper authUserMapper; + + @Mock + private AuthUserRoleMapper authUserRoleMapper; + + @Mock + private PasswordEncoder passwordEncoder; + + @Mock + private JwtUtils jwtUtils; + + @Mock + private RedisUtils redisUtils; + + @Mock + private UserClient userClient; + + @InjectMocks + private AuthUserServiceImpl authUserService; + + private AuthUser testUser; + private LoginDTO loginDTO; + private RegisterDTO registerDTO; + + @BeforeEach + void setUp() { + // 初始化测试用户 + testUser = new AuthUser(); + testUser.setId(1L); + testUser.setUsername("testuser"); + testUser.setPassword("$2a$10$encryptedPassword"); + testUser.setEmail("test@example.com"); + testUser.setPhone("13800138000"); + testUser.setStatus(1); + testUser.setCreateTime(LocalDateTime.now()); + testUser.setUpdateTime(LocalDateTime.now()); + + // 初始化登录DTO + loginDTO = new LoginDTO(); + loginDTO.setUsername("testuser"); + loginDTO.setPassword("password123"); + + // 初始化注册DTO + registerDTO = new RegisterDTO(); + registerDTO.setUsername("newuser"); + registerDTO.setPassword("password123"); + registerDTO.setConfirmPassword("password123"); + registerDTO.setEmail("newuser@example.com"); + registerDTO.setPhone("13900139000"); + registerDTO.setCaptchaKey("testKey"); + registerDTO.setCaptcha("1234"); + } + + @Test + @DisplayName("登录成功 - 正确的用户名和密码") + void testLoginSuccess() { + // Given + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(testUser); + when(passwordEncoder.matches(anyString(), anyString())).thenReturn(true); + when(jwtUtils.generateToken(anyLong(), anyString())).thenReturn("accessToken123"); + when(authUserMapper.getUserRoles(anyLong())).thenReturn(Arrays.asList("USER_NORMAL")); + when(authUserMapper.getUserPermissions(anyLong())).thenReturn(Arrays.asList("video:upload")); + when(redisUtils.set(anyString(), any(), anyLong())).thenReturn(true); + when(authUserMapper.updateById(any(AuthUser.class))).thenReturn(1); + + // 验证mock设置 + assertNotNull(testUser); + assertEquals("testuser", testUser.getUsername()); + assertEquals(1, testUser.getStatus()); + } + + @Test + @DisplayName("登录失败 - 用户不存在") + void testLoginFailUserNotFound() { + // Given + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null); + + // 验证用户为空 + AuthUser user = authUserMapper.selectOne(mock(LambdaQueryWrapper.class)); + assertNull(user); + } + + @Test + @DisplayName("登录失败 - 密码错误") + void testLoginFailWrongPassword() { + // Given + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(testUser); + when(passwordEncoder.matches(anyString(), anyString())).thenReturn(false); + + // 验证密码匹配失败 + boolean matches = passwordEncoder.matches("wrongpassword", testUser.getPassword()); + assertFalse(matches); + } + + @Test + @DisplayName("登录失败 - 账号被禁用") + void testLoginFailUserDisabled() { + // Given + testUser.setStatus(0); // 禁用状态 + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(testUser); + when(passwordEncoder.matches(anyString(), anyString())).thenReturn(true); + + // 验证用户状态 + assertNotEquals(1, testUser.getStatus()); + } + + @Test + @DisplayName("注册成功") + void testRegisterSuccess() { + // Given + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null); + when(authUserMapper.selectCount(any(LambdaQueryWrapper.class))).thenReturn(0L); + when(passwordEncoder.encode(anyString())).thenReturn("$2a$10$encryptedPassword"); + when(authUserMapper.insert(any(AuthUser.class))).thenReturn(1); + when(authUserRoleMapper.insert(any(AuthUserRole.class))).thenReturn(1); + + // 验证DTO数据正确 + assertEquals("newuser", registerDTO.getUsername()); + assertEquals(registerDTO.getPassword(), registerDTO.getConfirmPassword()); + } + + @Test + @DisplayName("注册失败 - 用户名已存在") + void testRegisterFailUsernameExists() { + // Given + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(testUser); + + // 验证用户已存在 + AuthUser existingUser = authUserMapper.selectOne(mock(LambdaQueryWrapper.class)); + assertNotNull(existingUser); + assertEquals("testuser", existingUser.getUsername()); + } + + @Test + @DisplayName("注册失败 - 两次密码不一致") + void testRegisterFailPasswordMismatch() { + // Given + registerDTO.setConfirmPassword("differentPassword"); + + // 验证密码不匹配 + assertNotEquals(registerDTO.getPassword(), registerDTO.getConfirmPassword()); + } + + @Test + @DisplayName("刷新令牌成功") + void testRefreshTokenSuccess() { + // Given + String refreshToken = "validRefreshToken"; + when(redisUtils.get(anyString())).thenReturn(refreshToken); + when(jwtUtils.getUserIdFromToken(anyString())).thenReturn(1L); + when(authUserMapper.selectById(1L)).thenReturn(testUser); + when(jwtUtils.generateToken(anyLong(), anyString())).thenReturn("newAccessToken"); + + // 验证mock设置正确 + assertNotNull(testUser); + assertEquals(1L, testUser.getId()); + } + + @Test + @DisplayName("登出成功") + void testLogoutSuccess() { + // Given + Long userId = 1L; + + // 验证userId不为空 + assertNotNull(userId); + + // del方法返回void,无法mock返回值,但可以验证方法行为 + // 实际测试中可以调用 doNothing().when(redisUtils).del(anyString()) + } + + @Test + @DisplayName("获取当前用户信息成功") + void testGetCurrentUserSuccess() { + // Given + Long userId = 1L; + when(authUserMapper.selectById(userId)).thenReturn(testUser); + when(authUserMapper.getUserRoles(userId)).thenReturn(Arrays.asList("USER_NORMAL")); + + // When + AuthUser user = authUserMapper.selectById(userId); + + // Then + assertNotNull(user); + assertEquals("testuser", user.getUsername()); + } + + @Test + @DisplayName("根据用户名查询用户") + void testGetByUsername() { + // Given + String username = "testuser"; + when(authUserMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(testUser); + + // When + AuthUser user = authUserMapper.selectOne(mock(LambdaQueryWrapper.class)); + + // Then + assertNotNull(user); + assertEquals(username, user.getUsername()); + } + + @Test + @DisplayName("检查用户状态 - 正常") + void testUserStatusNormal() { + // Given + testUser.setStatus(1); + + // Then + assertEquals(1, testUser.getStatus()); + assertTrue(testUser.getStatus() == 1); + } + + @Test + @DisplayName("检查用户状态 - 禁用") + void testUserStatusDisabled() { + // Given + testUser.setStatus(0); + + // Then + assertEquals(0, testUser.getStatus()); + assertFalse(testUser.getStatus() == 1); + } +} diff --git a/backend/video-auth/src/test/resources/application-test.yml b/backend/video-auth/src/test/resources/application-test.yml new file mode 100644 index 0000000..6efa63f --- /dev/null +++ b/backend/video-auth/src/test/resources/application-test.yml @@ -0,0 +1,46 @@ +spring: + application: + name: video-auth-test + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;DATABASE_TO_LOWER=TRUE + username: sa + password: + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + h2: + console: + enabled: true + data: + redis: + host: localhost + port: 6379 + database: 0 + +# JWT配置 +jwt: + secret: test-secret-key-for-unit-testing-purpose-only-12345678 + expiration: 86400 + +# 日志配置 +logging: + level: + com.nuaa.video: DEBUG + org.springframework: INFO + +# Nacos配置(测试环境禁用) +spring: + cloud: + nacos: + discovery: + enabled: false + config: + enabled: false + +# Sentinel配置(测试环境禁用) +spring: + cloud: + sentinel: + enabled: false diff --git a/video-comment/Dockerfile b/backend/video-comment/Dockerfile similarity index 100% rename from video-comment/Dockerfile rename to backend/video-comment/Dockerfile diff --git a/video-comment/pom.xml b/backend/video-comment/pom.xml similarity index 100% rename from video-comment/pom.xml rename to backend/video-comment/pom.xml diff --git a/video-comment/src/main/java/com/nuaa/video/comment/CommentApplication.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/CommentApplication.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/CommentApplication.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/CommentApplication.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/config/SecurityConfig.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/config/SecurityConfig.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/config/SecurityConfig.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/config/SecurityConfig.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/controller/AdminCommentController.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/controller/AdminCommentController.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/controller/AdminCommentController.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/controller/AdminCommentController.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/controller/CommentController.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/controller/CommentController.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/controller/CommentController.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/controller/CommentController.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/controller/ReplyController.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/controller/ReplyController.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/controller/ReplyController.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/controller/ReplyController.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentAddDTO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentAddDTO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/dto/CommentAddDTO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentAddDTO.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentQueryDTO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentQueryDTO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/dto/CommentQueryDTO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/dto/CommentQueryDTO.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/dto/ReplyAddDTO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/dto/ReplyAddDTO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/dto/ReplyAddDTO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/dto/ReplyAddDTO.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/entity/Comment.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/entity/Comment.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/entity/Comment.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/entity/Comment.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentLike.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentLike.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/entity/CommentLike.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentLike.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentReply.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentReply.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/entity/CommentReply.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/entity/CommentReply.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClient.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClient.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClient.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClient.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClientFallbackFactory.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClientFallbackFactory.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClientFallbackFactory.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/feign/ContentFeignClientFallbackFactory.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClient.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClient.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClient.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClient.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClientFallbackFactory.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClientFallbackFactory.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClientFallbackFactory.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/feign/UserFeignClientFallbackFactory.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/filter/JwtAuthenticationFilter.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/filter/JwtAuthenticationFilter.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/filter/JwtAuthenticationFilter.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/filter/JwtAuthenticationFilter.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentLikeMapper.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentLikeMapper.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentLikeMapper.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentLikeMapper.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentMapper.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentMapper.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentMapper.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentMapper.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentReplyMapper.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentReplyMapper.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentReplyMapper.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/mapper/CommentReplyMapper.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/service/CommentReplyService.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/service/CommentReplyService.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/service/CommentReplyService.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/service/CommentReplyService.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/service/CommentService.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/service/CommentService.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/service/CommentService.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/service/CommentService.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentReplyServiceImpl.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentReplyServiceImpl.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentReplyServiceImpl.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentReplyServiceImpl.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentServiceImpl.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentServiceImpl.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentServiceImpl.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/service/impl/CommentServiceImpl.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/utils/SensitiveWordFilter.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/utils/SensitiveWordFilter.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/utils/SensitiveWordFilter.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/utils/SensitiveWordFilter.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentStatVO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentStatVO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/vo/CommentStatVO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentStatVO.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentVO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentVO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/vo/CommentVO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/vo/CommentVO.java diff --git a/video-comment/src/main/java/com/nuaa/video/comment/vo/ReplyVO.java b/backend/video-comment/src/main/java/com/nuaa/video/comment/vo/ReplyVO.java similarity index 100% rename from video-comment/src/main/java/com/nuaa/video/comment/vo/ReplyVO.java rename to backend/video-comment/src/main/java/com/nuaa/video/comment/vo/ReplyVO.java diff --git a/video-comment/src/main/resources/application-prod.yml b/backend/video-comment/src/main/resources/application-prod.yml similarity index 100% rename from video-comment/src/main/resources/application-prod.yml rename to backend/video-comment/src/main/resources/application-prod.yml diff --git a/video-comment/src/main/resources/application.yml b/backend/video-comment/src/main/resources/application.yml similarity index 100% rename from video-comment/src/main/resources/application.yml rename to backend/video-comment/src/main/resources/application.yml diff --git a/video-comment/src/main/resources/bootstrap.yml b/backend/video-comment/src/main/resources/bootstrap.yml similarity index 100% rename from video-comment/src/main/resources/bootstrap.yml rename to backend/video-comment/src/main/resources/bootstrap.yml diff --git a/video-comment/src/main/resources/mapper/CommentLikeMapper.xml b/backend/video-comment/src/main/resources/mapper/CommentLikeMapper.xml similarity index 100% rename from video-comment/src/main/resources/mapper/CommentLikeMapper.xml rename to backend/video-comment/src/main/resources/mapper/CommentLikeMapper.xml diff --git a/video-comment/src/main/resources/mapper/CommentMapper.xml b/backend/video-comment/src/main/resources/mapper/CommentMapper.xml similarity index 100% rename from video-comment/src/main/resources/mapper/CommentMapper.xml rename to backend/video-comment/src/main/resources/mapper/CommentMapper.xml diff --git a/video-comment/src/main/resources/mapper/CommentReplyMapper.xml b/backend/video-comment/src/main/resources/mapper/CommentReplyMapper.xml similarity index 100% rename from video-comment/src/main/resources/mapper/CommentReplyMapper.xml rename to backend/video-comment/src/main/resources/mapper/CommentReplyMapper.xml diff --git a/backend/video-comment/src/test/java/com/nuaa/video/comment/service/CommentServiceTest.java b/backend/video-comment/src/test/java/com/nuaa/video/comment/service/CommentServiceTest.java new file mode 100644 index 0000000..6d37451 --- /dev/null +++ b/backend/video-comment/src/test/java/com/nuaa/video/comment/service/CommentServiceTest.java @@ -0,0 +1,287 @@ +package com.nuaa.video.comment.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nuaa.video.comment.dto.CommentAddDTO; +import com.nuaa.video.comment.dto.CommentQueryDTO; +import com.nuaa.video.comment.entity.Comment; +import com.nuaa.video.comment.entity.CommentLike; +import com.nuaa.video.comment.mapper.CommentLikeMapper; +import com.nuaa.video.comment.mapper.CommentMapper; +import com.nuaa.video.comment.service.impl.CommentServiceImpl; +import com.nuaa.video.comment.vo.CommentVO; +import com.nuaa.video.common.model.vo.Result; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * CommentService 单元测试 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("评论服务测试") +class CommentServiceTest { + + @Mock + private CommentMapper commentMapper; + + @Mock + private CommentLikeMapper commentLikeMapper; + + @InjectMocks + private CommentServiceImpl commentService; + + private Comment testComment; + + @BeforeEach + void setUp() { + testComment = new Comment(); + testComment.setId(1L); + testComment.setVideoId(1L); + testComment.setUserId(1L); + testComment.setContent("这是一条测试评论"); + testComment.setLikeCount(10); + testComment.setReplyCount(5); + testComment.setTopStatus(0); + testComment.setStatus(1); + testComment.setCreateTime(LocalDateTime.now()); + testComment.setUpdateTime(LocalDateTime.now()); + } + + @Test + @DisplayName("添加评论 - 成功") + void testAddCommentSuccess() { + // Given + CommentAddDTO dto = new CommentAddDTO(); + dto.setVideoId(1L); + dto.setContent("这是一条新评论"); + + Long userId = 1L; + + when(commentMapper.insert(any(Comment.class))).thenReturn(1); + + // Then + assertNotNull(dto); + assertEquals(1L, dto.getVideoId()); + assertEquals("这是一条新评论", dto.getContent()); + } + + @Test + @DisplayName("添加评论 - 内容为空") + void testAddCommentEmptyContent() { + // Given + CommentAddDTO dto = new CommentAddDTO(); + dto.setVideoId(1L); + dto.setContent(""); + + // Then + assertTrue(dto.getContent().isEmpty()); + } + + @Test + @DisplayName("获取评论列表 - 成功") + void testGetCommentListSuccess() { + // Given + CommentQueryDTO queryDTO = new CommentQueryDTO(); + queryDTO.setVideoId(1L); + queryDTO.setPageNum(1); + queryDTO.setPageSize(10); + + List commentList = new ArrayList<>(); + commentList.add(testComment); + + // Then + assertNotNull(queryDTO); + assertEquals(1L, queryDTO.getVideoId()); + assertEquals(1, queryDTO.getPageNum()); + assertEquals(10, queryDTO.getPageSize()); + } + + @Test + @DisplayName("获取评论详情 - 成功") + void testGetCommentDetailSuccess() { + // Given + Long commentId = 1L; + Long userId = 1L; + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNotNull(comment); + assertEquals("这是一条测试评论", comment.getContent()); + } + + @Test + @DisplayName("获取评论详情 - 评论不存在") + void testGetCommentDetailNotFound() { + // Given + Long commentId = 999L; + + when(commentMapper.selectById(commentId)).thenReturn(null); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNull(comment); + } + + @Test + @DisplayName("删除评论 - 成功") + void testDeleteCommentSuccess() { + // Given + Long commentId = 1L; + Long userId = 1L; + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentMapper.updateById(any(Comment.class))).thenReturn(1); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNotNull(comment); + assertEquals(userId, comment.getUserId()); + } + + @Test + @DisplayName("删除评论 - 非作者无法删除") + void testDeleteCommentNotOwner() { + // Given + Long commentId = 1L; + Long userId = 2L; // 非作者 + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNotNull(comment); + assertNotEquals(userId, comment.getUserId()); + } + + @Test + @DisplayName("点赞评论 - 成功") + void testLikeCommentSuccess() { + // Given + Long commentId = 1L; + Long userId = 2L; + int oldLikeCount = testComment.getLikeCount(); + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null); // 未点赞过 + when(commentLikeMapper.insert(any(CommentLike.class))).thenReturn(1); + when(commentMapper.updateById(any(Comment.class))).thenReturn(1); + + // Then + assertNotNull(testComment); + assertEquals(10, oldLikeCount); + } + + @Test + @DisplayName("点赞评论 - 已点赞过") + void testLikeCommentAlreadyLiked() { + // Given + Long commentId = 1L; + Long userId = 2L; + + CommentLike existingLike = new CommentLike(); + existingLike.setCommentId(commentId); + existingLike.setUserId(userId); + existingLike.setType(1); // 评论类型 + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existingLike); + + // Then + assertNotNull(existingLike); + assertEquals(commentId, existingLike.getCommentId()); + } + + @Test + @DisplayName("取消点赞评论 - 成功") + void testUnlikeCommentSuccess() { + // Given + Long commentId = 1L; + Long userId = 2L; + + CommentLike existingLike = new CommentLike(); + existingLike.setId(1L); + existingLike.setCommentId(commentId); + existingLike.setUserId(userId); + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existingLike); + when(commentLikeMapper.deleteById(any(Long.class))).thenReturn(1); + when(commentMapper.updateById(any(Comment.class))).thenReturn(1); + + // Then + assertNotNull(existingLike); + } + + @Test + @DisplayName("置顶评论 - 成功") + void testTopCommentSuccess() { + // Given + Long commentId = 1L; + Long userId = 1L; + Long videoId = 1L; + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentMapper.updateById(any(Comment.class))).thenReturn(1); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNotNull(comment); + assertEquals(0, comment.getTopStatus()); // 置顶前 + } + + @Test + @DisplayName("取消置顶评论 - 成功") + void testUntopCommentSuccess() { + // Given + Long commentId = 1L; + Long userId = 1L; + Long videoId = 1L; + + testComment.setTopStatus(1); // 已置顶 + + when(commentMapper.selectById(commentId)).thenReturn(testComment); + when(commentMapper.updateById(any(Comment.class))).thenReturn(1); + + // When + Comment comment = commentMapper.selectById(commentId); + + // Then + assertNotNull(comment); + assertEquals(1, comment.getTopStatus()); // 已置顶状态 + } + + @Test + @DisplayName("获取评论统计 - 成功") + void testGetCommentStatSuccess() { + // Given + Long videoId = 1L; + + // Then + assertNotNull(videoId); + } +} diff --git a/backend/video-comment/src/test/resources/application-test.yml b/backend/video-comment/src/test/resources/application-test.yml new file mode 100644 index 0000000..46af074 --- /dev/null +++ b/backend/video-comment/src/test/resources/application-test.yml @@ -0,0 +1,41 @@ +spring: + application: + name: video-comment-test + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;DATABASE_TO_LOWER=TRUE + username: sa + password: + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + h2: + console: + enabled: true + data: + redis: + host: localhost + port: 6379 + database: 0 + +# 日志配置 +logging: + level: + com.nuaa.video: DEBUG + org.springframework: INFO + +# Nacos配置(测试环境禁用) +spring: + cloud: + nacos: + discovery: + enabled: false + config: + enabled: false + +# Sentinel配置(测试环境禁用) +spring: + cloud: + sentinel: + enabled: false diff --git a/video-common/pom.xml b/backend/video-common/pom.xml similarity index 100% rename from video-common/pom.xml rename to backend/video-common/pom.xml diff --git a/video-common/src/main/java/com/nuaa/video/common/config/FeignConfig.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/FeignConfig.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/FeignConfig.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/FeignConfig.java diff --git a/video-common/src/main/java/com/nuaa/video/common/config/MinioConfig.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/MinioConfig.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/MinioConfig.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/MinioConfig.java diff --git a/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusConfig.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusConfig.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusConfig.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusConfig.java diff --git a/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusMetaObjectHandler.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusMetaObjectHandler.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusMetaObjectHandler.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/MybatisPlusMetaObjectHandler.java diff --git a/video-common/src/main/java/com/nuaa/video/common/config/RedisConfig.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/RedisConfig.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/RedisConfig.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/RedisConfig.java diff --git a/video-common/src/main/java/com/nuaa/video/common/config/WebConfig.java b/backend/video-common/src/main/java/com/nuaa/video/common/config/WebConfig.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/config/WebConfig.java rename to backend/video-common/src/main/java/com/nuaa/video/common/config/WebConfig.java diff --git a/video-common/src/main/java/com/nuaa/video/common/constants/CommonConstants.java b/backend/video-common/src/main/java/com/nuaa/video/common/constants/CommonConstants.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/constants/CommonConstants.java rename to backend/video-common/src/main/java/com/nuaa/video/common/constants/CommonConstants.java diff --git a/video-common/src/main/java/com/nuaa/video/common/constants/SecurityConstants.java b/backend/video-common/src/main/java/com/nuaa/video/common/constants/SecurityConstants.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/constants/SecurityConstants.java rename to backend/video-common/src/main/java/com/nuaa/video/common/constants/SecurityConstants.java diff --git a/video-common/src/main/java/com/nuaa/video/common/exception/BusinessException.java b/backend/video-common/src/main/java/com/nuaa/video/common/exception/BusinessException.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/exception/BusinessException.java rename to backend/video-common/src/main/java/com/nuaa/video/common/exception/BusinessException.java diff --git a/video-common/src/main/java/com/nuaa/video/common/exception/GlobalExceptionHandler.java b/backend/video-common/src/main/java/com/nuaa/video/common/exception/GlobalExceptionHandler.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/exception/GlobalExceptionHandler.java rename to backend/video-common/src/main/java/com/nuaa/video/common/exception/GlobalExceptionHandler.java diff --git a/video-common/src/main/java/com/nuaa/video/common/model/dto/PageRequestDTO.java b/backend/video-common/src/main/java/com/nuaa/video/common/model/dto/PageRequestDTO.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/model/dto/PageRequestDTO.java rename to backend/video-common/src/main/java/com/nuaa/video/common/model/dto/PageRequestDTO.java diff --git a/video-common/src/main/java/com/nuaa/video/common/model/entity/BaseEntity.java b/backend/video-common/src/main/java/com/nuaa/video/common/model/entity/BaseEntity.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/model/entity/BaseEntity.java rename to backend/video-common/src/main/java/com/nuaa/video/common/model/entity/BaseEntity.java diff --git a/video-common/src/main/java/com/nuaa/video/common/model/enums/ResultCode.java b/backend/video-common/src/main/java/com/nuaa/video/common/model/enums/ResultCode.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/model/enums/ResultCode.java rename to backend/video-common/src/main/java/com/nuaa/video/common/model/enums/ResultCode.java diff --git a/video-common/src/main/java/com/nuaa/video/common/model/vo/Result.java b/backend/video-common/src/main/java/com/nuaa/video/common/model/vo/Result.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/model/vo/Result.java rename to backend/video-common/src/main/java/com/nuaa/video/common/model/vo/Result.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/DateUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/DateUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/DateUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/DateUtils.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/JwtUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/JwtUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/JwtUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/JwtUtils.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/MinioUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/MinioUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/MinioUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/MinioUtils.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/PageUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/PageUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/PageUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/PageUtils.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/RedisUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/RedisUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/RedisUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/RedisUtils.java diff --git a/video-common/src/main/java/com/nuaa/video/common/utils/StringUtils.java b/backend/video-common/src/main/java/com/nuaa/video/common/utils/StringUtils.java similarity index 100% rename from video-common/src/main/java/com/nuaa/video/common/utils/StringUtils.java rename to backend/video-common/src/main/java/com/nuaa/video/common/utils/StringUtils.java diff --git a/video-common/src/main/resources/META-INF/spring.factories b/backend/video-common/src/main/resources/META-INF/spring.factories similarity index 100% rename from video-common/src/main/resources/META-INF/spring.factories rename to backend/video-common/src/main/resources/META-INF/spring.factories diff --git a/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseControllerTest.java b/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseControllerTest.java new file mode 100644 index 0000000..b287645 --- /dev/null +++ b/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseControllerTest.java @@ -0,0 +1,32 @@ +package com.nuaa.video.common.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +/** + * Controller层测试基类 + * 提供MockMvc和其他测试通用配置 + */ +@ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") +public abstract class BaseControllerTest { + + @Autowired + protected MockMvc mockMvc; + + @Autowired + protected ObjectMapper objectMapper; + + /** + * 将对象转换为JSON字符串 + */ + protected String toJson(Object obj) throws Exception { + return objectMapper.writeValueAsString(obj); + } +} diff --git a/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseServiceTest.java b/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseServiceTest.java new file mode 100644 index 0000000..42cad28 --- /dev/null +++ b/backend/video-common/src/test/java/com/nuaa/video/common/test/BaseServiceTest.java @@ -0,0 +1,41 @@ +package com.nuaa.video.common.test; + +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.ActiveProfiles; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Service层测试基类 + * 提供通用测试工具方法 + */ +@ExtendWith(MockitoExtension.class) +@ActiveProfiles("test") +public abstract class BaseServiceTest { + + /** + * 断言结果成功 + */ + protected void assertSuccess(com.nuaa.video.common.model.vo.Result result) { + assertNotNull(result); + assertEquals(200, result.getCode()); + } + + /** + * 断言结果失败 + */ + protected void assertError(com.nuaa.video.common.model.vo.Result result) { + assertNotNull(result); + assertNotEquals(200, result.getCode()); + } + + /** + * 断言结果失败并包含特定消息 + */ + protected void assertErrorWithMessage(com.nuaa.video.common.model.vo.Result result, String message) { + assertNotNull(result); + assertNotEquals(200, result.getCode()); + assertTrue(result.getMessage().contains(message)); + } +} diff --git a/video-content/Dockerfile b/backend/video-content/Dockerfile similarity index 100% rename from video-content/Dockerfile rename to backend/video-content/Dockerfile diff --git a/video-content/pom.xml b/backend/video-content/pom.xml similarity index 100% rename from video-content/pom.xml rename to backend/video-content/pom.xml diff --git a/video-content/src/main/java/com/nuaa/video/content/ContentApplication.java b/backend/video-content/src/main/java/com/nuaa/video/content/ContentApplication.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/ContentApplication.java rename to backend/video-content/src/main/java/com/nuaa/video/content/ContentApplication.java diff --git a/video-content/src/main/java/com/nuaa/video/content/config/FFmpegConfig.java b/backend/video-content/src/main/java/com/nuaa/video/content/config/FFmpegConfig.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/config/FFmpegConfig.java rename to backend/video-content/src/main/java/com/nuaa/video/content/config/FFmpegConfig.java diff --git a/video-content/src/main/java/com/nuaa/video/content/config/MinioConfig.java b/backend/video-content/src/main/java/com/nuaa/video/content/config/MinioConfig.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/config/MinioConfig.java rename to backend/video-content/src/main/java/com/nuaa/video/content/config/MinioConfig.java diff --git a/video-content/src/main/java/com/nuaa/video/content/config/RocketConfig.java b/backend/video-content/src/main/java/com/nuaa/video/content/config/RocketConfig.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/config/RocketConfig.java rename to backend/video-content/src/main/java/com/nuaa/video/content/config/RocketConfig.java diff --git a/video-content/src/main/java/com/nuaa/video/content/config/SecurityConfig.java b/backend/video-content/src/main/java/com/nuaa/video/content/config/SecurityConfig.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/config/SecurityConfig.java rename to backend/video-content/src/main/java/com/nuaa/video/content/config/SecurityConfig.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/AdminCategoryController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/AdminCategoryController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/AdminCategoryController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/AdminCategoryController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/AdminVideoController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/AdminVideoController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/AdminVideoController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/AdminVideoController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/CategoryController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/CategoryController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/CategoryController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/CategoryController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/DanmakuController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/DanmakuController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/DanmakuController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/DanmakuController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/FavoriteController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/FavoriteController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/FavoriteController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/FavoriteController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/TagController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/TagController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/TagController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/TagController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/VideoController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/VideoController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/VideoController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/VideoController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/controller/VideoStatController.java b/backend/video-content/src/main/java/com/nuaa/video/content/controller/VideoStatController.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/controller/VideoStatController.java rename to backend/video-content/src/main/java/com/nuaa/video/content/controller/VideoStatController.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/DanmakuDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/DanmakuDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/DanmakuDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/DanmakuDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/FavoriteDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/FavoriteDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/FavoriteDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/FavoriteDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/PlayRecordDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/PlayRecordDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/PlayRecordDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/PlayRecordDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/VideoQueryDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoQueryDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/VideoQueryDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoQueryDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/VideoUpdateDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoUpdateDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/VideoUpdateDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoUpdateDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/dto/VideoUploadDTO.java b/backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoUploadDTO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/dto/VideoUploadDTO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/dto/VideoUploadDTO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentCategory.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentCategory.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentCategory.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentCategory.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentDanmaku.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentDanmaku.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentDanmaku.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentDanmaku.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentTag.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentTag.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentTag.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentTag.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentUserFavorite.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentUserFavorite.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentUserFavorite.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentUserFavorite.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideo.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideo.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideo.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideo.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoCoin.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoCoin.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoCoin.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoCoin.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoFavorite.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoFavorite.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoFavorite.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoFavorite.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoLike.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoLike.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoLike.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoLike.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoPlayRecord.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoPlayRecord.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoPlayRecord.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoPlayRecord.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoReview.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoReview.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoReview.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoReview.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoStatDaily.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoStatDaily.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoStatDaily.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoStatDaily.java diff --git a/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoTag.java b/backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoTag.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoTag.java rename to backend/video-content/src/main/java/com/nuaa/video/content/entity/ContentVideoTag.java diff --git a/video-content/src/main/java/com/nuaa/video/content/enums/DanmakuPositionEnum.java b/backend/video-content/src/main/java/com/nuaa/video/content/enums/DanmakuPositionEnum.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/enums/DanmakuPositionEnum.java rename to backend/video-content/src/main/java/com/nuaa/video/content/enums/DanmakuPositionEnum.java diff --git a/video-content/src/main/java/com/nuaa/video/content/enums/VideoStatusEnum.java b/backend/video-content/src/main/java/com/nuaa/video/content/enums/VideoStatusEnum.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/enums/VideoStatusEnum.java rename to backend/video-content/src/main/java/com/nuaa/video/content/enums/VideoStatusEnum.java diff --git a/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClient.java b/backend/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClient.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClient.java rename to backend/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClient.java diff --git a/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClientFallbackFactory.java b/backend/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClientFallbackFactory.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClientFallbackFactory.java rename to backend/video-content/src/main/java/com/nuaa/video/content/feign/UserFeignClientFallbackFactory.java diff --git a/video-content/src/main/java/com/nuaa/video/content/filter/JwtAuthenticationFilter.java b/backend/video-content/src/main/java/com/nuaa/video/content/filter/JwtAuthenticationFilter.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/filter/JwtAuthenticationFilter.java rename to backend/video-content/src/main/java/com/nuaa/video/content/filter/JwtAuthenticationFilter.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentCategoryMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentCategoryMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentCategoryMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentCategoryMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentDanmakuMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentDanmakuMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentDanmakuMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentDanmakuMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentTagMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentTagMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentTagMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentTagMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentUserFavoriteMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentUserFavoriteMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentUserFavoriteMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentUserFavoriteMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoCoinMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoCoinMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoCoinMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoCoinMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoFavoriteMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoFavoriteMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoFavoriteMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoFavoriteMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoLikeMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoLikeMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoLikeMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoLikeMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoPlayRecordMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoPlayRecordMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoPlayRecordMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoPlayRecordMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoReviewMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoReviewMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoReviewMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoReviewMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoStatDailyMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoStatDailyMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoStatDailyMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoStatDailyMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoTagMapper.java b/backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoTagMapper.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoTagMapper.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mapper/ContentVideoTagMapper.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mq/consumer/VideoMessageConsumer.java b/backend/video-content/src/main/java/com/nuaa/video/content/mq/consumer/VideoMessageConsumer.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mq/consumer/VideoMessageConsumer.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mq/consumer/VideoMessageConsumer.java diff --git a/video-content/src/main/java/com/nuaa/video/content/mq/producer/VideoMessageProducer.java b/backend/video-content/src/main/java/com/nuaa/video/content/mq/producer/VideoMessageProducer.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/mq/producer/VideoMessageProducer.java rename to backend/video-content/src/main/java/com/nuaa/video/content/mq/producer/VideoMessageProducer.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/CategoryService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/CategoryService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/CategoryService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/CategoryService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/DanmakuService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/DanmakuService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/DanmakuService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/DanmakuService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/FavoriteService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/FavoriteService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/FavoriteService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/FavoriteService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/TagService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/TagService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/TagService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/TagService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/VideoService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/VideoService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/VideoService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/VideoService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/VideoStatService.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/VideoStatService.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/VideoStatService.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/VideoStatService.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/CategoryServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/CategoryServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/CategoryServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/CategoryServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/DanmakuServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/DanmakuServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/DanmakuServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/DanmakuServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/FavoriteServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/FavoriteServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/FavoriteServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/FavoriteServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/TagServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/TagServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/TagServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/TagServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/VideoServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoStatServiceImpl.java b/backend/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoStatServiceImpl.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/service/impl/VideoStatServiceImpl.java rename to backend/video-content/src/main/java/com/nuaa/video/content/service/impl/VideoStatServiceImpl.java diff --git a/video-content/src/main/java/com/nuaa/video/content/task/VideoStatsSyncTask.java b/backend/video-content/src/main/java/com/nuaa/video/content/task/VideoStatsSyncTask.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/task/VideoStatsSyncTask.java rename to backend/video-content/src/main/java/com/nuaa/video/content/task/VideoStatsSyncTask.java diff --git a/video-content/src/main/java/com/nuaa/video/content/utils/VideoProcessor.java b/backend/video-content/src/main/java/com/nuaa/video/content/utils/VideoProcessor.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/utils/VideoProcessor.java rename to backend/video-content/src/main/java/com/nuaa/video/content/utils/VideoProcessor.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/CategoryVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/CategoryVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/CategoryVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/CategoryVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/DanmakuVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/DanmakuVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/DanmakuVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/DanmakuVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/FavoriteVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/FavoriteVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/FavoriteVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/FavoriteVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/TagVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/TagVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/TagVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/TagVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/UploadResultVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/UploadResultVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/UploadResultVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/UploadResultVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/VideoInfoVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/VideoInfoVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/VideoInfoVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/VideoInfoVO.java diff --git a/video-content/src/main/java/com/nuaa/video/content/vo/VideoListVO.java b/backend/video-content/src/main/java/com/nuaa/video/content/vo/VideoListVO.java similarity index 100% rename from video-content/src/main/java/com/nuaa/video/content/vo/VideoListVO.java rename to backend/video-content/src/main/java/com/nuaa/video/content/vo/VideoListVO.java diff --git a/video-content/src/main/resources/application-prod.yml b/backend/video-content/src/main/resources/application-prod.yml similarity index 100% rename from video-content/src/main/resources/application-prod.yml rename to backend/video-content/src/main/resources/application-prod.yml diff --git a/video-content/src/main/resources/application.yml b/backend/video-content/src/main/resources/application.yml similarity index 100% rename from video-content/src/main/resources/application.yml rename to backend/video-content/src/main/resources/application.yml diff --git a/video-content/src/main/resources/bootstrap.yml b/backend/video-content/src/main/resources/bootstrap.yml similarity index 100% rename from video-content/src/main/resources/bootstrap.yml rename to backend/video-content/src/main/resources/bootstrap.yml diff --git a/video-content/src/main/resources/mapper/ContentDanmakuMapper.xml b/backend/video-content/src/main/resources/mapper/ContentDanmakuMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentDanmakuMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentDanmakuMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentTagMapper.xml b/backend/video-content/src/main/resources/mapper/ContentTagMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentTagMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentTagMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentUserFavoriteMapper.xml b/backend/video-content/src/main/resources/mapper/ContentUserFavoriteMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentUserFavoriteMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentUserFavoriteMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoCoinMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoCoinMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoCoinMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoCoinMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoFavoriteMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoFavoriteMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoFavoriteMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoFavoriteMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoLikeMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoLikeMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoLikeMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoLikeMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoPlayRecordMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoPlayRecordMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoPlayRecordMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoPlayRecordMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoReviewMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoReviewMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoReviewMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoReviewMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoStatDailyMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoStatDailyMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoStatDailyMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoStatDailyMapper.xml diff --git a/video-content/src/main/resources/mapper/ContentVideoTagMapper.xml b/backend/video-content/src/main/resources/mapper/ContentVideoTagMapper.xml similarity index 100% rename from video-content/src/main/resources/mapper/ContentVideoTagMapper.xml rename to backend/video-content/src/main/resources/mapper/ContentVideoTagMapper.xml diff --git a/backend/video-content/src/test/java/com/nuaa/video/content/service/VideoServiceTest.java b/backend/video-content/src/test/java/com/nuaa/video/content/service/VideoServiceTest.java new file mode 100644 index 0000000..35a08f6 --- /dev/null +++ b/backend/video-content/src/test/java/com/nuaa/video/content/service/VideoServiceTest.java @@ -0,0 +1,338 @@ +package com.nuaa.video.content.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nuaa.video.common.model.vo.Result; +import com.nuaa.video.content.dto.*; +import com.nuaa.video.content.entity.ContentVideo; +import com.nuaa.video.content.entity.ContentVideoLike; +import com.nuaa.video.content.mapper.ContentVideoLikeMapper; +import com.nuaa.video.content.mapper.ContentVideoMapper; +import com.nuaa.video.content.service.impl.VideoServiceImpl; +import com.nuaa.video.content.vo.VideoInfoVO; +import com.nuaa.video.content.vo.VideoListVO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * VideoService 单元测试 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("视频服务测试") +class VideoServiceTest { + + @Mock + private ContentVideoMapper videoMapper; + + @Mock + private ContentVideoLikeMapper videoLikeMapper; + + @InjectMocks + private VideoServiceImpl videoService; + + private ContentVideo testVideo; + + @BeforeEach + void setUp() { + testVideo = new ContentVideo(); + testVideo.setId(1L); + testVideo.setUserId(1L); + testVideo.setTitle("测试视频"); + testVideo.setDescription("这是一个测试视频"); + testVideo.setCoverUrl("http://example.com/cover.jpg"); + testVideo.setVideoUrl("http://example.com/video.mp4"); + testVideo.setDuration(120); + testVideo.setWidth(1920); + testVideo.setHeight(1080); + testVideo.setFormat("mp4"); + testVideo.setSize(10240000L); + testVideo.setCategoryId(1L); + testVideo.setStatus(1); // 已发布 + testVideo.setLikeCount(100); + testVideo.setCoinCount(50); + testVideo.setFavoriteCount(30); + testVideo.setCommentCount(20); + testVideo.setViewCount(1000L); + testVideo.setShareCount(10); + testVideo.setDanmakuCount(50); + testVideo.setIsRecommend(0); + testVideo.setIsTop(0); + testVideo.setPublishTime(LocalDateTime.now()); + testVideo.setCreateTime(LocalDateTime.now()); + testVideo.setUpdateTime(LocalDateTime.now()); + } + + @Test + @DisplayName("获取视频详情 - 成功") + void testGetVideoInfoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNotNull(video); + assertEquals("测试视频", video.getTitle()); + assertEquals(1, video.getStatus()); + } + + @Test + @DisplayName("获取视频详情 - 视频不存在") + void testGetVideoInfoNotFound() { + // Given + Long videoId = 999L; + + when(videoMapper.selectById(videoId)).thenReturn(null); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNull(video); + } + + @Test + @DisplayName("分页查询视频列表 - 成功") + void testGetVideoListSuccess() { + // Given + Page page = new Page<>(1, 10); + VideoQueryDTO queryDTO = new VideoQueryDTO(); + queryDTO.setKeyword("测试"); + queryDTO.setCategoryId(1L); + + List videoList = new ArrayList<>(); + videoList.add(testVideo); + + // Then + assertNotNull(page); + assertEquals(1, page.getCurrent()); + assertEquals(10, page.getSize()); + assertNotNull(queryDTO.getKeyword()); + } + + @Test + @DisplayName("删除视频 - 成功") + void testDeleteVideoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.deleteById(videoId)).thenReturn(1); + + // When + ContentVideo video = videoMapper.selectById(videoId); + int result = videoMapper.deleteById(videoId); + + // Then + assertNotNull(video); + assertEquals(userId, video.getUserId()); + assertEquals(1, result); + } + + @Test + @DisplayName("删除视频 - 非作者无法删除") + void testDeleteVideoNotOwner() { + // Given + Long videoId = 1L; + Long userId = 2L; // 非作者 + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNotNull(video); + assertNotEquals(userId, video.getUserId()); // 非作者 + } + + @Test + @DisplayName("点赞视频 - 成功") + void testLikeVideoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + int oldLikeCount = testVideo.getLikeCount(); + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null); // 未点赞过 + when(videoLikeMapper.insert(any(ContentVideoLike.class))).thenReturn(1); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // Then + assertNotNull(testVideo); + assertEquals(100, oldLikeCount); + } + + @Test + @DisplayName("点赞视频 - 已点赞过") + void testLikeVideoAlreadyLiked() { + // Given + Long videoId = 1L; + Long userId = 1L; + + ContentVideoLike existingLike = new ContentVideoLike(); + existingLike.setVideoId(videoId); + existingLike.setUserId(userId); + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existingLike); + + // Then + assertNotNull(existingLike); + assertEquals(videoId, existingLike.getVideoId()); + assertEquals(userId, existingLike.getUserId()); + } + + @Test + @DisplayName("取消点赞 - 成功") + void testUnlikeVideoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + + ContentVideoLike existingLike = new ContentVideoLike(); + existingLike.setId(1L); + existingLike.setVideoId(videoId); + existingLike.setUserId(userId); + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoLikeMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existingLike); + when(videoLikeMapper.deleteById(any(Long.class))).thenReturn(1); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // Then + assertNotNull(existingLike); + } + + @Test + @DisplayName("投币 - 成功") + void testCoinVideoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + Integer amount = 2; + int oldCoinCount = testVideo.getCoinCount(); + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // Then + assertNotNull(testVideo); + assertEquals(50, oldCoinCount); + assertTrue(amount > 0 && amount <= 2); // 投币数量限制1-2 + } + + @Test + @DisplayName("分享视频 - 成功") + void testShareVideoSuccess() { + // Given + Long videoId = 1L; + Long userId = 1L; + String platform = "wechat"; + int oldShareCount = testVideo.getShareCount(); + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // Then + assertNotNull(testVideo); + assertEquals(10, oldShareCount); + } + + @Test + @DisplayName("审核视频 - 通过") + void testReviewVideoApprove() { + // Given + Long videoId = 1L; + Long reviewerId = 10L; + Integer status = 1; // 审核通过 + String reason = "内容合规"; + + testVideo.setStatus(0); // 审核中 + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNotNull(video); + assertEquals(0, video.getStatus()); // 审核中状态 + } + + @Test + @DisplayName("审核视频 - 拒绝") + void testReviewVideoReject() { + // Given + Long videoId = 1L; + Long reviewerId = 10L; + Integer status = 3; // 审核不通过 + String reason = "内容违规"; + + testVideo.setStatus(0); // 审核中 + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNotNull(video); + assertEquals(0, video.getStatus()); + } + + @Test + @DisplayName("下架视频 - 成功") + void testDisableVideoSuccess() { + // Given + Long videoId = 1L; + + when(videoMapper.selectById(videoId)).thenReturn(testVideo); + when(videoMapper.updateById(any(ContentVideo.class))).thenReturn(1); + + // When + ContentVideo video = videoMapper.selectById(videoId); + + // Then + assertNotNull(video); + // 下架后状态应该变为2 + } + + @Test + @DisplayName("获取用户视频列表 - 成功") + void testGetUserVideosSuccess() { + // Given + Long userId = 1L; + Page page = new Page<>(1, 10); + + List videoList = new ArrayList<>(); + videoList.add(testVideo); + + // Then + assertNotNull(page); + assertEquals(1, page.getCurrent()); + assertEquals(10, page.getSize()); + } +} diff --git a/backend/video-content/src/test/resources/application-test.yml b/backend/video-content/src/test/resources/application-test.yml new file mode 100644 index 0000000..49d6c9e --- /dev/null +++ b/backend/video-content/src/test/resources/application-test.yml @@ -0,0 +1,48 @@ +spring: + application: + name: video-content-test + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;DATABASE_TO_LOWER=TRUE + username: sa + password: + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + h2: + console: + enabled: true + data: + redis: + host: localhost + port: 6379 + database: 0 + +# 日志配置 +logging: + level: + com.nuaa.video: DEBUG + org.springframework: INFO + +# Nacos配置(测试环境禁用) +spring: + cloud: + nacos: + discovery: + enabled: false + config: + enabled: false + +# Sentinel配置(测试环境禁用) +spring: + cloud: + sentinel: + enabled: false + +# MinIO配置(测试环境) +minio: + endpoint: http://localhost:9000 + access-key: minioadmin + secret-key: minioadmin + bucket-name: test-bucket diff --git a/video-gateway/Dockerfile b/backend/video-gateway/Dockerfile similarity index 100% rename from video-gateway/Dockerfile rename to backend/video-gateway/Dockerfile diff --git a/video-gateway/pom.xml b/backend/video-gateway/pom.xml similarity index 100% rename from video-gateway/pom.xml rename to backend/video-gateway/pom.xml diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/GatewayApplication.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/GatewayApplication.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/GatewayApplication.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/GatewayApplication.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/config/CorsConfig.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/CorsConfig.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/config/CorsConfig.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/CorsConfig.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/config/DynamicRouteConfig.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/DynamicRouteConfig.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/config/DynamicRouteConfig.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/DynamicRouteConfig.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/config/GatewayFallbackConfig.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/GatewayFallbackConfig.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/config/GatewayFallbackConfig.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/GatewayFallbackConfig.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/config/LoadBalancerConfig.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/LoadBalancerConfig.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/config/LoadBalancerConfig.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/config/LoadBalancerConfig.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/filter/AuthGlobalFilter.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/filter/AuthGlobalFilter.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/filter/AuthGlobalFilter.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/filter/AuthGlobalFilter.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/filter/RequestLogFilter.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/filter/RequestLogFilter.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/filter/RequestLogFilter.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/filter/RequestLogFilter.java diff --git a/video-gateway/src/main/java/com/nuaa/video/gateway/handler/GlobalExceptionHandler.java b/backend/video-gateway/src/main/java/com/nuaa/video/gateway/handler/GlobalExceptionHandler.java similarity index 100% rename from video-gateway/src/main/java/com/nuaa/video/gateway/handler/GlobalExceptionHandler.java rename to backend/video-gateway/src/main/java/com/nuaa/video/gateway/handler/GlobalExceptionHandler.java diff --git a/video-gateway/src/main/resources/application-prod.yml b/backend/video-gateway/src/main/resources/application-prod.yml similarity index 100% rename from video-gateway/src/main/resources/application-prod.yml rename to backend/video-gateway/src/main/resources/application-prod.yml diff --git a/video-gateway/src/main/resources/application.yml b/backend/video-gateway/src/main/resources/application.yml similarity index 100% rename from video-gateway/src/main/resources/application.yml rename to backend/video-gateway/src/main/resources/application.yml diff --git a/video-gateway/src/main/resources/bootstrap.yml b/backend/video-gateway/src/main/resources/bootstrap.yml similarity index 100% rename from video-gateway/src/main/resources/bootstrap.yml rename to backend/video-gateway/src/main/resources/bootstrap.yml diff --git a/video-gateway/src/main/resources/logback-spring.xml b/backend/video-gateway/src/main/resources/logback-spring.xml similarity index 100% rename from video-gateway/src/main/resources/logback-spring.xml rename to backend/video-gateway/src/main/resources/logback-spring.xml diff --git a/video-recommend/Dockerfile b/backend/video-recommend/Dockerfile similarity index 100% rename from video-recommend/Dockerfile rename to backend/video-recommend/Dockerfile diff --git a/video-recommend/pom.xml b/backend/video-recommend/pom.xml similarity index 100% rename from video-recommend/pom.xml rename to backend/video-recommend/pom.xml diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/RecommendApplication.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/RecommendApplication.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/RecommendApplication.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/RecommendApplication.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/config/SecurityConfig.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/config/SecurityConfig.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/config/SecurityConfig.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/config/SecurityConfig.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/controller/RecommendController.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/controller/RecommendController.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/controller/RecommendController.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/controller/RecommendController.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/dto/UserBehaviorDTO.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/dto/UserBehaviorDTO.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/dto/UserBehaviorDTO.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/dto/UserBehaviorDTO.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendHotVideo.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendHotVideo.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendHotVideo.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendHotVideo.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserBehavior.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserBehavior.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserBehavior.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserBehavior.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserInterest.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserInterest.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserInterest.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserInterest.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserRecommendation.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserRecommendation.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserRecommendation.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendUserRecommendation.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendVideoSimilarity.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendVideoSimilarity.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendVideoSimilarity.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/entity/RecommendVideoSimilarity.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClient.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClient.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClient.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClient.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClientFallbackFactory.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClientFallbackFactory.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClientFallbackFactory.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/ContentFeignClientFallbackFactory.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClient.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClient.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClient.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClient.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClientFallbackFactory.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClientFallbackFactory.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClientFallbackFactory.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/feign/UserFeignClientFallbackFactory.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/filter/JwtAuthenticationFilter.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/filter/JwtAuthenticationFilter.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/filter/JwtAuthenticationFilter.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/filter/JwtAuthenticationFilter.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendHotVideoMapper.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendHotVideoMapper.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendHotVideoMapper.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendHotVideoMapper.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserBehaviorMapper.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserBehaviorMapper.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserBehaviorMapper.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserBehaviorMapper.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserInterestMapper.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserInterestMapper.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserInterestMapper.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserInterestMapper.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserRecommendationMapper.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserRecommendationMapper.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserRecommendationMapper.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendUserRecommendationMapper.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendVideoSimilarityMapper.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendVideoSimilarityMapper.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendVideoSimilarityMapper.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/mapper/RecommendVideoSimilarityMapper.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/service/RecommendService.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/service/RecommendService.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/service/RecommendService.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/service/RecommendService.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/service/impl/RecommendServiceImpl.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/service/impl/RecommendServiceImpl.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/service/impl/RecommendServiceImpl.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/service/impl/RecommendServiceImpl.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/ContentBasedRecommendStrategy.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/ContentBasedRecommendStrategy.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/strategy/ContentBasedRecommendStrategy.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/ContentBasedRecommendStrategy.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/HotRecommendStrategy.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/HotRecommendStrategy.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/strategy/HotRecommendStrategy.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/HotRecommendStrategy.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategy.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategy.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategy.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategy.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategyFactory.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategyFactory.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategyFactory.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/strategy/RecommendStrategyFactory.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/task/HotVideoUpdateTask.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/task/HotVideoUpdateTask.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/task/HotVideoUpdateTask.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/task/HotVideoUpdateTask.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/task/VideoSimilarityCalculateTask.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/task/VideoSimilarityCalculateTask.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/task/VideoSimilarityCalculateTask.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/task/VideoSimilarityCalculateTask.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/vo/CategoryInterestVO.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/CategoryInterestVO.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/vo/CategoryInterestVO.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/CategoryInterestVO.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/vo/TagInterestVO.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/TagInterestVO.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/vo/TagInterestVO.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/TagInterestVO.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/vo/UserInterestVO.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/UserInterestVO.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/vo/UserInterestVO.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/UserInterestVO.java diff --git a/video-recommend/src/main/java/com/nuaa/video/recommend/vo/VideoRecommendVO.java b/backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/VideoRecommendVO.java similarity index 100% rename from video-recommend/src/main/java/com/nuaa/video/recommend/vo/VideoRecommendVO.java rename to backend/video-recommend/src/main/java/com/nuaa/video/recommend/vo/VideoRecommendVO.java diff --git a/video-recommend/src/main/resources/application-prod.yml b/backend/video-recommend/src/main/resources/application-prod.yml similarity index 100% rename from video-recommend/src/main/resources/application-prod.yml rename to backend/video-recommend/src/main/resources/application-prod.yml diff --git a/video-recommend/src/main/resources/application.yml b/backend/video-recommend/src/main/resources/application.yml similarity index 100% rename from video-recommend/src/main/resources/application.yml rename to backend/video-recommend/src/main/resources/application.yml diff --git a/video-recommend/src/main/resources/bootstrap.yml b/backend/video-recommend/src/main/resources/bootstrap.yml similarity index 100% rename from video-recommend/src/main/resources/bootstrap.yml rename to backend/video-recommend/src/main/resources/bootstrap.yml diff --git a/video-recommend/src/main/resources/mapper/RecommendHotVideoMapper.xml b/backend/video-recommend/src/main/resources/mapper/RecommendHotVideoMapper.xml similarity index 100% rename from video-recommend/src/main/resources/mapper/RecommendHotVideoMapper.xml rename to backend/video-recommend/src/main/resources/mapper/RecommendHotVideoMapper.xml diff --git a/video-recommend/src/main/resources/mapper/RecommendUserBehaviorMapper.xml b/backend/video-recommend/src/main/resources/mapper/RecommendUserBehaviorMapper.xml similarity index 100% rename from video-recommend/src/main/resources/mapper/RecommendUserBehaviorMapper.xml rename to backend/video-recommend/src/main/resources/mapper/RecommendUserBehaviorMapper.xml diff --git a/video-recommend/src/main/resources/mapper/RecommendUserInterestMapper.xml b/backend/video-recommend/src/main/resources/mapper/RecommendUserInterestMapper.xml similarity index 100% rename from video-recommend/src/main/resources/mapper/RecommendUserInterestMapper.xml rename to backend/video-recommend/src/main/resources/mapper/RecommendUserInterestMapper.xml diff --git a/video-recommend/src/main/resources/mapper/RecommendUserRecommendationMapper.xml b/backend/video-recommend/src/main/resources/mapper/RecommendUserRecommendationMapper.xml similarity index 100% rename from video-recommend/src/main/resources/mapper/RecommendUserRecommendationMapper.xml rename to backend/video-recommend/src/main/resources/mapper/RecommendUserRecommendationMapper.xml diff --git a/video-recommend/src/main/resources/mapper/RecommendVideoSimilarityMapper.xml b/backend/video-recommend/src/main/resources/mapper/RecommendVideoSimilarityMapper.xml similarity index 100% rename from video-recommend/src/main/resources/mapper/RecommendVideoSimilarityMapper.xml rename to backend/video-recommend/src/main/resources/mapper/RecommendVideoSimilarityMapper.xml diff --git a/video-user/Dockerfile b/backend/video-user/Dockerfile similarity index 100% rename from video-user/Dockerfile rename to backend/video-user/Dockerfile diff --git a/video-user/pom.xml b/backend/video-user/pom.xml similarity index 100% rename from video-user/pom.xml rename to backend/video-user/pom.xml diff --git a/video-user/src/main/java/com/nuaa/video/user/UserApplication.java b/backend/video-user/src/main/java/com/nuaa/video/user/UserApplication.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/UserApplication.java rename to backend/video-user/src/main/java/com/nuaa/video/user/UserApplication.java diff --git a/video-user/src/main/java/com/nuaa/video/user/config/FeignConfig.java b/backend/video-user/src/main/java/com/nuaa/video/user/config/FeignConfig.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/config/FeignConfig.java rename to backend/video-user/src/main/java/com/nuaa/video/user/config/FeignConfig.java diff --git a/video-user/src/main/java/com/nuaa/video/user/config/MinioConfig.java b/backend/video-user/src/main/java/com/nuaa/video/user/config/MinioConfig.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/config/MinioConfig.java rename to backend/video-user/src/main/java/com/nuaa/video/user/config/MinioConfig.java diff --git a/video-user/src/main/java/com/nuaa/video/user/config/SecurityConfig.java b/backend/video-user/src/main/java/com/nuaa/video/user/config/SecurityConfig.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/config/SecurityConfig.java rename to backend/video-user/src/main/java/com/nuaa/video/user/config/SecurityConfig.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/AdminUserController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/AdminUserController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/AdminUserController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/AdminUserController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/UserFollowController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/UserFollowController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/UserFollowController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/UserFollowController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/UserMessageController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/UserMessageController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/UserMessageController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/UserMessageController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/UserNotificationController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/UserNotificationController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/UserNotificationController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/UserNotificationController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/UserProfileController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/UserProfileController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/UserProfileController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/UserProfileController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/controller/UserSettingController.java b/backend/video-user/src/main/java/com/nuaa/video/user/controller/UserSettingController.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/controller/UserSettingController.java rename to backend/video-user/src/main/java/com/nuaa/video/user/controller/UserSettingController.java diff --git a/video-user/src/main/java/com/nuaa/video/user/dto/UserMessageDTO.java b/backend/video-user/src/main/java/com/nuaa/video/user/dto/UserMessageDTO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/dto/UserMessageDTO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/dto/UserMessageDTO.java diff --git a/video-user/src/main/java/com/nuaa/video/user/dto/UserProfileDTO.java b/backend/video-user/src/main/java/com/nuaa/video/user/dto/UserProfileDTO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/dto/UserProfileDTO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/dto/UserProfileDTO.java diff --git a/video-user/src/main/java/com/nuaa/video/user/dto/UserSettingDTO.java b/backend/video-user/src/main/java/com/nuaa/video/user/dto/UserSettingDTO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/dto/UserSettingDTO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/dto/UserSettingDTO.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserFollow.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserFollow.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserFollow.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserFollow.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserInfo.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserInfo.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserInfo.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserInfo.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserMessage.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserMessage.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserMessage.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserMessage.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserNotification.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserNotification.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserNotification.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserNotification.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserSetting.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserSetting.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserSetting.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserSetting.java diff --git a/video-user/src/main/java/com/nuaa/video/user/entity/UserStatDaily.java b/backend/video-user/src/main/java/com/nuaa/video/user/entity/UserStatDaily.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/entity/UserStatDaily.java rename to backend/video-user/src/main/java/com/nuaa/video/user/entity/UserStatDaily.java diff --git a/video-user/src/main/java/com/nuaa/video/user/feign/AuthFeignClient.java b/backend/video-user/src/main/java/com/nuaa/video/user/feign/AuthFeignClient.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/feign/AuthFeignClient.java rename to backend/video-user/src/main/java/com/nuaa/video/user/feign/AuthFeignClient.java diff --git a/video-user/src/main/java/com/nuaa/video/user/filter/JwtAuthenticationFilter.java b/backend/video-user/src/main/java/com/nuaa/video/user/filter/JwtAuthenticationFilter.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/filter/JwtAuthenticationFilter.java rename to backend/video-user/src/main/java/com/nuaa/video/user/filter/JwtAuthenticationFilter.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserFollowMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserFollowMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserFollowMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserFollowMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserInfoMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserInfoMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserInfoMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserInfoMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserMessageMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserMessageMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserMessageMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserMessageMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserNotificationMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserNotificationMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserNotificationMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserNotificationMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserSettingMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserSettingMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserSettingMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserSettingMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/mapper/UserStatDailyMapper.java b/backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserStatDailyMapper.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/mapper/UserStatDailyMapper.java rename to backend/video-user/src/main/java/com/nuaa/video/user/mapper/UserStatDailyMapper.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/UserFollowService.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/UserFollowService.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/UserFollowService.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/UserFollowService.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/UserInfoService.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/UserInfoService.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/UserInfoService.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/UserInfoService.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/UserMessageService.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/UserMessageService.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/UserMessageService.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/UserMessageService.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/UserNotificationService.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/UserNotificationService.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/UserNotificationService.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/UserNotificationService.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/UserSettingService.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/UserSettingService.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/UserSettingService.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/UserSettingService.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/impl/UserFollowServiceImpl.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserFollowServiceImpl.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/impl/UserFollowServiceImpl.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserFollowServiceImpl.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/impl/UserInfoServiceImpl.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserInfoServiceImpl.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/impl/UserInfoServiceImpl.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserInfoServiceImpl.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/impl/UserMessageServiceImpl.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserMessageServiceImpl.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/impl/UserMessageServiceImpl.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserMessageServiceImpl.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/impl/UserNotificationServiceImpl.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserNotificationServiceImpl.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/impl/UserNotificationServiceImpl.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserNotificationServiceImpl.java diff --git a/video-user/src/main/java/com/nuaa/video/user/service/impl/UserSettingServiceImpl.java b/backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserSettingServiceImpl.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/service/impl/UserSettingServiceImpl.java rename to backend/video-user/src/main/java/com/nuaa/video/user/service/impl/UserSettingServiceImpl.java diff --git a/video-user/src/main/java/com/nuaa/video/user/vo/UserMessageVO.java b/backend/video-user/src/main/java/com/nuaa/video/user/vo/UserMessageVO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/vo/UserMessageVO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/vo/UserMessageVO.java diff --git a/video-user/src/main/java/com/nuaa/video/user/vo/UserNotificationVO.java b/backend/video-user/src/main/java/com/nuaa/video/user/vo/UserNotificationVO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/vo/UserNotificationVO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/vo/UserNotificationVO.java diff --git a/video-user/src/main/java/com/nuaa/video/user/vo/UserProfileVO.java b/backend/video-user/src/main/java/com/nuaa/video/user/vo/UserProfileVO.java similarity index 100% rename from video-user/src/main/java/com/nuaa/video/user/vo/UserProfileVO.java rename to backend/video-user/src/main/java/com/nuaa/video/user/vo/UserProfileVO.java diff --git a/video-user/src/main/resources/application-prod.yml b/backend/video-user/src/main/resources/application-prod.yml similarity index 100% rename from video-user/src/main/resources/application-prod.yml rename to backend/video-user/src/main/resources/application-prod.yml diff --git a/video-user/src/main/resources/application.yml b/backend/video-user/src/main/resources/application.yml similarity index 100% rename from video-user/src/main/resources/application.yml rename to backend/video-user/src/main/resources/application.yml diff --git a/video-user/src/main/resources/bootstrap.yml b/backend/video-user/src/main/resources/bootstrap.yml similarity index 100% rename from video-user/src/main/resources/bootstrap.yml rename to backend/video-user/src/main/resources/bootstrap.yml diff --git a/video-user/src/main/resources/mapper/UserFollowMapper.xml b/backend/video-user/src/main/resources/mapper/UserFollowMapper.xml similarity index 100% rename from video-user/src/main/resources/mapper/UserFollowMapper.xml rename to backend/video-user/src/main/resources/mapper/UserFollowMapper.xml diff --git a/video-user/src/main/resources/mapper/UserInfoMapper.xml b/backend/video-user/src/main/resources/mapper/UserInfoMapper.xml similarity index 100% rename from video-user/src/main/resources/mapper/UserInfoMapper.xml rename to backend/video-user/src/main/resources/mapper/UserInfoMapper.xml diff --git a/video-user/src/main/resources/mapper/UserMessageMapper.xml b/backend/video-user/src/main/resources/mapper/UserMessageMapper.xml similarity index 100% rename from video-user/src/main/resources/mapper/UserMessageMapper.xml rename to backend/video-user/src/main/resources/mapper/UserMessageMapper.xml diff --git a/video-user/src/main/resources/mapper/UserNotificationMapper.xml b/backend/video-user/src/main/resources/mapper/UserNotificationMapper.xml similarity index 100% rename from video-user/src/main/resources/mapper/UserNotificationMapper.xml rename to backend/video-user/src/main/resources/mapper/UserNotificationMapper.xml diff --git a/backend/video-user/src/test/java/com/nuaa/video/user/service/UserFollowServiceTest.java b/backend/video-user/src/test/java/com/nuaa/video/user/service/UserFollowServiceTest.java new file mode 100644 index 0000000..566c706 --- /dev/null +++ b/backend/video-user/src/test/java/com/nuaa/video/user/service/UserFollowServiceTest.java @@ -0,0 +1,203 @@ +package com.nuaa.video.user.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nuaa.video.common.model.vo.Result; +import com.nuaa.video.user.entity.UserFollow; +import com.nuaa.video.user.entity.UserInfo; +import com.nuaa.video.user.mapper.UserFollowMapper; +import com.nuaa.video.user.mapper.UserInfoMapper; +import com.nuaa.video.user.service.impl.UserFollowServiceImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * UserFollowService 单元测试 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("用户关注服务测试") +class UserFollowServiceTest { + + @Mock + private UserFollowMapper userFollowMapper; + + @Mock + private UserInfoMapper userInfoMapper; + + @InjectMocks + private UserFollowServiceImpl userFollowService; + + private UserInfo testUser; + private UserInfo followUser; + private UserFollow userFollow; + + @BeforeEach + void setUp() { + // 初始化测试用户 + testUser = new UserInfo(); + testUser.setId(1L); + testUser.setNickname("测试用户"); + testUser.setFollowerCount(100); + testUser.setFollowingCount(50); + + // 初始化被关注用户 + followUser = new UserInfo(); + followUser.setId(2L); + followUser.setNickname("被关注用户"); + followUser.setFollowerCount(10); + followUser.setFollowingCount(5); + + // 初始化关注关系 + userFollow = new UserFollow(); + userFollow.setId(1L); + userFollow.setUserId(1L); + userFollow.setFollowId(2L); + userFollow.setCreateTime(LocalDateTime.now()); + } + + @Test + @DisplayName("关注用户 - 成功") + void testFollowUserSuccess() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userInfoMapper.selectById(userId)).thenReturn(testUser); + when(userInfoMapper.selectById(followId)).thenReturn(followUser); + when(userFollowMapper.selectOne(any())).thenReturn(null); // 未关注过 + when(userFollowMapper.insert(any(UserFollow.class))).thenReturn(1); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertNotNull(testUser); + assertNotNull(followUser); + } + + @Test + @DisplayName("关注用户 - 不能关注自己") + void testFollowUserCannotFollowSelf() { + // Given + Long userId = 1L; + Long followId = 1L; + + // Then + assertEquals(userId, followId); // 不能关注自己 + } + + @Test + @DisplayName("关注用户 - 已经关注过") + void testFollowUserAlreadyFollowed() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userFollowMapper.selectOne(any())).thenReturn(userFollow); // 已关注 + + // Then + assertNotNull(userFollow); + assertEquals(userId, userFollow.getUserId()); + assertEquals(followId, userFollow.getFollowId()); + } + + @Test + @DisplayName("取消关注 - 成功") + void testUnfollowUserSuccess() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userFollowMapper.selectOne(any())).thenReturn(userFollow); + when(userFollowMapper.deleteById(any())).thenReturn(1); + when(userInfoMapper.selectById(userId)).thenReturn(testUser); + when(userInfoMapper.selectById(followId)).thenReturn(followUser); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertNotNull(userFollow); + } + + @Test + @DisplayName("取消关注 - 未关注") + void testUnfollowUserNotFollowed() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userFollowMapper.selectOne(any())).thenReturn(null); // 未关注 + + // Then + // 取消关注应该返回"未关注"错误 + } + + @Test + @DisplayName("获取关注列表 - 成功") + void testGetFollowingListSuccess() { + // Given + Long userId = 1L; + Page page = new Page<>(1, 10); + + List followingList = new ArrayList<>(); + followingList.add(followUser); + + // Then + assertNotNull(page); + assertEquals(1, page.getCurrent()); + assertEquals(10, page.getSize()); + } + + @Test + @DisplayName("获取粉丝列表 - 成功") + void testGetFollowerListSuccess() { + // Given + Long userId = 1L; + Page page = new Page<>(1, 10); + + List followerList = new ArrayList<>(); + followerList.add(testUser); + + // Then + assertNotNull(page); + assertEquals(1, page.getCurrent()); + assertEquals(10, page.getSize()); + } + + @Test + @DisplayName("检查是否已关注 - 已关注") + void testCheckIsFollowedTrue() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userFollowMapper.selectOne(any())).thenReturn(userFollow); + + // Then + assertNotNull(userFollow); + assertEquals(userId, userFollow.getUserId()); + assertEquals(followId, userFollow.getFollowId()); + } + + @Test + @DisplayName("检查是否已关注 - 未关注") + void testCheckIsFollowedFalse() { + // Given + Long userId = 1L; + Long followId = 2L; + + when(userFollowMapper.selectOne(any())).thenReturn(null); + + // Then + // 应该返回false + } +} diff --git a/backend/video-user/src/test/java/com/nuaa/video/user/service/UserInfoServiceTest.java b/backend/video-user/src/test/java/com/nuaa/video/user/service/UserInfoServiceTest.java new file mode 100644 index 0000000..ae2108b --- /dev/null +++ b/backend/video-user/src/test/java/com/nuaa/video/user/service/UserInfoServiceTest.java @@ -0,0 +1,219 @@ +package com.nuaa.video.user.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nuaa.video.common.model.vo.Result; +import com.nuaa.video.user.dto.UserProfileDTO; +import com.nuaa.video.user.entity.UserInfo; +import com.nuaa.video.user.mapper.UserInfoMapper; +import com.nuaa.video.user.service.impl.UserInfoServiceImpl; +import com.nuaa.video.user.vo.UserProfileVO; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +/** + * UserInfoService 单元测试 + */ +@ExtendWith(MockitoExtension.class) +@DisplayName("用户信息服务测试") +class UserInfoServiceTest { + + @Mock + private UserInfoMapper userInfoMapper; + + @InjectMocks + private UserInfoServiceImpl userInfoService; + + private UserInfo testUserInfo; + + @BeforeEach + void setUp() { + testUserInfo = new UserInfo(); + testUserInfo.setId(1L); + testUserInfo.setNickname("测试用户"); + testUserInfo.setAvatar("http://example.com/avatar.jpg"); + testUserInfo.setGender(1); + testUserInfo.setSignature("这是签名"); + testUserInfo.setRegion("北京"); + testUserInfo.setFollowerCount(100); + testUserInfo.setFollowingCount(50); + testUserInfo.setVideoCount(10); + testUserInfo.setLikeCount(1000); + testUserInfo.setCoinCount(200); + testUserInfo.setFavoriteCount(30); + testUserInfo.setViewCount(5000L); + testUserInfo.setLevel(5); + testUserInfo.setVipLevel(1); + testUserInfo.setCreateTime(LocalDateTime.now()); + testUserInfo.setUpdateTime(LocalDateTime.now()); + } + + @Test + @DisplayName("创建用户信息 - 成功") + void testCreateUserInfoSuccess() { + // Given + Long userId = 1L; + String username = "testuser"; + + when(userInfoMapper.selectById(userId)).thenReturn(null); + when(userInfoMapper.insert(any(UserInfo.class))).thenReturn(1); + + // When + Result result = userInfoService.createUserInfo(userId, username); + + // Then + assertNotNull(result); + assertEquals(200, result.getCode()); + verify(userInfoMapper, times(1)).insert(any(UserInfo.class)); + } + + @Test + @DisplayName("创建用户信息 - 用户已存在") + void testCreateUserInfoAlreadyExists() { + // Given + Long userId = 1L; + String username = "testuser"; + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + + // When + Result result = userInfoService.createUserInfo(userId, username); + + // Then + assertNotNull(result); + assertEquals(200, result.getCode()); + verify(userInfoMapper, never()).insert(any(UserInfo.class)); + } + + @Test + @DisplayName("获取用户资料 - 成功") + void testGetUserProfileSuccess() { + // Given + Long userId = 1L; + Long currentUserId = 2L; + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + + // Then + assertNotNull(testUserInfo); + assertEquals("测试用户", testUserInfo.getNickname()); + } + + @Test + @DisplayName("获取用户资料 - 用户不存在") + void testGetUserProfileNotFound() { + // Given + Long userId = 999L; + + when(userInfoMapper.selectById(userId)).thenReturn(null); + + // When + UserInfo user = userInfoMapper.selectById(userId); + + // Then + assertNull(user); + } + + @Test + @DisplayName("更新用户资料 - 成功") + void testUpdateUserProfileSuccess() { + // Given + Long userId = 1L; + UserProfileDTO dto = new UserProfileDTO(); + dto.setNickname("新昵称"); + dto.setSignature("新签名"); + dto.setGender(1); + dto.setRegion("上海"); + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertNotNull(dto); + assertEquals("新昵称", dto.getNickname()); + } + + @Test + @DisplayName("获取简要用户信息 - 成功") + void testGetBriefUserInfoSuccess() { + // Given + Long userId = 1L; + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + + // When + UserInfo user = userInfoMapper.selectById(userId); + + // Then + assertNotNull(user); + assertEquals("测试用户", user.getNickname()); + } + + @Test + @DisplayName("搜索用户 - 成功") + void testSearchUsersSuccess() { + // Given + Page page = new Page<>(1, 10); + String keyword = "测试"; + + // Then + assertNotNull(page); + assertEquals(1, page.getCurrent()); + assertEquals(10, page.getSize()); + } + + @Test + @DisplayName("增加用户视频数量 - 成功") + void testIncreaseVideoCountSuccess() { + // Given + Long userId = 1L; + Integer count = 1; + int oldVideoCount = testUserInfo.getVideoCount(); + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertEquals(10, oldVideoCount); + } + + @Test + @DisplayName("增加用户获赞数量 - 成功") + void testIncreaseLikeCountSuccess() { + // Given + Long userId = 1L; + Integer count = 10; + int oldLikeCount = testUserInfo.getLikeCount(); + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertEquals(1000, oldLikeCount); + } + + @Test + @DisplayName("增加用户收藏数量 - 成功") + void testIncreaseFavoriteCountSuccess() { + // Given + Long userId = 1L; + Integer count = 5; + int oldFavoriteCount = testUserInfo.getFavoriteCount(); + + when(userInfoMapper.selectById(userId)).thenReturn(testUserInfo); + when(userInfoMapper.updateById(any(UserInfo.class))).thenReturn(1); + + // Then + assertEquals(30, oldFavoriteCount); + } +} diff --git a/backend/video-user/src/test/resources/application-test.yml b/backend/video-user/src/test/resources/application-test.yml new file mode 100644 index 0000000..b55f2b7 --- /dev/null +++ b/backend/video-user/src/test/resources/application-test.yml @@ -0,0 +1,48 @@ +spring: + application: + name: video-user-test + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;DATABASE_TO_LOWER=TRUE + username: sa + password: + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + h2: + console: + enabled: true + data: + redis: + host: localhost + port: 6379 + database: 0 + +# 日志配置 +logging: + level: + com.nuaa.video: DEBUG + org.springframework: INFO + +# Nacos配置(测试环境禁用) +spring: + cloud: + nacos: + discovery: + enabled: false + config: + enabled: false + +# Sentinel配置(测试环境禁用) +spring: + cloud: + sentinel: + enabled: false + +# MinIO配置(测试环境) +minio: + endpoint: http://localhost:9000 + access-key: minioadmin + secret-key: minioadmin + bucket-name: test-bucket diff --git a/docs/HA-DEPLOYMENT-GUIDE.md b/docs/HA-DEPLOYMENT-GUIDE.md new file mode 100644 index 0000000..57459bd --- /dev/null +++ b/docs/HA-DEPLOYMENT-GUIDE.md @@ -0,0 +1,339 @@ +# 高可用集群部署手册 + +## 一、环境准备 + +### 1.1 虚拟机配置要求 + +| 节点 | IP地址 | CPU | 内存 | 磁盘 | 操作系统 | +|------|--------|-----|------|------|----------| +| Node-01 | 192.168.1.101 | 4核 | 8GB | 100GB | Ubuntu 22.04 / CentOS 8 | +| Node-02 | 192.168.1.102 | 4核 | 8GB | 100GB | Ubuntu 22.04 / CentOS 8 | +| Node-03 | 192.168.1.103 | 4核 | 8GB | 100GB | Ubuntu 22.04 / CentOS 8 | + +### 1.2 软件依赖 + +每台虚拟机需要安装以下软件: + +```bash +# Ubuntu +apt-get update +apt-get install -y docker.io docker-compose-plugin openjdk-17-jdk maven git curl wget + +# CentOS +yum install -y docker docker-compose-plugin java-17-openjdk-devel maven git curl wget + +# 启动Docker +systemctl start docker +systemctl enable docker + +# 添加当前用户到docker组 +usermod -aG docker $USER +``` + +### 1.3 网络配置 + +确保三台虚拟机之间网络互通: + +```bash +# 在每台机器上测试 +ping 192.168.1.101 +ping 192.168.1.102 +ping 192.168.1.103 + +# 开放防火墙端口 +# Ubuntu +ufw allow 3306,6379,8848,9000,9001,9876,10911,8880,9000:9006/tcp + +# CentOS +firewall-cmd --permanent --add-port={3306,6379,8848,9000,9001,9876,10911,8880,9000-9006}/tcp +firewall-cmd --reload +``` + +--- + +## 二、部署步骤 + +### 2.1 克隆项目到所有节点 + +```bash +# 在所有节点执行 +git clone <项目地址> /opt/ha-ovp +cd /opt/ha-ovp +``` + +### 2.2 构建项目 + +```bash +# 在任意节点构建(只需执行一次) +cd /opt/ha-ovp + +# 构建common模块 +cd video-common +mvn clean install -DskipTests +cd .. + +# 构建所有服务 +mvn clean package -DskipTests + +# 构建Sentinel镜像 +cd sentinel-dashboard +docker build -t sentinel-dashboard:1.8.6 . +cd .. + +# 将构建产物分发到其他节点 +scp -r target/ video-*/target/ root@192.168.1.102:/opt/ha-ovp/ +scp -r target/ video-*/target/ root@192.168.1.103:/opt/ha-ovp/ +``` + +### 2.3 初始化各节点 + +```bash +# Node-01 (192.168.1.101) +chmod +x deploy-ha.sh +./deploy-ha.sh 1 init + +# Node-02 (192.168.1.102) +chmod +x deploy-ha.sh +./deploy-ha.sh 2 init + +# Node-03 (192.168.1.103) +chmod +x deploy-ha.sh +./deploy-ha.sh 3 init +``` + +### 2.4 按顺序启动服务 + +#### 步骤1: 启动基础设施 (所有节点) + +```bash +# Node-01 先启动 +./deploy-ha.sh 1 infra + +# 等待Node-01完全启动后 (约2分钟) +# Node-02 启动 +./deploy-ha.sh 2 infra + +# Node-03 启动 +./deploy-ha.sh 3 infra +``` + +#### 步骤2: 配置MySQL主从复制 + +```bash +# Node-01 查看主节点状态 +docker exec mysql mysql -uroot -proot123456 -e "SHOW MASTER STATUS\G" + +# 记录 File 和 Position 值 + +# Node-02 配置从节点 +docker exec mysql mysql -uroot -proot123456 <; +START SLAVE; +SHOW SLAVE STATUS\G +EOF + +# Node-03 配置从节点 (同上) +``` + +#### 步骤3: 配置Redis主从复制 + +```bash +# Node-02 和 Node-03 执行 +docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379 + +# 验证 +docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication +``` + +#### 步骤4: 配置Nacos集群 + +访问 http://192.168.1.101:8848/nacos (账号: nacos/nacos) + +创建命名空间 `public`,并添加以下配置文件: + +| Data ID | Group | 说明 | +|---------|-------|------| +| video-gateway.yaml | DEFAULT_GROUP | 网关配置 | +| video-auth.yaml | DEFAULT_GROUP | 认证服务配置 | +| video-user.yaml | DEFAULT_GROUP | 用户服务配置 | +| video-content.yaml | DEFAULT_GROUP | 内容服务配置 | +| video-comment.yaml | DEFAULT_GROUP | 评论服务配置 | +| video-recommend.yaml | DEFAULT_GROUP | 推荐服务配置 | +| video-admin.yaml | DEFAULT_GROUP | 管理后台配置 | + +#### 步骤5: 初始化MinIO + +```bash +# 任意节点执行 +docker run --rm --network ha-network minio/mc < status + +# 检查Nacos服务注册 +curl http://192.168.1.101:8848/nacos/v1/ns/instance/list?serviceName=video-gateway + +# 检查Redis主从 +docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication + +# 检查MySQL主从 +docker exec mysql mysql -uroot -proot123456 -e "SHOW SLAVE STATUS\G" +``` + +### 3.2 访问服务 + +| 服务 | 地址 | +|------|------| +| Nacos控制台 | http://192.168.1.101:8848/nacos | +| Sentinel控制台 | http://192.168.1.101:8880 | +| MinIO控制台 | http://192.168.1.101:9101 | +| RocketMQ控制台 | http://192.168.1.102:8080 (需额外部署) | +| API网关 | http://192.168.1.100 (通过Nginx) | + +### 3.3 高可用测试 + +#### 测试服务故障转移 + +```bash +# 停止Node-01上的网关服务 +docker stop video-gateway + +# 访问API验证(应该自动切换到Node-02) +curl http://192.168.1.100/auth/captcha + +# 恢复服务 +docker start video-gateway +``` + +#### 测试Redis主从切换 + +```bash +# 停止Node-01的Redis +docker stop redis + +# Sentinel会自动将从节点提升为主节点 +# 查看Sentinel日志 +docker logs redis-sentinel + +# 恢复Redis +docker start redis +``` + +#### 测试MySQL主从切换 + +```bash +# 停止主节点MySQL +docker stop mysql + +# 查看从节点状态 +docker exec mysql mysql -uroot -proot123456 -e "SHOW SLAVE STATUS\G" +``` + +--- + +## 四、常见问题 + +### Q1: Nacos集群无法启动 + +检查各节点时间是否同步: + +```bash +# 同步时间 +apt-get install -y ntpdate +ntpdate pool.ntp.org +``` + +### Q2: 服务注册不到Nacos + +检查网络连通性: + +```bash +# 测试Nacos连接 +curl http://192.168.1.101:8848/nacos/v1/console/health/liveness +``` + +### Q3: Redis连接失败 + +检查Redis密码配置是否一致: + +```bash +# 测试连接 +docker exec redis redis-cli -a redis_HA_Cluster_2024 ping +``` + +### Q4: MySQL主从同步失败 + +```bash +# 重置从节点 +docker exec mysql mysql -uroot -proot123456 <= 18.0 +- pnpm >= 8.0 (推荐) 或 npm >= 9.0 + +### 安装依赖 + +```bash +# 用户端 +cd video-platform-web +pnpm install + +# 管理端 +cd video-platform-admin +pnpm install +``` + +### 开发运行 + +```bash +# 用户端 (端口 3000) +cd video-platform-web +pnpm dev + +# 管理端 (端口 3100) +cd video-platform-admin +pnpm dev +``` + +### 构建部署 + +```bash +# 构建 +pnpm build + +# 预览 +pnpm preview +``` + +### 代理配置 + +在 `vite.config.ts` 中配置后端代理: + +```typescript +server: { + port: 3000, // 或 3100 + proxy: { + '/api': { + target: 'http://localhost:9000', // 后端网关地址 + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, '') + } + } +} +``` + +## 代码规范 + +### 命名规范 + +- 文件夹:kebab-case(如 `video-player`) +- Vue组件:PascalCase(如 `VideoPlayer.vue`) +- TypeScript文件:camelCase(如 `videoService.ts`) +- 常量:UPPER_SNAKE_CASE +- CSS类名:kebab-case + +### 组件规范 + +```vue + + + + + +``` + +### Git 提交规范 + +- `feat`: 新功能 +- `fix`: 修复bug +- `docs`: 文档更新 +- `style`: 代码格式 +- `refactor`: 重构 +- `test`: 测试 +- `chore`: 构建/工具 + +## 部署说明 + +### Nginx 配置示例 + +```nginx +# 用户端 +server { + listen 80; + server_name www.example.com; + + root /var/www/video-platform-web; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://localhost:9000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} + +# 管理端 +server { + listen 80; + server_name admin.example.com; + + root /var/www/video-platform-admin; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://localhost:9000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} +``` + +### 环境变量 + +创建 `.env.production` 文件: + +```env +VITE_API_BASE_URL=https://api.example.com +VITE_APP_TITLE=HAOVP +``` + +## 常见问题 + +### 1. 跨域问题 + +确保后端配置了 CORS,或在 Vite 代理中正确配置。 + +### 2. Token 过期 + +前端会自动检测 401 响应并跳转登录页。 + +### 3. 图片/视频上传失败 + +检查文件大小限制和 MinIO 配置。 + +## 更新日志 + +### v1.0.0 (2024-03) + +- 初始版本发布 +- 用户端完整功能 +- 管理端完整功能 diff --git a/frontend/video-frontend-admin/index.html b/frontend/video-frontend-admin/index.html new file mode 100644 index 0000000..9e5a5a0 --- /dev/null +++ b/frontend/video-frontend-admin/index.html @@ -0,0 +1,13 @@ + + + + + + + HAOVP 管理后台 + + +
+ + + diff --git a/frontend/video-frontend-admin/package.json b/frontend/video-frontend-admin/package.json new file mode 100644 index 0000000..b02923e --- /dev/null +++ b/frontend/video-frontend-admin/package.json @@ -0,0 +1,43 @@ +{ + "name": "video-platform-admin", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview", + "lint": "eslint --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", + "format": "prettier --write src" + }, + "dependencies": { + "vue": "^3.4.21", + "vue-router": "^4.3.0", + "pinia": "^2.1.7", + "axios": "^1.6.8", + "element-plus": "^2.6.3", + "@element-plus/icons-vue": "^2.3.1", + "echarts": "^5.5.0", + "dayjs": "^1.11.10", + "nprogress": "^0.2.0", + "sortablejs": "^1.15.2" + }, + "devDependencies": { + "@types/node": "^20.11.30", + "@types/nprogress": "^0.2.3", + "@types/sortablejs": "^1.15.8", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/tsconfig": "^0.5.1", + "sass": "^1.72.0", + "typescript": "~5.4.3", + "unplugin-auto-import": "^0.17.5", + "unplugin-vue-components": "^0.26.0", + "vite": "^5.2.6", + "vue-tsc": "^2.0.7", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.23.0", + "prettier": "^3.2.5" + } +} diff --git a/frontend/video-frontend-admin/pnpm-lock.yaml b/frontend/video-frontend-admin/pnpm-lock.yaml new file mode 100644 index 0000000..bbb3adc --- /dev/null +++ b/frontend/video-frontend-admin/pnpm-lock.yaml @@ -0,0 +1,3009 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@element-plus/icons-vue': + specifier: ^2.3.1 + version: 2.3.2(vue@3.5.30(typescript@5.4.5)) + axios: + specifier: ^1.6.8 + version: 1.13.6 + dayjs: + specifier: ^1.11.10 + version: 1.11.20 + echarts: + specifier: ^5.5.0 + version: 5.6.0 + element-plus: + specifier: ^2.6.3 + version: 2.13.5(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)) + nprogress: + specifier: ^0.2.0 + version: 0.2.0 + pinia: + specifier: ^2.1.7 + version: 2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)) + sortablejs: + specifier: ^1.15.2 + version: 1.15.7 + vue: + specifier: ^3.4.21 + version: 3.5.30(typescript@5.4.5) + vue-router: + specifier: ^4.3.0 + version: 4.6.4(vue@3.5.30(typescript@5.4.5)) + devDependencies: + '@types/node': + specifier: ^20.11.30 + version: 20.19.37 + '@types/nprogress': + specifier: ^0.2.3 + version: 0.2.3 + '@types/sortablejs': + specifier: ^1.15.8 + version: 1.15.9 + '@typescript-eslint/eslint-plugin': + specifier: ^7.3.1 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.3.1 + version: 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.2.4(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5)) + '@vue/tsconfig': + specifier: ^0.5.1 + version: 0.5.1 + eslint: + specifier: ^8.57.0 + version: 8.57.1 + eslint-plugin-vue: + specifier: ^9.23.0 + version: 9.33.0(eslint@8.57.1) + prettier: + specifier: ^3.2.5 + version: 3.8.1 + sass: + specifier: ^1.72.0 + version: 1.98.0 + typescript: + specifier: ~5.4.3 + version: 5.4.5 + unplugin-auto-import: + specifier: ^0.17.5 + version: 0.17.8(@vueuse/core@12.0.0(typescript@5.4.5))(rollup@4.59.0) + unplugin-vue-components: + specifier: ^0.26.0 + version: 0.26.0(@babel/parser@7.29.0)(rollup@4.59.0)(vue@3.5.30(typescript@5.4.5)) + vite: + specifier: ^5.2.6 + version: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + vue-tsc: + specifier: ^2.0.7 + version: 2.2.12(typescript@5.4.5) + +packages: + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==, tarball: https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==, tarball: https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@ctrl/tinycolor@4.2.0': + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==, tarball: https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz} + engines: {node: '>=14'} + + '@element-plus/icons-vue@2.3.2': + resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==, tarball: https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz} + peerDependencies: + vue: ^3.2.0 + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==, tarball: https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==, tarball: https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==, tarball: https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==, tarball: https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==, tarball: https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.5.tgz} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==, tarball: https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.6.tgz} + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==, tarball: https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.11.tgz} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==, tarball: https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, tarball: https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==, tarball: https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz} + deprecated: Use @eslint/object-schema instead + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, tarball: https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, tarball: https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, tarball: https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, tarball: https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==, tarball: https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==, tarball: https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==, tarball: https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==, tarball: https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, tarball: https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz} + cpu: [x64] + os: [win32] + + '@sxzz/popperjs-es@2.11.8': + resolution: {integrity: sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==, tarball: https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.8.tgz} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, tarball: https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==, tarball: https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz} + + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==, tarball: https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.24.tgz} + + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==, tarball: https://registry.npmmirror.com/@types/node/-/node-20.19.37.tgz} + + '@types/nprogress@0.2.3': + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==, tarball: https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.3.tgz} + + '@types/sortablejs@1.15.9': + resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==, tarball: https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.9.tgz} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==, tarball: https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==, tarball: https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==, tarball: https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==, tarball: https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==, tarball: https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==, tarball: https://registry.npmmirror.com/@typescript-eslint/types/-/types-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==, tarball: https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==, tarball: https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==, tarball: https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, tarball: https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz} + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.15': + resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==, tarball: https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.15.tgz} + + '@volar/source-map@2.4.15': + resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==, tarball: https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.15.tgz} + + '@volar/typescript@2.4.15': + resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==, tarball: https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.15.tgz} + + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==, tarball: https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.30.tgz} + + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==, tarball: https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz} + + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==, tarball: https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz} + + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==, tarball: https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==, tarball: https://registry.npmmirror.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==, tarball: https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz} + + '@vue/language-core@2.2.12': + resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==, tarball: https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.12.tgz} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==, tarball: https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.30.tgz} + + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==, tarball: https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.30.tgz} + + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==, tarball: https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz} + + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==, tarball: https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.30.tgz} + peerDependencies: + vue: 3.5.30 + + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==, tarball: https://registry.npmmirror.com/@vue/shared/-/shared-3.5.30.tgz} + + '@vue/tsconfig@0.5.1': + resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==, tarball: https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.5.1.tgz} + + '@vueuse/core@12.0.0': + resolution: {integrity: sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==, tarball: https://registry.npmmirror.com/@vueuse/core/-/core-12.0.0.tgz} + + '@vueuse/metadata@12.0.0': + resolution: {integrity: sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==, tarball: https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.0.0.tgz} + + '@vueuse/shared@12.0.0': + resolution: {integrity: sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==, tarball: https://registry.npmmirror.com/@vueuse/shared/-/shared-12.0.0.tgz} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, tarball: https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==, tarball: https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==, tarball: https://registry.npmmirror.com/ajv/-/ajv-6.14.0.tgz} + + alien-signals@1.0.13: + resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==, tarball: https://registry.npmmirror.com/alien-signals/-/alien-signals-1.0.13.tgz} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, tarball: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, tarball: https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz} + engines: {node: '>=8'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==, tarball: https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, tarball: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz} + + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==, tarball: https://registry.npmmirror.com/axios/-/axios-1.13.6.tgz} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, tarball: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, tarball: https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, tarball: https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, tarball: https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, tarball: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, tarball: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, tarball: https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, tarball: https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==, tarball: https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==, tarball: https://registry.npmmirror.com/confbox/-/confbox-0.2.4.tgz} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, tarball: https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, tarball: https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==, tarball: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==, tarball: https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, tarball: https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, tarball: https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, tarball: https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, tarball: https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, tarball: https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==, tarball: https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz} + engines: {node: '>=6.0.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, tarball: https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz} + engines: {node: '>= 0.4'} + + echarts@5.6.0: + resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==, tarball: https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz} + + element-plus@2.13.5: + resolution: {integrity: sha512-dmY24fhSREfZN/PuUt0YZigMso7wWzl+B5o+YKNN15kQIn/0hzamsPU+ebj9SES0IbUqsLX1wkrzYmzU8VrVOQ==, tarball: https://registry.npmmirror.com/element-plus/-/element-plus-2.13.5.tgz} + peerDependencies: + vue: ^3.3.0 + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, tarball: https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, tarball: https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, tarball: https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, tarball: https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, tarball: https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz} + engines: {node: '>=12'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz} + engines: {node: '>=12'} + + eslint-plugin-vue@9.33.0: + resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==, tarball: https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, tarball: https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, tarball: https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==, tarball: https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, tarball: https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==, tarball: https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, tarball: https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, tarball: https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, tarball: https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz} + engines: {node: '>=0.10.0'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==, tarball: https://registry.npmmirror.com/exsolve/-/exsolve-1.0.8.tgz} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, tarball: https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, tarball: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, tarball: https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, tarball: https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, tarball: https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, tarball: https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, tarball: https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==, tarball: https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.4.1: + resolution: {integrity: sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==, tarball: https://registry.npmmirror.com/flatted/-/flatted-3.4.1.tgz} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==, tarball: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==, tarball: https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz} + engines: {node: '>= 6'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, tarball: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, tarball: https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, tarball: https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, tarball: https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, tarball: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, tarball: https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, tarball: https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, tarball: https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz} + engines: {node: '>= 0.4'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, tarball: https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, tarball: https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, tarball: https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, tarball: https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, tarball: https://registry.npmmirror.com/he/-/he-1.2.0.tgz} + hasBin: true + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, tarball: https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz} + engines: {node: '>= 4'} + + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==, tarball: https://registry.npmmirror.com/immutable/-/immutable-5.1.5.tgz} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, tarball: https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, tarball: https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, tarball: https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, tarball: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, tarball: https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==, tarball: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, tarball: https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, tarball: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, tarball: https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==, tarball: https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==, tarball: https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, tarball: https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, tarball: https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, tarball: https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, tarball: https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, tarball: https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz} + engines: {node: '>= 0.8.0'} + + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz} + engines: {node: '>=14'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.1.tgz} + engines: {node: '>=14'} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz} + engines: {node: '>=10'} + + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==, tarball: https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.23.tgz} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==, tarball: https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, tarball: https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==, tarball: https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, tarball: https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz} + engines: {node: '>= 0.4'} + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==, tarball: https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, tarball: https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, tarball: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz} + engines: {node: '>= 0.6'} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.9.tgz} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.8.1: + resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==, tarball: https://registry.npmmirror.com/mlly/-/mlly-1.8.1.tgz} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==, tarball: https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, tarball: https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==, tarball: https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz} + engines: {node: '>=0.10.0'} + + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==, tarball: https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==, tarball: https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, tarball: https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, tarball: https://registry.npmmirror.com/once/-/once-1.4.0.tgz} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, tarball: https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, tarball: https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, tarball: https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz} + engines: {node: '>=6'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==, tarball: https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, tarball: https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, tarball: https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, tarball: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, tarball: https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz} + engines: {node: '>=12'} + + pinia@2.3.1: + resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==, tarball: https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz} + peerDependencies: + typescript: '>=4.4.4' + vue: ^2.7.0 || ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==, tarball: https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==, tarball: https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==, tarball: https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz} + engines: {node: '>=4'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, tarball: https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz} + engines: {node: '>= 0.8.0'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==, tarball: https://registry.npmmirror.com/prettier/-/prettier-3.8.1.tgz} + engines: {node: '>=14'} + hasBin: true + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, tarball: https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, tarball: https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz} + engines: {node: '>=6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, tarball: https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz} + engines: {node: '>= 14.18.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, tarball: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz} + engines: {node: '>=4'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==, tarball: https://registry.npmmirror.com/resolve/-/resolve-1.22.11.tgz} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, tarball: https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, tarball: https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, tarball: https://registry.npmmirror.com/rollup/-/rollup-4.59.0.tgz} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, tarball: https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz} + + sass@1.98.0: + resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==, tarball: https://registry.npmmirror.com/sass/-/sass-1.98.0.tgz} + engines: {node: '>=14.0.0'} + hasBin: true + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==, tarball: https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==, tarball: https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, tarball: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz} + engines: {node: '>=8'} + + sortablejs@1.15.7: + resolution: {integrity: sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==, tarball: https://registry.npmmirror.com/sortablejs/-/sortablejs-1.15.7.tgz} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, tarball: https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz} + engines: {node: '>=8'} + + strip-literal@2.1.1: + resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==, tarball: https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.1.tgz} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, tarball: https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz} + engines: {node: '>= 0.4'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, tarball: https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz} + engines: {node: '>=8.0'} + + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==, tarball: https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==, tarball: https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, tarball: https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz} + engines: {node: '>=10'} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==, tarball: https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==, tarball: https://registry.npmmirror.com/ufo/-/ufo-1.6.3.tgz} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==, tarball: https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz} + + unimport@3.14.6: + resolution: {integrity: sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==, tarball: https://registry.npmmirror.com/unimport/-/unimport-3.14.6.tgz} + + unplugin-auto-import@0.17.8: + resolution: {integrity: sha512-CHryj6HzJ+n4ASjzwHruD8arhbdl+UXvhuAIlHDs15Y/IMecG3wrf7FVg4pVH/DIysbq/n0phIjNHAjl7TG7Iw==, tarball: https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.17.8.tgz} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^3.2.2 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-vue-components@0.26.0: + resolution: {integrity: sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==, tarball: https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.26.0.tgz} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==, tarball: https://registry.npmmirror.com/unplugin/-/unplugin-1.16.1.tgz} + engines: {node: '>=14.0.0'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, tarball: https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, tarball: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz} + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==, tarball: https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==, tarball: https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==, tarball: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==, tarball: https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==, tarball: https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz} + peerDependencies: + vue: ^3.5.0 + + vue-tsc@2.2.12: + resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==, tarball: https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.12.tgz} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.30: + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==, tarball: https://registry.npmmirror.com/vue/-/vue-3.5.30.tgz} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==, tarball: https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmmirror.com/which/-/which-2.0.2.tgz} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, tarball: https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, tarball: https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, tarball: https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, tarball: https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz} + engines: {node: '>=10'} + + zrender@5.6.1: + resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==, tarball: https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz} + +snapshots: + + '@antfu/utils@0.7.10': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@ctrl/tinycolor@4.2.0': {} + + '@element-plus/icons-vue@2.3.2(vue@3.5.30(typescript@5.4.5))': + dependencies: + vue: 3.5.30(typescript@5.4.5) + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/utils@0.2.11': {} + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.59.0 + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@sxzz/popperjs-es@2.11.8': {} + + '@types/estree@1.0.8': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.24 + + '@types/lodash@4.17.24': {} + + '@types/node@20.19.37': + dependencies: + undici-types: 6.21.0 + + '@types/nprogress@0.2.3': {} + + '@types/sortablejs@1.15.9': {} + + '@types/web-bluetooth@0.0.20': {} + + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + debug: 4.4.3 + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.9 + semver: 7.7.4 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5))': + dependencies: + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + vue: 3.5.30(typescript@5.4.5) + + '@volar/language-core@2.4.15': + dependencies: + '@volar/source-map': 2.4.15 + + '@volar/source-map@2.4.15': {} + + '@volar/typescript@2.4.15': + dependencies: + '@volar/language-core': 2.4.15 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/compiler-core@3.5.30': + dependencies: + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.30': + dependencies: + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/compiler-sfc@3.5.30': + dependencies: + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.8 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.30': + dependencies: + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.4': {} + + '@vue/language-core@2.2.12(typescript@5.4.5)': + dependencies: + '@volar/language-core': 2.4.15 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.30 + alien-signals: 1.0.13 + minimatch: 9.0.9 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.4.5 + + '@vue/reactivity@3.5.30': + dependencies: + '@vue/shared': 3.5.30 + + '@vue/runtime-core@3.5.30': + dependencies: + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/runtime-dom@3.5.30': + dependencies: + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@5.4.5))': + dependencies: + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + vue: 3.5.30(typescript@5.4.5) + + '@vue/shared@3.5.30': {} + + '@vue/tsconfig@0.5.1': {} + + '@vueuse/core@12.0.0(typescript@5.4.5)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 12.0.0 + '@vueuse/shared': 12.0.0(typescript@5.4.5) + vue: 3.5.30(typescript@5.4.5) + transitivePeerDependencies: + - typescript + + '@vueuse/metadata@12.0.0': {} + + '@vueuse/shared@12.0.0(typescript@5.4.5)': + dependencies: + vue: 3.5.30(typescript@5.4.5) + transitivePeerDependencies: + - typescript + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + alien-signals@1.0.13: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + axios@1.13.6: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + dayjs@1.11.20: {} + + de-indent@1.0.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: + optional: true + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + echarts@5.6.0: + dependencies: + tslib: 2.3.0 + zrender: 5.6.1 + + element-plus@2.13.5(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@ctrl/tinycolor': 4.2.0 + '@element-plus/icons-vue': 2.3.2(vue@3.5.30(typescript@5.4.5)) + '@floating-ui/dom': 1.7.6 + '@popperjs/core': '@sxzz/popperjs-es@2.11.8' + '@types/lodash': 4.17.24 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 12.0.0(typescript@5.4.5) + async-validator: 4.2.5 + dayjs: 1.11.20 + lodash: 4.17.23 + lodash-es: 4.17.23 + lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.17.23) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.5.30(typescript@5.4.5) + transitivePeerDependencies: + - typescript + + entities@7.0.1: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-plugin-vue@9.33.0(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + eslint: 8.57.1 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.4 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + exsolve@1.0.8: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.4.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.4.1: {} + + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + ignore@5.3.2: {} + + immutable@5.1.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + isexe@2.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + local-pkg@0.4.3: {} + + local-pkg@0.5.1: + dependencies: + mlly: 1.8.1 + pkg-types: 1.3.1 + + local-pkg@1.1.2: + dependencies: + mlly: 1.8.1 + pkg-types: 2.3.0 + quansync: 0.2.11 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.23: {} + + lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.17.23): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.17.23 + lodash-es: 4.17.23 + + lodash.merge@4.6.2: {} + + lodash@4.17.23: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + memoize-one@6.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + + mlly@1.8.1: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-addon-api@7.1.1: + optional: true + + normalize-path@3.0.0: {} + + normalize-wheel-es@1.2.0: {} + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pinia@2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.30(typescript@5.4.5) + vue-demi: 0.14.10(vue@3.5.30(typescript@5.4.5)) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - '@vue/composition-api' + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.1 + pathe: 2.0.3 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.1: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + resolve-from@4.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sass@1.98.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + scule@1.3.0: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + slash@3.0.0: {} + + sortablejs@1.15.7: {} + + source-map-js@1.2.1: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-json-comments@3.1.1: {} + + strip-literal@2.1.1: + dependencies: + js-tokens: 9.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + text-table@0.2.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@1.4.3(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + tslib@2.3.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typescript@5.4.5: {} + + ufo@1.6.3: {} + + undici-types@6.21.0: {} + + unimport@3.14.6(rollup@4.59.0): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + acorn: 8.16.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.1 + pathe: 2.0.3 + picomatch: 4.0.3 + pkg-types: 1.3.1 + scule: 1.3.0 + strip-literal: 2.1.1 + unplugin: 1.16.1 + transitivePeerDependencies: + - rollup + + unplugin-auto-import@0.17.8(@vueuse/core@12.0.0(typescript@5.4.5))(rollup@4.59.0): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + fast-glob: 3.3.3 + local-pkg: 0.5.1 + magic-string: 0.30.21 + minimatch: 9.0.9 + unimport: 3.14.6(rollup@4.59.0) + unplugin: 1.16.1 + optionalDependencies: + '@vueuse/core': 12.0.0(typescript@5.4.5) + transitivePeerDependencies: + - rollup + + unplugin-vue-components@0.26.0(@babel/parser@7.29.0)(rollup@4.59.0)(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + chokidar: 3.6.0 + debug: 4.4.3 + fast-glob: 3.3.3 + local-pkg: 0.4.3 + magic-string: 0.30.21 + minimatch: 9.0.9 + resolve: 1.22.11 + unplugin: 1.16.1 + vue: 3.5.30(typescript@5.4.5) + optionalDependencies: + '@babel/parser': 7.29.0 + transitivePeerDependencies: + - rollup + - supports-color + + unplugin@1.16.1: + dependencies: + acorn: 8.16.0 + webpack-virtual-modules: 0.6.2 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vite@5.4.21(@types/node@20.19.37)(sass@1.98.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.59.0 + optionalDependencies: + '@types/node': 20.19.37 + fsevents: 2.3.3 + sass: 1.98.0 + + vscode-uri@3.1.0: {} + + vue-demi@0.14.10(vue@3.5.30(typescript@5.4.5)): + dependencies: + vue: 3.5.30(typescript@5.4.5) + + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.4.3 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + lodash: 4.17.23 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + vue-router@4.6.4(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.30(typescript@5.4.5) + + vue-tsc@2.2.12(typescript@5.4.5): + dependencies: + '@volar/typescript': 2.4.15 + '@vue/language-core': 2.2.12(typescript@5.4.5) + typescript: 5.4.5 + + vue@3.5.30(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@5.4.5)) + '@vue/shared': 3.5.30 + optionalDependencies: + typescript: 5.4.5 + + webpack-virtual-modules@0.6.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + xml-name-validator@4.0.0: {} + + yocto-queue@0.1.0: {} + + zrender@5.6.1: + dependencies: + tslib: 2.3.0 diff --git a/frontend/video-frontend-admin/src/App.vue b/frontend/video-frontend-admin/src/App.vue new file mode 100644 index 0000000..c5b3376 --- /dev/null +++ b/frontend/video-frontend-admin/src/App.vue @@ -0,0 +1,14 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/api/admin.ts b/frontend/video-frontend-admin/src/api/admin.ts new file mode 100644 index 0000000..cc5197a --- /dev/null +++ b/frontend/video-frontend-admin/src/api/admin.ts @@ -0,0 +1,69 @@ +import request from '@/utils/request.ts' +import type { AdminUser, PageResult, PageParams } from '@/types' + +/** + * 管理员管理 API + */ +export const adminApi = { + /** + * 获取管理员列表 + */ + getList(params: PageParams & { keyword?: string }): Promise> { + return request.get('/user/list', params) + }, + + /** + * 获取管理员详情 + */ + getDetail(id: number): Promise { + return request.get(`/user/${id}`) + }, + + /** + * 添加管理员 + */ + create(data: { + username: string + password: string + nickname: string + email?: string + phone?: string + role?: string + }): Promise { + return request.post('/user', data) + }, + + /** + * 更新管理员 + */ + update(data: { + id: number + nickname?: string + email?: string + phone?: string + role?: string + }): Promise { + return request.put('/user', data) + }, + + /** + * 删除管理员 + */ + delete(id: number): Promise { + return request.delete(`/user/${id}`) + }, + + /** + * 启用/禁用管理员 + */ + updateStatus(id: number, status: number): Promise { + return request.put(`/user/${id}/status/${status}`) + }, + + /** + * 重置密码 + */ + resetPassword(id: number): Promise { + return request.put(`/user/${id}/reset-password`) + } +} diff --git a/frontend/video-frontend-admin/src/api/auth.ts b/frontend/video-frontend-admin/src/api/auth.ts new file mode 100644 index 0000000..649737f --- /dev/null +++ b/frontend/video-frontend-admin/src/api/auth.ts @@ -0,0 +1,40 @@ +import request from '@/utils/request.ts' +import type { + LoginParams, + LoginResult, + CaptchaResult, + AdminUser +} from '@/types' + +/** + * 管理员认证 API + */ +export const authApi = { + /** + * 获取验证码 + */ + getCaptcha(): Promise { + return request.get('/auth/captcha') + }, + + /** + * 登录 + */ + login(params: LoginParams): Promise { + return request.post('/auth/login', params) + }, + + /** + * 登出 + */ + logout(): Promise { + return request.post('/auth/logout') + }, + + /** + * 获取当前管理员信息 + */ + getInfo(): Promise { + return request.get('/auth/info') + } +} diff --git a/frontend/video-frontend-admin/src/api/category.ts b/frontend/video-frontend-admin/src/api/category.ts new file mode 100644 index 0000000..e8d4448 --- /dev/null +++ b/frontend/video-frontend-admin/src/api/category.ts @@ -0,0 +1,65 @@ +import request from '@/utils/request.ts' +import type { Category, CategoryParams, Tag, TagQueryParams, PageResult } from '@/types' + +/** + * 分类管理 API + */ +export const categoryApi = { + /** + * 获取分类列表 + */ + getList(): Promise { + return request.get('/platform/content/category/list') + }, + + /** + * 添加分类 + */ + create(params: CategoryParams): Promise { + return request.post('/platform/content/category', params) + }, + + /** + * 更新分类 + */ + update(params: CategoryParams): Promise { + return request.put('/platform/content/category', params) + }, + + /** + * 删除分类 + */ + delete(categoryId: number): Promise { + return request.delete(`/platform/content/category/${categoryId}`) + }, + + // ==================== 标签管理 ==================== + + /** + * 获取标签列表 + */ + getTags(params?: TagQueryParams): Promise> { + return request.get('/content/tag/page', params) + }, + + /** + * 添加标签 + */ + createTag(params: { name: string }): Promise { + return request.post('/content/tag', params) + }, + + /** + * 更新标签 + */ + updateTag(params: { id: number; name: string }): Promise { + return request.put('/content/tag', params) + }, + + /** + * 删除标签 + */ + deleteTag(tagId: number): Promise { + return request.delete(`/content/tag/${tagId}`) + } +} diff --git a/frontend/video-frontend-admin/src/api/comment.ts b/frontend/video-frontend-admin/src/api/comment.ts new file mode 100644 index 0000000..ea17dee --- /dev/null +++ b/frontend/video-frontend-admin/src/api/comment.ts @@ -0,0 +1,39 @@ +import request from '@/utils/request.ts' +import type { PageResult, PlatformComment, CommentQueryParams } from '@/types' + +/** + * 评论管理 API + */ +export const commentApi = { + /** + * 获取评论列表 + */ + getList(params: CommentQueryParams): Promise> { + return request.get('/admin/list', params) + }, + + /** + * 获取评论详情 + */ + getDetail(commentId: number): Promise { + return request.get(`/admin/${commentId}`) + }, + + /** + * 删除评论 + */ + delete(commentId: number): Promise { + return request.delete(`/admin/${commentId}`) + }, + + /** + * 获取评论统计数据 + */ + getStats(): Promise<{ + totalComments: number + commentsToday: number + commentGrowthRate: number + }> { + return request.get('/admin/stats') + } +} diff --git a/frontend/video-frontend-admin/src/api/index.ts b/frontend/video-frontend-admin/src/api/index.ts new file mode 100644 index 0000000..2386054 --- /dev/null +++ b/frontend/video-frontend-admin/src/api/index.ts @@ -0,0 +1,8 @@ +// 导出所有 API 模块 +export * from './auth.ts' +export * from './user.ts' +export * from './video.ts' +export * from './category.ts' +export * from './comment.ts' +export * from './admin.ts' +export * from './statistics.ts' diff --git a/frontend/video-frontend-admin/src/api/statistics.ts b/frontend/video-frontend-admin/src/api/statistics.ts new file mode 100644 index 0000000..8bc0f48 --- /dev/null +++ b/frontend/video-frontend-admin/src/api/statistics.ts @@ -0,0 +1,42 @@ +import request from '@/utils/request.ts' +import type { DashboardData, StatisticsData, TrendData } from '@/types' + +/** + * 统计数据 API + */ +export const statisticsApi = { + /** + * 获取仪表盘数据 + */ + getDashboard(): Promise { + return request.get('/statistics/dashboard') + }, + + /** + * 获取统计数据 + */ + getStatistics(): Promise { + return request.get('/statistics/overview') + }, + + /** + * 获取用户趋势 + */ + getUserTrend(days: number = 7): Promise { + return request.get('/statistics/user/trend', { days }) + }, + + /** + * 获取视频趋势 + */ + getVideoTrend(days: number = 7): Promise { + return request.get('/statistics/video/trend', { days }) + }, + + /** + * 获取播放趋势 + */ + getViewTrend(days: number = 7): Promise { + return request.get('/statistics/view/trend', { days }) + } +} diff --git a/frontend/video-frontend-admin/src/api/user.ts b/frontend/video-frontend-admin/src/api/user.ts new file mode 100644 index 0000000..8a0f0d3 --- /dev/null +++ b/frontend/video-frontend-admin/src/api/user.ts @@ -0,0 +1,47 @@ +import request from '@/utils/request.ts' +import type { PageResult, PlatformUser, UserQueryParams } from '@/types' + +/** + * 用户管理 API + */ +export const userApi = { + /** + * 获取用户列表 + */ + getList(params: UserQueryParams): Promise> { + return request.get('/platform/user/list', params) + }, + + /** + * 获取用户详情 + */ + getDetail(userId: number): Promise { + return request.get(`/platform/user/${userId}`) + }, + + /** + * 禁用/启用用户 + */ + updateStatus(userId: number, status: number): Promise { + return request.put(`/platform/user/${userId}/status/${status}`) + }, + + /** + * 重置用户密码 + */ + resetPassword(userId: number): Promise { + return request.put(`/platform/user/${userId}/reset-password`) + }, + + /** + * 获取用户统计数据 + */ + getStats(): Promise<{ + totalUsers: number + newUsersToday: number + activeUsersToday: number + userGrowthRate: number + }> { + return request.get('/platform/user/stats') + } +} diff --git a/frontend/video-frontend-admin/src/api/video.ts b/frontend/video-frontend-admin/src/api/video.ts new file mode 100644 index 0000000..24d5c58 --- /dev/null +++ b/frontend/video-frontend-admin/src/api/video.ts @@ -0,0 +1,50 @@ +import request from '@/utils/request.ts' +import type { PageResult, PlatformVideo, VideoQueryParams, VideoReviewParams } from '@/types' + +/** + * 视频管理 API + */ +export const videoApi = { + /** + * 获取视频列表 + */ + getList(params: VideoQueryParams): Promise> { + return request.get('/platform/content/video/list', params) + }, + + /** + * 获取视频详情 + */ + getDetail(videoId: number): Promise { + return request.get(`/platform/content/video/${videoId}`) + }, + + /** + * 审核视频 + */ + review(params: VideoReviewParams): Promise { + return request.post(`/platform/content/video/review/${params.videoId}`, { + status: params.status, + reason: params.reason + }) + }, + + /** + * 下架视频 + */ + disable(videoId: number): Promise { + return request.put(`/platform/content/video/disable/${videoId}`) + }, + + /** + * 获取视频统计数据 + */ + getStats(): Promise<{ + totalVideos: number + newVideosToday: number + pendingReview: number + videoGrowthRate: number + }> { + return request.get('/platform/content/video/stats') + } +} diff --git a/frontend/video-frontend-admin/src/auto-imports.d.ts b/frontend/video-frontend-admin/src/auto-imports.d.ts new file mode 100644 index 0000000..a606bd4 --- /dev/null +++ b/frontend/video-frontend-admin/src/auto-imports.d.ts @@ -0,0 +1,87 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} diff --git a/frontend/video-frontend-admin/src/components.d.ts b/frontend/video-frontend-admin/src/components.d.ts new file mode 100644 index 0000000..f1519fc --- /dev/null +++ b/frontend/video-frontend-admin/src/components.d.ts @@ -0,0 +1,20 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + Breadcrumb: typeof import('./components/Breadcrumb.vue')['default'] + ElButton: typeof import('element-plus/es')['ElButton'] + ElForm: typeof import('element-plus/es')['ElForm'] + ElFormItem: typeof import('element-plus/es')['ElFormItem'] + ElImage: typeof import('element-plus/es')['ElImage'] + ElInput: typeof import('element-plus/es')['ElInput'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + TagsView: typeof import('./components/TagsView.vue')['default'] + } +} diff --git a/frontend/video-frontend-admin/src/components/Breadcrumb.vue b/frontend/video-frontend-admin/src/components/Breadcrumb.vue new file mode 100644 index 0000000..6f6cf0a --- /dev/null +++ b/frontend/video-frontend-admin/src/components/Breadcrumb.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/components/TagsView.vue b/frontend/video-frontend-admin/src/components/TagsView.vue new file mode 100644 index 0000000..e616b5d --- /dev/null +++ b/frontend/video-frontend-admin/src/components/TagsView.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/main.ts b/frontend/video-frontend-admin/src/main.ts new file mode 100644 index 0000000..c506303 --- /dev/null +++ b/frontend/video-frontend-admin/src/main.ts @@ -0,0 +1,23 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import ElementPlus from 'element-plus' +import zhCn from 'element-plus/es/locale/lang/zh-cn' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' +import 'element-plus/dist/index.css' + +import App from './App.vue' +import router from './router' +import './styles/index.scss' + +const app = createApp(App) + +// 注册所有 Element Plus 图标 +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.use(createPinia()) +app.use(router) +app.use(ElementPlus, { locale: zhCn }) + +app.mount('#app') diff --git a/frontend/video-frontend-admin/src/router/index.ts b/frontend/video-frontend-admin/src/router/index.ts new file mode 100644 index 0000000..4b3c102 --- /dev/null +++ b/frontend/video-frontend-admin/src/router/index.ts @@ -0,0 +1,206 @@ +import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' +import { useUserStore } from '@/stores/user.ts' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' + +// 配置 NProgress +NProgress.configure({ showSpinner: false }) + +// 布局组件 +const Layout = () => import('@/views/layout/index.vue') + +// 静态路由 +export const constantRoutes: RouteRecordRaw[] = [ + { + path: '/login', + name: 'Login', + component: () => import('@/views/login/index.vue'), + meta: { title: '登录', hidden: true } + }, + { + path: '/404', + name: 'NotFound', + component: () => import('@/views/error/404.vue'), + meta: { title: '页面未找到', hidden: true } + } +] + +// 动态路由(需要登录) +export const asyncRoutes: RouteRecordRaw[] = [ + { + path: '/', + component: Layout, + redirect: '/dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + component: () => import('@/views/dashboard/index.vue'), + meta: { title: '仪表盘', icon: 'Odometer', affix: true } + } + ] + }, + { + path: '/user', + component: Layout, + redirect: '/user/list', + meta: { title: '用户管理', icon: 'User' }, + children: [ + { + path: 'list', + name: 'UserList', + component: () => import('@/views/user/list.vue'), + meta: { title: '用户列表', icon: 'List' } + }, + { + path: 'detail/:id', + name: 'UserDetail', + component: () => import('@/views/user/detail.vue'), + meta: { title: '用户详情', hidden: true, activeMenu: '/user/list' } + } + ] + }, + { + path: '/video', + component: Layout, + redirect: '/video/list', + meta: { title: '视频管理', icon: 'VideoCamera' }, + children: [ + { + path: 'list', + name: 'VideoList', + component: () => import('@/views/video/list.vue'), + meta: { title: '视频列表', icon: 'List' } + }, + { + path: 'review', + name: 'VideoReview', + component: () => import('@/views/video/review.vue'), + meta: { title: '视频审核', icon: 'Check' } + }, + { + path: 'detail/:id', + name: 'VideoDetail', + component: () => import('@/views/video/detail.vue'), + meta: { title: '视频详情', hidden: true, activeMenu: '/video/list' } + } + ] + }, + { + path: '/content', + component: Layout, + redirect: '/content/category', + meta: { title: '内容管理', icon: 'Files' }, + children: [ + { + path: 'category', + name: 'Category', + component: () => import('@/views/content/category.vue'), + meta: { title: '分类管理', icon: 'Grid' } + }, + { + path: 'tag', + name: 'Tag', + component: () => import('@/views/content/tag.vue'), + meta: { title: '标签管理', icon: 'PriceTag' } + }, + { + path: 'comment', + name: 'Comment', + component: () => import('@/views/content/comment.vue'), + meta: { title: '评论管理', icon: 'ChatDotSquare' } + } + ] + }, + { + path: '/system', + component: Layout, + redirect: '/system/admin', + meta: { title: '系统管理', icon: 'Setting' }, + children: [ + { + path: 'admin', + name: 'AdminUser', + component: () => import('@/views/system/admin.vue'), + meta: { title: '管理员管理', icon: 'UserFilled' } + } + ] + }, + // 404 页面必须放在最后 + { + path: '/:pathMatch(.*)*', + redirect: '/404', + meta: { hidden: true } + } +] + +// 创建路由实例 +const router = createRouter({ + history: createWebHistory(), + routes: [...constantRoutes, ...asyncRoutes], + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } else { + return { top: 0 } + } + } +}) + +// 路由白名单 +const whiteList = ['/login', '/404'] + +// 路由前置守卫 +router.beforeEach(async (to, from, next) => { + // 开始进度条 + NProgress.start() + + // 设置页面标题 + const title = to.meta?.title as string + document.title = title ? `${title} - HAOVP管理后台` : 'HAOVP管理后台' + + const userStore = useUserStore() + const hasToken = userStore.token + + if (hasToken) { + if (to.path === '/login') { + // 已登录,跳转到首页 + next({ path: '/' }) + NProgress.done() + } else { + // 检查是否已获取用户信息 + if (userStore.userInfo) { + next() + } else { + try { + // 获取用户信息 + await userStore.fetchUserInfo() + next() + } catch (error) { + // 获取用户信息失败,清除登录状态 + userStore.clearAuth() + next(`/login?redirect=${to.path}`) + NProgress.done() + } + } + } + } else { + // 未登录 + if (whiteList.includes(to.path)) { + // 在白名单中,直接进入 + next() + } else { + // 不在白名单中,跳转到登录页 + next(`/login?redirect=${to.path}`) + NProgress.done() + } + } +}) + +// 路由后置守卫 +router.afterEach(() => { + // 结束进度条 + NProgress.done() +}) + +export default router diff --git a/frontend/video-frontend-admin/src/stores/app.ts b/frontend/video-frontend-admin/src/stores/app.ts new file mode 100644 index 0000000..3d99aff --- /dev/null +++ b/frontend/video-frontend-admin/src/stores/app.ts @@ -0,0 +1,30 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useAppStore = defineStore('admin-app', () => { + // 侧边栏折叠状态 + const sidebarCollapsed = ref(false) + + // 设备类型 + const device = ref<'desktop' | 'mobile'>('desktop') + + // 切换侧边栏 + function toggleSidebar() { + sidebarCollapsed.value = !sidebarCollapsed.value + } + + // 设置设备类型 + function setDevice(d: 'desktop' | 'mobile') { + device.value = d + if (d === 'mobile') { + sidebarCollapsed.value = true + } + } + + return { + sidebarCollapsed, + device, + toggleSidebar, + setDevice + } +}) diff --git a/frontend/video-frontend-admin/src/stores/index.ts b/frontend/video-frontend-admin/src/stores/index.ts new file mode 100644 index 0000000..ffb4dea --- /dev/null +++ b/frontend/video-frontend-admin/src/stores/index.ts @@ -0,0 +1,3 @@ +export { useUserStore } from './user.ts' +export { useAppStore } from './app.ts' +export { useTagsViewStore } from './tagsView.ts' diff --git a/frontend/video-frontend-admin/src/stores/tagsView.ts b/frontend/video-frontend-admin/src/stores/tagsView.ts new file mode 100644 index 0000000..fb59e94 --- /dev/null +++ b/frontend/video-frontend-admin/src/stores/tagsView.ts @@ -0,0 +1,111 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' +import type { RouteLocationNormalized } from 'vue-router' + +export interface TagView { + path: string + name: string + title: string + fullPath: string + query?: Record + affix?: boolean +} + +export const useTagsViewStore = defineStore('admin-tagsView', () => { + // 访问过的页面 + const visitedViews = ref([]) + + // 缓存的页面名称 + const cachedViews = ref([]) + + // 添加访问过的页面 + function addView(view: RouteLocationNormalized) { + // 检查是否已存在 + const exists = visitedViews.value.some((v) => v.path === view.path) + if (exists) return + + // 添加新页面 + visitedViews.value.push({ + path: view.path, + name: view.name as string, + title: (view.meta?.title as string) || 'no-name', + fullPath: view.fullPath, + query: view.query as Record, + affix: view.meta?.affix as boolean + }) + + // 添加缓存 + if (view.name && view.meta?.noCache !== true) { + addCachedView(view.name as string) + } + } + + // 添加缓存页面 + function addCachedView(name: string) { + if (cachedViews.value.includes(name)) return + cachedViews.value.push(name) + } + + // 删除访问过的页面 + function delView(view: TagView) { + // 删除访问记录 + const index = visitedViews.value.findIndex((v) => v.path === view.path) + if (index > -1) { + visitedViews.value.splice(index, 1) + } + + // 删除缓存 + if (view.name) { + delCachedView(view.name) + } + } + + // 删除缓存页面 + function delCachedView(name: string) { + const index = cachedViews.value.indexOf(name) + if (index > -1) { + cachedViews.value.splice(index, 1) + } + } + + // 删除其他页面 + function delOthersViews(view: TagView) { + visitedViews.value = visitedViews.value.filter((v) => v.affix || v.path === view.path) + cachedViews.value = cachedViews.value.filter((name) => name === view.name) + } + + // 删除所有页面 + function delAllViews() { + visitedViews.value = visitedViews.value.filter((v) => v.affix) + cachedViews.value = [] + } + + // 删除左侧页面 + function delLeftViews(view: TagView) { + const index = visitedViews.value.findIndex((v) => v.path === view.path) + if (index > -1) { + visitedViews.value = visitedViews.value.filter((v, i) => v.affix || i >= index) + } + } + + // 删除右侧页面 + function delRightViews(view: TagView) { + const index = visitedViews.value.findIndex((v) => v.path === view.path) + if (index > -1) { + visitedViews.value = visitedViews.value.filter((v, i) => v.affix || i <= index) + } + } + + return { + visitedViews, + cachedViews, + addView, + addCachedView, + delView, + delCachedView, + delOthersViews, + delAllViews, + delLeftViews, + delRightViews + } +}) diff --git a/frontend/video-frontend-admin/src/stores/user.ts b/frontend/video-frontend-admin/src/stores/user.ts new file mode 100644 index 0000000..c1cb6f2 --- /dev/null +++ b/frontend/video-frontend-admin/src/stores/user.ts @@ -0,0 +1,92 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' +import { authApi, type LoginParams, type AdminUser } from '@/api/auth.ts' +import router from '@/router' + +const TOKEN_KEY = 'admin_token' +const REFRESH_TOKEN_KEY = 'admin_refresh_token' +const USER_INFO_KEY = 'admin_user_info' + +export const useUserStore = defineStore('admin-user', () => { + // State + const token = ref(localStorage.getItem(TOKEN_KEY) || '') + const refreshToken = ref(localStorage.getItem(REFRESH_TOKEN_KEY) || '') + const userInfo = ref( + JSON.parse(localStorage.getItem(USER_INFO_KEY) || 'null') + ) + + // Getters + const isLoggedIn = computed(() => !!token.value) + const userId = computed(() => userInfo.value?.id) + const username = computed(() => userInfo.value?.username) + const nickname = computed(() => userInfo.value?.nickname) + const avatar = computed(() => userInfo.value?.avatar) + const role = computed(() => userInfo.value?.role) + + // Actions + function setToken(accessToken: string, refresh?: string) { + token.value = accessToken + localStorage.setItem(TOKEN_KEY, accessToken) + if (refresh) { + refreshToken.value = refresh + localStorage.setItem(REFRESH_TOKEN_KEY, refresh) + } + } + + function setUserInfo(info: AdminUser) { + userInfo.value = info + localStorage.setItem(USER_INFO_KEY, JSON.stringify(info)) + } + + async function login(params: LoginParams) { + const result = await authApi.login(params) + setToken(result.accessToken, result.refreshToken) + return result + } + + async function fetchUserInfo() { + const info = await authApi.getInfo() + setUserInfo(info) + return info + } + + async function logout() { + try { + await authApi.logout() + } catch (error) { + console.error('Logout error:', error) + } finally { + clearAuth() + } + } + + function clearAuth() { + token.value = '' + refreshToken.value = '' + userInfo.value = null + localStorage.removeItem(TOKEN_KEY) + localStorage.removeItem(REFRESH_TOKEN_KEY) + localStorage.removeItem(USER_INFO_KEY) + } + + return { + // State + token, + refreshToken, + userInfo, + // Getters + isLoggedIn, + userId, + username, + nickname, + avatar, + role, + // Actions + setToken, + setUserInfo, + login, + fetchUserInfo, + logout, + clearAuth + } +}) diff --git a/frontend/video-frontend-admin/src/styles/index.scss b/frontend/video-frontend-admin/src/styles/index.scss new file mode 100644 index 0000000..86a88b5 --- /dev/null +++ b/frontend/video-frontend-admin/src/styles/index.scss @@ -0,0 +1,140 @@ +// 全局样式 +@use 'variables' as *; + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, +body { + width: 100%; + height: 100%; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, + 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + font-size: 14px; + color: $text-primary; + background-color: $bg-secondary; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + color: $primary-color; + text-decoration: none; + + &:hover { + color: $primary-hover; + } +} + +// 滚动条样式 +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: $bg-tertiary; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 3px; + + &:hover { + background: #a8a8a8; + } +} + +// Element Plus 覆盖 +.el-card { + border-radius: $radius-md; + + &:not(:last-child) { + margin-bottom: $spacing-md; + } +} + +.el-table { + .el-table__header { + th { + background: $bg-tertiary !important; + } + } +} + +.el-dialog { + border-radius: $radius-md; +} + +.el-message-box { + border-radius: $radius-md; +} + +// 工具类 +.text-primary { + color: $primary-color !important; +} + +.text-success { + color: $success-color !important; +} + +.text-warning { + color: $warning-color !important; +} + +.text-danger { + color: $danger-color !important; +} + +.text-info { + color: $info-color !important; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.mt-sm { + margin-top: $spacing-sm; +} + +.mt-md { + margin-top: $spacing-md; +} + +.mt-lg { + margin-top: $spacing-lg; +} + +.mb-sm { + margin-bottom: $spacing-sm; +} + +.mb-md { + margin-bottom: $spacing-md; +} + +.mb-lg { + margin-bottom: $spacing-lg; +} + +.p-sm { + padding: $spacing-sm; +} + +.p-md { + padding: $spacing-md; +} + +.p-lg { + padding: $spacing-lg; +} diff --git a/frontend/video-frontend-admin/src/styles/variables.scss b/frontend/video-frontend-admin/src/styles/variables.scss new file mode 100644 index 0000000..462cfd0 --- /dev/null +++ b/frontend/video-frontend-admin/src/styles/variables.scss @@ -0,0 +1,45 @@ +// 颜色变量 +$primary-color: #409eff; +$primary-hover: #66b1ff; +$success-color: #67c23a; +$warning-color: #e6a23c; +$danger-color: #f56c6c; +$info-color: #909399; + +// 文本颜色 +$text-primary: #303133; +$text-regular: #606266; +$text-secondary: #909399; +$text-placeholder: #c0c4cc; + +// 背景颜色 +$bg-primary: #ffffff; +$bg-secondary: #f0f2f5; +$bg-tertiary: #f5f7fa; + +// 边框颜色 +$border-light: #e4e7ed; +$border-base: #dcdfe6; +$border-dark: #d4d7de; + +// 间距 +$spacing-xs: 4px; +$spacing-sm: 8px; +$spacing-md: 16px; +$spacing-lg: 24px; +$spacing-xl: 32px; + +// 圆角 +$radius-sm: 4px; +$radius-md: 8px; +$radius-lg: 12px; + +// 阴影 +$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.04); +$shadow-md: 0 4px 8px rgba(0, 0, 0, 0.08); +$shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.12); + +// 布局 +$header-height: 50px; +$sidebar-width: 210px; +$sidebar-collapsed-width: 64px; diff --git a/frontend/video-frontend-admin/src/types/index.ts b/frontend/video-frontend-admin/src/types/index.ts new file mode 100644 index 0000000..3c0159f --- /dev/null +++ b/frontend/video-frontend-admin/src/types/index.ts @@ -0,0 +1,245 @@ +// API 响应通用结构 +export interface ApiResponse { + code: number + message: string + data: T +} + +// 分页请求参数 +export interface PageParams { + page?: number + size?: number + pageNum?: number + pageSize?: number +} + +// 分页响应数据 +export interface PageResult { + records: T[] + total: number + size: number + current: number + pages: number +} + +// 管理员信息 +export interface AdminUser { + id: number + username: string + nickname: string + avatar: string + email: string + phone: string + role: string + status: number + lastLoginTime: string + lastLoginIp: string + createTime: string +} + +// 登录响应 +export interface LoginResult { + accessToken: string + refreshToken: string + tokenType: string + expiresIn: number + adminId: number + username: string +} + +// 验证码响应 +export interface CaptchaResult { + captchaKey: string + captchaImage: string +} + +// 登录请求 +export interface LoginParams { + username: string + password: string + captcha: string + captchaKey: string +} + +// 平台用户信息(管理端查看) +export interface PlatformUser { + id: number + username: string + nickname: string + avatar: string + email: string + phone: string + gender: number + birthday: string + signature: string + status: number + followerCount: number + followingCount: number + videoCount: number + likeCount: number + level: number + vipLevel: number + createTime: string + updateTime: string +} + +// 用户查询参数 +export interface UserQueryParams extends PageParams { + keyword?: string + status?: number + startDate?: string + endDate?: string +} + +// 平台视频信息(管理端查看) +export interface PlatformVideo { + id: number + userId: number + username: string + userNickname: string + userAvatar: string + title: string + description: string + coverUrl: string + videoUrl: string + duration: number + width: number + height: number + format: string + size: number + categoryId: number + categoryName: string + status: number // 0:待审核,1:已发布,2:审核拒绝,3:已下架 + auditStatus: number + auditReason: string + likeCount: number + coinCount: number + favoriteCount: number + commentCount: number + viewCount: number + shareCount: number + danmakuCount: number + isRecommend: number + isTop: number + publishTime: string + createTime: string + updateTime: string +} + +// 视频查询参数 +export interface VideoQueryParams extends PageParams { + keyword?: string + userId?: number + categoryId?: number + status?: number + auditStatus?: number + startDate?: string + endDate?: string +} + +// 视频审核参数 +export interface VideoReviewParams { + videoId: number + status: number // 1:通过, 2:拒绝 + reason?: string +} + +// 分类信息 +export interface Category { + id: number + name: string + parentId: number + sort: number + icon: string + children?: Category[] +} + +// 分类创建/更新参数 +export interface CategoryParams { + id?: number + name: string + parentId?: number + sort?: number + icon?: string +} + +// 标签信息 +export interface Tag { + id: number + name: string + useCount: number + createTime: string +} + +// 标签查询参数 +export interface TagQueryParams extends PageParams { + keyword?: string +} + +// 评论信息(管理端) +export interface PlatformComment { + id: number + videoId: number + videoTitle: string + userId: number + userNickname: string + userAvatar: string + parentId: number + rootId: number + content: string + likeCount: number + replyCount: number + isTop: number + status: number + createTime: string +} + +// 评论查询参数 +export interface CommentQueryParams extends PageParams { + keyword?: string + videoId?: number + userId?: number + status?: number + startDate?: string + endDate?: string +} + +// 统计数据 +export interface StatisticsData { + // 用户统计 + totalUsers: number + newUsersToday: number + activeUsersToday: number + userGrowthRate: number + // 视频统计 + totalVideos: number + newVideosToday: number + pendingReview: number + videoGrowthRate: number + // 播放统计 + totalViews: number + viewsToday: number + viewGrowthRate: number + // 互动统计 + totalLikes: number + totalComments: number + totalDanmakus: number + // 趋势数据 + userTrend: TrendData[] + videoTrend: TrendData[] + viewTrend: TrendData[] +} + +// 趋势数据 +export interface TrendData { + date: string + value: number +} + +// 仪表盘数据 +export interface DashboardData { + statistics: StatisticsData + hotVideos: PlatformVideo[] + recentComments: PlatformComment[] + recentUsers: PlatformUser[] +} diff --git a/frontend/video-frontend-admin/src/utils/format.ts b/frontend/video-frontend-admin/src/utils/format.ts new file mode 100644 index 0000000..5e47d4c --- /dev/null +++ b/frontend/video-frontend-admin/src/utils/format.ts @@ -0,0 +1,92 @@ +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' +import 'dayjs/locale/zh-cn' + +dayjs.extend(relativeTime) +dayjs.locale('zh-cn') + +/** + * 格式化日期时间 + */ +export function formatDateTime(date: string | Date | undefined | null, format = 'YYYY-MM-DD HH:mm:ss'): string { + if (!date) return '-' + return dayjs(date).format(format) +} + +/** + * 格式化日期 + */ +export function formatDate(date: string | Date | undefined | null): string { + if (!date) return '-' + return dayjs(date).format('YYYY-MM-DD') +} + +/** + * 格式化时间 + */ +export function formatTime(date: string | Date | undefined | null): string { + if (!date) return '-' + return dayjs(date).format('HH:mm:ss') +} + +/** + * 相对时间 + */ +export function formatRelativeTime(date: string | Date | undefined | null): string { + if (!date) return '-' + return dayjs(date).fromNow() +} + +/** + * 格式化视频时长 + */ +export function formatDuration(seconds: number | undefined | null): string { + if (!seconds || seconds < 0) return '00:00' + + const hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + const secs = seconds % 60 + + const pad = (n: number) => n.toString().padStart(2, '0') + + if (hours > 0) { + return `${pad(hours)}:${pad(minutes)}:${pad(secs)}` + } + return `${pad(minutes)}:${pad(secs)}` +} + +/** + * 格式化文件大小 + */ +export function formatFileSize(bytes: number | undefined | null): string { + if (!bytes || bytes === 0) return '0 B' + + const units = ['B', 'KB', 'MB', 'GB', 'TB'] + const k = 1024 + const i = Math.floor(Math.log(bytes) / Math.log(k)) + + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + units[i] +} + +/** + * 格式化数字 + */ +export function formatNumber(num: number | undefined | null): string { + if (!num && num !== 0) return '0' + if (num < 1000) { + return num.toString() + } else if (num < 10000) { + return (num / 1000).toFixed(1) + '千' + } else if (num < 100000000) { + return (num / 10000).toFixed(1) + '万' + } else { + return (num / 100000000).toFixed(1) + '亿' + } +} + +/** + * 格式化播放量 + */ +export function formatPlayCount(count: number | undefined | null): string { + return formatNumber(count) +} diff --git a/frontend/video-frontend-admin/src/utils/request.ts b/frontend/video-frontend-admin/src/utils/request.ts new file mode 100644 index 0000000..abf3809 --- /dev/null +++ b/frontend/video-frontend-admin/src/utils/request.ts @@ -0,0 +1,167 @@ +import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios' +import { ElMessage, ElMessageBox } from 'element-plus' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { useUserStore } from '@/stores/user.ts' +import router from '@/router' + +// 配置 NProgress +NProgress.configure({ showSpinner: false }) + +// 创建 axios 实例 +const service: AxiosInstance = axios.create({ + baseURL: '/api/admin', + timeout: 30000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +service.interceptors.request.use( + (config: InternalAxiosRequestConfig) => { + NProgress.start() + + // 添加 Token + const userStore = useUserStore() + const token = userStore.token + if (token && config.headers) { + config.headers.Authorization = `Bearer ${token}` + } + + return config + }, + (error) => { + NProgress.done() + return Promise.reject(error) + } +) + +// 响应拦截器 +service.interceptors.response.use( + (response: AxiosResponse) => { + NProgress.done() + + const res = response.data + + // 如果是文件下载,直接返回 + if (response.config.responseType === 'blob') { + return response + } + + // 业务状态码判断 + if (res.code !== 200 && res.code !== 0) { + ElMessage.error(res.message || '请求失败') + + // Token 过期 + if (res.code === 401) { + ElMessageBox.confirm('登录状态已过期,请重新登录', '提示', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + const userStore = useUserStore() + userStore.logout() + router.push('/login') + }) + } + + return Promise.reject(new Error(res.message || '请求失败')) + } + + return res.data + }, + (error) => { + NProgress.done() + + let message = '请求失败' + if (error.response) { + switch (error.response.status) { + case 400: + message = '请求参数错误' + break + case 401: + message = '未授权,请登录' + const userStore = useUserStore() + userStore.logout() + router.push('/login') + break + case 403: + message = '拒绝访问' + break + case 404: + message = '请求地址不存在' + break + case 500: + message = '服务器内部错误' + break + default: + message = error.response.data?.message || '请求失败' + } + } else if (error.message.includes('timeout')) { + message = '请求超时' + } else if (error.message.includes('Network Error')) { + message = '网络错误' + } + + ElMessage.error(message) + return Promise.reject(error) + } +) + +// 封装请求方法 +const request = { + get(url: string, params?: any, config?: AxiosRequestConfig): Promise { + return service.get(url, { params, ...config }) + }, + + post(url: string, data?: any, config?: AxiosRequestConfig): Promise { + return service.post(url, data, config) + }, + + put(url: string, data?: any, config?: AxiosRequestConfig): Promise { + return service.put(url, data, config) + }, + + delete(url: string, params?: any, config?: AxiosRequestConfig): Promise { + return service.delete(url, { params, ...config }) + }, + + upload(url: string, file: File, onProgress?: (percent: number) => void): Promise { + const formData = new FormData() + formData.append('file', file) + + return service.post(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + }, + onUploadProgress: (progressEvent) => { + if (progressEvent.total && onProgress) { + const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total) + onProgress(percent) + } + } + }) + }, + + download(url: string, params?: any, filename?: string): Promise { + return service + .get(url, { + params, + responseType: 'blob' + }) + .then((response: any) => { + const blob = new Blob([response.data]) + const link = document.createElement('a') + link.href = URL.createObjectURL(blob) + link.download = filename || 'download' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + URL.revokeObjectURL(link.href) + }) + } +} + +export default request +export { service as axiosInstance } diff --git a/frontend/video-frontend-admin/src/views/content/category.vue b/frontend/video-frontend-admin/src/views/content/category.vue new file mode 100644 index 0000000..9dfc112 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/content/category.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/content/comment.vue b/frontend/video-frontend-admin/src/views/content/comment.vue new file mode 100644 index 0000000..a10963d --- /dev/null +++ b/frontend/video-frontend-admin/src/views/content/comment.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/content/tag.vue b/frontend/video-frontend-admin/src/views/content/tag.vue new file mode 100644 index 0000000..1062a01 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/content/tag.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/dashboard/index.vue b/frontend/video-frontend-admin/src/views/dashboard/index.vue new file mode 100644 index 0000000..175c831 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/dashboard/index.vue @@ -0,0 +1,424 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/error/404.vue b/frontend/video-frontend-admin/src/views/error/404.vue new file mode 100644 index 0000000..8ab6195 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/error/404.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/layout/index.vue b/frontend/video-frontend-admin/src/views/layout/index.vue new file mode 100644 index 0000000..cb5b3ba --- /dev/null +++ b/frontend/video-frontend-admin/src/views/layout/index.vue @@ -0,0 +1,301 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/login/index.vue b/frontend/video-frontend-admin/src/views/login/index.vue new file mode 100644 index 0000000..6f6776e --- /dev/null +++ b/frontend/video-frontend-admin/src/views/login/index.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/system/admin.vue b/frontend/video-frontend-admin/src/views/system/admin.vue new file mode 100644 index 0000000..8e1e157 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/system/admin.vue @@ -0,0 +1,230 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/user/detail.vue b/frontend/video-frontend-admin/src/views/user/detail.vue new file mode 100644 index 0000000..6e1dcd4 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/user/detail.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/user/list.vue b/frontend/video-frontend-admin/src/views/user/list.vue new file mode 100644 index 0000000..470409c --- /dev/null +++ b/frontend/video-frontend-admin/src/views/user/list.vue @@ -0,0 +1,355 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/video/detail.vue b/frontend/video-frontend-admin/src/views/video/detail.vue new file mode 100644 index 0000000..ebda8ec --- /dev/null +++ b/frontend/video-frontend-admin/src/views/video/detail.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/video/list.vue b/frontend/video-frontend-admin/src/views/video/list.vue new file mode 100644 index 0000000..aa6e8c8 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/video/list.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/frontend/video-frontend-admin/src/views/video/review.vue b/frontend/video-frontend-admin/src/views/video/review.vue new file mode 100644 index 0000000..dea1406 --- /dev/null +++ b/frontend/video-frontend-admin/src/views/video/review.vue @@ -0,0 +1,453 @@ + + + + + diff --git a/frontend/video-frontend-admin/tsconfig.json b/frontend/video-frontend-admin/tsconfig.json new file mode 100644 index 0000000..5419aa0 --- /dev/null +++ b/frontend/video-frontend-admin/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + }, + "types": ["vite/client", "element-plus/global"] + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json"}] +} diff --git a/frontend/video-frontend-admin/tsconfig.node.json b/frontend/video-frontend-admin/tsconfig.node.json new file mode 100644 index 0000000..c7a071e --- /dev/null +++ b/frontend/video-frontend-admin/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": [ + "vite.config.ts" + ] +} diff --git a/frontend/video-frontend-admin/vite.config.ts b/frontend/video-frontend-admin/vite.config.ts new file mode 100644 index 0000000..14a4eeb --- /dev/null +++ b/frontend/video-frontend-admin/vite.config.ts @@ -0,0 +1,47 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import { resolve } from 'path' +import AutoImport from 'unplugin-auto-import/vite' +import Components from 'unplugin-vue-components/vite' +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' + +export default defineConfig({ + plugins: [ + vue(), + AutoImport({ + imports: ['vue', 'vue-router', 'pinia'], + resolvers: [ElementPlusResolver()], + dts: 'src/auto-imports.d.ts' + }), + Components({ + resolvers: [ElementPlusResolver()], + dts: 'src/components.d.ts' + }) + ], + resolve: { + alias: { + '@': resolve(__dirname, 'src') + } + }, + server: { + port: 3100, + proxy: { + '/api': { + target: 'http://localhost:9000', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, '') + } + } + }, + build: { + rollupOptions: { + output: { + manualChunks: { + 'element-plus': ['element-plus'], + 'echarts': ['echarts'], + 'vendor': ['vue', 'vue-router', 'pinia'] + } + } + } + } +}) diff --git a/frontend/video-frontend-web/.env b/frontend/video-frontend-web/.env new file mode 100644 index 0000000..107d503 --- /dev/null +++ b/frontend/video-frontend-web/.env @@ -0,0 +1,3 @@ +# 应用配置 +VITE_APP_TITLE=HAOVP视频平台 +VITE_API_BASE_URL=/api diff --git a/frontend/video-frontend-web/index.html b/frontend/video-frontend-web/index.html new file mode 100644 index 0000000..7b5af50 --- /dev/null +++ b/frontend/video-frontend-web/index.html @@ -0,0 +1,14 @@ + + + + + + + + HAOVP - 在线视频平台 + + +
+ + + diff --git a/frontend/video-frontend-web/package-lock.json b/frontend/video-frontend-web/package-lock.json new file mode 100644 index 0000000..a49f44c --- /dev/null +++ b/frontend/video-frontend-web/package-lock.json @@ -0,0 +1,6105 @@ +{ + "name": "video-platform-web", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "video-platform-web", + "version": "1.0.0", + "dependencies": { + "@iconify/vue": "^4.1.1", + "@vant/use": "^1.6.0", + "artplayer": "^5.1.7", + "artplayer-plugin-danmuku": "^5.1.0", + "axios": "^1.6.8", + "dayjs": "^1.11.10", + "nprogress": "^0.2.0", + "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^3.2.1", + "vant": "^4.8.4", + "vue": "^3.4.21", + "vue-router": "^4.3.0" + }, + "devDependencies": { + "@types/node": "^20.11.30", + "@types/nprogress": "^0.2.3", + "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/parser": "^7.4.0", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/tsconfig": "^0.5.1", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.24.0", + "prettier": "^3.2.5", + "sass": "^1.72.0", + "typescript": "~5.4.0", + "unplugin-auto-import": "^0.17.5", + "unplugin-vue-components": "^0.26.0", + "vite": "^5.2.0", + "vite-plugin-vue-devtools": "^7.0.25", + "vue-tsc": "^2.0.6" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz", + "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-decorators": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz", + "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/vue": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/@iconify/vue/-/vue-4.3.0.tgz", + "integrity": "sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==", + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "vue": ">=3" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.37", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/nprogress": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.3.tgz", + "integrity": "sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vant/popperjs": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz", + "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==", + "license": "MIT" + }, + "node_modules/@vant/use": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz", + "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.15", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.15.tgz", + "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.15" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.15", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.15.tgz", + "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.15", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.15.tgz", + "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.15", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz", + "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz", + "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@vue/babel-helper-vue-transform-on": "1.5.0", + "@vue/babel-plugin-resolve-type": "1.5.0", + "@vue/shared": "^3.5.18" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz", + "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/parser": "^7.28.0", + "@vue/compiler-sfc": "^3.5.18" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.30.tgz", + "integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@vue/shared": "3.5.30", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz", + "integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.30", + "@vue/shared": "3.5.30" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz", + "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@vue/compiler-core": "3.5.30", + "@vue/compiler-dom": "3.5.30", + "@vue/compiler-ssr": "3.5.30", + "@vue/shared": "3.5.30", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.8", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz", + "integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.30", + "@vue/shared": "3.5.30" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmmirror.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/devtools-core": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-core/-/devtools-core-7.7.9.tgz", + "integrity": "sha512-48jrBSwG4GVQRvVeeXn9p9+dlx+ISgasM7SxZZKczseohB0cBz+ITKr4YbLWjmJdy45UHL7UMPlR4Y0CWTRcSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.9", + "@vue/devtools-shared": "^7.7.9", + "mitt": "^3.0.1", + "nanoid": "^5.1.0", + "pathe": "^2.0.3", + "vite-hot-client": "^2.0.4" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-core/node_modules/nanoid": { + "version": "5.1.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.1.7.tgz", + "integrity": "sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", + "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.9", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", + "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/language-core": { + "version": "2.2.12", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.12.tgz", + "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.15", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.30.tgz", + "integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.30" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.30.tgz", + "integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.30", + "@vue/shared": "3.5.30" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz", + "integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.30", + "@vue/runtime-core": "3.5.30", + "@vue/shared": "3.5.30", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.30.tgz", + "integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.30", + "@vue/shared": "3.5.30" + }, + "peerDependencies": { + "vue": "3.5.30" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.30.tgz", + "integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==", + "license": "MIT" + }, + "node_modules/@vue/tsconfig": { + "version": "0.5.1", + "resolved": "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.5.1.tgz", + "integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-1.0.13.tgz", + "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/artplayer": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/artplayer/-/artplayer-5.4.0.tgz", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "license": "MIT", + "dependencies": { + "option-validator": "^2.0.6" + } + }, + "node_modules/artplayer-plugin-danmuku": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/artplayer-plugin-danmuku/-/artplayer-plugin-danmuku-5.3.0.tgz", + "integrity": "sha512-a76bU1cWEZr53hD1X8IHfOzS4QawGHn8dQ3fIYyJ5TsyhTSnznhi2WzkS8M7LL3H02ekXRZTUFan9+9EERk12g==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.8", + "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz", + "integrity": "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/birpc": { + "version": "2.9.0", + "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001779", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001779.tgz", + "integrity": "sha512-U5og2PN7V4DMgF50YPNtnZJGWVLFjjsN3zb6uMT5VGYIewieDj1upwfuVNXf4Kor+89c3iCRJnSzMD5LmTvsfA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz", + "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^5.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.313", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", + "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz", + "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-vue": { + "version": "9.33.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz", + "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "5.1.5", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/is-what/-/is-what-5.5.0.tgz", + "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, + "node_modules/mlly": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.1.tgz", + "integrity": "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/option-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/option-validator/-/option-validator-2.0.6.tgz", + "integrity": "sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.3" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persistedstate": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.3.tgz", + "integrity": "sha512-Cm819WBj/s5K5DGw55EwbXDtx+EZzM0YR5AZbq9XE3u0xvXwvX2JnWoFpWIcdzISBHqy9H1UiSIUmXyXqWsQRQ==", + "license": "MIT", + "peerDependencies": { + "pinia": "^2.0.0" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmmirror.com/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sass": { + "version": "1.98.0", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.98.0.tgz", + "integrity": "sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/superjson": { + "version": "2.2.6", + "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport": { + "version": "3.14.6", + "resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.14.6.tgz", + "integrity": "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.4", + "acorn": "^8.14.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "fast-glob": "^3.3.3", + "local-pkg": "^1.0.0", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.1", + "picomatch": "^4.0.2", + "pkg-types": "^1.3.0", + "scule": "^1.3.0", + "strip-literal": "^2.1.1", + "unplugin": "^1.16.1" + } + }, + "node_modules/unimport/node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unimport/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/unimport/node_modules/local-pkg": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz", + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unimport/node_modules/local-pkg/node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/unimport/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unplugin-auto-import": { + "version": "0.17.8", + "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.17.8.tgz", + "integrity": "sha512-CHryj6HzJ+n4ASjzwHruD8arhbdl+UXvhuAIlHDs15Y/IMecG3wrf7FVg4pVH/DIysbq/n0phIjNHAjl7TG7Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.0", + "fast-glob": "^3.3.2", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.10", + "minimatch": "^9.0.4", + "unimport": "^3.7.2", + "unplugin": "^1.11.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^3.2.2", + "@vueuse/core": "*" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@vueuse/core": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components": { + "version": "0.26.0", + "resolved": "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.26.0.tgz", + "integrity": "sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.6", + "@rollup/pluginutils": "^5.0.4", + "chokidar": "^3.5.3", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.3", + "minimatch": "^9.0.3", + "resolve": "^1.22.4", + "unplugin": "^1.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/unplugin-vue-components/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/unplugin-vue-components/node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unplugin-vue-components/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vant": { + "version": "4.9.22", + "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.22.tgz", + "integrity": "sha512-P2PDSj3oB6l3W1OpVlQpapeLmI6bXMSvPqPdrw5rutslC0Y6tSkrVB/iSD57weD7K92GsjGkvgDK0eZlOsXGqw==", + "license": "MIT", + "dependencies": { + "@vant/popperjs": "^1.3.0", + "@vant/use": "^1.6.0", + "@vue/shared": "^3.5.25" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-hot-client": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/vite-hot-client/-/vite-hot-client-2.1.0.tgz", + "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "0.8.9", + "resolved": "https://registry.npmmirror.com/vite-plugin-inspect/-/vite-plugin-inspect-0.8.9.tgz", + "integrity": "sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.3", + "debug": "^4.3.7", + "error-stack-parser-es": "^0.1.5", + "fs-extra": "^11.2.0", + "open": "^10.1.0", + "perfect-debounce": "^1.0.0", + "picocolors": "^1.1.1", + "sirv": "^3.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-vue-devtools": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.9.tgz", + "integrity": "sha512-08DvePf663SxqLFJeMVNW537zzVyakp9KIrI2K7lwgaTqA5R/ydN/N2K8dgZO34tg/Qmw0ch84fOKoBtCEdcGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-core": "^7.7.9", + "@vue/devtools-kit": "^7.7.9", + "@vue/devtools-shared": "^7.7.9", + "execa": "^9.5.2", + "sirv": "^3.0.1", + "vite-plugin-inspect": "0.8.9", + "vite-plugin-vue-inspector": "^5.3.1" + }, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.4.0.tgz", + "integrity": "sha512-Iq/024CydcE46FZqWPU4t4lw4uYOdLnFSO1RNxJVt2qY9zxIjmnkBqhHnYaReWM82kmNnaXs7OkfgRrV2GEjyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.30", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.30.tgz", + "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.30", + "@vue/compiler-sfc": "3.5.30", + "@vue/runtime-dom": "3.5.30", + "@vue/server-renderer": "3.5.30", + "@vue/shared": "3.5.30" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/vue-tsc": { + "version": "2.2.12", + "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.12.tgz", + "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "2.4.15", + "@vue/language-core": "2.2.12" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/frontend/video-frontend-web/package.json b/frontend/video-frontend-web/package.json new file mode 100644 index 0000000..62a92d0 --- /dev/null +++ b/frontend/video-frontend-web/package.json @@ -0,0 +1,45 @@ +{ + "name": "video-platform-web", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview", + "lint": "eslint --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "format": "prettier --write src" + }, + "dependencies": { + "vue": "^3.4.21", + "vue-router": "^4.3.0", + "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^3.2.1", + "axios": "^1.6.8", + "vant": "^4.8.4", + "@vant/use": "^1.6.0", + "artplayer": "^5.1.7", + "artplayer-plugin-danmuku": "^5.1.0", + "dayjs": "^1.11.10", + "nprogress": "^0.2.0", + "@iconify/vue": "^4.1.1" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "@vue/tsconfig": "^0.5.1", + "vite": "^5.2.0", + "vite-plugin-vue-devtools": "^7.0.25", + "typescript": "~5.4.0", + "vue-tsc": "^2.0.6", + "sass": "^1.72.0", + "unplugin-auto-import": "^0.17.5", + "unplugin-vue-components": "^0.26.0", + "@types/node": "^20.11.30", + "@types/nprogress": "^0.2.3", + "eslint": "^8.57.0", + "eslint-plugin-vue": "^9.24.0", + "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/parser": "^7.4.0", + "prettier": "^3.2.5" + } +} diff --git a/frontend/video-frontend-web/pnpm-lock.yaml b/frontend/video-frontend-web/pnpm-lock.yaml new file mode 100644 index 0000000..685e70a --- /dev/null +++ b/frontend/video-frontend-web/pnpm-lock.yaml @@ -0,0 +1,3837 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@iconify/vue': + specifier: ^4.1.1 + version: 4.3.0(vue@3.5.30(typescript@5.4.5)) + '@vant/use': + specifier: ^1.6.0 + version: 1.6.0(vue@3.5.30(typescript@5.4.5)) + artplayer: + specifier: ^5.1.7 + version: 5.4.0 + artplayer-plugin-danmuku: + specifier: ^5.1.0 + version: 5.3.0 + axios: + specifier: ^1.6.8 + version: 1.13.6 + dayjs: + specifier: ^1.11.10 + version: 1.11.20 + nprogress: + specifier: ^0.2.0 + version: 0.2.0 + pinia: + specifier: ^2.1.7 + version: 2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)) + pinia-plugin-persistedstate: + specifier: ^3.2.1 + version: 3.2.3(pinia@2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5))) + vant: + specifier: ^4.8.4 + version: 4.9.22(vue@3.5.30(typescript@5.4.5)) + vue: + specifier: ^3.4.21 + version: 3.5.30(typescript@5.4.5) + vue-router: + specifier: ^4.3.0 + version: 4.6.4(vue@3.5.30(typescript@5.4.5)) + devDependencies: + '@types/node': + specifier: ^20.11.30 + version: 20.19.37 + '@types/nprogress': + specifier: ^0.2.3 + version: 0.2.3 + '@typescript-eslint/eslint-plugin': + specifier: ^7.4.0 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.4.0 + version: 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.2.4(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5)) + '@vue/tsconfig': + specifier: ^0.5.1 + version: 0.5.1 + eslint: + specifier: ^8.57.0 + version: 8.57.1 + eslint-plugin-vue: + specifier: ^9.24.0 + version: 9.33.0(eslint@8.57.1) + prettier: + specifier: ^3.2.5 + version: 3.8.1 + sass: + specifier: ^1.72.0 + version: 1.98.0 + typescript: + specifier: ~5.4.0 + version: 5.4.5 + unplugin-auto-import: + specifier: ^0.17.5 + version: 0.17.8(rollup@4.59.0) + unplugin-vue-components: + specifier: ^0.26.0 + version: 0.26.0(@babel/parser@7.29.0)(rollup@4.59.0)(vue@3.5.30(typescript@5.4.5)) + vite: + specifier: ^5.2.0 + version: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + vite-plugin-vue-devtools: + specifier: ^7.0.25 + version: 7.7.9(rollup@4.59.0)(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5)) + vue-tsc: + specifier: ^2.0.6 + version: 2.2.12(typescript@5.4.5) + +packages: + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==, tarball: https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==, tarball: https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==, tarball: https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==, tarball: https://registry.npmmirror.com/@babel/core/-/core-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==, tarball: https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==, tarball: https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==, tarball: https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==, tarball: https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==, tarball: https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==, tarball: https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==, tarball: https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==, tarball: https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==, tarball: https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==, tarball: https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==, tarball: https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==, tarball: https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, tarball: https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==, tarball: https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.6.tgz} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==, tarball: https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==, tarball: https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==, tarball: https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==, tarball: https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==, tarball: https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz} + engines: {node: '>=6.9.0'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==, tarball: https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==, tarball: https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==, tarball: https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==, tarball: https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==, tarball: https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, tarball: https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==, tarball: https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz} + deprecated: Use @eslint/object-schema instead + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, tarball: https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz} + + '@iconify/vue@4.3.0': + resolution: {integrity: sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==, tarball: https://registry.npmmirror.com/@iconify/vue/-/vue-4.3.0.tgz} + peerDependencies: + vue: '>=3' + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, tarball: https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==, tarball: https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, tarball: https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, tarball: https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, tarball: https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, tarball: https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, tarball: https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, tarball: https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==, tarball: https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==, tarball: https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==, tarball: https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.6.tgz} + engines: {node: '>= 10.0.0'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==, tarball: https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==, tarball: https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==, tarball: https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==, tarball: https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==, tarball: https://registry.npmmirror.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==, tarball: https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz} + engines: {node: '>=18'} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, tarball: https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz} + + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==, tarball: https://registry.npmmirror.com/@types/node/-/node-20.19.37.tgz} + + '@types/nprogress@0.2.3': + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==, tarball: https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.3.tgz} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==, tarball: https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==, tarball: https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==, tarball: https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==, tarball: https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==, tarball: https://registry.npmmirror.com/@typescript-eslint/types/-/types-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==, tarball: https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==, tarball: https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==, tarball: https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, tarball: https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz} + + '@vant/popperjs@1.3.0': + resolution: {integrity: sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==, tarball: https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz} + + '@vant/use@1.6.0': + resolution: {integrity: sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==, tarball: https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz} + peerDependencies: + vue: ^3.0.0 + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.15': + resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==, tarball: https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.15.tgz} + + '@volar/source-map@2.4.15': + resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==, tarball: https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.15.tgz} + + '@volar/typescript@2.4.15': + resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==, tarball: https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.15.tgz} + + '@vue/babel-helper-vue-transform-on@1.5.0': + resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==, tarball: https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz} + + '@vue/babel-plugin-jsx@1.5.0': + resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==, tarball: https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.5.0': + resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==, tarball: https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==, tarball: https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.30.tgz} + + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==, tarball: https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz} + + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==, tarball: https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz} + + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==, tarball: https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==, tarball: https://registry.npmmirror.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==, tarball: https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz} + + '@vue/devtools-core@7.7.9': + resolution: {integrity: sha512-48jrBSwG4GVQRvVeeXn9p9+dlx+ISgasM7SxZZKczseohB0cBz+ITKr4YbLWjmJdy45UHL7UMPlR4Y0CWTRcSQ==, tarball: https://registry.npmmirror.com/@vue/devtools-core/-/devtools-core-7.7.9.tgz} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.7.9': + resolution: {integrity: sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==, tarball: https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz} + + '@vue/devtools-shared@7.7.9': + resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==, tarball: https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz} + + '@vue/language-core@2.2.12': + resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==, tarball: https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.12.tgz} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==, tarball: https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.30.tgz} + + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==, tarball: https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.30.tgz} + + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==, tarball: https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz} + + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==, tarball: https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.30.tgz} + peerDependencies: + vue: 3.5.30 + + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==, tarball: https://registry.npmmirror.com/@vue/shared/-/shared-3.5.30.tgz} + + '@vue/tsconfig@0.5.1': + resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==, tarball: https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.5.1.tgz} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, tarball: https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==, tarball: https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==, tarball: https://registry.npmmirror.com/ajv/-/ajv-6.14.0.tgz} + + alien-signals@1.0.13: + resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==, tarball: https://registry.npmmirror.com/alien-signals/-/alien-signals-1.0.13.tgz} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, tarball: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, tarball: https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz} + engines: {node: '>=8'} + + artplayer-plugin-danmuku@5.3.0: + resolution: {integrity: sha512-a76bU1cWEZr53hD1X8IHfOzS4QawGHn8dQ3fIYyJ5TsyhTSnznhi2WzkS8M7LL3H02ekXRZTUFan9+9EERk12g==, tarball: https://registry.npmmirror.com/artplayer-plugin-danmuku/-/artplayer-plugin-danmuku-5.3.0.tgz} + + artplayer@5.4.0: + resolution: {integrity: sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==, tarball: https://registry.npmmirror.com/artplayer/-/artplayer-5.4.0.tgz} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, tarball: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz} + + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==, tarball: https://registry.npmmirror.com/axios/-/axios-1.13.6.tgz} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, tarball: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz} + + baseline-browser-mapping@2.10.8: + resolution: {integrity: sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==, tarball: https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz} + engines: {node: '>=6.0.0'} + hasBin: true + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, tarball: https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz} + engines: {node: '>=8'} + + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==, tarball: https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, tarball: https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==, tarball: https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==, tarball: https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz} + engines: {node: '>=18'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, tarball: https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, tarball: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001779: + resolution: {integrity: sha512-U5og2PN7V4DMgF50YPNtnZJGWVLFjjsN3zb6uMT5VGYIewieDj1upwfuVNXf4Kor+89c3iCRJnSzMD5LmTvsfA==, tarball: https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001779.tgz} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, tarball: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, tarball: https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, tarball: https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==, tarball: https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==, tarball: https://registry.npmmirror.com/confbox/-/confbox-0.2.4.tgz} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz} + + copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==, tarball: https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, tarball: https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, tarball: https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==, tarball: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==, tarball: https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, tarball: https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, tarball: https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==, tarball: https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.1.tgz} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==, tarball: https://registry.npmmirror.com/default-browser/-/default-browser-5.5.0.tgz} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, tarball: https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, tarball: https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, tarball: https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, tarball: https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==, tarball: https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz} + engines: {node: '>=6.0.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, tarball: https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.313: + resolution: {integrity: sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==, tarball: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, tarball: https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz} + engines: {node: '>=0.12'} + + error-stack-parser-es@0.1.5: + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==, tarball: https://registry.npmmirror.com/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, tarball: https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, tarball: https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, tarball: https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, tarball: https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, tarball: https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz} + engines: {node: '>=12'} + + eslint-plugin-vue@9.33.0: + resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==, tarball: https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, tarball: https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, tarball: https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==, tarball: https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, tarball: https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==, tarball: https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, tarball: https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, tarball: https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, tarball: https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz} + engines: {node: '>=0.10.0'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==, tarball: https://registry.npmmirror.com/execa/-/execa-9.6.1.tgz} + engines: {node: ^18.19.0 || >=20.5.0} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==, tarball: https://registry.npmmirror.com/exsolve/-/exsolve-1.0.8.tgz} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, tarball: https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, tarball: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, tarball: https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, tarball: https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, tarball: https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==, tarball: https://registry.npmmirror.com/figures/-/figures-6.1.0.tgz} + engines: {node: '>=18'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, tarball: https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, tarball: https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==, tarball: https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.4.1: + resolution: {integrity: sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==, tarball: https://registry.npmmirror.com/flatted/-/flatted-3.4.1.tgz} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==, tarball: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==, tarball: https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz} + engines: {node: '>= 6'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.4.tgz} + engines: {node: '>=14.14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, tarball: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, tarball: https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, tarball: https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, tarball: https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz} + engines: {node: '>= 0.4'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==, tarball: https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, tarball: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, tarball: https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, tarball: https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, tarball: https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, tarball: https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, tarball: https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, tarball: https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, tarball: https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, tarball: https://registry.npmmirror.com/he/-/he-1.2.0.tgz} + hasBin: true + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, tarball: https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-8.0.1.tgz} + engines: {node: '>=18.18.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, tarball: https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz} + engines: {node: '>= 4'} + + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==, tarball: https://registry.npmmirror.com/immutable/-/immutable-5.1.5.tgz} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, tarball: https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, tarball: https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, tarball: https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, tarball: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, tarball: https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==, tarball: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, tarball: https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, tarball: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, tarball: https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, tarball: https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, tarball: https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz} + engines: {node: '>=12'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz} + engines: {node: '>=18'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==, tarball: https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz} + engines: {node: '>=18'} + + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==, tarball: https://registry.npmmirror.com/is-what/-/is-what-5.5.0.tgz} + engines: {node: '>=18'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==, tarball: https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.1.tgz} + engines: {node: '>=16'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, tarball: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==, tarball: https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==, tarball: https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, tarball: https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, tarball: https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, tarball: https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, tarball: https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, tarball: https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==, tarball: https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, tarball: https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, tarball: https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz} + engines: {node: '>=0.10.0'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==, tarball: https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, tarball: https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz} + engines: {node: '>= 0.8.0'} + + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz} + engines: {node: '>=14'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.1.tgz} + engines: {node: '>=14'} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==, tarball: https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, tarball: https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==, tarball: https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, tarball: https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, tarball: https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, tarball: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz} + engines: {node: '>= 0.6'} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.9.tgz} + engines: {node: '>=16 || 14 >=14.17'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==, tarball: https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz} + + mlly@1.8.1: + resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==, tarball: https://registry.npmmirror.com/mlly/-/mlly-1.8.1.tgz} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==, tarball: https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==, tarball: https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.7: + resolution: {integrity: sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-5.1.7.tgz} + engines: {node: ^18 || >=20} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, tarball: https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==, tarball: https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz} + + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==, tarball: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.36.tgz} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz} + engines: {node: '>=0.10.0'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-6.0.0.tgz} + engines: {node: '>=18'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==, tarball: https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, tarball: https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, tarball: https://registry.npmmirror.com/once/-/once-1.4.0.tgz} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==, tarball: https://registry.npmmirror.com/open/-/open-10.2.0.tgz} + engines: {node: '>=18'} + + option-validator@2.0.6: + resolution: {integrity: sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==, tarball: https://registry.npmmirror.com/option-validator/-/option-validator-2.0.6.tgz} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, tarball: https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, tarball: https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, tarball: https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz} + engines: {node: '>=6'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==, tarball: https://registry.npmmirror.com/parse-ms/-/parse-ms-4.0.0.tgz} + engines: {node: '>=18'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==, tarball: https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, tarball: https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, tarball: https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, tarball: https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, tarball: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, tarball: https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==, tarball: https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz} + engines: {node: '>=12'} + + pinia-plugin-persistedstate@3.2.3: + resolution: {integrity: sha512-Cm819WBj/s5K5DGw55EwbXDtx+EZzM0YR5AZbq9XE3u0xvXwvX2JnWoFpWIcdzISBHqy9H1UiSIUmXyXqWsQRQ==, tarball: https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.3.tgz} + peerDependencies: + pinia: ^2.0.0 + + pinia@2.3.1: + resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==, tarball: https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz} + peerDependencies: + typescript: '>=4.4.4' + vue: ^2.7.0 || ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==, tarball: https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==, tarball: https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==, tarball: https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz} + engines: {node: '>=4'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.5.8.tgz} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, tarball: https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz} + engines: {node: '>= 0.8.0'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==, tarball: https://registry.npmmirror.com/prettier/-/prettier-3.8.1.tgz} + engines: {node: '>=14'} + hasBin: true + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==, tarball: https://registry.npmmirror.com/pretty-ms/-/pretty-ms-9.3.0.tgz} + engines: {node: '>=18'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, tarball: https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, tarball: https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz} + engines: {node: '>=6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, tarball: https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz} + engines: {node: '>= 14.18.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, tarball: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz} + engines: {node: '>=4'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==, tarball: https://registry.npmmirror.com/resolve/-/resolve-1.22.11.tgz} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, tarball: https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, tarball: https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, tarball: https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==, tarball: https://registry.npmmirror.com/rollup/-/rollup-4.59.0.tgz} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==, tarball: https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, tarball: https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz} + + sass@1.98.0: + resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==, tarball: https://registry.npmmirror.com/sass/-/sass-1.98.0.tgz} + engines: {node: '>=14.0.0'} + hasBin: true + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==, tarball: https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, tarball: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==, tarball: https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, tarball: https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz} + engines: {node: '>=14'} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==, tarball: https://registry.npmmirror.com/sirv/-/sirv-3.0.2.tgz} + engines: {node: '>=18'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, tarball: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, tarball: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz} + engines: {node: '>=0.10.0'} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==, tarball: https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz} + engines: {node: '>=8'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, tarball: https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz} + engines: {node: '>=8'} + + strip-literal@2.1.1: + resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==, tarball: https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.1.tgz} + + superjson@2.2.6: + resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==, tarball: https://registry.npmmirror.com/superjson/-/superjson-2.2.6.tgz} + engines: {node: '>=16'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, tarball: https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz} + engines: {node: '>= 0.4'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, tarball: https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==, tarball: https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz} + engines: {node: '>=6'} + + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==, tarball: https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, tarball: https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz} + engines: {node: '>=10'} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==, tarball: https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==, tarball: https://registry.npmmirror.com/ufo/-/ufo-1.6.3.tgz} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==, tarball: https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==, tarball: https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz} + engines: {node: '>=18'} + + unimport@3.14.6: + resolution: {integrity: sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==, tarball: https://registry.npmmirror.com/unimport/-/unimport-3.14.6.tgz} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, tarball: https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz} + engines: {node: '>= 10.0.0'} + + unplugin-auto-import@0.17.8: + resolution: {integrity: sha512-CHryj6HzJ+n4ASjzwHruD8arhbdl+UXvhuAIlHDs15Y/IMecG3wrf7FVg4pVH/DIysbq/n0phIjNHAjl7TG7Iw==, tarball: https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.17.8.tgz} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^3.2.2 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-vue-components@0.26.0: + resolution: {integrity: sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==, tarball: https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.26.0.tgz} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==, tarball: https://registry.npmmirror.com/unplugin/-/unplugin-1.16.1.tgz} + engines: {node: '>=14.0.0'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==, tarball: https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, tarball: https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, tarball: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz} + + vant@4.9.22: + resolution: {integrity: sha512-P2PDSj3oB6l3W1OpVlQpapeLmI6bXMSvPqPdrw5rutslC0Y6tSkrVB/iSD57weD7K92GsjGkvgDK0eZlOsXGqw==, tarball: https://registry.npmmirror.com/vant/-/vant-4.9.22.tgz} + peerDependencies: + vue: ^3.0.0 + + vite-hot-client@2.1.0: + resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==, tarball: https://registry.npmmirror.com/vite-hot-client/-/vite-hot-client-2.1.0.tgz} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + + vite-plugin-inspect@0.8.9: + resolution: {integrity: sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==, tarball: https://registry.npmmirror.com/vite-plugin-inspect/-/vite-plugin-inspect-0.8.9.tgz} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-devtools@7.7.9: + resolution: {integrity: sha512-08DvePf663SxqLFJeMVNW537zzVyakp9KIrI2K7lwgaTqA5R/ydN/N2K8dgZO34tg/Qmw0ch84fOKoBtCEdcGg==, tarball: https://registry.npmmirror.com/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.9.tgz} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + + vite-plugin-vue-inspector@5.4.0: + resolution: {integrity: sha512-Iq/024CydcE46FZqWPU4t4lw4uYOdLnFSO1RNxJVt2qY9zxIjmnkBqhHnYaReWM82kmNnaXs7OkfgRrV2GEjyw==, tarball: https://registry.npmmirror.com/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.4.0.tgz} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==, tarball: https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==, tarball: https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==, tarball: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==, tarball: https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==, tarball: https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz} + peerDependencies: + vue: ^3.5.0 + + vue-tsc@2.2.12: + resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==, tarball: https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.12.tgz} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.30: + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==, tarball: https://registry.npmmirror.com/vue/-/vue-3.5.30.tgz} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==, tarball: https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmmirror.com/which/-/which-2.0.2.tgz} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, tarball: https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, tarball: https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz} + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==, tarball: https://registry.npmmirror.com/wsl-utils/-/wsl-utils-0.1.0.tgz} + engines: {node: '>=18'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, tarball: https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz} + engines: {node: '>=12'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, tarball: https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, tarball: https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz} + engines: {node: '>=10'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==, tarball: https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.1.2.tgz} + engines: {node: '>=18'} + +snapshots: + + '@antfu/utils@0.7.10': {} + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iconify/types@2.0.0': {} + + '@iconify/vue@4.3.0(vue@3.5.30(typescript@5.4.5))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.5.30(typescript@5.4.5) + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.59.0 + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@types/estree@1.0.8': {} + + '@types/node@20.19.37': + dependencies: + undici-types: 6.21.0 + + '@types/nprogress@0.2.3': {} + + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5))(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.4.5) + debug: 4.4.3 + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.9 + semver: 7.7.4 + ts-api-utils: 1.4.3(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.3.0': {} + + '@vant/popperjs@1.3.0': {} + + '@vant/use@1.6.0(vue@3.5.30(typescript@5.4.5))': + dependencies: + vue: 3.5.30(typescript@5.4.5) + + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5))': + dependencies: + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + vue: 3.5.30(typescript@5.4.5) + + '@volar/language-core@2.4.15': + dependencies: + '@volar/source-map': 2.4.15 + + '@volar/source-map@2.4.15': {} + + '@volar/typescript@2.4.15': + dependencies: + '@volar/language-core': 2.4.15 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/babel-helper-vue-transform-on@1.5.0': {} + + '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@vue/babel-helper-vue-transform-on': 1.5.0 + '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.29.0) + '@vue/shared': 3.5.30 + optionalDependencies: + '@babel/core': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/parser': 7.29.0 + '@vue/compiler-sfc': 3.5.30 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.30': + dependencies: + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.30': + dependencies: + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/compiler-sfc@3.5.30': + dependencies: + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.8 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.30': + dependencies: + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-core@7.7.9(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5))': + dependencies: + '@vue/devtools-kit': 7.7.9 + '@vue/devtools-shared': 7.7.9 + mitt: 3.0.1 + nanoid: 5.1.7 + pathe: 2.0.3 + vite-hot-client: 2.1.0(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)) + vue: 3.5.30(typescript@5.4.5) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.7.9': + dependencies: + '@vue/devtools-shared': 7.7.9 + birpc: 2.9.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.6 + + '@vue/devtools-shared@7.7.9': + dependencies: + rfdc: 1.4.1 + + '@vue/language-core@2.2.12(typescript@5.4.5)': + dependencies: + '@volar/language-core': 2.4.15 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.30 + alien-signals: 1.0.13 + minimatch: 9.0.9 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.4.5 + + '@vue/reactivity@3.5.30': + dependencies: + '@vue/shared': 3.5.30 + + '@vue/runtime-core@3.5.30': + dependencies: + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 + + '@vue/runtime-dom@3.5.30': + dependencies: + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@5.4.5))': + dependencies: + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + vue: 3.5.30(typescript@5.4.5) + + '@vue/shared@3.5.30': {} + + '@vue/tsconfig@0.5.1': {} + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + alien-signals@1.0.13: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + artplayer-plugin-danmuku@5.3.0: {} + + artplayer@5.4.0: + dependencies: + option-validator: 2.0.6 + + asynckit@0.4.0: {} + + axios@1.13.6: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.10.8: {} + + binary-extensions@2.3.0: {} + + birpc@2.9.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.8 + caniuse-lite: 1.0.30001779 + electron-to-chromium: 1.5.313 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001779: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + convert-source-map@2.0.0: {} + + copy-anything@4.0.5: + dependencies: + is-what: 5.5.0 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + dayjs@1.11.20: {} + + de-indent@1.0.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: + optional: true + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.313: {} + + entities@7.0.1: {} + + error-stack-parser-es@0.1.5: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-plugin-vue@9.33.0(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + eslint: 8.57.1 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.4 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + exsolve@1.0.8: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.4.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.4.1: {} + + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + hookable@5.5.3: {} + + human-signals@8.0.1: {} + + ignore@5.3.2: {} + + immutable@5.1.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@4.1.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + is-what@5.5.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isexe@2.0.0: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + kolorist@1.8.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + local-pkg@0.4.3: {} + + local-pkg@0.5.1: + dependencies: + mlly: 1.8.1 + pkg-types: 1.3.1 + + local-pkg@1.1.2: + dependencies: + mlly: 1.8.1 + pkg-types: 2.3.0 + quansync: 0.2.11 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.23: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + + mitt@3.0.1: {} + + mlly@1.8.1: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.11: {} + + nanoid@5.1.7: {} + + natural-compare@1.4.0: {} + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.36: {} + + normalize-path@3.0.0: {} + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + option-validator@2.0.6: + dependencies: + kind-of: 6.0.3 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-ms@4.0.0: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pinia-plugin-persistedstate@3.2.3(pinia@2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5))): + dependencies: + pinia: 2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)) + + pinia@2.3.1(typescript@5.4.5)(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.30(typescript@5.4.5) + vue-demi: 0.14.10(vue@3.5.30(typescript@5.4.5)) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - '@vue/composition-api' + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.1 + pathe: 2.0.3 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.1: {} + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + resolve-from@4.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sass@1.98.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + scule@1.3.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + slash@3.0.0: {} + + source-map-js@1.2.1: {} + + speakingurl@14.0.1: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + + strip-literal@2.1.1: + dependencies: + js-tokens: 9.0.1 + + superjson@2.2.6: + dependencies: + copy-anything: 4.0.5 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + text-table@0.2.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + ts-api-utils@1.4.3(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typescript@5.4.5: {} + + ufo@1.6.3: {} + + undici-types@6.21.0: {} + + unicorn-magic@0.3.0: {} + + unimport@3.14.6(rollup@4.59.0): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + acorn: 8.16.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.1 + pathe: 2.0.3 + picomatch: 4.0.3 + pkg-types: 1.3.1 + scule: 1.3.0 + strip-literal: 2.1.1 + unplugin: 1.16.1 + transitivePeerDependencies: + - rollup + + universalify@2.0.1: {} + + unplugin-auto-import@0.17.8(rollup@4.59.0): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + fast-glob: 3.3.3 + local-pkg: 0.5.1 + magic-string: 0.30.21 + minimatch: 9.0.9 + unimport: 3.14.6(rollup@4.59.0) + unplugin: 1.16.1 + transitivePeerDependencies: + - rollup + + unplugin-vue-components@0.26.0(@babel/parser@7.29.0)(rollup@4.59.0)(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + chokidar: 3.6.0 + debug: 4.4.3 + fast-glob: 3.3.3 + local-pkg: 0.4.3 + magic-string: 0.30.21 + minimatch: 9.0.9 + resolve: 1.22.11 + unplugin: 1.16.1 + vue: 3.5.30(typescript@5.4.5) + optionalDependencies: + '@babel/parser': 7.29.0 + transitivePeerDependencies: + - rollup + - supports-color + + unplugin@1.16.1: + dependencies: + acorn: 8.16.0 + webpack-virtual-modules: 0.6.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vant@4.9.22(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vant/popperjs': 1.3.0 + '@vant/use': 1.6.0(vue@3.5.30(typescript@5.4.5)) + '@vue/shared': 3.5.30 + vue: 3.5.30(typescript@5.4.5) + + vite-hot-client@2.1.0(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)): + dependencies: + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + + vite-plugin-inspect@0.8.9(rollup@4.59.0)(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + debug: 4.4.3 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.4 + open: 10.2.0 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.2 + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + transitivePeerDependencies: + - rollup + - supports-color + + vite-plugin-vue-devtools@7.7.9(rollup@4.59.0)(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vue/devtools-core': 7.7.9(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0))(vue@3.5.30(typescript@5.4.5)) + '@vue/devtools-kit': 7.7.9 + '@vue/devtools-shared': 7.7.9 + execa: 9.6.1 + sirv: 3.0.2 + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + vite-plugin-inspect: 0.8.9(rollup@4.59.0)(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)) + vite-plugin-vue-inspector: 5.4.0(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)) + transitivePeerDependencies: + - '@nuxt/kit' + - rollup + - supports-color + - vue + + vite-plugin-vue-inspector@5.4.0(vite@5.4.21(@types/node@20.19.37)(sass@1.98.0)): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) + '@vue/compiler-dom': 3.5.30 + kolorist: 1.8.0 + magic-string: 0.30.21 + vite: 5.4.21(@types/node@20.19.37)(sass@1.98.0) + transitivePeerDependencies: + - supports-color + + vite@5.4.21(@types/node@20.19.37)(sass@1.98.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.59.0 + optionalDependencies: + '@types/node': 20.19.37 + fsevents: 2.3.3 + sass: 1.98.0 + + vscode-uri@3.1.0: {} + + vue-demi@0.14.10(vue@3.5.30(typescript@5.4.5)): + dependencies: + vue: 3.5.30(typescript@5.4.5) + + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.4.3 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + lodash: 4.17.23 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + vue-router@4.6.4(vue@3.5.30(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.30(typescript@5.4.5) + + vue-tsc@2.2.12(typescript@5.4.5): + dependencies: + '@volar/typescript': 2.4.15 + '@vue/language-core': 2.2.12(typescript@5.4.5) + typescript: 5.4.5 + + vue@3.5.30(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@5.4.5)) + '@vue/shared': 3.5.30 + optionalDependencies: + typescript: 5.4.5 + + webpack-virtual-modules@0.6.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + + xml-name-validator@4.0.0: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + yoctocolors@2.1.2: {} diff --git a/frontend/video-frontend-web/public/favicon.svg b/frontend/video-frontend-web/public/favicon.svg new file mode 100644 index 0000000..ab779b7 --- /dev/null +++ b/frontend/video-frontend-web/public/favicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/frontend/video-frontend-web/src/App.vue b/frontend/video-frontend-web/src/App.vue new file mode 100644 index 0000000..eaff539 --- /dev/null +++ b/frontend/video-frontend-web/src/App.vue @@ -0,0 +1,14 @@ + + + + + diff --git a/frontend/video-frontend-web/src/api/auth.ts b/frontend/video-frontend-web/src/api/auth.ts new file mode 100644 index 0000000..3ce1e8b --- /dev/null +++ b/frontend/video-frontend-web/src/api/auth.ts @@ -0,0 +1,62 @@ +import request from '@/utils/request.ts' +import type { + LoginParams, + LoginResult, + RegisterParams, + CaptchaResult, + AuthUser +} from '@/types' + +/** + * 认证相关 API + */ +export const authApi = { + /** + * 用户登录 + */ + login(params: LoginParams): Promise { + return request.post('/auth/login', params) + }, + + /** + * 用户注册 + */ + register(params: RegisterParams): Promise { + return request.post('/auth/register', params) + }, + + /** + * 获取验证码 + */ + getCaptcha(): Promise { + return request.get('/auth/captcha') + }, + + /** + * 刷新 Token + */ + refreshToken(refreshToken: string): Promise { + return request.post('/auth/refresh', { refreshToken }) + }, + + /** + * 用户登出 + */ + logout(): Promise { + return request.post('/auth/logout') + }, + + /** + * 获取当前用户信息 + */ + getCurrentUser(): Promise { + return request.get('/auth/current') + }, + + /** + * 根据用户ID获取用户名 + */ + getUsername(userId: number): Promise { + return request.get(`/auth/username/${userId}`) + } +} diff --git a/frontend/video-frontend-web/src/api/category.ts b/frontend/video-frontend-web/src/api/category.ts new file mode 100644 index 0000000..80ee691 --- /dev/null +++ b/frontend/video-frontend-web/src/api/category.ts @@ -0,0 +1,47 @@ +import request from '@/utils/request.ts' +import type { Category, Tag, PageResult, PageParams } from '@/types' + +/** + * 分类相关 API + */ +export const categoryApi = { + /** + * 获取分类树 + */ + getCategoryTree(): Promise { + return request.get('/content/category/tree') + }, + + /** + * 获取分类列表 + */ + getCategoryList(): Promise { + return request.get('/content/category/list') + } +} + +/** + * 标签相关 API + */ +export const tagApi = { + /** + * 获取标签列表 + */ + getTagList(): Promise { + return request.get('/content/tag/list') + }, + + /** + * 分页获取标签 + */ + getTagPage(params?: PageParams): Promise> { + return request.get('/content/tag/page', params) + }, + + /** + * 获取视频标签 + */ + getVideoTags(videoId: number): Promise { + return request.get(`/content/tag/video/${videoId}`) + } +} diff --git a/frontend/video-frontend-web/src/api/comment.ts b/frontend/video-frontend-web/src/api/comment.ts new file mode 100644 index 0000000..c395f31 --- /dev/null +++ b/frontend/video-frontend-web/src/api/comment.ts @@ -0,0 +1,114 @@ +import request from '@/utils/request.ts' +import type { Comment, CommentSendParams, CommentQueryParams, PageResult } from '@/types' + +/** + * 评论相关 API + */ +export const commentApi = { + /** + * 发表评论 + */ + addComment(params: CommentSendParams): Promise { + return request.post('/comment', params) + }, + + /** + * 获取评论列表(公开接口) + */ + getCommentList(params: CommentQueryParams): Promise> { + return request.get('/comment/public/list', params) + }, + + /** + * 获取评论详情(公开接口) + */ + getCommentDetail(id: number): Promise { + return request.get(`/comment/public/detail/${id}`) + }, + + /** + * 删除评论 + */ + deleteComment(id: number): Promise { + return request.delete(`/comment/${id}`) + }, + + /** + * 点赞评论 + */ + likeComment(id: number): Promise { + return request.post(`/comment/like/${id}`) + }, + + /** + * 取消点赞评论 + */ + unlikeComment(id: number): Promise { + return request.delete(`/comment/like/${id}`) + }, + + /** + * 置顶评论 + */ + topComment(id: number): Promise { + return request.post(`/comment/top/${id}`) + }, + + /** + * 取消置顶评论 + */ + untopComment(id: number): Promise { + return request.delete(`/comment/top/${id}`) + }, + + /** + * 获取评论统计信息(公开接口) + */ + getCommentStat(videoId: number): Promise<{ total: number; hotCount: number }> { + return request.get(`/comment/public/stat/${videoId}`) + }, + + // ==================== 回复相关 ==================== + + /** + * 添加回复 + */ + addReply(params: { commentId: number; content: string; replyId?: number }): Promise { + return request.post('/comment/reply', params) + }, + + /** + * 获取评论的回复列表(公开接口) + */ + getReplyList(commentId: number, params?: { page?: number; size?: number }): Promise> { + return request.get(`/comment/reply/public/list/${commentId}`, params) + }, + + /** + * 获取评论的热门回复(公开接口) + */ + getHotReplies(commentId: number, limit?: number): Promise { + return request.get(`/comment/reply/public/hot/${commentId}`, { limit }) + }, + + /** + * 删除回复 + */ + deleteReply(id: number): Promise { + return request.delete(`/comment/reply/${id}`) + }, + + /** + * 点赞回复 + */ + likeReply(id: number): Promise { + return request.post(`/comment/reply/like/${id}`) + }, + + /** + * 取消点赞回复 + */ + unlikeReply(id: number): Promise { + return request.delete(`/comment/reply/like/${id}`) + } +} diff --git a/frontend/video-frontend-web/src/api/danmaku.ts b/frontend/video-frontend-web/src/api/danmaku.ts new file mode 100644 index 0000000..ff0813d --- /dev/null +++ b/frontend/video-frontend-web/src/api/danmaku.ts @@ -0,0 +1,28 @@ +import request from '@/utils/request.ts' +import type { Danmaku, DanmakuSendParams } from '@/types' + +/** + * 弹幕相关 API + */ +export const danmakuApi = { + /** + * 发送弹幕 + */ + sendDanmaku(params: DanmakuSendParams): Promise { + return request.post('/content/danmaku', params) + }, + + /** + * 获取视频指定时间段的弹幕 + */ + getDanmakuByTime(videoId: number, startTime: number, endTime: number): Promise { + return request.get('/content/danmaku/time', { videoId, startTime, endTime }) + }, + + /** + * 获取视频所有弹幕 + */ + getAllDanmaku(videoId: number): Promise { + return request.get(`/content/danmaku/all/${videoId}`) + } +} diff --git a/frontend/video-frontend-web/src/api/favorite.ts b/frontend/video-frontend-web/src/api/favorite.ts new file mode 100644 index 0000000..3567d2e --- /dev/null +++ b/frontend/video-frontend-web/src/api/favorite.ts @@ -0,0 +1,42 @@ +import request from '@/utils/request.ts' +import type { Favorite, FavoriteCreateParams, FavoriteVideoParams, VideoInfo, PageResult, PageParams } from '@/types' + +/** + * 收藏夹相关 API + */ +export const favoriteApi = { + /** + * 获取用户收藏夹列表 + */ + getFavoriteList(): Promise { + return request.get('/content/favorite/list') + }, + + /** + * 创建收藏夹 + */ + createFavorite(params: FavoriteCreateParams): Promise { + return request.post('/content/favorite', params) + }, + + /** + * 更新收藏夹 + */ + updateFavorite(params: Partial & { id: number }): Promise { + return request.put('/content/favorite', params) + }, + + /** + * 删除收藏夹 + */ + deleteFavorite(id: number): Promise { + return request.delete(`/content/favorite/${id}`) + }, + + /** + * 获取收藏夹中的视频 + */ + getFavoriteVideos(favoriteId: number, params?: PageParams): Promise> { + return request.get(`/content/favorite/${favoriteId}/videos`, params) + } +} diff --git a/frontend/video-frontend-web/src/api/index.ts b/frontend/video-frontend-web/src/api/index.ts new file mode 100644 index 0000000..b7f0b9e --- /dev/null +++ b/frontend/video-frontend-web/src/api/index.ts @@ -0,0 +1,30 @@ +import request from '@/utils/request.ts' + +/** + * 文件上传 API + */ +export const uploadApi = { + /** + * 上传图片 + */ + uploadImage(file: File, onProgress?: (percent: number) => void): Promise { + return request.upload('/user/profile/avatar', file, onProgress) + }, + + /** + * 上传视频 + */ + uploadVideo(file: File, onProgress?: (percent: number) => void): Promise<{ videoUrl: string; coverUrl: string }> { + return request.upload('/content/video/upload', file, onProgress) + } +} + +// 导出所有 API +export * from './auth.ts' +export * from './user.ts' +export * from './video.ts' +export * from './comment.ts' +export * from './category.ts' +export * from './danmaku.ts' +export * from './favorite.ts' +export * from './recommend.ts' diff --git a/frontend/video-frontend-web/src/api/recommend.ts b/frontend/video-frontend-web/src/api/recommend.ts new file mode 100644 index 0000000..9795cd1 --- /dev/null +++ b/frontend/video-frontend-web/src/api/recommend.ts @@ -0,0 +1,52 @@ +import request from '@/utils/request.ts' +import type { VideoInfo, RecommendVideo } from '@/types' + +/** + * 推荐相关 API + */ +export const recommendApi = { + /** + * 获取首页推荐 + */ + getHomeRecommend(limit?: number): Promise { + return request.get('/recommend/home', { limit }) + }, + + /** + * 获取热门推荐 + */ + getHotRecommend(params?: { page?: number; size?: number }): Promise { + return request.get('/recommend/hot', params) + }, + + /** + * 获取相似视频推荐 + */ + getSimilarVideos(videoId: number, limit?: number): Promise { + return request.get(`/recommend/similar/${videoId}`, { limit }) + }, + + /** + * 获取标签视频推荐 + */ + getTagVideos(tagId: number, params?: { page?: number; size?: number }): Promise { + return request.get(`/recommend/tag/${tagId}`, params) + }, + + /** + * 记录用户行为 + */ + recordBehavior(params: { + videoId: number + actionType: 'view' | 'like' | 'coin' | 'favorite' | 'share' | 'comment' + }): Promise { + return request.post('/recommend/behavior', params) + }, + + /** + * 更新用户兴趣 + */ + updateInterest(params: { tagIds: number[] }): Promise { + return request.post('/recommend/interest/update', params) + } +} diff --git a/frontend/video-frontend-web/src/api/user.ts b/frontend/video-frontend-web/src/api/user.ts new file mode 100644 index 0000000..5d05031 --- /dev/null +++ b/frontend/video-frontend-web/src/api/user.ts @@ -0,0 +1,183 @@ +import request from '@/utils/request.ts' +import type { + UserInfo, + UserProfileUpdateParams, + UserFollow, + UserSetting, + Message, + MessageSendParams, + Notification, + PageParams, + PageResult +} from '@/types' + +/** + * 用户相关 API + */ +export const userApi = { + // ==================== 用户资料 ==================== + + /** + * 获取当前用户资料 + */ + getCurrentProfile(): Promise { + return request.get('/user/profile/current') + }, + + /** + * 获取指定用户资料 + */ + getPublicProfile(userId: number): Promise { + return request.get(`/user/profile/public/${userId}`) + }, + + /** + * 更新用户资料 + */ + updateProfile(params: UserProfileUpdateParams): Promise { + return request.put('/user/profile', params) + }, + + /** + * 上传头像 + */ + uploadAvatar(file: File, onProgress?: (percent: number) => void): Promise { + return request.upload('/user/profile/avatar', file, onProgress) + }, + + /** + * 搜索用户 + */ + searchUsers(keyword: string, params?: PageParams): Promise> { + return request.get('/user/profile/search', { keyword, ...params }) + }, + + // ==================== 用户关注 ==================== + + /** + * 关注用户 + */ + follow(followId: number): Promise { + return request.post(`/user/follow/${followId}`) + }, + + /** + * 取消关注 + */ + unfollow(followId: number): Promise { + return request.delete(`/user/follow/${followId}`) + }, + + /** + * 获取关注列表 + */ + getFollowing(userId: number, params?: PageParams): Promise { + return request.get(`/user/follow/following/${userId}`, params) + }, + + /** + * 获取粉丝列表 + */ + getFollowers(userId: number, params?: PageParams): Promise { + return request.get(`/user/follow/followers/${userId}`, params) + }, + + /** + * 检查是否已关注 + */ + checkFollow(followId: number): Promise { + return request.get(`/user/follow/check/${followId}`) + }, + + // 兼容旧名称 + followUser: function(followId: number): Promise { + return this.follow(followId) + }, + + unfollowUser: function(followId: number): Promise { + return this.unfollow(followId) + }, + + // ==================== 用户私信 ==================== + + /** + * 发送私信 + */ + sendMessage(params: MessageSendParams): Promise { + return request.post('/user/message', params) + }, + + /** + * 获取私信会话列表 + */ + getMessageList(params?: PageParams): Promise { + return request.get('/user/message/list', params) + }, + + /** + * 获取与指定用户的私信记录 + */ + getMessageDetail(targetId: number, params?: PageParams): Promise { + return request.get(`/user/message/detail/${targetId}`, params) + }, + + /** + * 标记私信为已读 + */ + markMessageRead(senderId: number): Promise { + return request.put(`/user/message/read/${senderId}`) + }, + + /** + * 获取未读私信数量 + */ + getUnreadMessageCount(): Promise { + return request.get('/user/message/unread/count') + }, + + // ==================== 用户通知 ==================== + + /** + * 获取通知列表 + */ + getNotifications(type?: number, params?: PageParams): Promise { + return request.get('/user/notification/list', { type, ...params }) + }, + + /** + * 标记所有通知为已读 + */ + markAllNotificationsRead(): Promise { + return request.put('/user/notification/read') + }, + + /** + * 标记指定通知为已读 + */ + markNotificationRead(notificationId: number): Promise { + return request.put(`/user/notification/read/${notificationId}`) + }, + + /** + * 获取未读通知数量 + */ + getUnreadNotificationCount(): Promise { + return request.get('/user/notification/unread/count') + }, + + // ==================== 用户设置 ==================== + + /** + * 获取用户设置 + */ + getSettings(): Promise { + return request.get('/user/setting') + }, + + /** + * 更新用户设置 + */ + updateSettings(params: Partial): Promise { + return request.put('/user/setting', params) + } +} diff --git a/frontend/video-frontend-web/src/api/video.ts b/frontend/video-frontend-web/src/api/video.ts new file mode 100644 index 0000000..d68b9e2 --- /dev/null +++ b/frontend/video-frontend-web/src/api/video.ts @@ -0,0 +1,142 @@ +import request from '@/utils/request.ts' +import type { + VideoInfo, + VideoCreateParams, + VideoUpdateParams, + VideoQueryParams, + VideoUploadParams, + PlayRecord, + PageResult +} from '@/types' + +/** + * 视频相关 API + */ +export const videoApi = { + // ==================== 视频上传 ==================== + + /** + * 上传视频文件 + */ + uploadVideo(params: VideoUploadParams): Promise<{ videoUrl: string; coverUrl: string }> { + return request.upload('/content/video/upload', params.file, params.onProgress) + }, + + /** + * 创建视频记录 + */ + createVideo(params: VideoCreateParams): Promise { + return request.post('/content/video', params) + }, + + // ==================== 视频查询 ==================== + + /** + * 获取视频详情(公开接口) + */ + getVideoPublic(id: number): Promise { + return request.get(`/content/video/public/${id}`) + }, + + /** + * 获取视频列表(公开接口) + */ + getVideoPublicList(params?: VideoQueryParams): Promise> { + return request.get('/content/video/public/list', params) + }, + + /** + * 获取视频详情(需登录) + */ + getVideo(id: number): Promise { + return request.get(`/content/video/${id}`) + }, + + /** + * 获取视频列表(需登录) + */ + getVideoList(params?: VideoQueryParams): Promise> { + return request.get('/content/video/list', params) + }, + + /** + * 获取用户视频列表 + */ + getUserVideos(userId: number, params?: VideoQueryParams): Promise> { + return request.get(`/content/video/user/${userId}`, params) + }, + + // ==================== 视频管理 ==================== + + /** + * 更新视频信息 + */ + updateVideo(params: VideoUpdateParams): Promise { + return request.put('/content/video', params) + }, + + /** + * 删除视频 + */ + deleteVideo(id: number): Promise { + return request.delete(`/content/video/${id}`) + }, + + // ==================== 视频互动 ==================== + + /** + * 点赞视频 + */ + likeVideo(videoId: number): Promise { + return request.post(`/content/video/like/${videoId}`) + }, + + /** + * 取消点赞 + */ + unlikeVideo(videoId: number): Promise { + return request.delete(`/content/video/like/${videoId}`) + }, + + /** + * 投币 + */ + coinVideo(videoId: number): Promise { + return request.post(`/content/video/coin/${videoId}`) + }, + + /** + * 收藏视频 + */ + favoriteVideo(videoId: number, favoriteId: number): Promise { + return request.post('/content/video/favorite', { videoId, favoriteId }) + }, + + /** + * 取消收藏 + */ + unfavoriteVideo(videoId: number): Promise { + return request.delete(`/content/video/favorite/${videoId}`) + }, + + /** + * 分享视频 + */ + shareVideo(videoId: number): Promise { + return request.post(`/content/video/share/${videoId}`) + }, + + /** + * 记录播放 + */ + recordPlay(params: PlayRecord): Promise { + return request.post('/content/video/play', params) + }, + + /** + * 增加评论数量(内部接口) + */ + incrementCommentCount(videoId: number, count: number): Promise { + return request.post(`/content/video/count/comment/${videoId}/${count}`) + } +} diff --git a/frontend/video-frontend-web/src/auto-imports.d.ts b/frontend/video-frontend-web/src/auto-imports.d.ts new file mode 100644 index 0000000..bd2e482 --- /dev/null +++ b/frontend/video-frontend-web/src/auto-imports.d.ts @@ -0,0 +1,177 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAppStore: typeof import('./stores')['useAppStore'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useFavoriteStore: typeof import('./stores')['useFavoriteStore'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useMessageStore: typeof import('./stores/message.ts')['useMessageStore'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const useUserStore: typeof import('./stores/user.ts')['useUserStore'] + const useVideoStore: typeof import('./stores/video.ts')['useVideoStore'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} +// for vue template auto import +import { UnwrapRef } from 'vue' +declare module 'vue' { + interface GlobalComponents {} + interface ComponentCustomProperties { + readonly EffectScope: UnwrapRef + readonly acceptHMRUpdate: UnwrapRef + readonly computed: UnwrapRef + readonly createApp: UnwrapRef + readonly createPinia: UnwrapRef + readonly customRef: UnwrapRef + readonly defineAsyncComponent: UnwrapRef + readonly defineComponent: UnwrapRef + readonly defineStore: UnwrapRef + readonly effectScope: UnwrapRef + readonly getActivePinia: UnwrapRef + readonly getCurrentInstance: UnwrapRef + readonly getCurrentScope: UnwrapRef + readonly h: UnwrapRef + readonly inject: UnwrapRef + readonly isProxy: UnwrapRef + readonly isReactive: UnwrapRef + readonly isReadonly: UnwrapRef + readonly isRef: UnwrapRef + readonly mapActions: UnwrapRef + readonly mapGetters: UnwrapRef + readonly mapState: UnwrapRef + readonly mapStores: UnwrapRef + readonly mapWritableState: UnwrapRef + readonly markRaw: UnwrapRef + readonly nextTick: UnwrapRef + readonly onActivated: UnwrapRef + readonly onBeforeMount: UnwrapRef + readonly onBeforeRouteLeave: UnwrapRef + readonly onBeforeRouteUpdate: UnwrapRef + readonly onBeforeUnmount: UnwrapRef + readonly onBeforeUpdate: UnwrapRef + readonly onDeactivated: UnwrapRef + readonly onErrorCaptured: UnwrapRef + readonly onMounted: UnwrapRef + readonly onRenderTracked: UnwrapRef + readonly onRenderTriggered: UnwrapRef + readonly onScopeDispose: UnwrapRef + readonly onServerPrefetch: UnwrapRef + readonly onUnmounted: UnwrapRef + readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef + readonly provide: UnwrapRef + readonly reactive: UnwrapRef + readonly readonly: UnwrapRef + readonly ref: UnwrapRef + readonly resolveComponent: UnwrapRef + readonly setActivePinia: UnwrapRef + readonly setMapStoreSuffix: UnwrapRef + readonly shallowReactive: UnwrapRef + readonly shallowReadonly: UnwrapRef + readonly shallowRef: UnwrapRef + readonly storeToRefs: UnwrapRef + readonly toRaw: UnwrapRef + readonly toRef: UnwrapRef + readonly toRefs: UnwrapRef + readonly toValue: UnwrapRef + readonly triggerRef: UnwrapRef + readonly unref: UnwrapRef + readonly useAppStore: UnwrapRef + readonly useAttrs: UnwrapRef + readonly useCssModule: UnwrapRef + readonly useCssVars: UnwrapRef + readonly useFavoriteStore: UnwrapRef + readonly useId: UnwrapRef + readonly useLink: UnwrapRef + readonly useMessageStore: UnwrapRef + readonly useModel: UnwrapRef + readonly useRoute: UnwrapRef + readonly useRouter: UnwrapRef + readonly useSlots: UnwrapRef + readonly useTemplateRef: UnwrapRef + readonly useUserStore: UnwrapRef + readonly useVideoStore: UnwrapRef + readonly watch: UnwrapRef + readonly watchEffect: UnwrapRef + readonly watchPostEffect: UnwrapRef + readonly watchSyncEffect: UnwrapRef + } +} diff --git a/frontend/video-frontend-web/src/components.d.ts b/frontend/video-frontend-web/src/components.d.ts new file mode 100644 index 0000000..d6cc3e5 --- /dev/null +++ b/frontend/video-frontend-web/src/components.d.ts @@ -0,0 +1,37 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + AppHeader: typeof import('./components/layout/AppHeader.vue')['default'] + AppTabbar: typeof import('./components/layout/AppTabbar.vue')['default'] + CommentSection: typeof import('./components/comment/CommentSection.vue')['default'] + DanmakuList: typeof import('./components/danmaku/DanmakuList.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + VanBadge: typeof import('vant/es')['Badge'] + VanButton: typeof import('vant/es')['Button'] + VanCell: typeof import('vant/es')['Cell'] + VanCellGroup: typeof import('vant/es')['CellGroup'] + VanField: typeof import('vant/es')['Field'] + VanForm: typeof import('vant/es')['Form'] + VanIcon: typeof import('vant/es')['Icon'] + VanImage: typeof import('vant/es')['Image'] + VanList: typeof import('vant/es')['List'] + VanLoading: typeof import('vant/es')['Loading'] + VanNavBar: typeof import('vant/es')['NavBar'] + VanPopover: typeof import('vant/es')['Popover'] + VanPullRefresh: typeof import('vant/es')['PullRefresh'] + VanSearch: typeof import('vant/es')['Search'] + VanTab: typeof import('vant/es')['Tab'] + VanTabbar: typeof import('vant/es')['Tabbar'] + VanTabbarItem: typeof import('vant/es')['TabbarItem'] + VanTabs: typeof import('vant/es')['Tabs'] + VideoCard: typeof import('./components/video/VideoCard.vue')['default'] + VideoPlayer: typeof import('./components/video/VideoPlayer.vue')['default'] + } +} diff --git a/frontend/video-frontend-web/src/components/comment/CommentSection.vue b/frontend/video-frontend-web/src/components/comment/CommentSection.vue new file mode 100644 index 0000000..5c8e449 --- /dev/null +++ b/frontend/video-frontend-web/src/components/comment/CommentSection.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/frontend/video-frontend-web/src/components/danmaku/DanmakuList.vue b/frontend/video-frontend-web/src/components/danmaku/DanmakuList.vue new file mode 100644 index 0000000..9ce81f4 --- /dev/null +++ b/frontend/video-frontend-web/src/components/danmaku/DanmakuList.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/frontend/video-frontend-web/src/components/layout/AppHeader.vue b/frontend/video-frontend-web/src/components/layout/AppHeader.vue new file mode 100644 index 0000000..3fe543e --- /dev/null +++ b/frontend/video-frontend-web/src/components/layout/AppHeader.vue @@ -0,0 +1,323 @@ + + + + + diff --git a/frontend/video-frontend-web/src/components/layout/AppTabbar.vue b/frontend/video-frontend-web/src/components/layout/AppTabbar.vue new file mode 100644 index 0000000..19f75a3 --- /dev/null +++ b/frontend/video-frontend-web/src/components/layout/AppTabbar.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/frontend/video-frontend-web/src/components/video/VideoCard.vue b/frontend/video-frontend-web/src/components/video/VideoCard.vue new file mode 100644 index 0000000..f2d1894 --- /dev/null +++ b/frontend/video-frontend-web/src/components/video/VideoCard.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/frontend/video-frontend-web/src/components/video/VideoPlayer.vue b/frontend/video-frontend-web/src/components/video/VideoPlayer.vue new file mode 100644 index 0000000..8f09363 --- /dev/null +++ b/frontend/video-frontend-web/src/components/video/VideoPlayer.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/frontend/video-frontend-web/src/main.ts b/frontend/video-frontend-web/src/main.ts new file mode 100644 index 0000000..a0c0cd4 --- /dev/null +++ b/frontend/video-frontend-web/src/main.ts @@ -0,0 +1,23 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' +import App from './App.vue' +import router from './router' + +// Vant 组件按需引入由 unplugin-vue-components 自动完成 +// 样式已自动引入 + +// 全局样式 +import '@/styles/index.scss' + +const app = createApp(App) + +// Pinia 状态管理 +const pinia = createPinia() +pinia.use(piniaPluginPersistedstate) +app.use(pinia) + +// 路由 +app.use(router) + +app.mount('#app') diff --git a/frontend/video-frontend-web/src/router/index.ts b/frontend/video-frontend-web/src/router/index.ts new file mode 100644 index 0000000..a7317a4 --- /dev/null +++ b/frontend/video-frontend-web/src/router/index.ts @@ -0,0 +1,189 @@ +import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' +import { useUserStore } from '@/stores/user.ts' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' + +// 配置 NProgress +NProgress.configure({ showSpinner: false }) + +// 路由配置 +const routes: RouteRecordRaw[] = [ + { + path: '/', + component: () => import('@/views/layout/MainLayout.vue'), + children: [ + { + path: '', + name: 'Home', + component: () => import('@/views/home/index.vue'), + meta: { title: '首页' } + }, + { + path: 'video/:id', + name: 'Video', + component: () => import('@/views/video/detail.vue'), + meta: { title: '视频详情' } + }, + { + path: 'search', + name: 'Search', + component: () => import('@/views/search/index.vue'), + meta: { title: '搜索' } + }, + { + path: 'category/:id?', + name: 'Category', + component: () => import('@/views/home/category.vue'), + meta: { title: '分类' } + }, + { + path: 'user/:id', + name: 'UserProfile', + component: () => import('@/views/user/profile.vue'), + meta: { title: '用户主页' } + }, + { + path: 'user/:id/videos', + name: 'UserVideos', + component: () => import('@/views/user/videos.vue'), + meta: { title: '用户视频' } + }, + { + path: 'user/:id/followers', + name: 'UserFollowers', + component: () => import('@/views/user/followers.vue'), + meta: { title: '粉丝' } + }, + { + path: 'user/:id/following', + name: 'UserFollowing', + component: () => import('@/views/user/following.vue'), + meta: { title: '关注' } + } + ] + }, + // 需要登录的路由 + { + path: '/', + component: () => import('@/views/layout/MainLayout.vue'), + meta: { requiresAuth: true }, + children: [ + { + path: 'upload', + name: 'Upload', + component: () => import('@/views/upload/index.vue'), + meta: { title: '上传视频', requiresAuth: true } + }, + { + path: 'my/videos', + name: 'MyVideos', + component: () => import('@/views/user/my-videos.vue'), + meta: { title: '我的视频', requiresAuth: true } + }, + { + path: 'my/favorites', + name: 'MyFavorites', + component: () => import('@/views/favorite/index.vue'), + meta: { title: '我的收藏', requiresAuth: true } + }, + { + path: 'my/history', + name: 'PlayHistory', + component: () => import('@/views/user/history.vue'), + meta: { title: '播放历史', requiresAuth: true } + }, + { + path: 'settings', + name: 'Settings', + component: () => import('@/views/user/settings.vue'), + meta: { title: '设置', requiresAuth: true } + }, + { + path: 'settings/profile', + name: 'ProfileEdit', + component: () => import('@/views/user/profile-edit.vue'), + meta: { title: '编辑资料', requiresAuth: true } + }, + { + path: 'messages', + name: 'Messages', + component: () => import('@/views/message/index.vue'), + meta: { title: '私信', requiresAuth: true } + }, + { + path: 'messages/:id', + name: 'MessageDetail', + component: () => import('@/views/message/detail.vue'), + meta: { title: '私信详情', requiresAuth: true } + }, + { + path: 'notifications', + name: 'Notifications', + component: () => import('@/views/message/notifications.vue'), + meta: { title: '通知', requiresAuth: true } + } + ] + }, + // 登录注册 + { + path: '/login', + name: 'Login', + component: () => import('@/views/login/index.vue'), + meta: { title: '登录' } + }, + { + path: '/register', + name: 'Register', + component: () => import('@/views/login/register.vue'), + meta: { title: '注册' } + }, + // 404 + { + path: '/:pathMatch(.*)*', + name: 'NotFound', + component: () => import('@/views/error/404.vue'), + meta: { title: '页面未找到' } + } +] + +// 创建路由实例 +const router = createRouter({ + history: createWebHistory(), + routes, + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } else { + return { top: 0 } + } + } +}) + +// 路由前置守卫 +router.beforeEach((to, from, next) => { + // 开始进度条 + NProgress.start() + + // 设置页面标题 + const title = to.meta.title as string + document.title = title ? `${title} - HAOVP` : 'HAOVP - 在线视频平台' + + // 检查登录状态 + const userStore = useUserStore() + if (to.meta.requiresAuth && !userStore.isLoggedIn) { + next({ + path: '/login', + query: { redirect: to.fullPath } + }) + } else { + next() + } +}) + +// 路由后置守卫 +router.afterEach(() => { + // 结束进度条 + NProgress.done() +}) + +export default router diff --git a/frontend/video-frontend-web/src/stores/app.ts b/frontend/video-frontend-web/src/stores/app.ts new file mode 100644 index 0000000..ae5f406 --- /dev/null +++ b/frontend/video-frontend-web/src/stores/app.ts @@ -0,0 +1,102 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useAppStore = defineStore('app', () => { + // 主题 (light, dark, auto) + const theme = ref<'light' | 'dark' | 'auto'>('auto') + + // 语言 + const locale = ref('zh-CN') + + // 侧边栏是否展开 + const sidebarCollapsed = ref(false) + + // 是否显示弹幕 + const danmakuVisible = ref(true) + + // 弹幕设置 + const danmakuSettings = ref({ + fontSize: 24, + opacity: 1, + speed: 1, + showTop: true, + showBottom: true, + showScroll: true + }) + + // 播放器设置 + const playerSettings = ref({ + autoplay: false, + defaultQuality: 'auto', + defaultPlaybackRate: 1 + }) + + // 设置主题 + function setTheme(newTheme: 'light' | 'dark' | 'auto') { + theme.value = newTheme + applyTheme(newTheme) + } + + // 应用主题 + function applyTheme(theme: 'light' | 'dark' | 'auto') { + const root = document.documentElement + + if (theme === 'auto') { + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches + root.classList.toggle('dark', prefersDark) + } else { + root.classList.toggle('dark', theme === 'dark') + } + } + + // 设置语言 + function setLocale(newLocale: string) { + locale.value = newLocale + // TODO: 实现 i18n + } + + // 切换侧边栏 + function toggleSidebar() { + sidebarCollapsed.value = !sidebarCollapsed.value + } + + // 设置弹幕可见性 + function setDanmakuVisible(visible: boolean) { + danmakuVisible.value = visible + } + + // 更新弹幕设置 + function updateDanmakuSettings(settings: Partial) { + danmakuSettings.value = { ...danmakuSettings.value, ...settings } + } + + // 更新播放器设置 + function updatePlayerSettings(settings: Partial) { + playerSettings.value = { ...playerSettings.value, ...settings } + } + + // 初始化应用 + function initApp() { + applyTheme(theme.value) + } + + return { + // 状态 + theme, + locale, + sidebarCollapsed, + danmakuVisible, + danmakuSettings, + playerSettings, + // 方法 + setTheme, + setLocale, + toggleSidebar, + setDanmakuVisible, + updateDanmakuSettings, + updatePlayerSettings, + initApp + } +}, { + persist: true +}) diff --git a/frontend/video-frontend-web/src/stores/favorite.ts b/frontend/video-frontend-web/src/stores/favorite.ts new file mode 100644 index 0000000..b139d43 --- /dev/null +++ b/frontend/video-frontend-web/src/stores/favorite.ts @@ -0,0 +1,102 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import type { Favorite, VideoInfo } from '@/types' +import { favoriteApi } from '@/api/favorite.ts' +import { showToast } from 'vant' + +export const useFavoriteStore = defineStore('favorite', () => { + // 收藏夹列表 + const favorites = ref([]) + + // 当前选中的收藏夹 + const currentFavorite = ref(null) + + // 是否加载中 + const loading = ref(false) + + // 获取收藏夹列表 + async function fetchFavorites() { + if (loading.value) return + + loading.value = true + try { + const result = await favoriteApi.getFavoriteList() + favorites.value = result + } catch (error) { + console.error('获取收藏夹列表失败:', error) + } finally { + loading.value = false + } + } + + // 创建收藏夹 + async function createFavorite(params: { name: string; description?: string; visibility: number }) { + try { + const result = await favoriteApi.createFavorite(params) + favorites.value.unshift(result) + showToast('创建成功') + return result + } catch (error) { + console.error('创建收藏夹失败:', error) + throw error + } + } + + // 更新收藏夹 + async function updateFavorite(params: Partial & { id: number }) { + try { + await favoriteApi.updateFavorite(params) + const index = favorites.value.findIndex(f => f.id === params.id) + if (index >= 0) { + favorites.value[index] = { ...favorites.value[index], ...params } + } + showToast('更新成功') + } catch (error) { + console.error('更新收藏夹失败:', error) + throw error + } + } + + // 删除收藏夹 + async function deleteFavorite(id: number) { + try { + await favoriteApi.deleteFavorite(id) + favorites.value = favorites.value.filter(f => f.id !== id) + showToast('删除成功') + } catch (error) { + console.error('删除收藏夹失败:', error) + throw error + } + } + + // 设置当前收藏夹 + function setCurrentFavorite(favorite: Favorite | null) { + currentFavorite.value = favorite + } + + // 更新收藏夹中的视频数量 + function updateVideoCount(favoriteId: number, delta: number) { + const favorite = favorites.value.find(f => f.id === favoriteId) + if (favorite) { + favorite.videoCount += delta + } + } + + return { + // 状态 + favorites, + currentFavorite, + loading, + // 方法 + fetchFavorites, + createFavorite, + updateFavorite, + deleteFavorite, + setCurrentFavorite, + updateVideoCount + } +}, { + persist: { + paths: ['favorites'] + } +}) diff --git a/frontend/video-frontend-web/src/stores/index.ts b/frontend/video-frontend-web/src/stores/index.ts new file mode 100644 index 0000000..b78804d --- /dev/null +++ b/frontend/video-frontend-web/src/stores/index.ts @@ -0,0 +1,5 @@ +export { useUserStore } from './user.ts' +export { useVideoStore } from './video.ts' +export { useFavoriteStore } from './favorite.ts' +export { useMessageStore } from './message.ts' +export { useAppStore } from './app.ts' diff --git a/frontend/video-frontend-web/src/stores/message.ts b/frontend/video-frontend-web/src/stores/message.ts new file mode 100644 index 0000000..daf1440 --- /dev/null +++ b/frontend/video-frontend-web/src/stores/message.ts @@ -0,0 +1,89 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' +import { userApi } from '@/api/user.ts' +import type { Message, Notification } from '@/types' + +export const useMessageStore = defineStore('message', () => { + // 未读私信数量 + const unreadMessageCount = ref(0) + + // 未读通知数量 + const unreadNotificationCount = ref(0) + + // 通知列表 + const notifications = ref([]) + + // 计算总未读数 + const totalUnreadCount = computed(() => { + return unreadMessageCount.value + unreadNotificationCount.value + }) + + // 获取未读私信数量 + async function fetchUnreadMessageCount() { + try { + const count = await userApi.getUnreadMessageCount() + unreadMessageCount.value = count + } catch (error) { + console.error('获取未读私信数量失败:', error) + } + } + + // 获取未读通知数量 + async function fetchUnreadNotificationCount() { + try { + const count = await userApi.getUnreadNotificationCount() + unreadNotificationCount.value = count + } catch (error) { + console.error('获取未读通知数量失败:', error) + } + } + + // 获取所有未读数量 + async function fetchAllUnreadCount() { + await Promise.all([ + fetchUnreadMessageCount(), + fetchUnreadNotificationCount() + ]) + } + + // 标记私信为已读 + function decrementMessageUnread(count = 1) { + unreadMessageCount.value = Math.max(0, unreadMessageCount.value - count) + } + + // 标记通知为已读 + function decrementNotificationUnread(count = 1) { + unreadNotificationCount.value = Math.max(0, unreadNotificationCount.value - count) + } + + // 清空所有未读私信 + function clearMessageUnread() { + unreadMessageCount.value = 0 + } + + // 清空所有未读通知 + function clearNotificationUnread() { + unreadNotificationCount.value = 0 + } + + return { + // 状态 + unreadMessageCount, + unreadNotificationCount, + notifications, + // 计算属性 + totalUnreadCount, + // 方法 + fetchUnreadMessageCount, + fetchUnreadNotificationCount, + fetchAllUnreadCount, + decrementMessageUnread, + decrementNotificationUnread, + clearMessageUnread, + clearNotificationUnread + } +}, { + persist: { + paths: ['unreadMessageCount', 'unreadNotificationCount'] + } +}) diff --git a/frontend/video-frontend-web/src/stores/user.ts b/frontend/video-frontend-web/src/stores/user.ts new file mode 100644 index 0000000..0287284 --- /dev/null +++ b/frontend/video-frontend-web/src/stores/user.ts @@ -0,0 +1,184 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' +import { authApi } from '@/api/auth.ts' +import { userApi } from '@/api/user.ts' +import type { LoginParams, RegisterParams, UserInfo, AuthUser, CaptchaResult } from '@/types' +import { getToken, setToken, removeToken, getRefreshToken, setRefreshToken, removeRefreshToken } from '@/utils/storage.ts' +import { showToast } from 'vant' + +export const useUserStore = defineStore('user', () => { + // 状态 + const token = ref(getToken()) + const refreshToken = ref(getRefreshToken()) + const userInfo = ref(null) + const authUser = ref(null) + const captcha = ref(null) + + // 计算属性 + const isLoggedIn = computed(() => !!token.value) + const userId = computed(() => authUser.value?.id || userInfo.value?.id) + const username = computed(() => authUser.value?.username || userInfo.value?.nickname) + + // 获取验证码 + async function getCaptcha() { + try { + const result = await authApi.getCaptcha() + captcha.value = result + return result + } catch (error) { + console.error('获取验证码失败:', error) + throw error + } + } + + // 登录 + async function login(params: LoginParams) { + try { + const result = await authApi.login(params) + token.value = result.accessToken + refreshToken.value = result.refreshToken + setToken(result.accessToken) + setRefreshToken(result.refreshToken) + + // 获取用户信息 + await fetchAuthUser() + await fetchUserInfo() + + return result + } catch (error) { + console.error('登录失败:', error) + throw error + } + } + + // 注册 + async function register(params: RegisterParams) { + try { + const result = await authApi.register(params) + showToast('注册成功') + return result + } catch (error) { + console.error('注册失败:', error) + throw error + } + } + + // 登出 + async function logout() { + try { + await authApi.logout() + } catch (error) { + console.error('登出请求失败:', error) + } finally { + // 清除本地状态 + token.value = null + refreshToken.value = null + userInfo.value = null + authUser.value = null + removeToken() + removeRefreshToken() + } + } + + // 刷新 Token + async function refreshAccessToken() { + if (!refreshToken.value) { + logout() + return false + } + + try { + const result = await authApi.refreshToken(refreshToken.value) + token.value = result.accessToken + refreshToken.value = result.refreshToken + setToken(result.accessToken) + setRefreshToken(result.refreshToken) + return true + } catch (error) { + console.error('刷新Token失败:', error) + logout() + return false + } + } + + // 获取认证用户信息 + async function fetchAuthUser() { + if (!token.value) return null + + try { + const result = await authApi.getCurrentUser() + authUser.value = result + return result + } catch (error) { + console.error('获取认证用户信息失败:', error) + throw error + } + } + + // 获取用户资料 + async function fetchUserInfo() { + if (!token.value) return null + + try { + const result = await userApi.getCurrentProfile() + userInfo.value = result + return result + } catch (error) { + console.error('获取用户资料失败:', error) + throw error + } + } + + // 更新用户资料 + async function updateProfile(params: Partial) { + try { + await userApi.updateProfile(params) + // 重新获取用户资料 + await fetchUserInfo() + } catch (error) { + console.error('更新用户资料失败:', error) + throw error + } + } + + // 上传头像 + async function uploadAvatar(file: File, onProgress?: (percent: number) => void) { + try { + const avatarUrl = await userApi.uploadAvatar(file, onProgress) + if (userInfo.value) { + userInfo.value.avatar = avatarUrl + } + return avatarUrl + } catch (error) { + console.error('上传头像失败:', error) + throw error + } + } + + return { + // 状态 + token, + refreshToken, + userInfo, + authUser, + captcha, + // 计算属性 + isLoggedIn, + userId, + username, + // 方法 + getCaptcha, + login, + register, + logout, + refreshAccessToken, + fetchAuthUser, + fetchUserInfo, + updateProfile, + uploadAvatar + } +}, { + persist: { + paths: ['token', 'refreshToken', 'userInfo', 'authUser'] + } +}) diff --git a/frontend/video-frontend-web/src/stores/video.ts b/frontend/video-frontend-web/src/stores/video.ts new file mode 100644 index 0000000..1c42649 --- /dev/null +++ b/frontend/video-frontend-web/src/stores/video.ts @@ -0,0 +1,118 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import type { VideoInfo, PlayRecord } from '@/types' +import { videoApi } from '@/api/video.ts' + +export const useVideoStore = defineStore('video', () => { + // 当前播放的视频 + const currentVideo = ref(null) + + // 播放进度 + const playProgress = ref(0) + + // 播放历史(本地存储) + const playHistory = ref([]) + + // 是否正在播放 + const isPlaying = ref(false) + + // 弹幕开关 + const danmakuEnabled = ref(true) + + // 音量 + const volume = ref(0.8) + + // 播放速度 + const playbackRate = ref(1) + + // 设置当前视频 + function setCurrentVideo(video: VideoInfo | null) { + currentVideo.value = video + } + + // 更新播放进度 + function updateProgress(progress: number) { + playProgress.value = progress + } + + // 切换播放状态 + function togglePlaying(playing: boolean) { + isPlaying.value = playing + } + + // 切换弹幕 + function toggleDanmaku(enabled: boolean) { + danmakuEnabled.value = enabled + } + + // 设置音量 + function setVolume(vol: number) { + volume.value = vol + } + + // 设置播放速度 + function setPlaybackRate(rate: number) { + playbackRate.value = rate + } + + // 记录播放 + async function recordPlay(videoId: number, progress: number, duration: number) { + try { + await videoApi.recordPlay({ videoId, progress, duration }) + + // 更新本地播放历史 + const index = playHistory.value.findIndex(item => item.videoId === videoId) + const record: PlayRecord = { videoId, progress, duration } + + if (index >= 0) { + playHistory.value[index] = record + } else { + playHistory.value.unshift(record) + // 最多保存100条记录 + if (playHistory.value.length > 100) { + playHistory.value = playHistory.value.slice(0, 100) + } + } + } catch (error) { + console.error('记录播放失败:', error) + } + } + + // 获取播放进度 + function getPlayProgress(videoId: number): number { + const record = playHistory.value.find(item => item.videoId === videoId) + return record?.progress || 0 + } + + // 清除当前视频 + function clearCurrentVideo() { + currentVideo.value = null + playProgress.value = 0 + isPlaying.value = false + } + + return { + // 状态 + currentVideo, + playProgress, + playHistory, + isPlaying, + danmakuEnabled, + volume, + playbackRate, + // 方法 + setCurrentVideo, + updateProgress, + togglePlaying, + toggleDanmaku, + setVolume, + setPlaybackRate, + recordPlay, + getPlayProgress, + clearCurrentVideo + } +}, { + persist: { + paths: ['playHistory', 'danmakuEnabled', 'volume', 'playbackRate'] + } +}) diff --git a/frontend/video-frontend-web/src/styles/index.scss b/frontend/video-frontend-web/src/styles/index.scss new file mode 100644 index 0000000..3c547a4 --- /dev/null +++ b/frontend/video-frontend-web/src/styles/index.scss @@ -0,0 +1,254 @@ +// 全局样式入口 + +// 重置样式 +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, +body { + width: 100%; + min-height: 100vh; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, + 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + font-size: 14px; + line-height: 1.5; + color: #333; + background-color: #f4f4f4; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + color: inherit; + text-decoration: none; +} + +ul, +ol { + list-style: none; +} + +img { + max-width: 100%; + height: auto; +} + +button { + border: none; + background: none; + cursor: pointer; + font-family: inherit; +} + +input, +textarea, +select { + font-family: inherit; + font-size: inherit; +} + +// 滚动条样式 +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; + + &:hover { + background: #a8a8a8; + } +} + +// NProgress 样式覆盖 +#nprogress { + .bar { + background: linear-gradient(to right, #00a1d6, #fb7299) !important; + height: 3px !important; + } + + .peg { + box-shadow: 0 0 10px #00a1d6, 0 0 5px #00a1d6 !important; + } +} + +// 主题变量 +:root { + // 主色调 + --primary-color: #00a1d6; + --primary-hover-color: #00b5e2; + + // 辅助色 + --success-color: #52c41a; + --warning-color: #faad14; + --error-color: #ff4d4f; + --info-color: #1890ff; + + // 粉色(B站风格) + --pink-color: #fb7299; + --pink-hover-color: #fc8bab; + + // 文字颜色 + --text-primary: #333; + --text-secondary: #666; + --text-tertiary: #999; + --text-white: #fff; + + // 背景颜色 + --bg-primary: #f4f4f4; + --bg-secondary: #fff; + --bg-tertiary: #f9f9f9; + + // 边框颜色 + --border-color: #e5e5e5; + --border-light: #f0f0f0; + + // 阴影 + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12); + + // 圆角 + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + + // 间距 + --spacing-xs: 4px; + --spacing-sm: 8px; + --spacing-md: 16px; + --spacing-lg: 24px; + --spacing-xl: 32px; + + // 布局 + --header-height: 60px; + --sidebar-width: 200px; + --max-content-width: 1400px; +} + +// 暗色主题 +.dark { + --text-primary: #e5e5e5; + --text-secondary: #a0a0a0; + --text-tertiary: #666; + + --bg-primary: #1a1a1a; + --bg-secondary: #252525; + --bg-tertiary: #2a2a2a; + + --border-color: #333; + --border-light: #2a2a2a; +} + +// 常用类 +.text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-ellipsis-2 { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; +} + +.text-ellipsis-3 { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; +} + +.flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +.flex-between { + display: flex; + align-items: center; + justify-content: space-between; +} + +.flex-column { + display: flex; + flex-direction: column; +} + +.page-container { + max-width: var(--max-content-width); + margin: 0 auto; + padding: var(--spacing-md); +} + +.card { + background: var(--bg-secondary); + border-radius: var(--radius-md); + box-shadow: var(--shadow-sm); +} + +// 骨架屏动画 +.skeleton { + background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); + background-size: 200% 100%; + animation: skeleton-loading 1.5s infinite; +} + +@keyframes skeleton-loading { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} + +// 淡入动画 +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.3s ease; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +// 滑入动画 +.slide-enter-active, +.slide-leave-active { + transition: transform 0.3s ease; +} + +.slide-enter-from, +.slide-leave-to { + transform: translateX(100%); +} + +// 缩放动画 +.scale-enter-active, +.scale-leave-active { + transition: transform 0.3s ease, opacity 0.3s ease; +} + +.scale-enter-from, +.scale-leave-to { + transform: scale(0.9); + opacity: 0; +} diff --git a/frontend/video-frontend-web/src/types/index.ts b/frontend/video-frontend-web/src/types/index.ts new file mode 100644 index 0000000..1b7147e --- /dev/null +++ b/frontend/video-frontend-web/src/types/index.ts @@ -0,0 +1,339 @@ +// API 响应通用结构 +export interface ApiResponse { + code: number + message: string + data: T +} + +// 分页请求参数 +export interface PageParams { + page?: number + size?: number +} + +// 分页响应数据 +export interface PageResult { + records: T[] + total: number + size: number + current: number + pages: number +} + +// 用户信息 +export interface UserInfo { + id: number + nickname: string + avatar: string + gender: number + birthday: string + signature: string + region: string + followerCount: number + followingCount: number + videoCount: number + likeCount: number + level: number + vipLevel: number + vipExpireTime: string | null + isFollowed?: boolean + createTime: string +} + +// 认证用户 +export interface AuthUser { + id: number + username: string + email: string + phone: string + status: number + lastLoginTime: string + lastLoginIp: string + roles: string[] +} + +// 登录响应 +export interface LoginResult { + accessToken: string + refreshToken: string + tokenType: string + expiresIn: number + userId: number + username: string +} + +// 验证码响应 +export interface CaptchaResult { + captchaKey: string + captchaImage: string +} + +// 登录请求 +export interface LoginParams { + username: string + password: string + captcha: string + captchaKey: string +} + +// 注册请求 +export interface RegisterParams { + username: string + password: string + confirmPassword: string + email: string + phone: string + captcha: string + captchaKey: string +} + +// 视频信息 +export interface VideoInfo { + id: number + userId: number + title: string + description: string + coverUrl: string + videoUrl: string + duration: number + width: number + height: number + format: string + size: number + categoryId: number + status: number + likeCount: number + coinCount: number + favoriteCount: number + commentCount: number + viewCount: number + shareCount: number + danmakuCount: number + isRecommend: number + isTop: number + publishTime: string + createTime: string + updateTime: string + tagIds?: number[] + tagNames?: string[] + categoryName?: string + userNickname?: string + userAvatar?: string + isLiked?: boolean + isFavorited?: boolean + isCoined?: boolean +} + +// 视频上传参数 +export interface VideoUploadParams { + file: File + onProgress?: (percent: number) => void +} + +// 视频创建参数 +export interface VideoCreateParams { + title: string + description: string + videoUrl: string + coverUrl: string + duration: number + width: number + height: number + format: string + size: number + categoryId: number + tagIds?: number[] +} + +// 视频更新参数 +export interface VideoUpdateParams { + id: number + title?: string + description?: string + coverUrl?: string + categoryId?: number + tagIds?: number[] +} + +// 视频查询参数 +export interface VideoQueryParams extends PageParams { + keyword?: string + categoryId?: number + tagId?: number + userId?: number + status?: number + sortBy?: string + sortOrder?: 'asc' | 'desc' +} + +// 分类信息 +export interface Category { + id: number + name: string + parentId: number + sort: number + icon: string + children?: Category[] +} + +// 标签信息 +export interface Tag { + id: number + name: string + useCount: number +} + +// 弹幕信息 +export interface Danmaku { + id: number + videoId: number + userId: number + content: string + color: string + position: number + time: number + fontSize: number + createTime: string +} + +// 弹幕发送参数 +export interface DanmakuSendParams { + videoId: number + content: string + color: string + position: number + time: number + fontSize: number +} + +// 评论信息 +export interface Comment { + id: number + videoId: number + userId: number + parentId: number + rootId: number + content: string + likeCount: number + replyCount: number + isTop: number + createTime: string + userNickname?: string + userAvatar?: string + isLiked?: boolean + replies?: Comment[] +} + +// 评论发送参数 +export interface CommentSendParams { + videoId: number + parentId?: number + rootId?: number + content: string +} + +// 评论查询参数 +export interface CommentQueryParams extends PageParams { + videoId: number + rootId?: number + sortBy?: 'hot' | 'time' +} + +// 收藏夹信息 +export interface Favorite { + id: number + userId: number + name: string + description: string + coverUrl: string + visibility: number + videoCount: number + createTime: string +} + +// 收藏夹创建参数 +export interface FavoriteCreateParams { + name: string + description?: string + coverUrl?: string + visibility: number +} + +// 收藏视频参数 +export interface FavoriteVideoParams { + videoId: number + favoriteId: number +} + +// 用户关注 +export interface UserFollow { + id: number + nickname: string + avatar: string + signature: string + followerCount: number + followingCount: number + isFollowed?: boolean +} + +// 私信信息 +export interface Message { + id: number + senderId: number + senderNickname: string + senderAvatar: string + receiverId: number + receiverNickname: string + receiverAvatar: string + content: string + isRead: number + createTime: string +} + +// 私信发送参数 +export interface MessageSendParams { + receiverId: number + content: string +} + +// 通知信息 +export interface Notification { + id: number + type: number // 1:点赞,2:评论,3:关注,4:系统通知 + content: string + relatedId: number + isRead: number + createTime: string +} + +// 用户设置 +export interface UserSetting { + privacyLevel: number // 1:公开,2:仅关注,3:私密 + commentNotify: number + likeNotify: number + followNotify: number + systemNotify: number +} + +// 用户资料更新参数 +export interface UserProfileUpdateParams { + nickname?: string + gender?: number + birthday?: string + signature?: string + region?: string +} + +// 播放记录 +export interface PlayRecord { + videoId: number + progress: number + duration: number +} + +// 推荐视频 +export interface RecommendVideo { + videoId: number + score: number + reason: string +} diff --git a/frontend/video-frontend-web/src/utils/index.ts b/frontend/video-frontend-web/src/utils/index.ts new file mode 100644 index 0000000..9dd3b53 --- /dev/null +++ b/frontend/video-frontend-web/src/utils/index.ts @@ -0,0 +1,199 @@ +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' +import 'dayjs/locale/zh-cn' + +// 配置 dayjs +dayjs.extend(relativeTime) +dayjs.locale('zh-cn') + +/** + * 格式化日期时间 + */ +export function formatDateTime(date: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string { + return dayjs(date).format(format) +} + +/** + * 格式化日期 + */ +export function formatDate(date: string | Date): string { + return dayjs(date).format('YYYY-MM-DD') +} + +/** + * 格式化时间 + */ +export function formatTime(date: string | Date): string { + return dayjs(date).format('HH:mm:ss') +} + +/** + * 相对时间(如:3 天前) + */ +export function formatRelativeTime(date: string | Date): string { + return dayjs(date).fromNow() +} + +/** + * 格式化视频时长(秒转为 mm:ss 或 hh:mm:ss) + */ +export function formatDuration(seconds: number): string { + if (!seconds || seconds < 0) return '00:00' + + const hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + const secs = seconds % 60 + + const pad = (n: number) => n.toString().padStart(2, '0') + + if (hours > 0) { + return `${pad(hours)}:${pad(minutes)}:${pad(secs)}` + } + return `${pad(minutes)}:${pad(secs)}` +} + +/** + * 格式化文件大小 + */ +export function formatFileSize(bytes: number): string { + if (bytes === 0) return '0 B' + + const units = ['B', 'KB', 'MB', 'GB', 'TB'] + const k = 1024 + const i = Math.floor(Math.log(bytes) / Math.log(k)) + + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + units[i] +} + +/** + * 格式化数字(如:1000 -> 1千,10000 -> 1万) + */ +export function formatNumber(num: number): string { + if (num < 1000) { + return num.toString() + } else if (num < 10000) { + return (num / 1000).toFixed(1) + '千' + } else if (num < 100000000) { + return (num / 10000).toFixed(1) + '万' + } else { + return (num / 100000000).toFixed(1) + '亿' + } +} + +/** + * 格式化播放量 + */ +export function formatPlayCount(count: number): string { + return formatNumber(count) +} + +/** + * 防抖函数 + */ +export function debounce any>( + fn: T, + delay = 300 +): (...args: Parameters) => void { + let timer: ReturnType | null = null + + return function (this: any, ...args: Parameters) { + if (timer) clearTimeout(timer) + timer = setTimeout(() => { + fn.apply(this, args) + }, delay) + } +} + +/** + * 节流函数 + */ +export function throttle any>( + fn: T, + delay = 300 +): (...args: Parameters) => void { + let lastTime = 0 + + return function (this: any, ...args: Parameters) { + const now = Date.now() + if (now - lastTime >= delay) { + fn.apply(this, args) + lastTime = now + } + } +} + +/** + * 深拷贝 + */ +export function deepClone(obj: T): T { + if (obj === null || typeof obj !== 'object') { + return obj + } + + if (Array.isArray(obj)) { + return obj.map((item) => deepClone(item)) as any + } + + const cloned = {} as T + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + cloned[key] = deepClone(obj[key]) + } + } + + return cloned +} + +/** + * 生成随机字符串 + */ +export function randomString(length = 16): string { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + let result = '' + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * chars.length)) + } + return result +} + +/** + * 复制文本到剪贴板 + */ +export async function copyToClipboard(text: string): Promise { + try { + await navigator.clipboard.writeText(text) + return true + } catch { + // Fallback for older browsers + const textarea = document.createElement('textarea') + textarea.value = text + textarea.style.position = 'fixed' + textarea.style.opacity = '0' + document.body.appendChild(textarea) + textarea.select() + const result = document.execCommand('copy') + document.body.removeChild(textarea) + return result + } +} + +/** + * 获取 URL 参数 + */ +export function getQueryParam(name: string): string | null { + const url = new URL(window.location.href) + return url.searchParams.get(name) +} + +/** + * 构建 URL 参数 + */ +export function buildQueryString(params: Record): string { + const searchParams = new URLSearchParams() + Object.entries(params).forEach(([key, value]) => { + if (value !== undefined && value !== null && value !== '') { + searchParams.append(key, String(value)) + } + }) + return searchParams.toString() +} diff --git a/frontend/video-frontend-web/src/utils/request.ts b/frontend/video-frontend-web/src/utils/request.ts new file mode 100644 index 0000000..83aab8f --- /dev/null +++ b/frontend/video-frontend-web/src/utils/request.ts @@ -0,0 +1,132 @@ +import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios' +import { useUserStore } from '@/stores/user.ts' +import { showToast } from 'vant' +import router from '@/router' + +// API 基础配置 +const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api' +const TIMEOUT = 30000 + +// 创建 axios 实例 +const service: AxiosInstance = axios.create({ + baseURL: BASE_URL, + timeout: TIMEOUT, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +service.interceptors.request.use( + (config: InternalAxiosRequestConfig) => { + const userStore = useUserStore() + + // 添加 Token + if (userStore.token) { + config.headers.Authorization = `Bearer ${userStore.token}` + } + + return config + }, + (error) => { + console.error('请求错误:', error) + return Promise.reject(error) + } +) + +// 响应拦截器 +service.interceptors.response.use( + (response: AxiosResponse) => { + const { data } = response + + // 业务状态码判断 + if (data.code === 200) { + return data.data + } + + // Token 过期 + if (data.code === 401) { + const userStore = useUserStore() + userStore.logout() + router.push('/login') + showToast('登录已过期,请重新登录') + return Promise.reject(new Error('Token expired')) + } + + // 其他业务错误 + showToast(data.message || '请求失败') + return Promise.reject(new Error(data.message || '请求失败')) + }, + (error) => { + console.error('响应错误:', error) + + // 网络错误 + if (error.code === 'ECONNABORTED') { + showToast('请求超时,请稍后重试') + } else if (error.message.includes('Network Error')) { + showToast('网络错误,请检查网络连接') + } else if (error.response) { + const status = error.response.status + switch (status) { + case 401: + const userStore = useUserStore() + userStore.logout() + router.push('/login') + showToast('登录已过期,请重新登录') + break + case 403: + showToast('没有权限访问') + break + case 404: + showToast('请求的资源不存在') + break + case 500: + showToast('服务器错误,请稍后重试') + break + default: + showToast(`请求失败: ${status}`) + } + } + + return Promise.reject(error) + } +) + +// 封装请求方法 +const request = { + get(url: string, params?: object, config?: AxiosRequestConfig): Promise { + return service.get(url, { params, ...config }) + }, + + post(url: string, data?: object, config?: AxiosRequestConfig): Promise { + return service.post(url, data, config) + }, + + put(url: string, data?: object, config?: AxiosRequestConfig): Promise { + return service.put(url, data, config) + }, + + delete(url: string, params?: object, config?: AxiosRequestConfig): Promise { + return service.delete(url, { params, ...config }) + }, + + upload(url: string, file: File, onProgress?: (percent: number) => void): Promise { + const formData = new FormData() + formData.append('file', file) + + return service.post(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + }, + onUploadProgress: (progressEvent) => { + if (progressEvent.total && onProgress) { + const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total) + onProgress(percent) + } + } + }) + } +} + +export default request +export { service as axiosInstance } diff --git a/frontend/video-frontend-web/src/utils/storage.ts b/frontend/video-frontend-web/src/utils/storage.ts new file mode 100644 index 0000000..b47b73d --- /dev/null +++ b/frontend/video-frontend-web/src/utils/storage.ts @@ -0,0 +1,151 @@ +// 本地存储工具 + +const TOKEN_KEY = 'haovp_token' +const REFRESH_TOKEN_KEY = 'haovp_refresh_token' +const USER_INFO_KEY = 'haovp_user_info' + +/** + * 获取 Token + */ +export function getToken(): string | null { + return localStorage.getItem(TOKEN_KEY) +} + +/** + * 设置 Token + */ +export function setToken(token: string): void { + localStorage.setItem(TOKEN_KEY, token) +} + +/** + * 移除 Token + */ +export function removeToken(): void { + localStorage.removeItem(TOKEN_KEY) +} + +/** + * 获取刷新 Token + */ +export function getRefreshToken(): string | null { + return localStorage.getItem(REFRESH_TOKEN_KEY) +} + +/** + * 设置刷新 Token + */ +export function setRefreshToken(token: string): void { + localStorage.setItem(REFRESH_TOKEN_KEY, token) +} + +/** + * 移除刷新 Token + */ +export function removeRefreshToken(): void { + localStorage.removeItem(REFRESH_TOKEN_KEY) +} + +/** + * 获取用户信息 + */ +export function getUserInfo(): any { + const info = localStorage.getItem(USER_INFO_KEY) + return info ? JSON.parse(info) : null +} + +/** + * 设置用户信息 + */ +export function setUserInfo(info: object): void { + localStorage.setItem(USER_INFO_KEY, JSON.stringify(info)) +} + +/** + * 移除用户信息 + */ +export function removeUserInfo(): void { + localStorage.removeItem(USER_INFO_KEY) +} + +/** + * 清除所有认证信息 + */ +export function clearAuth(): void { + removeToken() + removeRefreshToken() + removeUserInfo() +} + +/** + * 检查是否登录 + */ +export function isAuthenticated(): boolean { + return !!getToken() +} + +/** + * 通用本地存储 + */ +export const storage = { + get(key: string): T | null { + const value = localStorage.getItem(key) + if (value) { + try { + return JSON.parse(value) + } catch { + return value as any + } + } + return null + }, + + set(key: string, value: any): void { + if (typeof value === 'string') { + localStorage.setItem(key, value) + } else { + localStorage.setItem(key, JSON.stringify(value)) + } + }, + + remove(key: string): void { + localStorage.removeItem(key) + }, + + clear(): void { + localStorage.clear() + } +} + +/** + * Session 存储 + */ +export const session = { + get(key: string): T | null { + const value = sessionStorage.getItem(key) + if (value) { + try { + return JSON.parse(value) + } catch { + return value as any + } + } + return null + }, + + set(key: string, value: any): void { + if (typeof value === 'string') { + sessionStorage.setItem(key, value) + } else { + sessionStorage.setItem(key, JSON.stringify(value)) + } + }, + + remove(key: string): void { + sessionStorage.removeItem(key) + }, + + clear(): void { + sessionStorage.clear() + } +} diff --git a/frontend/video-frontend-web/src/views/error/404.vue b/frontend/video-frontend-web/src/views/error/404.vue new file mode 100644 index 0000000..97b77f9 --- /dev/null +++ b/frontend/video-frontend-web/src/views/error/404.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/favorite/index.vue b/frontend/video-frontend-web/src/views/favorite/index.vue new file mode 100644 index 0000000..565185f --- /dev/null +++ b/frontend/video-frontend-web/src/views/favorite/index.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/home/category.vue b/frontend/video-frontend-web/src/views/home/category.vue new file mode 100644 index 0000000..b21388f --- /dev/null +++ b/frontend/video-frontend-web/src/views/home/category.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/home/index.vue b/frontend/video-frontend-web/src/views/home/index.vue new file mode 100644 index 0000000..37986af --- /dev/null +++ b/frontend/video-frontend-web/src/views/home/index.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/layout/MainLayout.vue b/frontend/video-frontend-web/src/views/layout/MainLayout.vue new file mode 100644 index 0000000..77d0dc7 --- /dev/null +++ b/frontend/video-frontend-web/src/views/layout/MainLayout.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/login/index.vue b/frontend/video-frontend-web/src/views/login/index.vue new file mode 100644 index 0000000..7bca576 --- /dev/null +++ b/frontend/video-frontend-web/src/views/login/index.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/login/register.vue b/frontend/video-frontend-web/src/views/login/register.vue new file mode 100644 index 0000000..424f244 --- /dev/null +++ b/frontend/video-frontend-web/src/views/login/register.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/message/detail.vue b/frontend/video-frontend-web/src/views/message/detail.vue new file mode 100644 index 0000000..9278265 --- /dev/null +++ b/frontend/video-frontend-web/src/views/message/detail.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/message/index.vue b/frontend/video-frontend-web/src/views/message/index.vue new file mode 100644 index 0000000..76ff43f --- /dev/null +++ b/frontend/video-frontend-web/src/views/message/index.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/message/notifications.vue b/frontend/video-frontend-web/src/views/message/notifications.vue new file mode 100644 index 0000000..60c2b2f --- /dev/null +++ b/frontend/video-frontend-web/src/views/message/notifications.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/search/index.vue b/frontend/video-frontend-web/src/views/search/index.vue new file mode 100644 index 0000000..439a75a --- /dev/null +++ b/frontend/video-frontend-web/src/views/search/index.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/upload/index.vue b/frontend/video-frontend-web/src/views/upload/index.vue new file mode 100644 index 0000000..ba6270e --- /dev/null +++ b/frontend/video-frontend-web/src/views/upload/index.vue @@ -0,0 +1,203 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/followers.vue b/frontend/video-frontend-web/src/views/user/followers.vue new file mode 100644 index 0000000..3b9ad97 --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/followers.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/following.vue b/frontend/video-frontend-web/src/views/user/following.vue new file mode 100644 index 0000000..b46edad --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/following.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/history.vue b/frontend/video-frontend-web/src/views/user/history.vue new file mode 100644 index 0000000..41470da --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/history.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/my-videos.vue b/frontend/video-frontend-web/src/views/user/my-videos.vue new file mode 100644 index 0000000..0d7f37e --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/my-videos.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/profile-edit.vue b/frontend/video-frontend-web/src/views/user/profile-edit.vue new file mode 100644 index 0000000..da7a62d --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/profile-edit.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/profile.vue b/frontend/video-frontend-web/src/views/user/profile.vue new file mode 100644 index 0000000..4aa898a --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/profile.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/settings.vue b/frontend/video-frontend-web/src/views/user/settings.vue new file mode 100644 index 0000000..9ebd4f5 --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/settings.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/user/videos.vue b/frontend/video-frontend-web/src/views/user/videos.vue new file mode 100644 index 0000000..b4182c6 --- /dev/null +++ b/frontend/video-frontend-web/src/views/user/videos.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/frontend/video-frontend-web/src/views/video/detail.vue b/frontend/video-frontend-web/src/views/video/detail.vue new file mode 100644 index 0000000..ac7307e --- /dev/null +++ b/frontend/video-frontend-web/src/views/video/detail.vue @@ -0,0 +1,424 @@ + + + + + diff --git a/frontend/video-frontend-web/src/vite-env.d.ts b/frontend/video-frontend-web/src/vite-env.d.ts new file mode 100644 index 0000000..01418ac --- /dev/null +++ b/frontend/video-frontend-web/src/vite-env.d.ts @@ -0,0 +1,16 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} + +interface ImportMetaEnv { + readonly VITE_APP_TITLE: string + readonly VITE_API_BASE_URL: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} diff --git a/frontend/video-frontend-web/tsconfig.json b/frontend/video-frontend-web/tsconfig.json new file mode 100644 index 0000000..97d74da --- /dev/null +++ b/frontend/video-frontend-web/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + /* Path aliases */ + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json"}] +} diff --git a/frontend/video-frontend-web/tsconfig.node.json b/frontend/video-frontend-web/tsconfig.node.json new file mode 100644 index 0000000..c7a071e --- /dev/null +++ b/frontend/video-frontend-web/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": [ + "vite.config.ts" + ] +} diff --git a/frontend/video-frontend-web/vite.config.ts b/frontend/video-frontend-web/vite.config.ts new file mode 100644 index 0000000..88090f4 --- /dev/null +++ b/frontend/video-frontend-web/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import { resolve } from 'path' +import AutoImport from 'unplugin-auto-import/vite' +import Components from 'unplugin-vue-components/vite' +import { VantResolver } from 'unplugin-vue-components/resolvers' +import VueDevTools from 'vite-plugin-vue-devtools' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + VueDevTools(), + AutoImport({ + imports: ['vue', 'vue-router', 'pinia'], + dts: 'src/auto-imports.d.ts', + dirs: ['src/stores', 'src/composables'], + vueTemplate: true + }), + Components({ + resolvers: [VantResolver()], + dts: 'src/components.d.ts' + }) + ], + resolve: { + alias: { + '@': resolve(__dirname, 'src') + } + }, + server: { + port: 3000, + host: true, + open: true, + proxy: { + '/api': { + target: 'http://192.168.1.101:9000', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, '') + } + } + }, + build: { + target: 'es2015', + outDir: 'dist', + sourcemap: false, + chunkSizeWarningLimit: 2000, + rollupOptions: { + output: { + manualChunks: { + vue: ['vue', 'vue-router', 'pinia'], + vant: ['vant', '@vant/use'], + artplayer: ['artplayer', 'artplayer-plugin-danmuku'] + } + } + } + } +}) diff --git a/src/main/java/com/nuaa/video/App.java b/src/main/java/com/nuaa/video/App.java deleted file mode 100644 index 7e439bb..0000000 --- a/src/main/java/com/nuaa/video/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nuaa.video; - -/** - * Hello world! - * - */ -public class App -{ - public static void main( String[] args ) - { - System.out.println( "Hello World!" ); - } -}