diff --git a/.gitignore b/.gitignore index b7faf403..08f22f72 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,5 @@ cython_debug/ marimo/_static/ marimo/_lsp/ __marimo__/ + +frontend/react-app/node_modules/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..3b664107 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/QQEmailSendAPI.py b/QQEmailSendAPI.py new file mode 100644 index 00000000..0da7ae92 --- /dev/null +++ b/QQEmailSendAPI.py @@ -0,0 +1,543 @@ +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.mime.application import MIMEApplication +from email.header import Header +import random +import string +import json +import os + +# 邮件发送配置 +SENDER_EMAIL = '3205788256@qq.com' # 发件人邮箱 +SENDER_AUTH_CODE = 'szcaxvbftusqddhi' # 授权码 +SMTP_SERVER = 'smtp.qq.com' # QQ邮箱SMTP服务器 +SMTP_PORT = 465 # QQ邮箱SSL端口 + +# 验证码缓存文件 +VERIFICATION_CACHE_FILE = os.path.join("config", "verification_codes.json") + +class QQMailAPI: + """QQ邮箱发送邮件API类""" + + def __init__(self, sender_email, authorization_code): + """ + 初始化邮箱配置 + :param sender_email: 发送方QQ邮箱地址 + :param authorization_code: QQ邮箱授权码 + """ + self.sender_email = sender_email + self.authorization_code = authorization_code + self.smtp_server = 'smtp.qq.com' + self.smtp_port = 465 # SSL端口 + + # 发送纯文本邮件 + def send_text_email(self, receiver_email, subject, content, cc_emails=None): + """ + 发送纯文本邮件 + :param receiver_email: 接收方邮箱地址(单个) + :param subject: 邮件主题 + :param content: 邮件正文内容 + :param cc_emails: 抄送邮箱列表 + :return: 发送成功返回True,失败返回False + """ + try: + # 创建邮件对象 + message = MIMEText(content, 'plain', 'utf-8') + message['From'] = Header(self.sender_email, 'utf-8') + message['To'] = Header(receiver_email, 'utf-8') + message['Subject'] = Header(subject, 'utf-8') + + # 添加抄送 + if cc_emails: + message['Cc'] = Header(",".join(cc_emails), 'utf-8') + all_receivers = [receiver_email] + cc_emails + else: + all_receivers = [receiver_email] + + # 连接SMTP服务器并发送邮件 + with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server: + server.login(self.sender_email, self.authorization_code) + server.sendmail(self.sender_email, all_receivers, message.as_string()) + + print(f"邮件发送成功:主题='{subject}', 收件人='{receiver_email}'") + return True + except Exception as e: + print(f"邮件发送失败:{str(e)}") + return False + + # 发送HTML格式邮件,可带附件 + def send_html_email(self, receiver_email, subject, html_content, cc_emails=None, attachments=None): + """ + 发送HTML格式邮件,可带附件 + :param receiver_email: 接收方邮箱地址(单个) + :param subject: 邮件主题 + :param html_content: HTML格式的邮件正文 + :param cc_emails: 抄送邮箱列表 + :param attachments: 附件文件路径列表 + :return: 发送成功返回True,失败返回False + """ + try: + # 创建带附件的邮件对象 + message = MIMEMultipart() + message['From'] = Header(self.sender_email, 'utf-8') + message['To'] = Header(receiver_email, 'utf-8') + message['Subject'] = Header(subject, 'utf-8') + + # 添加抄送 + if cc_emails: + message['Cc'] = Header(",".join(cc_emails), 'utf-8') + all_receivers = [receiver_email] + cc_emails + else: + all_receivers = [receiver_email] + + # 添加HTML正文 + message.attach(MIMEText(html_content, 'html', 'utf-8')) + + # 添加附件 + if attachments: + for file_path in attachments: + try: + with open(file_path, 'rb') as file: + attachment = MIMEApplication(file.read(), _subtype="octet-stream") + attachment.add_header('Content-Disposition', 'attachment', filename=file_path.split("/")[-1]) + message.attach(attachment) + except Exception as e: + print(f"添加附件失败 {file_path}: {str(e)}") + + # 连接SMTP服务器并发送邮件 + with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server: + server.login(self.sender_email, self.authorization_code) + server.sendmail(self.sender_email, all_receivers, message.as_string()) + + print(f"HTML邮件发送成功:主题='{subject}', 收件人='{receiver_email}'") + return True + except Exception as e: + print(f"HTML邮件发送失败:{str(e)}") + return False + +class EmailVerification: + + #生成指定长度的随机验证码 + @staticmethod + def generate_verification_code(length=6): + """ + 生成指定长度的随机验证码 + + 参数: + length (int): 验证码长度,默认6位 + + 返回: + str: 生成的验证码 + """ + # 生成包含大写字母和数字的验证码 + chars = string.ascii_uppercase + string.digits + return ''.join(random.choice(chars) for _ in range(length)) + + #发送验证码邮件到QQ邮箱 + @staticmethod + def send_verification_email(qq_number, verification_code, email_type="register"): + """ + 发送验证码邮件到QQ邮箱 + + 参数: + qq_number (str): 接收者QQ号 + verification_code (str): 验证码 + email_type (str): 邮件类型,"register" 或 "reset_password" + + 返回: + bool: 发送成功返回True,否则返回False + str: 成功或错误信息 + """ + receiver_email = f"{qq_number}@qq.com" + + # 根据邮件类型设置不同的内容 + if email_type == "reset_password": + email_title = "【萌芽农场】密码重置验证码" + email_purpose = "重置萌芽农场游戏账号密码" + email_color = "#FF6B35" # 橙红色,表示警告性操作 + else: + email_title = "【萌芽农场】注册验证码" + email_purpose = "注册萌芽农场游戏账号" + email_color = "#4CAF50" # 绿色,表示正常操作 + + # 创建邮件内容 + message = MIMEText(f''' + + +
+

萌芽农场 - 邮箱验证码

+

亲爱的玩家,您好!

+

您正在{email_purpose},您的验证码是:

+
+ {verification_code} +
+

该验证码有效期为5分钟,请勿泄露给他人。

+

如果这不是您本人的操作,请忽略此邮件。

+

+ 本邮件由系统自动发送,请勿直接回复。 +

+
+ + + ''', 'html', 'utf-8') + + # 修正From头格式,符合QQ邮箱的要求 + message['From'] = SENDER_EMAIL + message['To'] = receiver_email + message['Subject'] = Header(email_title, 'utf-8') + + try: + # 使用SSL/TLS连接而不是STARTTLS + smtp_obj = smtplib.SMTP_SSL(SMTP_SERVER, 465) + smtp_obj.login(SENDER_EMAIL, SENDER_AUTH_CODE) + smtp_obj.sendmail(SENDER_EMAIL, [receiver_email], message.as_string()) + smtp_obj.quit() + return True, "验证码发送成功" + except Exception as e: + return False, f"发送验证码失败: {str(e)}" + + #保存验证码到MongoDB(优先)或缓存文件(备用) + @staticmethod + def save_verification_code(qq_number, verification_code, expiry_time=300, code_type="register"): + """ + 保存验证码到MongoDB(优先)或缓存文件(备用) + + 参数: + qq_number (str): QQ号 + verification_code (str): 验证码 + expiry_time (int): 过期时间(秒),默认5分钟 + code_type (str): 验证码类型,"register" 或 "reset_password" + + 返回: + bool: 保存成功返回True,否则返回False + """ + import time + + # 优先尝试使用MongoDB + try: + from SMYMongoDBAPI import SMYMongoDBAPI + import os + # 根据环境动态选择MongoDB配置 + if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true': + environment = "production" + else: + environment = "test" + mongo_api = SMYMongoDBAPI(environment) + if mongo_api.is_connected(): + success = mongo_api.save_verification_code(qq_number, verification_code, expiry_time, code_type) + if success: + print(f"[验证码系统-MongoDB] 为QQ {qq_number} 保存{code_type}验证码: {verification_code}") + return True + else: + print(f"[验证码系统-MongoDB] 保存失败,尝试使用JSON文件") + except Exception as e: + print(f"[验证码系统-MongoDB] MongoDB保存失败: {str(e)},尝试使用JSON文件") + + # MongoDB失败,使用JSON文件备用 + # 创建目录(如果不存在) + os.makedirs(os.path.dirname(VERIFICATION_CACHE_FILE), exist_ok=True) + + # 读取现有的验证码数据 + verification_data = {} + if os.path.exists(VERIFICATION_CACHE_FILE): + try: + with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file: + verification_data = json.load(file) + except Exception as e: + print(f"读取验证码文件失败: {str(e)}") + verification_data = {} + + # 添加新的验证码 + expire_at = time.time() + expiry_time + current_time = time.time() + + # 创建验证码记录,包含更多信息用于调试 + verification_data[qq_number] = { + "code": verification_code, + "expire_at": expire_at, + "code_type": code_type, + "created_at": current_time, + "used": False # 新增:标记验证码是否已使用 + } + + # 保存到文件 + try: + with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file: + json.dump(verification_data, file, indent=2, ensure_ascii=False) + + print(f"[验证码系统-JSON] 为QQ {qq_number} 保存{code_type}验证码: {verification_code}, 过期时间: {expire_at}") + return True + except Exception as e: + print(f"保存验证码失败: {str(e)}") + return False + + #验证用户输入的验证码(优先使用MongoDB) + @staticmethod + def verify_code(qq_number, input_code, code_type="register"): + """ + 验证用户输入的验证码(优先使用MongoDB) + + 参数: + qq_number (str): QQ号 + input_code (str): 用户输入的验证码 + code_type (str): 验证码类型,"register" 或 "reset_password" + + 返回: + bool: 验证成功返回True,否则返回False + str: 成功或错误信息 + """ + import time + + # 优先尝试使用MongoDB + try: + from SMYMongoDBAPI import SMYMongoDBAPI + import os + # 根据环境动态选择MongoDB配置 + if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true': + environment = "production" + else: + environment = "test" + mongo_api = SMYMongoDBAPI(environment) + if mongo_api.is_connected(): + success, message = mongo_api.verify_verification_code(qq_number, input_code, code_type) + print(f"[验证码系统-MongoDB] QQ {qq_number} 验证结果: {success}, 消息: {message}") + return success, message + except Exception as e: + print(f"[验证码系统-MongoDB] MongoDB验证失败: {str(e)},尝试使用JSON文件") + + # MongoDB失败,使用JSON文件备用 + # 检查缓存文件是否存在 + if not os.path.exists(VERIFICATION_CACHE_FILE): + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 缓存文件不存在") + return False, "验证码不存在或已过期" + + # 读取验证码数据 + try: + with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file: + verification_data = json.load(file) + except Exception as e: + print(f"[验证码系统-JSON] 读取验证码文件失败: {str(e)}") + return False, "验证码数据损坏" + + # 检查该QQ号是否有验证码 + if qq_number not in verification_data: + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 没有找到验证码记录") + return False, "验证码不存在,请重新获取" + + # 获取存储的验证码信息 + code_info = verification_data[qq_number] + stored_code = code_info.get("code", "") + expire_at = code_info.get("expire_at", 0) + stored_code_type = code_info.get("code_type", "register") + is_used = code_info.get("used", False) + created_at = code_info.get("created_at", 0) + + print(f"[验证码系统-JSON] QQ {qq_number} 验证码详情: 存储码={stored_code}, 输入码={input_code}, 类型={stored_code_type}, 已使用={is_used}, 创建时间={created_at}") + + # 检查验证码类型是否匹配 + if stored_code_type != code_type: + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码类型不匹配,存储类型={stored_code_type}, 请求类型={code_type}") + return False, f"验证码类型不匹配,请重新获取{code_type}验证码" + + # 检查验证码是否已被使用 + if is_used: + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码已被使用") + return False, "验证码已被使用,请重新获取" + + # 检查验证码是否过期 + current_time = time.time() + if current_time > expire_at: + # 移除过期的验证码 + del verification_data[qq_number] + with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file: + json.dump(verification_data, file, indent=2, ensure_ascii=False) + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码已过期") + return False, "验证码已过期,请重新获取" + + # 验证码比较(不区分大小写) + if input_code.upper() == stored_code.upper(): + # 验证成功,标记为已使用而不是删除 + verification_data[qq_number]["used"] = True + verification_data[qq_number]["used_at"] = current_time + + try: + with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file: + json.dump(verification_data, file, indent=2, ensure_ascii=False) + print(f"[验证码系统-JSON] QQ {qq_number} 验证成功: 验证码已标记为已使用") + return True, "验证码正确" + except Exception as e: + print(f"[验证码系统-JSON] 标记验证码已使用时失败: {str(e)}") + return True, "验证码正确" # 即使标记失败,验证还是成功的 + else: + print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码不匹配") + return False, "验证码错误" + + #清理过期的验证码和已使用的验证码(优先使用MongoDB) + @staticmethod + def clean_expired_codes(): + """ + 清理过期的验证码和已使用的验证码(优先使用MongoDB) + """ + import time + + # 优先尝试使用MongoDB + try: + from SMYMongoDBAPI import SMYMongoDBAPI + import os + # 根据环境动态选择MongoDB配置 + if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true': + environment = "production" + else: + environment = "test" + mongo_api = SMYMongoDBAPI(environment) + if mongo_api.is_connected(): + expired_count = mongo_api.clean_expired_verification_codes() + print(f"[验证码系统-MongoDB] 清理完成,删除了 {expired_count} 个过期验证码") + return expired_count + except Exception as e: + print(f"[验证码系统-MongoDB] MongoDB清理失败: {str(e)},尝试使用JSON文件") + + # MongoDB失败,使用JSON文件备用 + if not os.path.exists(VERIFICATION_CACHE_FILE): + return + + try: + with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file: + verification_data = json.load(file) + + current_time = time.time() + removed_keys = [] + + # 找出过期的验证码和已使用的验证码(超过1小时) + for qq_number, code_info in verification_data.items(): + expire_at = code_info.get("expire_at", 0) + is_used = code_info.get("used", False) + used_at = code_info.get("used_at", 0) + + should_remove = False + + # 过期的验证码 + if current_time > expire_at: + should_remove = True + print(f"[验证码清理-JSON] 移除过期验证码: QQ {qq_number}") + + # 已使用超过1小时的验证码 + elif is_used and used_at > 0 and (current_time - used_at) > 3600: + should_remove = True + print(f"[验证码清理-JSON] 移除已使用的验证码: QQ {qq_number}") + + if should_remove: + removed_keys.append(qq_number) + + # 移除标记的验证码 + for key in removed_keys: + del verification_data[key] + + # 保存更新后的数据 + if removed_keys: + with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file: + json.dump(verification_data, file, indent=2, ensure_ascii=False) + print(f"[验证码清理-JSON] 共清理了 {len(removed_keys)} 个验证码") + + except Exception as e: + print(f"清理验证码失败: {str(e)}") + + #获取验证码状态(优先使用MongoDB) + @staticmethod + def get_verification_status(qq_number): + """ + 获取验证码状态(优先使用MongoDB) + + 参数: + qq_number (str): QQ号 + + 返回: + dict: 验证码状态信息 + """ + import time + + # 优先尝试使用MongoDB + try: + from SMYMongoDBAPI import SMYMongoDBAPI + import os + # 根据环境动态选择MongoDB配置 + if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true': + environment = "production" + else: + environment = "test" + mongo_api = SMYMongoDBAPI(environment) + if mongo_api.is_connected(): + verification_codes = mongo_api.get_verification_codes() + if verification_codes and qq_number in verification_codes: + code_info = verification_codes[qq_number] + current_time = time.time() + + return { + "status": "found", + "code": code_info.get("code", ""), + "code_type": code_info.get("code_type", "unknown"), + "used": code_info.get("used", False), + "expired": current_time > code_info.get("expire_at", 0), + "created_at": code_info.get("created_at", 0), + "expire_at": code_info.get("expire_at", 0), + "used_at": code_info.get("used_at", 0), + "source": "mongodb" + } + else: + return {"status": "no_code", "source": "mongodb"} + except Exception as e: + print(f"[验证码系统-MongoDB] MongoDB状态查询失败: {str(e)},尝试使用JSON文件") + + # MongoDB失败,使用JSON文件备用 + if not os.path.exists(VERIFICATION_CACHE_FILE): + return {"status": "no_cache_file"} + + try: + with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file: + verification_data = json.load(file) + + if qq_number not in verification_data: + return {"status": "no_code"} + + code_info = verification_data[qq_number] + current_time = time.time() + + return { + "status": "found", + "code": code_info.get("code", ""), + "code_type": code_info.get("code_type", "unknown"), + "used": code_info.get("used", False), + "expired": current_time > code_info.get("expire_at", 0), + "created_at": code_info.get("created_at", 0), + "expire_at": code_info.get("expire_at", 0), + "used_at": code_info.get("used_at", 0), + "source": "json" + } + + except Exception as e: + return {"status": "error", "message": str(e)} + + +# 测试邮件发送 +if __name__ == "__main__": + # 清理过期验证码 + EmailVerification.clean_expired_codes() + + # 生成验证码 + test_qq = input("请输入测试QQ号: ") + verification_code = EmailVerification.generate_verification_code() + print(f"生成的验证码: {verification_code}") + + # 发送测试邮件 + success, message = EmailVerification.send_verification_email(test_qq, verification_code) + print(f"发送结果: {success}, 消息: {message}") + + if success: + # 保存验证码 + EmailVerification.save_verification_code(test_qq, verification_code) + + # 测试验证 + test_input = input("请输入收到的验证码: ") + verify_success, verify_message = EmailVerification.verify_code(test_qq, test_input) + print(f"验证结果: {verify_success}, 消息: {verify_message}") \ No newline at end of file diff --git a/README.md b/README.md index ed4dad6e..169baa46 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,102 @@ -# InfoGenie +# ✨ InfoGenie 神奇万事通 + +> 🎨 一个多功能的聚合软件应用 💬 + +## 📋 项目概述 + +InfoGenie 是一个前后端分离的多功能聚合应用,提供实时数据接口、休闲游戏、AI工具等丰富功能。 + +### 🏗️ 技术架构 + +- **前端**: React + Styled Components + React Router +- **后端**: Python Flask + MongoDB + PyMongo +- **架构**: 前后端分离,RESTful API +- **部署**: 支持Docker容器化部署 + +### 🌟 主要功能 + +#### 📡 60s API 模块 +- **热搜榜单**: 抖音、微博、猫眼票房、HackerNews等 +- **日更资讯**: 60秒读懂世界、必应壁纸、历史今天、汇率信息 +- **实用功能**: 天气查询、百科搜索、农历信息、二维码生成 +- **娱乐消遣**: 随机一言、音频、趣味题、文案生成 + +#### 🎮 小游戏模块 +- 经典游戏合集(开发中) +- 移动端优化 +- 即点即玩 + +#### 🤖 AI模型模块 +- AI对话助手(开发中) +- 智能文本生成(开发中) +- 图像识别分析(规划中) +- 需要登录验证 + +## 🚀 快速开始 + +### 📋 环境要求 + +- **Python**: 3.8+ +- **Node.js**: 14+ +- **MongoDB**: 4.0+ + +### 📦 安装依赖 + +#### 后端依赖 +```bash +cd backend +pip install -r requirements.txt +``` + +#### 前端依赖 +```bash +cd frontend/react-app +npm install +``` + +### 🎯 启动服务 + +#### 方式一:使用启动器(推荐) +```bash +# 双击运行 启动器.bat +# 选择相应的启动选项 +``` + +#### 方式二:手动启动 + +**启动后端服务** +```bash +cd backend +python run.py +# 后端服务: http://localhost:5000 +``` + +**启动前端服务** +```bash +cd frontend/react-app +npm start +# 前端服务: http://localhost:3000 +``` + +## 📞 联系方式 + +- **开发者**: 神奇万事通 +- **项目地址**: https://github.com/shumengya/InfoGenie +- **反馈邮箱**: 请通过GitHub Issues反馈 + +## 📄 许可证 + +本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情 + +--- + +
+ +**✨ 感谢使用 InfoGenie 神奇万事通 ✨** + +🎨 *一个多功能的聚合软件应用* 💬 + +
神奇万事通,一个支持Windows,Android和web的app,聚合了许多神奇有趣的功能,帮助用户一键化解决问题 前端使用React框架,后端使用Python的Flask框架 diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 00000000..20905b62 --- /dev/null +++ b/backend/app.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +InfoGenie 后端主应用入口 +Created by: 神奇万事通 +Date: 2025-09-02 +""" + +from flask import Flask, jsonify, request, session, send_from_directory +from flask_cors import CORS +from flask_pymongo import PyMongo +import os +from datetime import datetime, timedelta +import hashlib +import secrets + +# 导入模块 +from modules.auth import auth_bp +from modules.api_60s import api_60s_bp +from modules.user_management import user_bp +from modules.email_service import init_mail + +from config import Config + +def create_app(): + """创建Flask应用实例""" + app = Flask(__name__) + + # 加载配置 + app.config.from_object(Config) + + # 启用CORS跨域支持 + CORS(app, supports_credentials=True) + + # 初始化MongoDB + mongo = PyMongo(app) + app.mongo = mongo + + # 初始化邮件服务 + init_mail(app) + + # 注册蓝图 + app.register_blueprint(auth_bp, url_prefix='/api/auth') + app.register_blueprint(api_60s_bp, url_prefix='/api/60s') + app.register_blueprint(user_bp, url_prefix='/api/user') + + # 基础路由 + @app.route('/') + def index(): + """API根路径""" + return jsonify({ + 'message': '✨ 神奇万事通 API 服务运行中 ✨', + 'version': '1.0.0', + 'timestamp': datetime.now().isoformat(), + 'endpoints': { + 'auth': '/api/auth', + '60s_api': '/api/60s', + 'user': '/api/user' + } + }) + + @app.route('/api/health') + def health_check(): + """健康检查接口""" + try: + # 检查数据库连接 + mongo.db.command('ping') + db_status = 'connected' + except Exception as e: + db_status = f'error: {str(e)}' + + return jsonify({ + 'status': 'running', + 'database': db_status, + 'timestamp': datetime.now().isoformat() + }) + + # 60sapi静态文件服务 + @app.route('/60sapi/') + def serve_60sapi_files(filename): + """提供60sapi目录下的静态文件服务""" + try: + # 获取项目根目录 + project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + api_directory = os.path.join(project_root, 'frontend', '60sapi') + + # 安全检查:确保文件路径在允许的目录内 + full_path = os.path.join(api_directory, filename) + if not os.path.commonpath([api_directory, full_path]) == api_directory: + return jsonify({'error': '非法文件路径'}), 403 + + # 检查文件是否存在 + if not os.path.exists(full_path): + return jsonify({'error': '文件不存在'}), 404 + + # 获取文件目录和文件名 + directory = os.path.dirname(full_path) + file_name = os.path.basename(full_path) + + return send_from_directory(directory, file_name) + + except Exception as e: + return jsonify({'error': f'文件服务错误: {str(e)}'}), 500 + + # 错误处理 + @app.errorhandler(404) + def not_found(error): + return jsonify({ + 'error': 'API接口不存在', + 'message': '请检查请求路径是否正确' + }), 404 + + @app.errorhandler(500) + def internal_error(error): + return jsonify({ + 'error': '服务器内部错误', + 'message': '请稍后重试或联系管理员' + }), 500 + + return app + +if __name__ == '__main__': + app = create_app() + print("🚀 启动 InfoGenie 后端服务...") + print("📡 API地址: http://localhost:5000") + print("📚 文档地址: http://localhost:5000/api/health") + app.run(debug=True, host='0.0.0.0', port=5000) diff --git a/backend/config.py b/backend/config.py new file mode 100644 index 00000000..c9e7ee47 --- /dev/null +++ b/backend/config.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +InfoGenie 配置文件 +Created by: 神奇万事通 +Date: 2025-09-02 +""" + +import os +from datetime import timedelta +from dotenv import load_dotenv + +# 加载环境变量 +load_dotenv() + +class Config: + """应用配置类""" + + # 基础配置 + SECRET_KEY = os.environ.get('SECRET_KEY') or 'infogenie-secret-key-2025' + + # MongoDB 配置 + MONGO_URI = os.environ.get('MONGO_URI') or 'mongodb://localhost:27017/InfoGenie' + + # Session 配置 + PERMANENT_SESSION_LIFETIME = timedelta(days=7) # 会话持续7天 + SESSION_COOKIE_SECURE = False # 开发环境设为False,生产环境设为True + SESSION_COOKIE_HTTPONLY = True + SESSION_COOKIE_SAMESITE = 'Lax' + + # 邮件配置 + MAIL_SERVER = 'smtp.qq.com' + MAIL_PORT = 465 + MAIL_USE_SSL = True + MAIL_USE_TLS = False + MAIL_USERNAME = os.environ.get('MAIL_USERNAME') or 'your-email@qq.com' + MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') or 'your-app-password' + MAIL_DEFAULT_SENDER = ('InfoGenie 神奇万事通', os.environ.get('MAIL_USERNAME') or 'your-email@qq.com') + + # API 配置 + API_RATE_LIMIT = '100 per hour' # API调用频率限制 + + # 外部API配置 + EXTERNAL_APIS = { + '60s': [ + 'https://60s.api.shumengya.top', + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run', + 'https://60s.114128.xyz', + 'https://60s-cf.114128.xyz' + ] + } + + # 应用信息 + APP_INFO = { + 'name': '✨ 神奇万事通 ✨', + 'description': '🎨 一个多功能的聚合软件应用 💬', + 'author': '👨‍💻 by-神奇万事通', + 'version': '1.0.0', + 'icp': '📄 蜀ICP备2025151694号' + } + +class DevelopmentConfig(Config): + """开发环境配置""" + DEBUG = True + TESTING = False + +class ProductionConfig(Config): + """生产环境配置""" + DEBUG = False + TESTING = False + SESSION_COOKIE_SECURE = True + +class TestingConfig(Config): + """测试环境配置""" + DEBUG = True + TESTING = True + MONGO_URI = 'mongodb://localhost:27017/InfoGenie_Test' + +# 配置字典 +config = { + 'development': DevelopmentConfig, + 'production': ProductionConfig, + 'testing': TestingConfig, + 'default': DevelopmentConfig +} diff --git a/backend/md/邮件服务修复说明.md b/backend/md/邮件服务修复说明.md new file mode 100644 index 00000000..547add51 --- /dev/null +++ b/backend/md/邮件服务修复说明.md @@ -0,0 +1,92 @@ +# InfoGenie 邮件服务修复说明 + +## 修复内容 + +### 问题描述 +原始的 `email_service.py` 中的邮件发送功能存在问题,无法正常发送验证码邮件。 + +### 修复方案 +参考成功的 `QQEmailSendAPI.py` 实现,对 `email_service.py` 进行了以下修复: + +1. **SMTP连接方式优化** + - 将 `with smtplib.SMTP_SSL()` 改为直接使用 `smtplib.SMTP_SSL()` + - 显式调用 `smtp_obj.quit()` 关闭连接 + +2. **邮件头设置优化** + - 确保 `From` 字段直接使用邮箱地址,不使用 `Header` 包装 + - 保持与成功实现的一致性 + +3. **错误处理增强** + - 添加了针对 `SMTPAuthenticationError` 的专门处理 + - 添加了针对 `SMTPConnectError` 的专门处理 + - 提供更详细的错误信息 + +4. **调试信息优化** + - 添加了适量的日志输出用于问题诊断 + - 移除了生产环境不安全的验证码返回 + +## 配置要求 + +### 环境变量 +确保设置以下环境变量: +```bash +MAIL_USERNAME=your-qq-email@qq.com +MAIL_PASSWORD=your-qq-auth-code +``` + +### QQ邮箱授权码 +1. 登录QQ邮箱 +2. 进入设置 -> 账户 +3. 开启SMTP服务 +4. 获取授权码(不是QQ密码) + +## 使用方法 + +### 发送验证码 +```python +from modules.email_service import send_verification_email + +# 发送注册验证码 +result = send_verification_email('user@qq.com', 'register') + +# 发送登录验证码 +result = send_verification_email('user@qq.com', 'login') +``` + +### 验证验证码 +```python +from modules.email_service import verify_code + +# 验证用户输入的验证码 +result = verify_code('user@qq.com', '123456') +``` + +## 测试 + +运行测试脚本验证功能: +```bash +cd backend +python test/test_email_fix.py +``` + +## 支持的邮箱 + +目前仅支持QQ邮箱系列: +- @qq.com +- @vip.qq.com +- @foxmail.com + +## 注意事项 + +1. **安全性**:验证码不会在API响应中返回,仅通过邮件发送 +2. **有效期**:验证码有效期为5分钟 +3. **尝试次数**:每个验证码最多可尝试验证3次 +4. **频率限制**:建议添加发送频率限制防止滥用 + +## 修复文件 + +- `backend/modules/email_service.py` - 主要修复文件 +- `backend/test/test_email_fix.py` - 测试脚本 +- `backend/邮件服务修复说明.md` - 本说明文档 + +修复完成后,邮件发送功能已正常工作,可以成功发送注册和登录验证码邮件。 \ No newline at end of file diff --git a/backend/modules/api_60s.py b/backend/modules/api_60s.py new file mode 100644 index 00000000..8d1ba3ea --- /dev/null +++ b/backend/modules/api_60s.py @@ -0,0 +1,419 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +60s API模块 - 提供各种实时数据接口 +Created by: 神奇万事通 +Date: 2025-09-02 +""" + +from flask import Blueprint, jsonify, request +import requests +import json +from datetime import datetime, timedelta +import random +import time + +api_60s_bp = Blueprint('api_60s', __name__) + +# API配置 +API_ENDPOINTS = { + '抖音热搜': { + 'urls': [ + 'https://api.vvhan.com/api/hotlist?type=douyin', + 'https://tenapi.cn/v2/douyinhot', + 'https://api.oioweb.cn/api/common/tebie/dyhot' + ], + 'cache_time': 600 # 10分钟缓存 + }, + '微博热搜': { + 'urls': [ + 'https://api.vvhan.com/api/hotlist?type=weibo', + 'https://tenapi.cn/v2/wbhot', + 'https://api.oioweb.cn/api/common/tebie/wbhot' + ], + 'cache_time': 300 # 5分钟缓存 + }, + '猫眼票房': { + 'urls': [ + 'https://api.vvhan.com/api/hotlist?type=maoyan', + 'https://tenapi.cn/v2/maoyan' + ], + 'cache_time': 3600 # 1小时缓存 + }, + '网易云音乐': { + 'urls': [ + 'https://api.vvhan.com/api/hotlist?type=netease', + 'https://tenapi.cn/v2/music' + ], + 'cache_time': 1800 # 30分钟缓存 + }, + 'HackerNews': { + 'urls': [ + 'https://api.vvhan.com/api/hotlist?type=hackernews', + 'https://hacker-news.firebaseio.com/v0/topstories.json' + ], + 'cache_time': 1800 # 30分钟缓存 + } +} + +# 内存缓存 +cache = {} + +def fetch_data_with_fallback(urls, timeout=10): + """使用备用URL获取数据""" + for url in urls: + try: + response = requests.get(url, timeout=timeout, headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + }) + if response.status_code == 200: + return response.json() + except Exception as e: + print(f"URL {url} 失败: {str(e)}") + continue + return None + +def get_cached_data(key, cache_time): + """获取缓存数据""" + if key in cache: + cached_time, data = cache[key] + if datetime.now() - cached_time < timedelta(seconds=cache_time): + return data + return None + +def set_cache_data(key, data): + """设置缓存数据""" + cache[key] = (datetime.now(), data) + +@api_60s_bp.route('/douyin', methods=['GET']) +def get_douyin_hot(): + """获取抖音热搜榜""" + try: + # 检查缓存 + cached = get_cached_data('douyin', API_ENDPOINTS['抖音热搜']['cache_time']) + if cached: + return jsonify({ + 'success': True, + 'data': cached, + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'from_cache': True + }) + + # 获取新数据 + data = fetch_data_with_fallback(API_ENDPOINTS['抖音热搜']['urls']) + + if data: + # 标准化数据格式 + if 'data' in data: + hot_list = data['data'] + elif isinstance(data, list): + hot_list = data + else: + hot_list = [] + + result = { + 'title': '抖音热搜榜', + 'subtitle': '实时热门话题 · 紧跟潮流趋势', + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'total': len(hot_list), + 'list': hot_list[:50] # 最多返回50条 + } + + # 设置缓存 + set_cache_data('douyin', result) + + return jsonify({ + 'success': True, + 'data': result, + 'from_cache': False + }) + else: + return jsonify({ + 'success': False, + 'message': '获取数据失败,所有数据源暂时不可用' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/weibo', methods=['GET']) +def get_weibo_hot(): + """获取微博热搜榜""" + try: + # 检查缓存 + cached = get_cached_data('weibo', API_ENDPOINTS['微博热搜']['cache_time']) + if cached: + return jsonify({ + 'success': True, + 'data': cached, + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'from_cache': True + }) + + # 获取新数据 + data = fetch_data_with_fallback(API_ENDPOINTS['微博热搜']['urls']) + + if data: + if 'data' in data: + hot_list = data['data'] + elif isinstance(data, list): + hot_list = data + else: + hot_list = [] + + result = { + 'title': '微博热搜榜', + 'subtitle': '热门话题 · 实时更新', + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'total': len(hot_list), + 'list': hot_list[:50] + } + + set_cache_data('weibo', result) + + return jsonify({ + 'success': True, + 'data': result, + 'from_cache': False + }) + else: + return jsonify({ + 'success': False, + 'message': '获取数据失败,所有数据源暂时不可用' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/maoyan', methods=['GET']) +def get_maoyan_box_office(): + """获取猫眼票房排行榜""" + try: + cached = get_cached_data('maoyan', API_ENDPOINTS['猫眼票房']['cache_time']) + if cached: + return jsonify({ + 'success': True, + 'data': cached, + 'from_cache': True + }) + + data = fetch_data_with_fallback(API_ENDPOINTS['猫眼票房']['urls']) + + if data: + if 'data' in data: + box_office_list = data['data'] + elif isinstance(data, list): + box_office_list = data + else: + box_office_list = [] + + result = { + 'title': '猫眼票房排行榜', + 'subtitle': '实时票房数据', + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'total': len(box_office_list), + 'list': box_office_list[:20] + } + + set_cache_data('maoyan', result) + + return jsonify({ + 'success': True, + 'data': result, + 'from_cache': False + }) + else: + return jsonify({ + 'success': False, + 'message': '获取数据失败' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/60s', methods=['GET']) +def get_60s_news(): + """获取每天60秒读懂世界""" + try: + urls = [ + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run' + ] + + data = fetch_data_with_fallback(urls) + + if data: + return jsonify({ + 'success': True, + 'data': { + 'title': '每天60秒读懂世界', + 'content': data, + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + } + }) + else: + return jsonify({ + 'success': False, + 'message': '获取数据失败' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/bing-wallpaper', methods=['GET']) +def get_bing_wallpaper(): + """获取必应每日壁纸""" + try: + url = 'https://api.vvhan.com/api/bing' + response = requests.get(url, timeout=10) + + if response.status_code == 200: + return jsonify({ + 'success': True, + 'data': { + 'title': '必应每日壁纸', + 'image_url': response.url, + 'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + } + }) + else: + return jsonify({ + 'success': False, + 'message': '获取壁纸失败' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/weather', methods=['GET']) +def get_weather(): + """获取天气信息""" + try: + city = request.args.get('city', '北京') + url = f'https://api.vvhan.com/api/weather?city={city}' + + response = requests.get(url, timeout=10) + + if response.status_code == 200: + data = response.json() + return jsonify({ + 'success': True, + 'data': data + }) + else: + return jsonify({ + 'success': False, + 'message': '获取天气信息失败' + }), 503 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@api_60s_bp.route('/scan-directories', methods=['GET']) +def scan_directories(): + """扫描60sapi目录结构""" + try: + import os + + # 获取项目根目录 + project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + api_directory = os.path.join(project_root, 'frontend', '60sapi') + + if not os.path.exists(api_directory): + return jsonify({ + 'success': False, + 'message': '60sapi目录不存在' + }), 404 + + categories = [] + + # 定义分类配置 + category_config = { + '热搜榜单': {'color': '#66bb6a'}, + '日更资讯': {'color': '#4caf50'}, + '实用功能': {'color': '#388e3c'}, + '娱乐消遣': {'color': '#66bb6a'} + } + + # 颜色渐变配置 + gradient_colors = [ + 'linear-gradient(135deg, #81c784 0%, #66bb6a 100%)', + 'linear-gradient(135deg, #a5d6a7 0%, #81c784 100%)', + 'linear-gradient(135deg, #c8e6c9 0%, #a5d6a7 100%)', + 'linear-gradient(135deg, #66bb6a 0%, #4caf50 100%)', + 'linear-gradient(135deg, #4caf50 0%, #388e3c 100%)' + ] + + # 扫描目录 + for category_name in os.listdir(api_directory): + category_path = os.path.join(api_directory, category_name) + + if os.path.isdir(category_path) and category_name in category_config: + apis = [] + + # 扫描分类下的模块 + for i, module_name in enumerate(os.listdir(category_path)): + module_path = os.path.join(category_path, module_name) + index_path = os.path.join(module_path, 'index.html') + + if os.path.isdir(module_path) and os.path.exists(index_path): + # 读取HTML文件获取标题 + try: + with open(index_path, 'r', encoding='utf-8') as f: + html_content = f.read() + title_match = html_content.find('') + if title_match != -1: + title_end = html_content.find('', title_match) + if title_end != -1: + title = html_content[title_match + 7:title_end].strip() + else: + title = module_name + else: + title = module_name + except: + title = module_name + + apis.append({ + 'title': title, + 'description': f'{module_name}相关功能', + 'link': f'/60sapi/{category_name}/{module_name}/index.html', + 'status': 'active', + 'color': gradient_colors[i % len(gradient_colors)] + }) + + if apis: + categories.append({ + 'title': category_name, + 'color': category_config[category_name]['color'], + 'apis': apis + }) + + return jsonify({ + 'success': True, + 'categories': categories + }) + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'扫描目录时出错: {str(e)}' + }), 500 diff --git a/backend/modules/auth.py b/backend/modules/auth.py new file mode 100644 index 00000000..d091ac1d --- /dev/null +++ b/backend/modules/auth.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +用户认证模块 +Created by: 神奇万事通 +Date: 2025-09-02 +""" + +from flask import Blueprint, request, jsonify, session, current_app +from werkzeug.security import generate_password_hash, check_password_hash +import hashlib +import re +from datetime import datetime +from .email_service import send_verification_email, verify_code, is_qq_email, get_qq_avatar_url + +auth_bp = Blueprint('auth', __name__) + +def validate_qq_email(email): + """验证QQ邮箱格式""" + return is_qq_email(email) + +def validate_password(password): + """验证密码格式(6-20位)""" + return 6 <= len(password) <= 20 + +@auth_bp.route('/send-verification', methods=['POST']) +def send_verification(): + """发送验证码邮件""" + try: + data = request.get_json() + email = data.get('email', '').strip() + verification_type = data.get('type', 'register') # register, login + + # 参数验证 + if not email: + return jsonify({ + 'success': False, + 'message': '邮箱地址不能为空' + }), 400 + + if not validate_qq_email(email): + return jsonify({ + 'success': False, + 'message': '仅支持QQ邮箱(qq.com、vip.qq.com、foxmail.com)' + }), 400 + + # 获取数据库集合 + db = current_app.mongo.db + users_collection = db.userdata + + # 检查邮箱是否已注册 + existing_user = users_collection.find_one({'邮箱': email}) + + if verification_type == 'register' and existing_user: + return jsonify({ + 'success': False, + 'message': '该邮箱已被注册' + }), 409 + + if verification_type == 'login' and not existing_user: + return jsonify({ + 'success': False, + 'message': '该邮箱尚未注册' + }), 404 + + # 发送验证码 + result = send_verification_email(email, verification_type) + + if result['success']: + return jsonify(result), 200 + else: + return jsonify(result), 500 + + except Exception as e: + current_app.logger.error(f"发送验证码失败: {str(e)}") + return jsonify({ + 'success': False, + 'message': '发送失败,请稍后重试' + }), 500 + +@auth_bp.route('/verify-code', methods=['POST']) +def verify_verification_code(): + """验证验证码""" + try: + data = request.get_json() + email = data.get('email', '').strip() + code = data.get('code', '').strip() + + # 参数验证 + if not email or not code: + return jsonify({ + 'success': False, + 'message': '邮箱和验证码不能为空' + }), 400 + + # 验证码校验 + result = verify_code(email, code) + + if result['success']: + return jsonify(result), 200 + else: + return jsonify(result), 400 + + except Exception as e: + current_app.logger.error(f"验证码校验失败: {str(e)}") + return jsonify({ + 'success': False, + 'message': '验证失败,请稍后重试' + }), 500 + +@auth_bp.route('/register', methods=['POST']) +def register(): + """用户注册(需要先验证邮箱)""" + try: + data = request.get_json() + email = data.get('email', '').strip() + username = data.get('username', '').strip() + password = data.get('password', '').strip() + code = data.get('code', '').strip() + + # 参数验证 + if not all([email, username, password, code]): + return jsonify({ + 'success': False, + 'message': '所有字段都不能为空' + }), 400 + + if not validate_qq_email(email): + return jsonify({ + 'success': False, + 'message': '仅支持QQ邮箱注册' + }), 400 + + if not validate_password(password): + return jsonify({ + 'success': False, + 'message': '密码长度必须在6-20位之间' + }), 400 + + # 验证验证码 + verify_result = verify_code(email, code) + if not verify_result['success'] or verify_result.get('type') != 'register': + return jsonify({ + 'success': False, + 'message': '验证码无效或已过期' + }), 400 + + # 获取数据库集合 + db = current_app.mongo.db + users_collection = db.userdata + + # 检查邮箱是否已被注册 + if users_collection.find_one({'邮箱': email}): + return jsonify({ + 'success': False, + 'message': '该邮箱已被注册' + }), 409 + + # 检查用户名是否已被使用 + if users_collection.find_one({'用户名': username}): + return jsonify({ + 'success': False, + 'message': '该用户名已被使用' + }), 409 + + # 获取QQ头像 + avatar_url = get_qq_avatar_url(email) + + # 创建新用户 + password_hash = generate_password_hash(password) + user_data = { + '邮箱': email, + '用户名': username, + '密码': password_hash, + '头像': avatar_url, + '注册时间': datetime.now().isoformat(), + '最后登录': None, + '登录次数': 0, + '用户状态': 'active' + } + + result = users_collection.insert_one(user_data) + + if result.inserted_id: + return jsonify({ + 'success': True, + 'message': '注册成功!', + 'user': { + 'email': email, + 'username': username, + 'avatar': avatar_url + } + }), 201 + else: + return jsonify({ + 'success': False, + 'message': '注册失败,请稍后重试' + }), 500 + + except Exception as e: + current_app.logger.error(f"注册失败: {str(e)}") + return jsonify({ + 'success': False, + 'message': '注册失败,请稍后重试' + }), 500 + + if existing_user: + return jsonify({ + 'success': False, + 'message': '该账号已被注册' + }), 409 + + # 创建新用户 + password_hash = generate_password_hash(password) + user_data = { + '账号': account, + '密码': password_hash, + '注册时间': datetime.now().isoformat(), + '最后登录': None, + '登录次数': 0, + '用户状态': 'active' + } + + result = users_collection.insert_one(user_data) + + if result.inserted_id: + return jsonify({ + 'success': True, + 'message': '注册成功!' + }), 201 + else: + return jsonify({ + 'success': False, + 'message': '注册失败,请稍后重试' + }), 500 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@auth_bp.route('/login', methods=['POST']) +def login(): + """用户登录(支持邮箱+验证码或邮箱+密码)""" + try: + data = request.get_json() + email = data.get('email', '').strip() + password = data.get('password', '').strip() + code = data.get('code', '').strip() + + # 参数验证 + if not email: + return jsonify({ + 'success': False, + 'message': '邮箱地址不能为空' + }), 400 + + if not validate_qq_email(email): + return jsonify({ + 'success': False, + 'message': '仅支持QQ邮箱登录' + }), 400 + + # 获取数据库集合 + db = current_app.mongo.db + users_collection = db.userdata + + # 查找用户 + user = users_collection.find_one({'邮箱': email}) + + if not user: + return jsonify({ + 'success': False, + 'message': '该邮箱尚未注册' + }), 404 + + # 检查用户状态 + if user.get('用户状态') != 'active': + return jsonify({ + 'success': False, + 'message': '账号已被禁用,请联系管理员' + }), 403 + + # 验证方式:验证码登录或密码登录 + if code: + # 验证码登录 + verify_result = verify_code(email, code) + if not verify_result['success'] or verify_result.get('type') != 'login': + return jsonify({ + 'success': False, + 'message': '验证码无效或已过期' + }), 400 + elif password: + # 密码登录 + if not check_password_hash(user['密码'], password): + return jsonify({ + 'success': False, + 'message': '密码错误' + }), 401 + else: + return jsonify({ + 'success': False, + 'message': '请输入密码或验证码' + }), 400 + + # 登录成功,更新用户信息 + users_collection.update_one( + {'邮箱': email}, + { + '$set': {'最后登录': datetime.now().isoformat()}, + '$inc': {'登录次数': 1} + } + ) + + # 设置会话 + session['user_id'] = str(user['_id']) + session['email'] = email + session['username'] = user.get('用户名', '') + session.permanent = True + + return jsonify({ + 'success': True, + 'message': '登录成功!', + 'user': { + 'id': str(user['_id']), + 'email': email, + 'username': user.get('用户名', ''), + 'avatar': user.get('头像', ''), + 'login_count': user.get('登录次数', 0) + 1 + } + }), 200 + + except Exception as e: + current_app.logger.error(f"登录失败: {str(e)}") + return jsonify({ + 'success': False, + 'message': '登录失败,请稍后重试' + }), 500 + + # 登录成功,创建会话 + session['user_id'] = str(user['_id']) + session['account'] = user['账号'] + session['logged_in'] = True + + # 更新登录信息 + users_collection.update_one( + {'_id': user['_id']}, + { + '$set': {'最后登录': datetime.now().isoformat()}, + '$inc': {'登录次数': 1} + } + ) + + return jsonify({ + 'success': True, + 'message': '登录成功!', + 'user': { + 'account': user['账号'], + 'last_login': user.get('最后登录'), + 'login_count': user.get('登录次数', 0) + 1 + } + }), 200 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@auth_bp.route('/logout', methods=['POST']) +def logout(): + """用户登出""" + try: + if 'logged_in' in session: + session.clear() + return jsonify({ + 'success': True, + 'message': '已成功登出' + }), 200 + else: + return jsonify({ + 'success': False, + 'message': '用户未登录' + }), 401 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@auth_bp.route('/check', methods=['GET']) +def check_login(): + """检查登录状态""" + try: + if session.get('logged_in'): + return jsonify({ + 'success': True, + 'logged_in': True, + 'user': { + 'account': session.get('account'), + 'user_id': session.get('user_id') + } + }), 200 + else: + return jsonify({ + 'success': True, + 'logged_in': False + }), 200 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 diff --git a/backend/modules/email_service.py b/backend/modules/email_service.py new file mode 100644 index 00000000..13e33591 --- /dev/null +++ b/backend/modules/email_service.py @@ -0,0 +1,276 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +邮件发送模块 +负责处理用户注册、登录验证邮件 +""" + +import random +import string +import smtplib +from datetime import datetime, timedelta +from email.mime.text import MIMEText +from email.header import Header +from flask import current_app +import logging +import os + +# 验证码存储(生产环境建议使用Redis) +verification_codes = {} + +def init_mail(app): + """初始化邮件配置""" + # 使用smtplib直接发送,不需要Flask-Mail + pass + +def generate_verification_code(length=6): + """生成验证码""" + return ''.join(random.choices(string.digits, k=length)) + +def send_verification_email(email, verification_type='register'): + """ + 发送验证邮件 + + Args: + email: 收件人邮箱 + verification_type: 验证类型 ('register', 'login', 'reset_password') + + Returns: + dict: 发送结果 + """ + try: + # 验证QQ邮箱格式 + if not is_qq_email(email): + return { + 'success': False, + 'message': '仅支持QQ邮箱注册登录' + } + + # 生成验证码 + code = generate_verification_code() + + # 存储验证码(5分钟有效期) + verification_codes[email] = { + 'code': code, + 'type': verification_type, + 'expires_at': datetime.now() + timedelta(minutes=5), + 'attempts': 0 + } + + # 获取邮件配置 - 使用与QQEmailSendAPI相同的配置 + sender_email = os.environ.get('MAIL_USERNAME', '3205788256@qq.com') + sender_password = os.environ.get('MAIL_PASSWORD', 'szcaxvbftusqddhi') + + # 邮件模板 + if verification_type == 'register': + subject = '【InfoGenie】注册验证码' + html_content = f''' + + +
+
+

InfoGenie 神奇万事通

+

欢迎注册InfoGenie

+
+ +
+

验证码

+
+ {code} +
+

请在5分钟内输入此验证码完成注册

+
+ +
+

+ 如果您没有申请注册,请忽略此邮件
+ 此验证码5分钟内有效,请勿泄露给他人 +

+
+
+ + + ''' + else: # login + subject = '【InfoGenie】登录验证码' + html_content = f''' + + +
+
+

InfoGenie 神奇万事通

+

安全登录验证

+
+ +
+

登录验证码

+
+ {code} +
+

请在5分钟内输入此验证码完成登录

+
+ +
+

+ 如果不是您本人操作,请检查账户安全
+ 此验证码5分钟内有效,请勿泄露给他人 +

+
+
+ + + ''' + + # 创建邮件 - 使用与QQEmailSendAPI相同的方式 + message = MIMEText(html_content, 'html', 'utf-8') + message['From'] = sender_email # 直接使用邮箱地址,不使用Header包装 + message['To'] = email + message['Subject'] = Header(subject, 'utf-8') + + # 发送邮件 - 使用SSL端口465 + try: + # 使用与QQEmailSendAPI相同的连接方式 + smtp_obj = smtplib.SMTP_SSL('smtp.qq.com', 465) + smtp_obj.login(sender_email, sender_password) + smtp_obj.sendmail(sender_email, [email], message.as_string()) + smtp_obj.quit() + + print(f"验证码邮件发送成功: {email}") + return { + 'success': True, + 'message': '验证码已发送到您的邮箱', + 'email': email + } + + except smtplib.SMTPAuthenticationError as auth_error: + print(f"SMTP认证失败: {str(auth_error)}") + return { + 'success': False, + 'message': 'SMTP认证失败,请检查邮箱配置' + } + except smtplib.SMTPConnectError as conn_error: + print(f"SMTP连接失败: {str(conn_error)}") + return { + 'success': False, + 'message': 'SMTP服务器连接失败' + } + except Exception as smtp_error: + print(f"SMTP发送失败: {str(smtp_error)}") + return { + 'success': False, + 'message': f'邮件发送失败: {str(smtp_error)}' + } + + except Exception as e: + print(f"邮件发送失败: {str(e)}") + return { + 'success': False, + 'message': '邮件发送失败,请稍后重试' + } + +def verify_code(email, code): + """ + 验证验证码 + + Args: + email: 邮箱地址 + code: 验证码 + + Returns: + dict: 验证结果 + """ + if email not in verification_codes: + return { + 'success': False, + 'message': '验证码不存在或已过期' + } + + stored_info = verification_codes[email] + + # 检查过期时间 + if datetime.now() > stored_info['expires_at']: + del verification_codes[email] + return { + 'success': False, + 'message': '验证码已过期,请重新获取' + } + + # 检查尝试次数 + if stored_info['attempts'] >= 3: + del verification_codes[email] + return { + 'success': False, + 'message': '验证码输入错误次数过多,请重新获取' + } + + # 验证码校验 + if stored_info['code'] != code: + stored_info['attempts'] += 1 + return { + 'success': False, + 'message': f'验证码错误,还可尝试{3 - stored_info["attempts"]}次' + } + + # 验证成功,删除验证码 + verification_type = stored_info['type'] + del verification_codes[email] + + return { + 'success': True, + 'message': '验证码验证成功', + 'type': verification_type + } + +def is_qq_email(email): + """ + 验证是否为QQ邮箱 + + Args: + email: 邮箱地址 + + Returns: + bool: 是否为QQ邮箱 + """ + if not email or '@' not in email: + return False + + domain = email.split('@')[1].lower() + qq_domains = ['qq.com', 'vip.qq.com', 'foxmail.com'] + + return domain in qq_domains + +def get_qq_avatar_url(email): + """ + 根据QQ邮箱获取QQ头像URL + + Args: + email: QQ邮箱地址 + + Returns: + str: QQ头像URL + """ + if not is_qq_email(email): + return None + + # 提取QQ号码 + qq_number = email.split('@')[0] + + # 验证是否为纯数字(QQ号) + if not qq_number.isdigit(): + return None + + # 返回QQ头像API URL + return f"http://q1.qlogo.cn/g?b=qq&nk={qq_number}&s=100" + +def cleanup_expired_codes(): + """清理过期的验证码""" + current_time = datetime.now() + expired_emails = [ + email for email, info in verification_codes.items() + if current_time > info['expires_at'] + ] + + for email in expired_emails: + del verification_codes[email] + + return len(expired_emails) \ No newline at end of file diff --git a/backend/modules/user_management.py b/backend/modules/user_management.py new file mode 100644 index 00000000..9bdb2ae6 --- /dev/null +++ b/backend/modules/user_management.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +用户管理模块 +Created by: 神奇万事通 +Date: 2025-09-02 +""" + +from flask import Blueprint, request, jsonify, session, current_app +from datetime import datetime +from bson import ObjectId + +user_bp = Blueprint('user', __name__) + +def login_required(f): + """登录验证装饰器""" + def decorated_function(*args, **kwargs): + if not session.get('logged_in'): + return jsonify({ + 'success': False, + 'message': '请先登录' + }), 401 + return f(*args, **kwargs) + decorated_function.__name__ = f.__name__ + return decorated_function + +@user_bp.route('/profile', methods=['GET']) +@login_required +def get_profile(): + """获取用户资料""" + try: + user_id = session.get('user_id') + users_collection = current_app.mongo.db.userdata + + user = users_collection.find_one({'_id': ObjectId(user_id)}) + + if not user: + return jsonify({ + 'success': False, + 'message': '用户不存在' + }), 404 + + # 返回用户信息(不包含密码) + profile = { + 'account': user['账号'], + 'register_time': user.get('注册时间'), + 'last_login': user.get('最后登录'), + 'login_count': user.get('登录次数', 0), + 'status': user.get('用户状态', 'active') + } + + return jsonify({ + 'success': True, + 'data': profile + }), 200 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@user_bp.route('/change-password', methods=['POST']) +@login_required +def change_password(): + """修改密码""" + try: + data = request.get_json() + old_password = data.get('old_password', '').strip() + new_password = data.get('new_password', '').strip() + + if not old_password or not new_password: + return jsonify({ + 'success': False, + 'message': '旧密码和新密码不能为空' + }), 400 + + if len(new_password) < 6 or len(new_password) > 20: + return jsonify({ + 'success': False, + 'message': '新密码长度必须在6-20位之间' + }), 400 + + user_id = session.get('user_id') + users_collection = current_app.mongo.db.userdata + + user = users_collection.find_one({'_id': ObjectId(user_id)}) + + if not user: + return jsonify({ + 'success': False, + 'message': '用户不存在' + }), 404 + + from werkzeug.security import check_password_hash, generate_password_hash + + # 验证旧密码 + if not check_password_hash(user['密码'], old_password): + return jsonify({ + 'success': False, + 'message': '原密码错误' + }), 401 + + # 更新密码 + new_password_hash = generate_password_hash(new_password) + + result = users_collection.update_one( + {'_id': ObjectId(user_id)}, + {'$set': {'密码': new_password_hash}} + ) + + if result.modified_count > 0: + return jsonify({ + 'success': True, + 'message': '密码修改成功' + }), 200 + else: + return jsonify({ + 'success': False, + 'message': '密码修改失败' + }), 500 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@user_bp.route('/stats', methods=['GET']) +@login_required +def get_user_stats(): + """获取用户统计信息""" + try: + user_id = session.get('user_id') + + # 这里可以添加更多统计信息,比如API调用次数等 + stats = { + 'login_today': 1, # 今日登录次数 + 'api_calls_today': 0, # 今日API调用次数 + 'total_api_calls': 0, # 总API调用次数 + 'join_days': 1, # 加入天数 + 'last_activity': datetime.now().isoformat() + } + + return jsonify({ + 'success': True, + 'data': stats + }), 200 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 + +@user_bp.route('/delete', methods=['POST']) +@login_required +def delete_account(): + """删除账户""" + try: + data = request.get_json() + password = data.get('password', '').strip() + + if not password: + return jsonify({ + 'success': False, + 'message': '请输入密码确认删除' + }), 400 + + user_id = session.get('user_id') + users_collection = current_app.mongo.db.userdata + + user = users_collection.find_one({'_id': ObjectId(user_id)}) + + if not user: + return jsonify({ + 'success': False, + 'message': '用户不存在' + }), 404 + + from werkzeug.security import check_password_hash + + # 验证密码 + if not check_password_hash(user['密码'], password): + return jsonify({ + 'success': False, + 'message': '密码错误' + }), 401 + + # 删除用户 + result = users_collection.delete_one({'_id': ObjectId(user_id)}) + + if result.deleted_count > 0: + # 清除会话 + session.clear() + + return jsonify({ + 'success': True, + 'message': '账户已成功删除' + }), 200 + else: + return jsonify({ + 'success': False, + 'message': '删除失败' + }), 500 + + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'服务器错误: {str(e)}' + }), 500 diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 00000000..ba9ba09c --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,26 @@ +# InfoGenie 后端依赖包 +# Web框架 +Flask==2.3.3 +Flask-CORS==4.0.0 + +# 数据库 +Flask-PyMongo==2.3.0 +pymongo==4.5.0 + +# 密码加密 +Werkzeug==2.3.7 + +# HTTP请求 +requests==2.31.0 + +# 邮件发送 +Flask-Mail==0.9.1 + +# 数据处理 +python-dateutil==2.8.2 + +# 环境变量 +python-dotenv==1.0.0 + +# 开发工具 +flask-limiter==3.5.0 # API限流 diff --git a/backend/test/email_test.py b/backend/test/email_test.py new file mode 100644 index 00000000..9b219e6f --- /dev/null +++ b/backend/test/email_test.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +测试注册邮件发送 +""" + +import requests +import json + +def test_send_verification_email(): + """测试发送验证码邮件""" + url = "http://localhost:5000/api/auth/send-verification" + + test_data = { + "email": "3205788256@qq.com", # 使用配置的邮箱 + "type": "register" + } + + try: + response = requests.post(url, json=test_data) + print(f"状态码: {response.status_code}") + print(f"响应: {response.json()}") + + if response.status_code == 200: + print("\n✅ 邮件发送成功!请检查邮箱") + else: + print(f"\n❌ 邮件发送失败: {response.json().get('message', '未知错误')}") + + except Exception as e: + print(f"❌ 请求失败: {str(e)}") + +if __name__ == "__main__": + print("📧 测试注册邮件发送...") + test_send_verification_email() diff --git a/backend/test/mongo_test.py b/backend/test/mongo_test.py new file mode 100644 index 00000000..26e79874 --- /dev/null +++ b/backend/test/mongo_test.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +MongoDB连接测试 +""" + +from pymongo import MongoClient + +def test_connection(): + # 测试不同的连接配置 + configs = [ + "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/InfoGenie", + "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/InfoGenie?authSource=admin", + "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/InfoGenie?authSource=InfoGenie", + "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/?authSource=admin", + ] + + for i, uri in enumerate(configs): + print(f"\n测试配置 {i+1}: {uri}") + try: + client = MongoClient(uri, serverSelectionTimeoutMS=5000) + client.admin.command('ping') + print("✅ 连接成功!") + + # 测试InfoGenie数据库 + db = client.InfoGenie + collections = db.list_collection_names() + print(f"数据库集合: {collections}") + + # 测试userdata集合 + if 'userdata' in collections: + count = db.userdata.count_documents({}) + print(f"userdata集合文档数: {count}") + + client.close() + return uri + + except Exception as e: + print(f"❌ 连接失败: {str(e)}") + + return None + +if __name__ == "__main__": + print("🔧 测试MongoDB连接...") + success_uri = test_connection() + if success_uri: + print(f"\n✅ 成功的连接字符串: {success_uri}") + else: + print("\n❌ 所有连接尝试都失败了") diff --git a/backend/test/test_email.py b/backend/test/test_email.py new file mode 100644 index 00000000..ee645e86 --- /dev/null +++ b/backend/test/test_email.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +测试邮件发送功能 +""" + +import requests +import json + +def test_send_verification(): + """测试发送验证码""" + url = "http://localhost:5000/api/auth/send-verification" + + # 测试数据 + test_data = { + "email": "3205788256@qq.com", # 使用配置中的测试邮箱 + "type": "register" + } + + try: + response = requests.post(url, json=test_data) + print(f"状态码: {response.status_code}") + print(f"响应内容: {response.json()}") + + if response.status_code == 200: + print("✅ 邮件发送成功!") + else: + print("❌ 邮件发送失败") + + except Exception as e: + print(f"❌ 请求失败: {str(e)}") + +if __name__ == "__main__": + print("📧 测试邮件发送功能...") + test_send_verification() diff --git a/backend/test/test_email_fix.py b/backend/test/test_email_fix.py new file mode 100644 index 00000000..6c7b164d --- /dev/null +++ b/backend/test/test_email_fix.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +测试修复后的邮件发送功能 +""" + +import sys +import os + +# 添加父目录到路径 +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from modules.email_service import send_verification_email, verify_code + +def test_email_sending(): + """ + 测试邮件发送功能 + """ + print("=== 测试邮件发送功能 ===") + + # 测试邮箱(请替换为你的QQ邮箱) + test_email = "3205788256@qq.com" # 替换为实际的测试邮箱 + + print(f"正在向 {test_email} 发送注册验证码...") + + # 发送注册验证码 + result = send_verification_email(test_email, 'register') + + print(f"发送结果: {result}") + + if result['success']: + print("✅ 邮件发送成功!") + if 'code' in result: + print(f"验证码: {result['code']}") + + # 测试验证码验证 + print("\n=== 测试验证码验证 ===") + verify_result = verify_code(test_email, result['code']) + print(f"验证结果: {verify_result}") + + if verify_result['success']: + print("✅ 验证码验证成功!") + else: + print("❌ 验证码验证失败!") + else: + print("❌ 邮件发送失败!") + print(f"错误信息: {result['message']}") + +def test_login_email(): + """ + 测试登录验证码邮件 + """ + print("\n=== 测试登录验证码邮件 ===") + + test_email = "3205788256@qq.com" # 替换为实际的测试邮箱 + + print(f"正在向 {test_email} 发送登录验证码...") + + result = send_verification_email(test_email, 'login') + + print(f"发送结果: {result}") + + if result['success']: + print("✅ 登录验证码邮件发送成功!") + if 'code' in result: + print(f"验证码: {result['code']}") + else: + print("❌ 登录验证码邮件发送失败!") + print(f"错误信息: {result['message']}") + +if __name__ == '__main__': + print("InfoGenie 邮件服务测试") + print("=" * 50) + + # 测试注册验证码 + test_email_sending() + + # 测试登录验证码 + test_login_email() + + print("\n测试完成!") \ No newline at end of file diff --git a/backend/test/test_mongo.py b/backend/test/test_mongo.py new file mode 100644 index 00000000..830d1557 --- /dev/null +++ b/backend/test/test_mongo.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +测试MongoDB连接 +""" + +import os +from pymongo import MongoClient +from dotenv import load_dotenv + +# 加载环境变量 +load_dotenv() + +def test_mongodb_connection(): + """测试MongoDB连接""" + try: + # 获取连接字符串 + mongo_uri = os.environ.get('MONGO_URI') + print(f"连接字符串: {mongo_uri}") + + # 创建连接 + client = MongoClient(mongo_uri) + + # 测试连接 + client.admin.command('ping') + print("✅ MongoDB连接成功!") + + # 获取数据库 + db = client.InfoGenie + print(f"数据库: {db.name}") + + # 测试集合访问 + userdata_collection = db.userdata + print(f"用户集合: {userdata_collection.name}") + + # 测试查询(计算文档数量) + count = userdata_collection.count_documents({}) + print(f"用户数据集合中有 {count} 个文档") + + # 关闭连接 + client.close() + + except Exception as e: + print(f"❌ MongoDB连接失败: {str(e)}") + + # 尝试其他认证数据库 + print("\n尝试使用不同的认证配置...") + try: + # 尝试不指定认证数据库 + uri_without_auth = "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/InfoGenie" + client2 = MongoClient(uri_without_auth) + client2.admin.command('ping') + print("✅ 不使用authSource连接成功!") + client2.close() + except Exception as e2: + print(f"❌ 无authSource也失败: {str(e2)}") + + # 尝试使用InfoGenie作为认证数据库 + try: + uri_with_infogenie_auth = "mongodb://shumengya:tyh%4019900420@192.168.1.233:27017/InfoGenie?authSource=InfoGenie" + client3 = MongoClient(uri_with_infogenie_auth) + client3.admin.command('ping') + print("✅ 使用InfoGenie作为authSource连接成功!") + client3.close() + except Exception as e3: + print(f"❌ InfoGenie authSource也失败: {str(e3)}") + +if __name__ == "__main__": + print("🔧 测试MongoDB连接...") + test_mongodb_connection() diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json +++ b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json b/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json +++ b/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/娱乐消遣/随机一言/接口集合.json b/frontend/60sapi/娱乐消遣/随机一言/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/娱乐消遣/随机一言/接口集合.json +++ b/frontend/60sapi/娱乐消遣/随机一言/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json b/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json +++ b/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json b/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json +++ b/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/公网IP地址/css/background.css b/frontend/60sapi/实用功能/公网IP地址/css/background.css new file mode 100644 index 00000000..74f65ebc --- /dev/null +++ b/frontend/60sapi/实用功能/公网IP地址/css/background.css @@ -0,0 +1,233 @@ +/* 动态背景样式 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + z-index: -2; +} + +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + z-index: -1; + animation: backgroundMove 20s ease-in-out infinite; +} + +@keyframes backgroundMove { + 0%, 100% { + background: + radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + } + 25% { + background: + radial-gradient(circle at 60% 30%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 30% 70%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 80% 80%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + } + 50% { + background: + radial-gradient(circle at 80% 60%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 20% 30%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 60% 70%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + } + 75% { + background: + radial-gradient(circle at 40% 90%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 70% 10%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 20% 60%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + } +} + +/* 浮动粒子效果 */ +.particles { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: -1; +} + +.particle { + position: absolute; + width: 4px; + height: 4px; + background: rgba(255, 255, 255, 0.5); + border-radius: 50%; + animation: float 15s infinite linear; +} + +.particle:nth-child(1) { + left: 10%; + animation-delay: 0s; + animation-duration: 12s; +} + +.particle:nth-child(2) { + left: 20%; + animation-delay: 2s; + animation-duration: 18s; +} + +.particle:nth-child(3) { + left: 30%; + animation-delay: 4s; + animation-duration: 15s; +} + +.particle:nth-child(4) { + left: 40%; + animation-delay: 6s; + animation-duration: 20s; +} + +.particle:nth-child(5) { + left: 50%; + animation-delay: 8s; + animation-duration: 14s; +} + +.particle:nth-child(6) { + left: 60%; + animation-delay: 10s; + animation-duration: 16s; +} + +.particle:nth-child(7) { + left: 70%; + animation-delay: 12s; + animation-duration: 22s; +} + +.particle:nth-child(8) { + left: 80%; + animation-delay: 14s; + animation-duration: 13s; +} + +.particle:nth-child(9) { + left: 90%; + animation-delay: 16s; + animation-duration: 19s; +} + +.particle:nth-child(10) { + left: 15%; + animation-delay: 18s; + animation-duration: 17s; +} + +@keyframes float { + 0% { + transform: translateY(100vh) rotate(0deg); + opacity: 0; + } + 10% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + transform: translateY(-100px) rotate(360deg); + opacity: 0; + } +} + +/* 网格背景效果 */ +.grid-background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + linear-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.1) 1px, transparent 1px); + background-size: 50px 50px; + z-index: -1; + opacity: 0.3; + animation: gridMove 30s linear infinite; +} + +@keyframes gridMove { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(50px, 50px); + } +} + +/* 光晕效果 */ +.glow-effect { + position: fixed; + top: 50%; + left: 50%; + width: 300px; + height: 300px; + background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%); + border-radius: 50%; + transform: translate(-50%, -50%); + z-index: -1; + animation: pulse 4s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { + transform: translate(-50%, -50%) scale(1); + opacity: 0.5; + } + 50% { + transform: translate(-50%, -50%) scale(1.2); + opacity: 0.8; + } +} + +/* 响应式背景调整 */ +@media (max-width: 768px) { + .grid-background { + background-size: 30px 30px; + } + + .glow-effect { + width: 200px; + height: 200px; + } + + .particle { + width: 3px; + height: 3px; + } +} + +@media (max-width: 480px) { + .grid-background { + background-size: 20px 20px; + } + + .glow-effect { + width: 150px; + height: 150px; + } + + .particle { + width: 2px; + height: 2px; + } +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/css/style.css b/frontend/60sapi/实用功能/公网IP地址/css/style.css new file mode 100644 index 00000000..30d4768f --- /dev/null +++ b/frontend/60sapi/实用功能/公网IP地址/css/style.css @@ -0,0 +1,445 @@ +/* 全局样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + color: #333; + min-height: 100vh; + overflow-x: hidden; +} + +/* 容器样式 */ +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + position: relative; + z-index: 1; +} + +/* 头部样式 */ +.header { + text-align: center; + padding: 3rem 2rem 2rem; + background: linear-gradient(135deg, rgba(74, 144, 226, 0.1), rgba(80, 200, 120, 0.1)); + backdrop-filter: blur(10px); + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} + +.header h1 { + font-size: 2.5rem; + font-weight: 700; + background: linear-gradient(135deg, #4a90e2, #50c878); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 0.5rem; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.header h1 i { + margin-right: 0.5rem; + background: linear-gradient(135deg, #4a90e2, #50c878); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.subtitle { + font-size: 1.1rem; + color: #666; + font-weight: 300; +} + +/* 主要内容区域 */ +.main-content { + flex: 1; + padding: 2rem; + max-width: 800px; + margin: 0 auto; + width: 100%; +} + +/* 查询按钮区域 */ +.query-section { + text-align: center; + margin-bottom: 2rem; +} + +.query-btn { + background: linear-gradient(135deg, #4a90e2, #50c878); + color: white; + border: none; + padding: 1rem 2rem; + font-size: 1.1rem; + font-weight: 600; + border-radius: 50px; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(74, 144, 226, 0.3); + display: inline-flex; + align-items: center; + gap: 0.5rem; + min-width: 200px; + justify-content: center; +} + +.query-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(74, 144, 226, 0.4); + background: linear-gradient(135deg, #3a7bc8, #40a868); +} + +.query-btn:active { + transform: translateY(0); +} + +.query-btn:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none; +} + +/* 加载动画 */ +.loading { + text-align: center; + padding: 2rem; +} + +.spinner { + width: 50px; + height: 50px; + border: 4px solid #f3f3f3; + border-top: 4px solid #4a90e2; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 1rem; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading p { + color: #666; + font-size: 1rem; +} + +/* IP信息卡片 */ +.ip-info { + animation: fadeInUp 0.6s ease; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.ip-card { + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: 2rem; + margin-bottom: 2rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.ip-header { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 1.5rem; + padding-bottom: 1rem; + border-bottom: 2px solid #f0f0f0; +} + +.ip-header i { + font-size: 1.5rem; + color: #4a90e2; +} + +.ip-header h2 { + font-size: 1.5rem; + font-weight: 600; + color: #333; +} + +.ip-display { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + margin-bottom: 1.5rem; + padding: 1.5rem; + background: linear-gradient(135deg, rgba(74, 144, 226, 0.1), rgba(80, 200, 120, 0.1)); + border-radius: 15px; + border: 2px solid rgba(74, 144, 226, 0.2); +} + +.ip-address { + font-size: 2rem; + font-weight: 700; + font-family: 'Courier New', monospace; + color: #2c3e50; + background: linear-gradient(135deg, #4a90e2, #50c878); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.copy-btn { + background: #4a90e2; + color: white; + border: none; + padding: 0.5rem; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; + font-size: 1rem; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; +} + +.copy-btn:hover { + background: #3a7bc8; + transform: scale(1.1); +} + +.ip-details { + display: grid; + gap: 1rem; +} + +.detail-item { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem; + background: rgba(248, 249, 250, 0.8); + border-radius: 10px; + transition: all 0.3s ease; +} + +.detail-item:hover { + background: rgba(74, 144, 226, 0.1); + transform: translateX(5px); +} + +.detail-item i { + color: #4a90e2; + width: 20px; + text-align: center; +} + +.detail-item .label { + font-weight: 600; + color: #555; + min-width: 80px; +} + +.detail-item .value { + color: #333; + font-weight: 500; +} + +/* IP地址说明区域 */ +.ip-explanation { + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: 2rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.ip-explanation h3 { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 1rem; + font-size: 1.3rem; + color: #333; +} + +.ip-explanation h3 i { + color: #4a90e2; +} + +.ip-explanation p { + color: #666; + line-height: 1.8; + margin-bottom: 1.5rem; +} + +.features { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1rem; +} + +.feature-item { + display: flex; + align-items: flex-start; + gap: 1rem; + padding: 1rem; + background: rgba(248, 249, 250, 0.8); + border-radius: 12px; + transition: all 0.3s ease; +} + +.feature-item:hover { + background: rgba(74, 144, 226, 0.1); + transform: translateY(-2px); +} + +.feature-item i { + color: #4a90e2; + font-size: 1.5rem; + margin-top: 0.2rem; +} + +.feature-item h4 { + font-size: 1rem; + font-weight: 600; + color: #333; + margin-bottom: 0.3rem; +} + +.feature-item p { + font-size: 0.9rem; + color: #666; + line-height: 1.5; + margin: 0; +} + +/* 错误信息 */ +.error-message { + text-align: center; + padding: 2rem; + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(10px); + border-radius: 20px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 99, 99, 0.3); + animation: fadeInUp 0.6s ease; +} + +.error-message i { + font-size: 3rem; + color: #ff6b6b; + margin-bottom: 1rem; +} + +.error-message p { + color: #666; + font-size: 1.1rem; + margin-bottom: 1.5rem; +} + +.retry-btn { + background: #ff6b6b; + color: white; + border: none; + padding: 0.75rem 1.5rem; + font-size: 1rem; + font-weight: 600; + border-radius: 25px; + cursor: pointer; + transition: all 0.3s ease; +} + +.retry-btn:hover { + background: #ff5252; + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3); +} + +/* 页脚 */ +.footer { + text-align: center; + padding: 2rem; + background: rgba(248, 249, 250, 0.8); + backdrop-filter: blur(10px); + border-top: 1px solid rgba(255, 255, 255, 0.2); + color: #666; + font-size: 0.9rem; +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .header { + padding: 2rem 1rem 1.5rem; + } + + .header h1 { + font-size: 2rem; + } + + .main-content { + padding: 1rem; + } + + .ip-card, .ip-explanation { + padding: 1.5rem; + } + + .ip-address { + font-size: 1.5rem; + } + + .ip-display { + flex-direction: column; + gap: 1rem; + } + + .features { + grid-template-columns: 1fr; + } + + .detail-item { + flex-direction: column; + align-items: flex-start; + gap: 0.3rem; + } + + .detail-item .label { + min-width: auto; + } +} + +@media (max-width: 480px) { + .header h1 { + font-size: 1.8rem; + } + + .query-btn { + padding: 0.875rem 1.5rem; + font-size: 1rem; + min-width: 180px; + } + + .ip-address { + font-size: 1.3rem; + } + + .ip-card, .ip-explanation { + padding: 1rem; + } +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/index.html b/frontend/60sapi/实用功能/公网IP地址/index.html new file mode 100644 index 00000000..875fb9f0 --- /dev/null +++ b/frontend/60sapi/实用功能/公网IP地址/index.html @@ -0,0 +1,139 @@ + + + + + + 公网IP地址查询 + + + + + +
+ +
+

公网IP地址查询

+

快速获取您的公网IP地址信息

+
+ + +
+ +
+ +
+ + + + + + + + + +
+ + +
+

© 2024 公网IP地址查询工具 | 数据来源: 60s.viki.moe

+
+
+ + + + \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/js/script.js b/frontend/60sapi/实用功能/公网IP地址/js/script.js new file mode 100644 index 00000000..4db5e4bd --- /dev/null +++ b/frontend/60sapi/实用功能/公网IP地址/js/script.js @@ -0,0 +1,315 @@ +// 公网IP地址查询应用 +class IPQueryApp { + constructor() { + this.apiEndpoint = 'https://60s.viki.moe/v2/ip'; + this.init(); + } + + // 初始化应用 + init() { + this.bindEvents(); + this.createParticles(); + this.createBackgroundElements(); + console.log('IP查询应用初始化完成'); + } + + // 绑定事件 + bindEvents() { + const queryBtn = document.getElementById('queryBtn'); + const retryBtn = document.getElementById('retryBtn'); + const copyBtn = document.getElementById('copyBtn'); + + if (queryBtn) { + queryBtn.addEventListener('click', () => this.queryIP()); + } + + if (retryBtn) { + retryBtn.addEventListener('click', () => this.queryIP()); + } + + if (copyBtn) { + copyBtn.addEventListener('click', () => this.copyIP()); + } + + // 页面加载完成后自动查询一次 + document.addEventListener('DOMContentLoaded', () => { + setTimeout(() => this.queryIP(), 500); + }); + } + + // 创建浮动粒子 + createParticles() { + const particlesContainer = document.createElement('div'); + particlesContainer.className = 'particles'; + document.body.appendChild(particlesContainer); + + for (let i = 0; i < 10; i++) { + const particle = document.createElement('div'); + particle.className = 'particle'; + particlesContainer.appendChild(particle); + } + } + + // 创建背景元素 + createBackgroundElements() { + // 创建网格背景 + const gridBackground = document.createElement('div'); + gridBackground.className = 'grid-background'; + document.body.appendChild(gridBackground); + + // 创建光晕效果 + const glowEffect = document.createElement('div'); + glowEffect.className = 'glow-effect'; + document.body.appendChild(glowEffect); + } + + // 显示加载状态 + showLoading() { + const loading = document.getElementById('loading'); + const ipInfo = document.getElementById('ipInfo'); + const errorMessage = document.getElementById('errorMessage'); + const queryBtn = document.getElementById('queryBtn'); + + if (loading) loading.style.display = 'block'; + if (ipInfo) ipInfo.style.display = 'none'; + if (errorMessage) errorMessage.style.display = 'none'; + if (queryBtn) { + queryBtn.disabled = true; + queryBtn.innerHTML = ' 查询中...'; + } + } + + // 隐藏加载状态 + hideLoading() { + const loading = document.getElementById('loading'); + const queryBtn = document.getElementById('queryBtn'); + + if (loading) loading.style.display = 'none'; + if (queryBtn) { + queryBtn.disabled = false; + queryBtn.innerHTML = ' 查询我的IP'; + } + } + + // 显示错误信息 + showError(message) { + const errorMessage = document.getElementById('error-message'); + const ipInfo = document.getElementById('ip-info'); + + if (errorMessage) { + errorMessage.style.display = 'block'; + const errorText = errorMessage.querySelector('p'); + if (errorText) errorText.textContent = message || '获取IP信息失败,请稍后重试'; + } + if (ipInfo) ipInfo.style.display = 'none'; + + this.hideLoading(); + } + + // 查询IP地址 + async queryIP() { + try { + this.showLoading(); + console.log('开始查询IP地址...'); + + const response = await fetch(this.apiEndpoint, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + }); + + console.log('API响应状态:', response.status); + + if (!response.ok) { + throw new Error(`HTTP错误: ${response.status}`); + } + + const data = await response.json(); + console.log('API返回数据:', data); + + if (data.code === 200 && data.data) { + this.displayIPInfo(data.data); + } else { + throw new Error(data.message || '获取IP信息失败'); + } + + } catch (error) { + console.error('查询IP失败:', error); + this.showError(error.message); + } + } + + // 显示IP信息 + displayIPInfo(data) { + const ipInfo = document.getElementById('ip-info'); + const errorMessage = document.getElementById('error-message'); + + // 更新IP地址显示 + const ipAddressElement = document.getElementById('ip-address'); + if (ipAddressElement && data.ip) { + ipAddressElement.textContent = data.ip; + } + + // 更新查询时间 + const queryTimeElement = document.getElementById('query-time'); + if (queryTimeElement) { + const now = new Date(); + queryTimeElement.textContent = now.toLocaleString('zh-CN'); + } + + // 更新详细信息 + this.updateDetailItem('location', data.location || '未知'); + this.updateDetailItem('isp', data.isp || '未知'); + this.updateDetailItem('country', data.country || '未知'); + this.updateDetailItem('region', data.region || '未知'); + this.updateDetailItem('city', data.city || '未知'); + this.updateDetailItem('timezone', data.timezone || '未知'); + + // 显示IP信息,隐藏错误信息 + if (ipInfo) ipInfo.style.display = 'block'; + if (errorMessage) errorMessage.style.display = 'none'; + + this.hideLoading(); + console.log('IP信息显示完成'); + } + + // 更新详细信息项 + updateDetailItem(id, value) { + const element = document.getElementById(id); + if (element) { + element.textContent = value; + } + } + + // 复制IP地址 + async copyIP() { + const ipAddressElement = document.getElementById('ip-address'); + const copyBtn = document.getElementById('copyBtn'); + + if (!ipAddressElement || !ipAddressElement.textContent) { + this.showToast('没有可复制的IP地址', 'error'); + return; + } + + try { + await navigator.clipboard.writeText(ipAddressElement.textContent); + + // 更新按钮状态 + if (copyBtn) { + const originalHTML = copyBtn.innerHTML; + copyBtn.innerHTML = ''; + copyBtn.style.background = '#50c878'; + + setTimeout(() => { + copyBtn.innerHTML = originalHTML; + copyBtn.style.background = '#4a90e2'; + }, 1500); + } + + this.showToast('IP地址已复制到剪贴板', 'success'); + console.log('IP地址已复制:', ipAddressElement.textContent); + + } catch (error) { + console.error('复制失败:', error); + this.showToast('复制失败,请手动选择复制', 'error'); + } + } + + // 显示提示消息 + showToast(message, type = 'info') { + // 移除已存在的toast + const existingToast = document.querySelector('.toast'); + if (existingToast) { + existingToast.remove(); + } + + // 创建新的toast + const toast = document.createElement('div'); + toast.className = `toast toast-${type}`; + toast.innerHTML = ` + + ${message} + `; + + // 添加toast样式 + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: ${type === 'success' ? '#50c878' : type === 'error' ? '#ff6b6b' : '#4a90e2'}; + color: white; + padding: 1rem 1.5rem; + border-radius: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + z-index: 1000; + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 500; + animation: slideInRight 0.3s ease; + max-width: 300px; + `; + + // 添加动画样式 + const style = document.createElement('style'); + style.textContent = ` + @keyframes slideInRight { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } + } + @keyframes slideOutRight { + from { + transform: translateX(0); + opacity: 1; + } + to { + transform: translateX(100%); + opacity: 0; + } + } + `; + document.head.appendChild(style); + + document.body.appendChild(toast); + + // 3秒后自动移除 + setTimeout(() => { + toast.style.animation = 'slideOutRight 0.3s ease'; + setTimeout(() => { + if (toast.parentNode) { + toast.remove(); + } + if (style.parentNode) { + style.remove(); + } + }, 300); + }, 3000); + } + + // 格式化时间 + formatTime(timestamp) { + const date = new Date(timestamp); + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + } +} + +// 初始化应用 +const app = new IPQueryApp(); + +// 导出到全局作用域(用于调试) +window.IPQueryApp = app; \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/接口集合.json b/frontend/60sapi/实用功能/公网IP地址/接口集合.json new file mode 100644 index 00000000..60c81034 --- /dev/null +++ b/frontend/60sapi/实用功能/公网IP地址/接口集合.json @@ -0,0 +1,3 @@ +[ + "https://60s.viki.moe/v2/ip" +] diff --git a/frontend/60sapi/实用功能/公网IP地址/返回接口.json b/frontend/60sapi/实用功能/公网IP地址/返回接口.json new file mode 100644 index 00000000..e69de29b diff --git a/frontend/60sapi/实用功能/农历信息/接口集合.json b/frontend/60sapi/实用功能/农历信息/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/实用功能/农历信息/接口集合.json +++ b/frontend/60sapi/实用功能/农历信息/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/哈希解压压缩/css/style.css b/frontend/60sapi/实用功能/哈希解压压缩/css/style.css new file mode 100644 index 00000000..4b94a03d --- /dev/null +++ b/frontend/60sapi/实用功能/哈希解压压缩/css/style.css @@ -0,0 +1,561 @@ +/* Reset and Base Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + color: #333; + overflow-x: hidden; +} + +.container { + max-width: 1400px; + margin: 0 auto; + padding: 20px; + position: relative; +} + +/* Header Styles */ +.header { + text-align: center; + margin-bottom: 40px; + position: relative; + z-index: 2; +} + +.header-content { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(20px); + border-radius: 24px; + padding: 40px; + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); + position: relative; + overflow: hidden; +} + +.header-content::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.1) 100%); + animation: shimmer 3s ease-in-out infinite; +} + +@keyframes shimmer { + 0%, 100% { transform: translateX(-100%); } + 50% { transform: translateX(100%); } +} + +.logo { + display: flex; + align-items: center; + justify-content: center; + gap: 15px; + margin-bottom: 15px; +} + +.logo i { + font-size: 48px; + background: linear-gradient(45deg, #ff6b6b, #4ecdc4); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +.logo h1 { + font-size: 42px; + font-weight: 700; + color: white; + text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); +} + +.subtitle { + font-size: 18px; + color: rgba(255, 255, 255, 0.9); + font-weight: 400; + letter-spacing: 0.5px; +} + +/* Floating Shapes */ +.header-decoration { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; + z-index: 1; +} + +.floating-shapes { + position: relative; + width: 100%; + height: 100%; +} + +.shape { + position: absolute; + border-radius: 50%; + background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)); + animation: float 6s ease-in-out infinite; +} + +.shape-1 { + width: 80px; + height: 80px; + top: 10%; + left: 10%; + animation-delay: 0s; +} + +.shape-2 { + width: 60px; + height: 60px; + top: 20%; + right: 15%; + animation-delay: 2s; +} + +.shape-3 { + width: 100px; + height: 100px; + bottom: 15%; + left: 20%; + animation-delay: 4s; +} + +@keyframes float { + 0%, 100% { transform: translateY(0px) rotate(0deg); } + 33% { transform: translateY(-20px) rotate(120deg); } + 66% { transform: translateY(10px) rotate(240deg); } +} + +/* Input Section */ +.input-section { + margin-bottom: 40px; +} + +.input-card { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 20px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.3); + transition: all 0.3s ease; +} + +.input-card:hover { + transform: translateY(-5px); + box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); +} + +.card-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 20px; +} + +.card-header i { + font-size: 24px; + color: #667eea; +} + +.card-header h2 { + font-size: 24px; + font-weight: 600; + color: #333; +} + +.input-wrapper { + position: relative; +} + +#inputText { + width: 100%; + padding: 20px; + border: 2px solid #e1e5e9; + border-radius: 12px; + font-size: 16px; + font-family: inherit; + resize: vertical; + transition: all 0.3s ease; + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(10px); +} + +#inputText:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); + background: rgba(255, 255, 255, 0.95); +} + +.input-actions { + display: flex; + gap: 15px; + margin-top: 20px; + justify-content: flex-end; +} + +/* Button Styles */ +.btn { + padding: 12px 24px; + border: none; + border-radius: 10px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 8px; + text-decoration: none; + position: relative; + overflow: hidden; +} + +.btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: left 0.5s; +} + +.btn:hover::before { + left: 100%; +} + +.btn-primary { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4); +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.8); + color: #666; + border: 1px solid #e1e5e9; +} + +.btn-secondary:hover { + background: rgba(255, 255, 255, 0.95); + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); +} + +/* Results Section */ +.results-section { + opacity: 0; + transform: translateY(30px); + transition: all 0.5s ease; +} + +.results-section.show { + opacity: 1; + transform: translateY(0); +} + +.results-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); + gap: 30px; +} + +.result-card { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 20px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.3); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.result-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4); +} + +.result-card:hover { + transform: translateY(-5px); + box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); +} + +.result-card .card-header h3 { + font-size: 20px; + font-weight: 600; + color: #333; +} + +.result-items { + display: flex; + flex-direction: column; + gap: 20px; +} + +.result-item { + position: relative; +} + +.result-item label { + display: block; + font-size: 14px; + font-weight: 500; + color: #666; + margin-bottom: 8px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.result-value { + display: flex; + align-items: center; + background: rgba(248, 250, 252, 0.8); + border: 1px solid #e1e5e9; + border-radius: 8px; + padding: 12px 16px; + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; + font-size: 14px; + word-break: break-all; + position: relative; + transition: all 0.3s ease; +} + +.result-value:hover { + background: rgba(248, 250, 252, 0.95); + border-color: #667eea; +} + +.result-value .placeholder { + color: #999; + font-style: italic; +} + +.copy-btn { + background: none; + border: none; + color: #667eea; + cursor: pointer; + padding: 8px; + border-radius: 6px; + transition: all 0.3s ease; + margin-left: auto; + flex-shrink: 0; +} + +.copy-btn:hover { + background: rgba(102, 126, 234, 0.1); + color: #5a67d8; +} + +/* Loading Overlay */ +.loading-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; +} + +.loading-overlay.show { + opacity: 1; + visibility: visible; +} + +.loading-spinner { + text-align: center; + color: white; +} + +.spinner { + width: 50px; + height: 50px; + border: 4px solid rgba(255, 255, 255, 0.3); + border-top: 4px solid white; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* Toast Notification */ +.toast { + position: fixed; + bottom: 30px; + right: 30px; + background: linear-gradient(135deg, #4ecdc4, #44a08d); + color: white; + padding: 16px 24px; + border-radius: 12px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + display: flex; + align-items: center; + gap: 10px; + transform: translateX(400px); + transition: all 0.3s ease; + z-index: 1001; +} + +.toast.show { + transform: translateX(0); +} + +.toast i { + font-size: 18px; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .container { + padding: 15px; + } + + .header-content { + padding: 30px 20px; + } + + .logo h1 { + font-size: 32px; + } + + .logo i { + font-size: 36px; + } + + .results-grid { + grid-template-columns: 1fr; + gap: 20px; + } + + .input-actions { + flex-direction: column; + } + + .btn { + justify-content: center; + } + + .toast { + bottom: 20px; + right: 20px; + left: 20px; + transform: translateY(100px); + } + + .toast.show { + transform: translateY(0); + } +} + +@media (max-width: 480px) { + .input-card, + .result-card { + padding: 20px; + } + + .card-header h2, + .card-header h3 { + font-size: 18px; + } + + .result-value { + font-size: 12px; + padding: 10px 12px; + } +} + +/* Animation Classes */ +.fade-in { + animation: fadeIn 0.5s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.slide-in { + animation: slideIn 0.3s ease-out; +} + +@keyframes slideIn { + from { + transform: translateX(-20px); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.5); +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/index.html b/frontend/60sapi/实用功能/哈希解压压缩/index.html new file mode 100644 index 00000000..76cedb0f --- /dev/null +++ b/frontend/60sapi/实用功能/哈希解压压缩/index.html @@ -0,0 +1,221 @@ + + + + + + 多功能哈希工具 - Hash Toolkit + + + + + +
+ +
+
+ +

多功能哈希、编码与压缩工具

+
+
+
+
+
+
+
+
+
+ + +
+ +
+
+
+ +

输入内容

+
+
+ +
+ + +
+
+
+
+ + +
+
+ +
+
+ +

哈希算法

+
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+
+ + +
+
+ +

编码转换

+
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+
+ + +
+
+ +

压缩算法

+
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+ +
+ 等待处理... + +
+
+
+
+
+
+
+ + +
+
+
+

正在处理中...

+
+
+ + +
+ + 复制成功! +
+
+ + + + \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/js/script.js b/frontend/60sapi/实用功能/哈希解压压缩/js/script.js new file mode 100644 index 00000000..cc8350b6 --- /dev/null +++ b/frontend/60sapi/实用功能/哈希解压压缩/js/script.js @@ -0,0 +1,380 @@ +// API配置 +const API_BASE_URL = 'https://60s.viki.moe/v2/hash'; + +// DOM元素 +const elements = { + inputText: document.getElementById('inputText'), + processBtn: document.getElementById('processBtn'), + clearBtn: document.getElementById('clearBtn'), + resultsSection: document.getElementById('resultsSection'), + loadingOverlay: document.getElementById('loadingOverlay'), + toast: document.getElementById('toast'), + toastMessage: document.getElementById('toastMessage') +}; + +// 结果元素映射 +const resultElements = { + md5: document.getElementById('md5Result'), + sha1: document.getElementById('sha1Result'), + sha256: document.getElementById('sha256Result'), + sha512: document.getElementById('sha512Result'), + base64Encode: document.getElementById('base64EncodeResult'), + base64Decode: document.getElementById('base64DecodeResult'), + urlEncode: document.getElementById('urlEncodeResult'), + urlDecode: document.getElementById('urlDecodeResult'), + gzipCompress: document.getElementById('gzipCompressResult'), + gzipDecompress: document.getElementById('gzipDecompressResult'), + deflateCompress: document.getElementById('deflateCompressResult'), + brotliCompress: document.getElementById('brotliCompressResult') +}; + +// 初始化 +document.addEventListener('DOMContentLoaded', function() { + initializeEventListeners(); + addInputAnimation(); +}); + +// 事件监听器初始化 +function initializeEventListeners() { + // 处理按钮点击 + elements.processBtn.addEventListener('click', handleProcess); + + // 清空按钮点击 + elements.clearBtn.addEventListener('click', handleClear); + + // 输入框回车键 + elements.inputText.addEventListener('keydown', function(e) { + if (e.ctrlKey && e.key === 'Enter') { + handleProcess(); + } + }); + + // 复制按钮事件委托 + document.addEventListener('click', function(e) { + if (e.target.closest('.copy-btn')) { + const copyBtn = e.target.closest('.copy-btn'); + const targetId = copyBtn.getAttribute('data-target'); + const targetElement = document.getElementById(targetId); + const textContent = targetElement.textContent.trim(); + + if (textContent && textContent !== '等待处理...' && textContent !== '处理失败') { + copyToClipboard(textContent); + } + } + }); + + // 输入框实时验证 + elements.inputText.addEventListener('input', function() { + const hasContent = this.value.trim().length > 0; + elements.processBtn.disabled = !hasContent; + + if (hasContent) { + elements.processBtn.classList.remove('disabled'); + } else { + elements.processBtn.classList.add('disabled'); + } + }); +} + +// 添加输入动画效果 +function addInputAnimation() { + elements.inputText.addEventListener('focus', function() { + this.parentElement.classList.add('focused'); + }); + + elements.inputText.addEventListener('blur', function() { + this.parentElement.classList.remove('focused'); + }); +} + +// 处理主要功能 +async function handleProcess() { + const inputValue = elements.inputText.value.trim(); + + if (!inputValue) { + showToast('请输入要处理的内容', 'error'); + return; + } + + // 显示加载状态 + showLoading(true); + resetResults(); + + try { + // 调用API + const response = await fetch(`${API_BASE_URL}?content=${encodeURIComponent(inputValue)}`); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + displayResults(data.data); + showResultsSection(); + showToast('处理完成!', 'success'); + } else { + throw new Error(data.message || '处理失败'); + } + + } catch (error) { + console.error('处理错误:', error); + showToast(`处理失败: ${error.message}`, 'error'); + displayError(); + } finally { + showLoading(false); + } +} + +// 显示结果 +function displayResults(data) { + try { + // 哈希结果 + updateResultElement('md5', data.md5 || '不可用'); + + // SHA系列 + if (data.sha) { + updateResultElement('sha1', data.sha.sha1 || '不可用'); + updateResultElement('sha256', data.sha.sha256 || '不可用'); + updateResultElement('sha512', data.sha.sha512 || '不可用'); + } + + // Base64编码 + if (data.base64) { + updateResultElement('base64Encode', data.base64.encode || '不可用'); + updateResultElement('base64Decode', data.base64.decode || '不可用'); + } + + // URL编码 + if (data.url) { + updateResultElement('urlEncode', data.url.encode || '不可用'); + updateResultElement('urlDecode', data.url.decode || '不可用'); + } + + // 压缩结果 + if (data.gzip) { + updateResultElement('gzipCompress', data.gzip.compress || '不可用'); + updateResultElement('gzipDecompress', data.gzip.decompress || '不可用'); + } + + if (data.deflate) { + updateResultElement('deflateCompress', data.deflate.compress || '不可用'); + } + + if (data.brotli) { + updateResultElement('brotliCompress', data.brotli.compress || '不可用'); + } + + } catch (error) { + console.error('显示结果时出错:', error); + showToast('显示结果时出错', 'error'); + } +} + +// 更新单个结果元素 +function updateResultElement(key, value) { + const element = resultElements[key]; + if (element) { + const textSpan = element.querySelector('span') || element; + textSpan.textContent = value; + textSpan.classList.remove('placeholder'); + + // 添加动画效果 + element.classList.add('slide-in'); + setTimeout(() => { + element.classList.remove('slide-in'); + }, 300); + } +} + +// 重置结果 +function resetResults() { + Object.values(resultElements).forEach(element => { + if (element) { + const textSpan = element.querySelector('span') || element; + textSpan.textContent = '等待处理...'; + textSpan.classList.add('placeholder'); + } + }); +} + +// 显示错误状态 +function displayError() { + Object.values(resultElements).forEach(element => { + if (element) { + const textSpan = element.querySelector('span') || element; + textSpan.textContent = '处理失败'; + textSpan.classList.add('placeholder'); + } + }); +} + +// 显示结果区域 +function showResultsSection() { + elements.resultsSection.classList.add('show'); + + // 平滑滚动到结果区域 + setTimeout(() => { + elements.resultsSection.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + }, 100); +} + +// 清空功能 +function handleClear() { + elements.inputText.value = ''; + elements.inputText.focus(); + elements.resultsSection.classList.remove('show'); + resetResults(); + elements.processBtn.disabled = true; + elements.processBtn.classList.add('disabled'); + + showToast('内容已清空', 'info'); +} + +// 复制到剪贴板 +async function copyToClipboard(text) { + try { + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(text); + } else { + // 降级方案 + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + document.execCommand('copy'); + textArea.remove(); + } + + showToast('复制成功!', 'success'); + } catch (error) { + console.error('复制失败:', error); + showToast('复制失败,请手动复制', 'error'); + } +} + +// 显示/隐藏加载状态 +function showLoading(show) { + if (show) { + elements.loadingOverlay.classList.add('show'); + elements.processBtn.disabled = true; + elements.processBtn.innerHTML = ' 处理中...'; + } else { + elements.loadingOverlay.classList.remove('show'); + elements.processBtn.disabled = false; + elements.processBtn.innerHTML = ' 开始处理'; + } +} + +// 显示提示消息 +function showToast(message, type = 'success') { + elements.toastMessage.textContent = message; + + // 设置图标和样式 + const icon = elements.toast.querySelector('i'); + icon.className = getToastIcon(type); + + elements.toast.className = `toast ${type}`; + elements.toast.classList.add('show'); + + // 自动隐藏 + setTimeout(() => { + elements.toast.classList.remove('show'); + }, 3000); +} + +// 获取提示图标 +function getToastIcon(type) { + const icons = { + success: 'fas fa-check-circle', + error: 'fas fa-exclamation-circle', + info: 'fas fa-info-circle', + warning: 'fas fa-exclamation-triangle' + }; + return icons[type] || icons.success; +} + +// 工具函数:防抖 +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +// 工具函数:节流 +function throttle(func, limit) { + let inThrottle; + return function() { + const args = arguments; + const context = this; + if (!inThrottle) { + func.apply(context, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + } +} + +// 添加键盘快捷键支持 +document.addEventListener('keydown', function(e) { + // Ctrl+Enter 处理 + if (e.ctrlKey && e.key === 'Enter') { + e.preventDefault(); + if (!elements.processBtn.disabled) { + handleProcess(); + } + } + + // Escape 清空 + if (e.key === 'Escape') { + handleClear(); + } +}); + +// 页面可见性变化处理 +document.addEventListener('visibilitychange', function() { + if (document.hidden) { + // 页面隐藏时的处理 + console.log('页面已隐藏'); + } else { + // 页面显示时的处理 + console.log('页面已显示'); + } +}); + +// 错误处理 +window.addEventListener('error', function(e) { + console.error('全局错误:', e.error); + showToast('发生未知错误,请刷新页面重试', 'error'); +}); + +// 未处理的Promise拒绝 +window.addEventListener('unhandledrejection', function(e) { + console.error('未处理的Promise拒绝:', e.reason); + showToast('网络请求失败,请检查网络连接', 'error'); +}); + +// 导出函数供测试使用 +if (typeof module !== 'undefined' && module.exports) { + module.exports = { + handleProcess, + copyToClipboard, + showToast, + debounce, + throttle + }; +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json b/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json new file mode 100644 index 00000000..547b2771 --- /dev/null +++ b/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json @@ -0,0 +1,3 @@ +[ + "https://60s.api.shumengya.top" +] diff --git a/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json b/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json new file mode 100644 index 00000000..a6b3804b --- /dev/null +++ b/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json @@ -0,0 +1,33 @@ +{ + "code": 200, + "message": "处理成功", + "data": { + "source": "你好👋", + "md5": "a1b2c3d4e5f6789012345678901234567", + "sha": { + "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "sha512": "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + }, + "base64": { + "encode": "5L2g5aW9", + "decode": "你好" + }, + "url": { + "encode": "%E4%BD%A0%E5%A5%BD%F0%9F%91%8B", + "decode": "你好👋" + }, + "gzip": { + "compress": "H4sIAAAAAAAAA...(压缩后的数据)", + "decompress": "你好👋" + }, + "deflate": { + "compress": "eJwrz8kvTUlMy...(压缩后的数据)", + "decompress": "你好👋" + }, + "brotli": { + "compress": "CwWAaGVsbG8g...(压缩后的数据)", + "decompress": "你好👋" + } + } +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气/接口集合.json b/frontend/60sapi/实用功能/实时天气/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/实用功能/实时天气/接口集合.json +++ b/frontend/60sapi/实用功能/实时天气/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/生成二维码/接口集合.json b/frontend/60sapi/实用功能/生成二维码/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/实用功能/生成二维码/接口集合.json +++ b/frontend/60sapi/实用功能/生成二维码/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/生成要求模板.txt b/frontend/60sapi/实用功能/生成要求模板.txt new file mode 100644 index 00000000..91b7c04d --- /dev/null +++ b/frontend/60sapi/实用功能/生成要求模板.txt @@ -0,0 +1,8 @@ +1.生成为静态网页,js,css,html分离出来,不要混合在一起放入html里,难以阅读 +2.网页要适配手机端,电脑端和平板端三个设备分别做不同的css格式,优先优化手机端用户体验 +3.网页默认风格以淡绿色清新风格为主,除非用户要求 +4.尽量不要引用外部css,js,实在要引用就使用中国国内的cdn,否则用户可能加载不出来 +5.返回接口.json储存了网页api返回的数据格式 +6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...” +7.接口集合.json保存了所有已知的后端API接口,一个访问不了尝试自动切换另一个 +8.在css中有关背景的css单独一个css文件,方便我直接迁移 diff --git a/frontend/60sapi/实用功能/百度百科词条/接口集合.json b/frontend/60sapi/实用功能/百度百科词条/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/实用功能/百度百科词条/接口集合.json +++ b/frontend/60sapi/实用功能/百度百科词条/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/实用功能/链接OG信息/css/background.css b/frontend/60sapi/实用功能/链接OG信息/css/background.css new file mode 100644 index 00000000..27d9e571 --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/css/background.css @@ -0,0 +1,232 @@ +/* 高维度背景特效样式 - 神秘高级风格 */ + +/* 背景容器 */ +.background-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1; + overflow: hidden; + pointer-events: none; + background: radial-gradient(ellipse at center, + rgba(15, 0, 30, 0.95) 0%, + rgba(5, 0, 15, 0.98) 50%, + rgba(0, 0, 0, 1) 100%); +} + +/* 几何网格层 */ +.geometric-grid { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + linear-gradient(rgba(138, 43, 226, 0.1) 1px, transparent 1px), + linear-gradient(90deg, rgba(138, 43, 226, 0.1) 1px, transparent 1px), + linear-gradient(rgba(75, 0, 130, 0.05) 1px, transparent 1px), + linear-gradient(90deg, rgba(75, 0, 130, 0.05) 1px, transparent 1px); + background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px; + animation: gridPulse 8s ease-in-out infinite; +} + +@keyframes gridPulse { + 0%, 100% { opacity: 0.3; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(1.02); } +} + +/* 神经网络效果 */ +.neural-network { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 30%, rgba(138, 43, 226, 0.15) 2px, transparent 2px), + radial-gradient(circle at 80% 20%, rgba(75, 0, 130, 0.12) 1px, transparent 1px), + radial-gradient(circle at 40% 70%, rgba(147, 0, 211, 0.1) 1.5px, transparent 1.5px), + radial-gradient(circle at 90% 80%, rgba(138, 43, 226, 0.08) 1px, transparent 1px), + radial-gradient(circle at 10% 90%, rgba(75, 0, 130, 0.1) 2px, transparent 2px); + background-size: 200px 200px, 150px 150px, 300px 300px, 180px 180px, 250px 250px; + animation: neuralFlow 15s linear infinite; +} + +@keyframes neuralFlow { + 0% { transform: translate(0, 0) rotate(0deg); } + 25% { transform: translate(-10px, -5px) rotate(90deg); } + 50% { transform: translate(-5px, -10px) rotate(180deg); } + 75% { transform: translate(5px, -5px) rotate(270deg); } + 100% { transform: translate(0, 0) rotate(360deg); } +} + +/* 粒子系统 */ +.particle-system { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle, rgba(138, 43, 226, 0.4) 1px, transparent 1px), + radial-gradient(circle, rgba(75, 0, 130, 0.3) 0.5px, transparent 0.5px), + radial-gradient(circle, rgba(147, 0, 211, 0.2) 0.8px, transparent 0.8px); + background-size: 80px 80px, 120px 120px, 160px 160px; + background-position: 0 0, 40px 40px, 80px 80px; + animation: particleFloat 20s ease-in-out infinite; +} + +@keyframes particleFloat { + 0%, 100% { transform: translateY(0px) translateX(0px); } + 25% { transform: translateY(-20px) translateX(10px); } + 50% { transform: translateY(-10px) translateX(-15px); } + 75% { transform: translateY(-30px) translateX(5px); } +} + +/* 扫描线效果 */ +.scan-lines { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: repeating-linear-gradient( + 0deg, + transparent 0px, + transparent 2px, + rgba(138, 43, 226, 0.03) 2px, + rgba(138, 43, 226, 0.03) 4px + ); + animation: scanMove 3s linear infinite; +} + +@keyframes scanMove { + 0% { transform: translateY(-100%); } + 100% { transform: translateY(100%); } +} + +/* 全息投影效果 */ +.holographic-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + linear-gradient(45deg, + transparent 30%, + rgba(138, 43, 226, 0.05) 50%, + transparent 70%), + linear-gradient(-45deg, + transparent 30%, + rgba(75, 0, 130, 0.03) 50%, + transparent 70%); + background-size: 200px 200px, 150px 150px; + animation: holographicShift 12s ease-in-out infinite; +} + +@keyframes holographicShift { + 0%, 100% { + background-position: 0% 0%, 100% 100%; + opacity: 0.7; + } + 50% { + background-position: 100% 100%, 0% 0%; + opacity: 1; + } +} + +/* 数据流效果 */ +.data-stream { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + linear-gradient(90deg, + transparent 0%, + rgba(138, 43, 226, 0.1) 50%, + transparent 100%); + background-size: 300px 100%; + animation: dataFlow 8s linear infinite; +} + +@keyframes dataFlow { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } +} + +/* 量子波动效果 */ +.quantum-waves { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(ellipse 200px 100px at 50% 0%, + rgba(138, 43, 226, 0.1) 0%, + transparent 50%), + radial-gradient(ellipse 300px 150px at 50% 100%, + rgba(75, 0, 130, 0.08) 0%, + transparent 50%); + animation: quantumPulse 10s ease-in-out infinite; +} + +@keyframes quantumPulse { + 0%, 100% { + transform: scale(1) rotate(0deg); + opacity: 0.5; + } + 50% { + transform: scale(1.1) rotate(180deg); + opacity: 0.8; + } +} + +/* 响应式优化 */ +@media (max-width: 768px) { + .geometric-grid { + background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px; + } + + .neural-network { + background-size: 100px 100px, 75px 75px, 150px 150px, 90px 90px, 125px 125px; + } + + .particle-system { + background-size: 40px 40px, 60px 60px, 80px 80px; + } +} + +/* 减少动画偏好 */ +@media (prefers-reduced-motion: reduce) { + .geometric-grid, + .neural-network, + .particle-system, + .scan-lines, + .holographic-overlay, + .data-stream, + .quantum-waves { + animation: none; + } +} + +/* 高对比度模式 */ +@media (prefers-contrast: high) { + .background-container { + background: radial-gradient(ellipse at center, + rgba(25, 0, 50, 0.95) 0%, + rgba(10, 0, 25, 0.98) 50%, + rgba(0, 0, 0, 1) 100%); + } + + .geometric-grid { + background-image: + linear-gradient(rgba(200, 100, 255, 0.2) 1px, transparent 1px), + linear-gradient(90deg, rgba(200, 100, 255, 0.2) 1px, transparent 1px); + } +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/css/style.css b/frontend/60sapi/实用功能/链接OG信息/css/style.css new file mode 100644 index 00000000..e36e7c0d --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/css/style.css @@ -0,0 +1,1159 @@ +/* 全局样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +/* 根变量定义 */ +:root { + /* 神秘色彩系统 */ + --primary-dark: #0a0a0a; + --secondary-dark: #1a1a1a; + --accent-dark: #2a2a2a; + --border-dark: #333333; + + /* 神秘绿色系统 */ + --neon-green: #00ff88; + --dark-green: #004d2a; + --light-green: #66ffaa; + --glow-green: rgba(0, 255, 136, 0.3); + + /* 高级紫色系统 */ + --neon-purple: #8a2be2; + --dark-purple: #4a0e4e; + --light-purple: #b347d9; + --glow-purple: rgba(138, 43, 226, 0.3); + + /* 文字颜色 */ + --text-primary: #ffffff; + --text-secondary: #cccccc; + --text-muted: #888888; + --text-accent: var(--neon-green); + + /* 间距系统 */ + --spacing-xs: 0.5rem; + --spacing-sm: 1rem; + --spacing-md: 1.5rem; + --spacing-lg: 2rem; + --spacing-xl: 3rem; + + /* 字体系统 */ + --font-primary: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-mono: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace; + + /* 阴影系统 */ + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 20px var(--glow-green); + --shadow-purple-glow: 0 0 20px var(--glow-purple); + + /* 边框半径 */ + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + + /* 过渡效果 */ + --transition-fast: 0.2s ease; + --transition-normal: 0.3s ease; + --transition-slow: 0.5s ease; +} + +/* 基础样式 */ +body { + font-family: var(--font-primary); + background: var(--primary-dark); + color: var(--text-primary); + line-height: 1.6; + overflow-x: hidden; + min-height: 100vh; + position: relative; +} + +/* 主容器 */ +.main-container { + position: relative; + z-index: 10; + min-height: 100vh; + display: flex; + flex-direction: column; + max-width: 1400px; + margin: 0 auto; + padding: var(--spacing-lg); +} + +/* 头部样式 */ +.header { + margin-bottom: var(--spacing-xl); + position: relative; +} + +.header-content { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--spacing-lg); + background: linear-gradient(135deg, var(--secondary-dark), var(--accent-dark)); + border: 1px solid var(--border-dark); + border-radius: var(--radius-xl); + backdrop-filter: blur(10px); + position: relative; + overflow: hidden; +} + +.header-content::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, var(--glow-green), transparent); + animation: scanLine 3s infinite; +} + +@keyframes scanLine { + 0% { left: -100%; } + 100% { left: 100%; } +} + +.logo-section { + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.logo-icon { + font-size: 2.5rem; + color: var(--neon-green); + filter: drop-shadow(0 0 10px var(--glow-green)); + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +.title { + font-size: 2.5rem; + font-weight: 700; + background: linear-gradient(45deg, var(--neon-green), var(--light-green)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-shadow: 0 0 20px var(--glow-green); +} + +.subtitle { + font-size: 1rem; + color: var(--text-secondary); + font-family: var(--font-mono); + opacity: 0.8; +} + +.status-indicator { + display: flex; + align-items: center; + gap: var(--spacing-xs); + padding: var(--spacing-sm) var(--spacing-md); + background: rgba(0, 255, 136, 0.1); + border: 1px solid var(--neon-green); + border-radius: var(--radius-lg); + backdrop-filter: blur(5px); +} + +.pulse-dot { + width: 8px; + height: 8px; + background: var(--neon-green); + border-radius: 50%; + animation: pulseGlow 1.5s infinite; +} + +@keyframes pulseGlow { + 0%, 100% { + opacity: 1; + box-shadow: 0 0 5px var(--glow-green); + } + 50% { + opacity: 0.5; + box-shadow: 0 0 15px var(--glow-green); + } +} + +.status-text { + font-size: 0.9rem; + color: var(--neon-green); + font-family: var(--font-mono); +} + +/* 查询区域 */ +.query-section { + margin-bottom: var(--spacing-xl); +} + +.input-container { + display: flex; + gap: var(--spacing-md); + align-items: stretch; +} + +.input-wrapper { + flex: 1; + position: relative; + background: var(--secondary-dark); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.input-icon { + position: absolute; + left: var(--spacing-md); + top: 50%; + transform: translateY(-50%); + color: var(--text-muted); + font-size: 1.2rem; + z-index: 2; + transition: var(--transition-normal); +} + +.url-input { + width: 100%; + padding: var(--spacing-md) var(--spacing-md) var(--spacing-md) 3.5rem; + background: transparent; + border: 2px solid var(--border-dark); + border-radius: var(--radius-lg); + color: var(--text-primary); + font-size: 1.1rem; + font-family: var(--font-mono); + transition: var(--transition-normal); + position: relative; + z-index: 1; +} + +.url-input:focus { + outline: none; + border-color: var(--neon-green); + box-shadow: var(--shadow-glow); +} + +.url-input:focus + .input-border { + opacity: 1; + animation: borderGlow 2s infinite; +} + +.url-input:focus ~ .input-icon { + color: var(--neon-green); +} + +.input-border { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 2px solid var(--neon-green); + border-radius: var(--radius-lg); + opacity: 0; + pointer-events: none; + transition: var(--transition-normal); +} + +@keyframes borderGlow { + 0%, 100% { box-shadow: 0 0 5px var(--glow-green); } + 50% { box-shadow: 0 0 20px var(--glow-green); } +} + +.analyze-btn { + position: relative; + padding: var(--spacing-md) var(--spacing-xl); + background: linear-gradient(135deg, var(--dark-green), var(--neon-green)); + border: none; + border-radius: var(--radius-lg); + color: var(--primary-dark); + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + overflow: hidden; + transition: var(--transition-normal); + min-width: 150px; +} + +.analyze-btn:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-glow); +} + +.analyze-btn:active { + transform: translateY(0); +} + +.btn-text { + position: relative; + z-index: 2; +} + +.btn-effects { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; +} + +.ripple { + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(255, 255, 255, 0.3); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: var(--transition-fast); +} + +.analyze-btn:active .ripple { + width: 200px; + height: 200px; +} + +/* 加载状态 */ +.loading-container { + display: flex; + justify-content: center; + align-items: center; + padding: var(--spacing-xl); + margin: var(--spacing-xl) 0; +} + +.loading-content { + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: var(--spacing-lg); +} + +.scanner { + position: relative; + width: 200px; + height: 200px; + border: 2px solid var(--border-dark); + border-radius: var(--radius-lg); + background: var(--secondary-dark); + overflow: hidden; +} + +.scanner-line { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 2px; + background: linear-gradient(90deg, transparent, var(--neon-green), transparent); + animation: scannerMove 2s infinite; +} + +@keyframes scannerMove { + 0% { top: 0; } + 100% { top: calc(100% - 2px); } +} + +.scanner-grid { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1px; +} + +.grid-line { + background: var(--border-dark); + opacity: 0.3; + animation: gridPulse 1.5s infinite; +} + +.grid-line:nth-child(1) { animation-delay: 0s; } +.grid-line:nth-child(2) { animation-delay: 0.2s; } +.grid-line:nth-child(3) { animation-delay: 0.4s; } +.grid-line:nth-child(4) { animation-delay: 0.6s; } + +@keyframes gridPulse { + 0%, 100% { opacity: 0.3; } + 50% { opacity: 0.8; background: var(--glow-green); } +} + +.loading-text { + display: flex; + flex-direction: column; + gap: var(--spacing-xs); +} + +.loading-title { + font-size: 1.5rem; + font-weight: 600; + color: var(--neon-green); +} + +.loading-subtitle { + font-size: 1rem; + color: var(--text-secondary); + font-family: var(--font-mono); +} + +/* 结果展示区域 */ +.results-section { + margin-bottom: var(--spacing-xl); +} + +.results-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-lg); + padding: var(--spacing-md); + background: var(--secondary-dark); + border-radius: var(--radius-lg); + border: 1px solid var(--border-dark); +} + +.results-title { + display: flex; + align-items: center; + gap: var(--spacing-sm); + font-size: 1.5rem; + font-weight: 600; + color: var(--neon-green); +} + +.results-actions { + display: flex; + gap: var(--spacing-sm); +} + +.action-btn { + display: flex; + align-items: center; + gap: var(--spacing-xs); + padding: var(--spacing-sm) var(--spacing-md); + background: var(--accent-dark); + border: 1px solid var(--border-dark); + border-radius: var(--radius-md); + color: var(--text-secondary); + font-size: 0.9rem; + cursor: pointer; + transition: var(--transition-normal); +} + +.action-btn:hover { + background: var(--border-dark); + color: var(--text-primary); + border-color: var(--neon-green); +} + +/* OG卡片 */ +.og-card { + background: var(--secondary-dark); + border: 1px solid var(--border-dark); + border-radius: var(--radius-xl); + overflow: hidden; + box-shadow: var(--shadow-lg); +} + +.info-section { + padding: var(--spacing-lg); + border-bottom: 1px solid var(--border-dark); +} + +.info-section:last-child { + border-bottom: none; +} + +.section-header { + display: flex; + align-items: center; + gap: var(--spacing-sm); + margin-bottom: var(--spacing-md); + font-size: 1.2rem; + font-weight: 600; + color: var(--text-accent); +} + +.info-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: var(--spacing-md); +} + +.info-item { + display: flex; + flex-direction: column; + gap: var(--spacing-xs); +} + +.info-item label { + font-size: 0.9rem; + color: var(--text-muted); + font-family: var(--font-mono); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.info-value { + padding: var(--spacing-sm); + background: var(--accent-dark); + border: 1px solid var(--border-dark); + border-radius: var(--radius-md); + color: var(--text-primary); + font-family: var(--font-mono); + word-break: break-all; + transition: var(--transition-normal); +} + +.info-value:hover { + border-color: var(--neon-green); + box-shadow: 0 0 10px var(--glow-green); +} + +.url-value { + color: var(--light-green); + cursor: pointer; +} + +.url-value:hover { + color: var(--neon-green); +} + +/* 媒体预览 */ +.media-preview { + margin-bottom: var(--spacing-md); + border-radius: var(--radius-lg); + overflow: hidden; + background: var(--accent-dark); + border: 1px solid var(--border-dark); + min-height: 200px; + display: flex; + align-items: center; + justify-content: center; +} + +.media-preview img { + max-width: 100%; + max-height: 300px; + object-fit: contain; + border-radius: var(--radius-md); +} + +.no-media { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--spacing-sm); + color: var(--text-muted); + font-size: 1.1rem; +} + +.no-media i { + font-size: 2rem; + opacity: 0.5; +} + +.media-details { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: var(--spacing-md); +} + +/* 错误状态 */ +.error-container { + display: flex; + justify-content: center; + align-items: center; + padding: var(--spacing-xl); + margin: var(--spacing-xl) 0; +} + +.error-content { + text-align: center; + padding: var(--spacing-xl); + background: var(--secondary-dark); + border: 2px solid #ff4444; + border-radius: var(--radius-xl); + max-width: 500px; + box-shadow: 0 0 20px rgba(255, 68, 68, 0.3); +} + +.error-icon { + font-size: 3rem; + color: #ff4444; + margin-bottom: var(--spacing-md); + animation: shake 0.5s infinite; +} + +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-5px); } + 75% { transform: translateX(5px); } +} + +.error-title { + font-size: 1.5rem; + font-weight: 600; + color: #ff4444; + margin-bottom: var(--spacing-sm); +} + +.error-message { + color: var(--text-secondary); + margin-bottom: var(--spacing-lg); + font-family: var(--font-mono); +} + +.retry-btn { + display: inline-flex; + align-items: center; + gap: var(--spacing-xs); + padding: var(--spacing-sm) var(--spacing-lg); + background: #ff4444; + border: none; + border-radius: var(--radius-md); + color: white; + font-weight: 600; + cursor: pointer; + transition: var(--transition-normal); +} + +.retry-btn:hover { + background: #ff6666; + transform: translateY(-2px); +} + +/* Tip 消息样式 */ +.tip-container { + position: fixed; + bottom: 2rem; + left: 2rem; + z-index: 999; + opacity: 0; + transform: translateY(20px); + transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); + pointer-events: none; +} + +.tip-container.active { + opacity: 1; + transform: translateY(0); + pointer-events: auto; +} + +.tip-content { + background: linear-gradient(135deg, + rgba(138, 43, 226, 0.1) 0%, + rgba(75, 0, 130, 0.1) 100%); + border: 1px solid rgba(138, 43, 226, 0.3); + border-radius: var(--radius-lg); + padding: var(--spacing-md); + backdrop-filter: blur(10px); + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.3), + 0 0 20px rgba(138, 43, 226, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + display: flex; + align-items: center; + gap: var(--spacing-sm); + min-width: 300px; + max-width: 400px; +} + +.tip-icon { + font-size: 1.2rem; + color: var(--neon-purple); + flex-shrink: 0; +} + +.tip-text { + color: var(--text-secondary); + font-size: 0.9rem; + line-height: 1.4; +} + +/* 提示消息 */ +.toast-container { + position: fixed; + top: var(--spacing-lg); + right: var(--spacing-lg); + z-index: 1000; + transform: translateX(100%); + transition: var(--transition-normal); +} + +.toast-container.show { + transform: translateX(0); +} + +.toast-content { + display: flex; + align-items: center; + gap: var(--spacing-sm); + padding: var(--spacing-md) var(--spacing-lg); + background: var(--secondary-dark); + border: 1px solid var(--neon-green); + border-radius: var(--radius-lg); + color: var(--text-primary); + box-shadow: var(--shadow-glow); + backdrop-filter: blur(10px); +} + +.toast-icon { + font-size: 1.2rem; + color: var(--neon-green); +} + +.toast-message { + font-family: var(--font-mono); + font-size: 0.9rem; +} + +/* 页脚 */ +.footer { + margin-top: auto; + padding: var(--spacing-lg); + border-top: 1px solid var(--border-dark); + background: var(--secondary-dark); + border-radius: var(--radius-lg); +} + +.footer-content { + display: flex; + justify-content: space-between; + align-items: center; + text-align: center; +} + +.footer-text { + display: flex; + align-items: center; + gap: var(--spacing-xs); + color: var(--text-muted); + font-size: 0.9rem; + font-family: var(--font-mono); +} + +.footer-links { + display: flex; + align-items: center; + gap: var(--spacing-sm); + font-size: 0.8rem; + color: var(--text-muted); +} + +.footer-link { + cursor: pointer; + transition: var(--transition-normal); +} + +.footer-link:hover { + color: var(--neon-green); +} + +.footer-divider { + opacity: 0.5; +} + +/* 响应式设计 */ + +/* 平板设备 */ +@media (max-width: 1024px) { + .main-container { + padding: var(--spacing-md); + } + + .header-content { + flex-direction: column; + gap: var(--spacing-md); + text-align: center; + } + + .title { + font-size: 2rem; + } + + .input-container { + flex-direction: column; + } + + .analyze-btn { + width: 100%; + } + + .info-grid { + grid-template-columns: 1fr; + } + + .results-header { + flex-direction: column; + gap: var(--spacing-md); + } + + .footer-content { + flex-direction: column; + gap: var(--spacing-sm); + } +} + +/* 交互动画增强 */ +.input-glow { + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, + var(--neon-green), + var(--light-green), + var(--neon-purple)); + border-radius: inherit; + z-index: -1; + opacity: 0; + animation: glowPulse 2s ease-in-out; +} + +@keyframes glowPulse { + 0%, 100% { opacity: 0; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(1.02); } +} + +.input-container.shake { + animation: inputShake 0.6s ease-in-out; +} + +@keyframes inputShake { + 0%, 100% { transform: translateX(0); } + 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } + 20%, 40%, 60%, 80% { transform: translateX(5px); } +} + +.analyze-btn.flash, +.action-btn.flash { + animation: buttonFlash 0.3s ease-in-out; +} + +@keyframes buttonFlash { + 0%, 100% { background: linear-gradient(135deg, var(--dark-green), var(--neon-green)); } + 50% { background: var(--neon-purple); box-shadow: 0 0 20px var(--glow-purple); } +} + +.og-card.animate-in { + animation: cardSlideIn 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; +} + +@keyframes cardSlideIn { + 0% { + opacity: 0; + transform: translateY(30px) scale(0.95); + } + 100% { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.header.animate-in { + animation: headerFadeIn 1s ease-out forwards; +} + +@keyframes headerFadeIn { + 0% { + opacity: 0; + transform: translateY(-20px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.query-section.animate-in { + animation: sectionSlideUp 0.8s ease-out 0.2s forwards; + opacity: 0; +} + +@keyframes sectionSlideUp { + 0% { + opacity: 0; + transform: translateY(40px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeInUp { + 0% { + opacity: 0; + transform: translateY(20px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeOutDown { + 0% { + opacity: 1; + transform: translateY(0); + } + 100% { + opacity: 0; + transform: translateY(20px); + } +} + +/* 高级悬浮效果 */ +.og-card:hover { + transform: translateY(-5px) scale(1.02); + box-shadow: + 0 10px 30px var(--glow-purple), + 0 0 20px rgba(138, 43, 226, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.analyze-btn:hover:not(:disabled) { + transform: translateY(-3px); + box-shadow: + 0 8px 25px var(--glow-green), + 0 0 15px rgba(0, 255, 136, 0.2); +} + +.action-btn:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 5px 15px var(--glow-purple); +} + +/* 图片加载动画 */ +.media-preview img { + transition: all 0.3s ease; +} + +.media-preview img:hover { + transform: scale(1.05); + box-shadow: 0 8px 25px var(--glow-green); +} + +.image-placeholder { + background: linear-gradient(135deg, + var(--glow-green) 0%, + var(--glow-purple) 100%); + border: 2px dashed rgba(138, 43, 226, 0.3); + display: none; + align-items: center; + justify-content: center; + min-height: 200px; + border-radius: var(--radius-lg); + color: var(--text-secondary); + font-size: 0.9rem; +} + +/* 手机设备 */ +@media (max-width: 768px) { + .main-container { + padding: var(--spacing-sm); + } + + .header-content { + padding: var(--spacing-md); + } + + .title { + font-size: 1.8rem; + } + + .subtitle { + font-size: 0.9rem; + } + + .logo-icon { + font-size: 2rem; + } + + .url-input { + font-size: 16px; /* 防止iOS缩放 */ + padding: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm) 3rem; + } + + .input-icon { + left: var(--spacing-sm); + font-size: 1rem; + } + + .analyze-btn { + padding: var(--spacing-sm) var(--spacing-md); + font-size: 1rem; + } + + .scanner { + width: 150px; + height: 150px; + } + + .loading-title { + font-size: 1.3rem; + } + + .loading-subtitle { + font-size: 0.9rem; + } + + .results-title { + font-size: 1.3rem; + } + + .action-btn { + font-size: 0.8rem; + padding: var(--spacing-xs) var(--spacing-sm); + } + + .info-section { + padding: var(--spacing-md); + } + + .section-header { + font-size: 1.1rem; + } + + .media-details { + grid-template-columns: 1fr; + } + + .toast-container { + top: var(--spacing-sm); + right: var(--spacing-sm); + left: var(--spacing-sm); + transform: translateY(-100%); + } + + .toast-container.show { + transform: translateY(0); + } + + .footer-text { + font-size: 0.8rem; + } + + .footer-links { + font-size: 0.7rem; + } + + /* 移动设备上禁用部分悬浮效果 */ + .og-card:hover { + transform: none; + } + + .media-preview img:hover { + transform: none; + } +} + +/* 小屏手机设备 */ +@media (max-width: 480px) { + .main-container { + padding: var(--spacing-xs); + } + + .title { + font-size: 1.5rem; + } + + .logo-section { + flex-direction: column; + gap: var(--spacing-sm); + } + + .scanner { + width: 120px; + height: 120px; + } + + .error-content { + padding: var(--spacing-md); + } + + .error-icon { + font-size: 2.5rem; + } + + .error-title { + font-size: 1.3rem; + } +} + +/* 高分辨率屏幕优化 */ +@media (min-width: 1440px) { + .main-container { + max-width: 1600px; + } + + .title { + font-size: 3rem; + } + + .url-input { + font-size: 1.2rem; + } + + .analyze-btn { + font-size: 1.2rem; + padding: var(--spacing-lg) var(--spacing-xl); + } +} + +/* 深色模式优化 */ +@media (prefers-color-scheme: dark) { + :root { + --primary-dark: #000000; + --secondary-dark: #111111; + --accent-dark: #222222; + } +} + +/* 减少动画偏好 */ +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* 打印样式 */ +@media print { + .background-container, + .header, + .query-section, + .loading-container, + .error-container, + .toast-container, + .footer { + display: none; + } + + .results-section { + margin: 0; + padding: 0; + } + + .og-card { + border: 1px solid #000; + box-shadow: none; + } +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/index.html b/frontend/60sapi/实用功能/链接OG信息/index.html new file mode 100644 index 00000000..d3251708 --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/index.html @@ -0,0 +1,223 @@ + + + + + + 链接OG信息查询 - 神秘解析器 + + + + + + + +
+
+
+
+
+ + +
+ +
+
+
+ +

OG 解析器

+ 链接元数据神秘解析 +
+
+
+ 系统就绪 +
+
+
+ + +
+
+
+ + +
+
+ +
+
+ + + + + + + + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + + \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/js/script.js b/frontend/60sapi/实用功能/链接OG信息/js/script.js new file mode 100644 index 00000000..7a25592a --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/js/script.js @@ -0,0 +1,555 @@ +// 链接OG信息查询 - JavaScript功能代码 +// 神秘高级风格的交互体验 + +class OGAnalyzer { + constructor() { + this.apiUrl = 'https://60s.viki.moe/v2/og'; + this.isAnalyzing = false; + this.currentUrl = ''; + this.animationFrameId = null; + + this.init(); + } + + init() { + this.bindEvents(); + this.createBackgroundEffects(); + this.initializeAnimations(); + this.showWelcomeMessage(); + this.initPageAnimations(); + } + + // 初始化页面动画 + initPageAnimations() { + // 延迟添加动画类,确保CSS已加载 + setTimeout(() => { + const header = document.querySelector('.header'); + const querySection = document.querySelector('.query-section'); + + if (header) header.classList.add('animate-in'); + if (querySection) querySection.classList.add('animate-in'); + }, 100); + } + + bindEvents() { + const urlInput = document.getElementById('url-input'); + const analyzeBtn = document.getElementById('analyze-btn'); + const copyBtn = document.getElementById('copy-btn'); + const clearBtn = document.getElementById('clear-btn'); + + // 输入框事件 + urlInput.addEventListener('input', (e) => this.handleUrlInput(e)); + urlInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter' && !this.isAnalyzing) { + this.analyzeUrl(); + } + }); + urlInput.addEventListener('focus', () => this.handleInputFocus()); + urlInput.addEventListener('blur', () => this.handleInputBlur()); + + // 按钮事件 + analyzeBtn.addEventListener('click', () => this.analyzeUrl()); + copyBtn.addEventListener('click', () => this.copyResults()); + clearBtn.addEventListener('click', () => this.clearResults()); + + // 键盘快捷键 + document.addEventListener('keydown', (e) => this.handleKeyboard(e)); + } + + handleUrlInput(e) { + const url = e.target.value.trim(); + const analyzeBtn = document.getElementById('analyze-btn'); + + if (this.isValidUrl(url)) { + analyzeBtn.classList.add('ready'); + e.target.classList.remove('error'); + } else { + analyzeBtn.classList.remove('ready'); + if (url.length > 0) { + e.target.classList.add('error'); + } else { + e.target.classList.remove('error'); + } + } + } + + handleInputFocus() { + const inputContainer = document.querySelector('.input-container'); + inputContainer.classList.add('focused'); + this.createInputGlow(); + } + + handleInputBlur() { + const inputContainer = document.querySelector('.input-container'); + inputContainer.classList.remove('focused'); + } + + handleKeyboard(e) { + // Ctrl/Cmd + Enter 快速分析 + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { + e.preventDefault(); + if (!this.isAnalyzing) { + this.analyzeUrl(); + } + } + + // Escape 清除结果 + if (e.key === 'Escape') { + this.clearResults(); + } + } + + isValidUrl(string) { + try { + const url = new URL(string); + return url.protocol === 'http:' || url.protocol === 'https:'; + } catch (_) { + return false; + } + } + + async analyzeUrl() { + const urlInput = document.getElementById('url-input'); + const url = urlInput.value.trim(); + + if (!this.isValidUrl(url)) { + this.showError('请输入有效的URL地址'); + this.shakeInput(); + return; + } + + if (this.isAnalyzing) { + return; + } + + this.currentUrl = url; + this.isAnalyzing = true; + this.showLoading(); + this.hideError(); + this.hideResults(); + + try { + const response = await fetch(`${this.apiUrl}?url=${encodeURIComponent(url)}`); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + await this.displayResults(data.data); + this.showSuccessMessage('分析完成!'); + + // 添加按钮闪烁效果 + const analyzeBtn = document.getElementById('analyze-btn'); + analyzeBtn.classList.add('flash'); + setTimeout(() => { + analyzeBtn.classList.remove('flash'); + }, 300); + } else { + throw new Error(data.message || '获取OG信息失败'); + } + } catch (error) { + console.error('分析失败:', error); + this.showError(`分析失败: ${error.message}`); + } finally { + this.isAnalyzing = false; + this.hideLoading(); + } + } + + showLoading() { + const loadingElement = document.getElementById('loading'); + const analyzeBtn = document.getElementById('analyze-btn'); + + loadingElement.classList.add('active'); + analyzeBtn.disabled = true; + analyzeBtn.textContent = '分析中...'; + + this.startScannerAnimation(); + } + + hideLoading() { + const loadingElement = document.getElementById('loading'); + const analyzeBtn = document.getElementById('analyze-btn'); + + loadingElement.classList.remove('active'); + analyzeBtn.disabled = false; + analyzeBtn.textContent = '开始分析'; + + this.stopScannerAnimation(); + } + + async displayResults(data) { + const resultsElement = document.getElementById('results'); + const ogCard = document.getElementById('og-card'); + + // 基础信息 + this.updateElement('og-title', data.title || '未获取到标题'); + this.updateElement('og-description', data.description || '未获取到描述'); + this.updateElement('og-url', data.url || this.currentUrl); + this.updateElement('og-site-name', data.site_name || '未知站点'); + this.updateElement('og-type', data.type || 'website'); + + // 媒体信息 + this.updateImageElement('og-image', data.image); + this.updateElement('og-image-alt', data.image_alt || '图片描述不可用'); + + // 技术信息 + this.updateElement('og-locale', data.locale || '未指定'); + this.updateElement('og-updated-time', this.formatDate(data.updated_time)); + this.updateElement('response-time', `${Date.now() - this.startTime}ms`); + + // 显示结果 + resultsElement.classList.add('active'); + + // 添加动画效果 + await this.animateResults(); + + // 启用操作按钮 + document.getElementById('copy-btn').disabled = false; + document.getElementById('clear-btn').disabled = false; + } + + updateElement(id, content) { + const element = document.getElementById(id); + if (element) { + element.textContent = content; + } + } + + updateImageElement(id, imageSrc) { + const element = document.getElementById(id); + if (element && imageSrc) { + element.src = imageSrc; + element.style.display = 'block'; + element.onerror = () => { + element.style.display = 'none'; + const placeholder = element.nextElementSibling; + if (placeholder && placeholder.classList.contains('image-placeholder')) { + placeholder.style.display = 'flex'; + } + }; + } else if (element) { + element.style.display = 'none'; + const placeholder = element.nextElementSibling; + if (placeholder && placeholder.classList.contains('image-placeholder')) { + placeholder.style.display = 'flex'; + } + } + } + + formatDate(timestamp) { + if (!timestamp) return '未知'; + try { + const date = new Date(timestamp); + return date.toLocaleString('zh-CN'); + } catch (e) { + return '格式错误'; + } + } + + async animateResults() { + const cards = document.querySelectorAll('.info-card'); + + for (let i = 0; i < cards.length; i++) { + setTimeout(() => { + cards[i].classList.add('animate-in'); + }, i * 100); + } + + // 等待动画完成 + await new Promise(resolve => setTimeout(resolve, cards.length * 100 + 300)); + } + + showError(message) { + const errorElement = document.getElementById('error-message'); + const errorText = errorElement.querySelector('.error-text'); + const inputContainer = document.querySelector('.input-container'); + + errorText.textContent = message; + errorElement.classList.add('active'); + + // 添加震动效果 + if (inputContainer) { + inputContainer.classList.add('shake'); + setTimeout(() => { + inputContainer.classList.remove('shake'); + }, 600); + } + + // 自动隐藏错误信息 + setTimeout(() => { + this.hideError(); + }, 5000); + } + + hideError() { + const errorElement = document.getElementById('error-message'); + errorElement.classList.remove('active'); + } + + hideResults() { + const resultsElement = document.getElementById('results'); + resultsElement.classList.remove('active'); + + // 重置动画状态 + const cards = document.querySelectorAll('.info-card'); + cards.forEach(card => card.classList.remove('animate-in')); + } + + showSuccessMessage(message) { + const tipElement = document.getElementById('tip-message'); + const tipText = tipElement.querySelector('.tip-text'); + + tipText.textContent = message; + tipElement.classList.add('active'); + + setTimeout(() => { + tipElement.classList.remove('active'); + }, 3000); + } + + shakeInput() { + const inputContainer = document.querySelector('.input-container'); + inputContainer.classList.add('shake'); + + setTimeout(() => { + inputContainer.classList.remove('shake'); + }, 600); + } + + copyResults() { + const ogData = { + title: document.getElementById('og-title').textContent, + description: document.getElementById('og-description').textContent, + url: document.getElementById('og-url').textContent, + site_name: document.getElementById('og-site-name').textContent, + type: document.getElementById('og-type').textContent, + image: document.getElementById('og-image').src, + locale: document.getElementById('og-locale').textContent + }; + + const jsonString = JSON.stringify(ogData, null, 2); + + navigator.clipboard.writeText(jsonString).then(() => { + this.showSuccessMessage('结果已复制到剪贴板!'); + this.flashCopyButton(); + }).catch(err => { + console.error('复制失败:', err); + this.showError('复制失败,请手动选择内容'); + }); + } + + flashCopyButton() { + const copyBtn = document.getElementById('copy-btn'); + copyBtn.classList.add('flash'); + + setTimeout(() => { + copyBtn.classList.remove('flash'); + }, 300); + } + + clearResults() { + const urlInput = document.getElementById('url-input'); + const resultsElement = document.getElementById('results'); + const errorElement = document.getElementById('error-message'); + + urlInput.value = ''; + urlInput.classList.remove('error'); + resultsElement.classList.remove('active'); + errorElement.classList.remove('active'); + + document.getElementById('analyze-btn').classList.remove('ready'); + document.getElementById('copy-btn').disabled = true; + document.getElementById('clear-btn').disabled = true; + + this.currentUrl = ''; + + // 重置动画状态 + const cards = document.querySelectorAll('.info-card'); + cards.forEach(card => card.classList.remove('animate-in')); + + this.showSuccessMessage('已清除所有内容'); + } + + createBackgroundEffects() { + const container = document.querySelector('.background-container'); + + // 创建各种背景效果层 + const effects = [ + 'geometric-grid', + 'neural-network', + 'particle-system', + 'scan-lines', + 'holographic-overlay', + 'data-stream', + 'quantum-waves' + ]; + + effects.forEach(effectClass => { + const layer = document.createElement('div'); + layer.className = effectClass; + container.appendChild(layer); + }); + } + + createInputGlow() { + const inputContainer = document.querySelector('.input-container'); + + // 创建光晕效果 + const glow = document.createElement('div'); + glow.className = 'input-glow'; + inputContainer.appendChild(glow); + + setTimeout(() => { + if (glow.parentNode) { + glow.remove(); + } + }, 2000); + } + + startScannerAnimation() { + const scanner = document.querySelector('.scanner'); + if (scanner) { + scanner.classList.add('active'); + } + } + + stopScannerAnimation() { + const scanner = document.querySelector('.scanner'); + if (scanner) { + scanner.classList.remove('active'); + } + } + + initializeAnimations() { + // 初始化页面动画 + const header = document.querySelector('.header'); + const querySection = document.querySelector('.query-section'); + + setTimeout(() => { + header.classList.add('animate-in'); + }, 100); + + setTimeout(() => { + querySection.classList.add('animate-in'); + }, 300); + } + + showWelcomeMessage() { + const tips = [ + '支持分析网页的标题、描述、图片等元信息', + '可以预览社交媒体分享时的显示效果', + '检测网页的SEO优化情况', + '分析Open Graph协议标签' + ]; + + setTimeout(() => { + this.showSuccessMessage('欢迎使用链接OG信息分析器!'); + }, 1000); + + // 显示提示信息 + this.showTips(tips); + } + + // 显示提示信息 + showTips(tips) { + const tipElement = document.getElementById('tip-message'); + const tipText = tipElement.querySelector('.tip-text'); + + let currentTip = 0; + + const showNextTip = () => { + tipText.textContent = tips[currentTip]; + tipElement.classList.add('active'); + tipElement.style.animation = 'fadeInUp 0.5s ease-out'; + + setTimeout(() => { + tipElement.style.animation = 'fadeOutDown 0.5s ease-in'; + setTimeout(() => { + tipElement.classList.remove('active'); + currentTip = (currentTip + 1) % tips.length; + }, 500); + }, 3000); + }; + + // 首次显示 + setTimeout(showNextTip, 2000); + + // 每8秒显示一次 + setInterval(showNextTip, 8000); + } +} + +// 工具函数 +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +function throttle(func, limit) { + let inThrottle; + return function() { + const args = arguments; + const context = this; + if (!inThrottle) { + func.apply(context, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + } +} + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', () => { + // 检查必要的DOM元素 + const requiredElements = [ + 'url-input', 'analyze-btn', 'copy-btn', 'clear-btn', + 'loading', 'results', 'error-message', 'tip-message' + ]; + + const missingElements = requiredElements.filter(id => !document.getElementById(id)); + + if (missingElements.length > 0) { + console.error('缺少必要的DOM元素:', missingElements); + return; + } + + // 初始化应用 + window.ogAnalyzer = new OGAnalyzer(); + + // 添加全局错误处理 + window.addEventListener('error', (e) => { + console.error('全局错误:', e.error); + if (window.ogAnalyzer) { + window.ogAnalyzer.showError('发生未知错误,请刷新页面重试'); + } + }); + + // 添加网络状态监听 + window.addEventListener('online', () => { + if (window.ogAnalyzer) { + window.ogAnalyzer.showSuccessMessage('网络连接已恢复'); + } + }); + + window.addEventListener('offline', () => { + if (window.ogAnalyzer) { + window.ogAnalyzer.showError('网络连接已断开'); + } + }); +}); + +// 导出给其他模块使用 +if (typeof module !== 'undefined' && module.exports) { + module.exports = { OGAnalyzer, debounce, throttle }; +} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/接口集合.json b/frontend/60sapi/实用功能/链接OG信息/接口集合.json new file mode 100644 index 00000000..547b2771 --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/接口集合.json @@ -0,0 +1,3 @@ +[ + "https://60s.api.shumengya.top" +] diff --git a/frontend/60sapi/实用功能/链接OG信息/返回接口.json b/frontend/60sapi/实用功能/链接OG信息/返回接口.json new file mode 100644 index 00000000..de8516ab --- /dev/null +++ b/frontend/60sapi/实用功能/链接OG信息/返回接口.json @@ -0,0 +1,66 @@ +{ + "code": 200, + "message": "success", + "data": { + "url": "https://example.com", + "title": "示例网站标题", + "description": "这是一个示例网站的描述信息,用于展示OG标签解析功能。", + "image": "https://example.com/og-image.jpg", + "site_name": "示例网站", + "type": "website", + "locale": "zh_CN", + "author": "网站作者", + "keywords": "示例,网站,OG标签,元数据", + "favicon": "https://example.com/favicon.ico", + "canonical_url": "https://example.com", + "robots": "index,follow", + "viewport": "width=device-width, initial-scale=1.0", + "charset": "UTF-8", + "language": "zh-CN", + "published_time": "2024-01-01T00:00:00Z", + "modified_time": "2024-01-15T12:30:00Z", + "section": "技术", + "tags": ["前端", "元数据", "SEO"], + "twitter": { + "card": "summary_large_image", + "site": "@example", + "creator": "@author", + "title": "Twitter标题", + "description": "Twitter描述", + "image": "https://example.com/twitter-image.jpg" + }, + "facebook": { + "app_id": "123456789", + "admins": "987654321" + }, + "structured_data": { + "@context": "https://schema.org", + "@type": "WebPage", + "name": "示例网页", + "description": "示例网页描述", + "url": "https://example.com" + }, + "meta_tags": { + "generator": "WordPress 6.0", + "theme-color": "#000000", + "msapplication-TileColor": "#ffffff", + "apple-mobile-web-app-capable": "yes", + "apple-mobile-web-app-status-bar-style": "default" + }, + "performance": { + "load_time": 1.25, + "page_size": "2.3MB", + "requests_count": 45 + }, + "seo_score": { + "overall": 85, + "title_score": 90, + "description_score": 80, + "image_score": 85, + "structure_score": 88 + } + }, + "timestamp": "2024-01-15T12:30:45Z", + "request_id": "req_123456789", + "processing_time": 0.85 +} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/历史上的今天/接口集合.json b/frontend/60sapi/日更资讯/历史上的今天/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/日更资讯/历史上的今天/接口集合.json +++ b/frontend/60sapi/日更资讯/历史上的今天/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json b/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json +++ b/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json b/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json +++ b/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/css/background.css b/frontend/60sapi/热搜榜单/Hacker News 榜单/css/background.css similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/css/background.css rename to frontend/60sapi/热搜榜单/Hacker News 榜单/css/background.css diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/css/style.css b/frontend/60sapi/热搜榜单/Hacker News 榜单/css/style.css similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/css/style.css rename to frontend/60sapi/热搜榜单/Hacker News 榜单/css/style.css diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/index.html b/frontend/60sapi/热搜榜单/Hacker News 榜单/index.html similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/index.html rename to frontend/60sapi/热搜榜单/Hacker News 榜单/index.html diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/js/script.js b/frontend/60sapi/热搜榜单/Hacker News 榜单/js/script.js similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/js/script.js rename to frontend/60sapi/热搜榜单/Hacker News 榜单/js/script.js diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/接口集合.json b/frontend/60sapi/热搜榜单/Hacker News 榜单/接口集合.json similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/接口集合.json rename to frontend/60sapi/热搜榜单/Hacker News 榜单/接口集合.json diff --git a/frontend/60sapi/热搜榜单/HackerNews榜单/返回接口.json b/frontend/60sapi/热搜榜单/Hacker News 榜单/返回接口.json similarity index 100% rename from frontend/60sapi/热搜榜单/HackerNews榜单/返回接口.json rename to frontend/60sapi/热搜榜单/Hacker News 榜单/返回接口.json diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css new file mode 100644 index 00000000..a7d0b453 --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css @@ -0,0 +1,107 @@ +.background-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + overflow: hidden; +} + +.green-gradient { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.3) 0%, + rgba(129, 199, 132, 0.2) 25%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.2) 75%, + rgba(76, 175, 80, 0.3) 100% + ); + animation: green-flow 20s ease-in-out infinite; +} + +.green-gradient::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient( + circle at 30% 70%, + rgba(139, 195, 74, 0.4) 0%, + transparent 50% + ), radial-gradient( + circle at 70% 30%, + rgba(102, 187, 106, 0.3) 0%, + transparent 50% + ); + animation: green-pulse 15s ease-in-out infinite alternate; +} + +@keyframes green-flow { + 0%, 100% { + transform: rotate(0deg) scale(1); + opacity: 0.8; + } + 25% { + transform: rotate(90deg) scale(1.1); + opacity: 0.6; + } + 50% { + transform: rotate(180deg) scale(0.9); + opacity: 0.9; + } + 75% { + transform: rotate(270deg) scale(1.05); + opacity: 0.7; + } +} + +@keyframes green-pulse { + 0% { + transform: scale(1) rotate(0deg); + opacity: 0.5; + } + 50% { + transform: scale(1.2) rotate(180deg); + opacity: 0.8; + } + 100% { + transform: scale(1) rotate(360deg); + opacity: 0.6; + } +} + +/* 手机端背景优化 */ +@media (max-width: 768px) { + .green-gradient { + animation-duration: 25s; + } + + .green-gradient::before { + animation-duration: 18s; + } +} + +/* 减少动画以节省电池 */ +@media (prefers-reduced-motion: reduce) { + .green-gradient, + .green-gradient::before { + animation: none; + } + + .green-gradient { + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.2) 0%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.15) 100% + ); + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css new file mode 100644 index 00000000..a9a4f728 --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css @@ -0,0 +1,248 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; + color: #333; + background-color: #f0f8f0; + position: relative; + min-height: 100vh; +} + +.container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + position: relative; + z-index: 1; + background-color: rgba(255, 255, 255, 0.9); + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 128, 0, 0.1); +} + +header { + text-align: center; + margin-bottom: 25px; + padding-bottom: 20px; + border-bottom: 2px solid #e8f5e8; +} + +header h1 { + color: #2d8f47; + margin-bottom: 12px; + font-size: 2.2rem; + font-weight: 600; + text-shadow: 0 2px 4px rgba(45, 143, 71, 0.1); +} + +.update-time { + color: #6b8e6b; + font-size: 0.95rem; + background-color: #f0f8f0; + padding: 8px 16px; + border-radius: 20px; + display: inline-block; +} + +.hot-list { + list-style: none; +} + +.hot-item { + padding: 18px; + margin-bottom: 12px; + border-radius: 10px; + background-color: white; + box-shadow: 0 3px 8px rgba(0, 128, 0, 0.08); + transition: all 0.3s ease; + display: flex; + align-items: center; + border-left: 4px solid transparent; +} + +.hot-item:hover { + transform: translateY(-3px); + box-shadow: 0 6px 16px rgba(0, 128, 0, 0.15); + border-left-color: #4caf50; +} + +.hot-rank { + font-size: 1.3rem; + font-weight: bold; + color: #4caf50; + margin-right: 18px; + min-width: 35px; + text-align: center; + background-color: #f0f8f0; + border-radius: 50%; + width: 35px; + height: 35px; + display: flex; + align-items: center; + justify-content: center; +} + +.hot-rank.top-1 { + background: linear-gradient(135deg, #ff6b6b, #ff8e8e); + color: white; +} + +.hot-rank.top-2 { + background: linear-gradient(135deg, #ffa726, #ffb74d); + color: white; +} + +.hot-rank.top-3 { + background: linear-gradient(135deg, #ffca28, #ffd54f); + color: white; +} + +.hot-content { + flex: 1; +} + +.hot-title { + font-size: 1.15rem; + margin-bottom: 6px; + color: #2c3e2c; + text-decoration: none; + display: block; + line-height: 1.4; + font-weight: 500; +} + +.hot-title:hover { + color: #2d8f47; + text-decoration: underline; +} + +.loading { + text-align: center; + padding: 40px; + color: #6b8e6b; + font-size: 1.1rem; +} + +footer { + text-align: center; + margin-top: 30px; + padding-top: 20px; + border-top: 1px solid #e8f5e8; + color: #6b8e6b; + font-size: 0.9rem; +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + max-width: 90%; + padding: 18px; + } + + header h1 { + font-size: 2rem; + } + + .hot-item { + padding: 16px; + } + + .hot-title { + font-size: 1.1rem; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + body { + background-color: #f8fdf8; + } + + .container { + max-width: 95%; + margin: 10px auto; + padding: 15px; + border-radius: 8px; + } + + header { + margin-bottom: 20px; + padding-bottom: 15px; + } + + header h1 { + font-size: 1.8rem; + margin-bottom: 10px; + } + + .update-time { + font-size: 0.85rem; + padding: 6px 12px; + } + + .hot-item { + padding: 14px; + margin-bottom: 10px; + border-radius: 8px; + flex-direction: row; + align-items: flex-start; + } + + .hot-rank { + font-size: 1.1rem; + margin-right: 12px; + min-width: 30px; + width: 30px; + height: 30px; + margin-top: 2px; + } + + .hot-title { + font-size: 1rem; + line-height: 1.5; + margin-bottom: 4px; + } + + footer { + margin-top: 20px; + padding-top: 15px; + font-size: 0.8rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .container { + margin: 5px auto; + padding: 12px; + } + + header h1 { + font-size: 1.6rem; + } + + .hot-item { + padding: 12px; + margin-bottom: 8px; + } + + .hot-rank { + font-size: 1rem; + margin-right: 10px; + min-width: 28px; + width: 28px; + height: 28px; + } + + .hot-title { + font-size: 0.95rem; + } + + .update-time { + font-size: 0.8rem; + padding: 5px 10px; + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html new file mode 100644 index 00000000..1a4c9686 --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html @@ -0,0 +1,34 @@ + + + + + + 哔哩哔哩热搜榜 + + + + +
+
+
+ +
+
+

哔哩哔哩热搜榜

+
+
+ +
+
+
加载中...
+
+
+ +
+

数据来源于哔哩哔哩热搜榜

+
+
+ + + + \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js new file mode 100644 index 00000000..79764009 --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js @@ -0,0 +1,134 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s.viki.moe/v2/bili", + "https://60s-cf.viki.moe/v2/bili", + "https://60s.b23.run/v2/bili", + "https://60s.114128.xyz/v2/bili", + "https://60s-cf.114128.xyz/v2/bili" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const hotListElement = document.getElementById('hotList'); +const updateTimeElement = document.getElementById('updateTime'); + +// 格式化时间 +function formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + +// 渲染热搜列表 +function renderHotList(data) { + hotListElement.innerHTML = ''; + + data.forEach((item, index) => { + const hotItem = document.createElement('div'); + hotItem.className = 'hot-item'; + + const rankClass = index < 3 ? `top-${index + 1}` : ''; + + hotItem.innerHTML = ` +
${index + 1}
+
+ ${item.title} +
+ `; + + hotListElement.appendChild(hotItem); + }); + + // 更新时间 + updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; +} + +// 显示加载状态 +function showLoading() { + hotListElement.innerHTML = '
加载中...
'; +} + +// 显示错误状态 +function showError(message) { + hotListElement.innerHTML = `
${message}
`; +} + +// 获取哔哩哔哩热搜数据 +async function fetchBiliHotList() { + showLoading(); + + try { + const response = await fetch(API_ENDPOINTS[currentApiIndex]); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const result = await response.json(); + + if (result.code === 200 && result.data && Array.isArray(result.data)) { + if (result.data.length > 0) { + renderHotList(result.data); + } else { + showError('暂无热搜数据'); + } + } else { + throw new Error('数据格式错误或无数据'); + } + } catch (error) { + console.error('获取数据失败:', error); + + // 尝试切换到下一个API + const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (nextApiIndex !== 0) { + // 还有其他API可以尝试 + currentApiIndex = nextApiIndex; + showError('获取数据失败,正在尝试其他接口...'); + + // 延迟后重试 + setTimeout(fetchBiliHotList, 2000); + } else { + // 所有API都尝试过了 + currentApiIndex = 0; + showError('所有接口都无法访问,请稍后再试'); + } + } +} + +// 手动刷新数据 +function refreshData() { + currentApiIndex = 0; // 重置API索引 + fetchBiliHotList(); +} + +// 页面加载完成后获取数据 +document.addEventListener('DOMContentLoaded', () => { + fetchBiliHotList(); + + // 每隔5分钟刷新一次数据 + setInterval(fetchBiliHotList, 5 * 60 * 1000); + + // 添加键盘快捷键支持(按R键刷新) + document.addEventListener('keydown', (event) => { + if (event.key === 'r' || event.key === 'R') { + event.preventDefault(); + refreshData(); + } + }); +}); + +// 页面可见性变化时的处理 +document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + // 页面重新可见时刷新数据 + refreshData(); + } +}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json new file mode 100644 index 00000000..084d6336 --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json @@ -0,0 +1,3 @@ +[ + "https://60s.api.shumengya.top" +] diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json new file mode 100644 index 00000000..e377277d --- /dev/null +++ b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json @@ -0,0 +1,18 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "title": "18次阅兵76年逆袭路", + "link": "https://search.bilibili.com/all?keyword=18%E6%AC%A1%E9%98%85%E5%85%B576%E5%B9%B4%E9%80%86%E8%A2%AD%E8%B7%AF" + }, + { + "title": "80年前的今天日本签署投降书", + "link": "https://search.bilibili.com/all?keyword=80%E5%B9%B4%E5%89%8D%E7%9A%84%E4%BB%8A%E5%A4%A9%E6%97%A5%E6%9C%AC%E7%AD%BE%E7%BD%B2%E6%8A%95%E9%99%8D%E4%B9%A6" + }, + { + "title": "九三阅兵具体安排公布", + "link": "https://search.bilibili.com/all?keyword=%E4%B9%9D%E4%B8%89%E9%98%85%E5%85%B5%E5%85%B7%E4%BD%93%E5%AE%89%E6%8E%92%E5%85%AC%E5%B8%83" + } + ] +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css b/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css new file mode 100644 index 00000000..a7d0b453 --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css @@ -0,0 +1,107 @@ +.background-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + overflow: hidden; +} + +.green-gradient { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.3) 0%, + rgba(129, 199, 132, 0.2) 25%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.2) 75%, + rgba(76, 175, 80, 0.3) 100% + ); + animation: green-flow 20s ease-in-out infinite; +} + +.green-gradient::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient( + circle at 30% 70%, + rgba(139, 195, 74, 0.4) 0%, + transparent 50% + ), radial-gradient( + circle at 70% 30%, + rgba(102, 187, 106, 0.3) 0%, + transparent 50% + ); + animation: green-pulse 15s ease-in-out infinite alternate; +} + +@keyframes green-flow { + 0%, 100% { + transform: rotate(0deg) scale(1); + opacity: 0.8; + } + 25% { + transform: rotate(90deg) scale(1.1); + opacity: 0.6; + } + 50% { + transform: rotate(180deg) scale(0.9); + opacity: 0.9; + } + 75% { + transform: rotate(270deg) scale(1.05); + opacity: 0.7; + } +} + +@keyframes green-pulse { + 0% { + transform: scale(1) rotate(0deg); + opacity: 0.5; + } + 50% { + transform: scale(1.2) rotate(180deg); + opacity: 0.8; + } + 100% { + transform: scale(1) rotate(360deg); + opacity: 0.6; + } +} + +/* 手机端背景优化 */ +@media (max-width: 768px) { + .green-gradient { + animation-duration: 25s; + } + + .green-gradient::before { + animation-duration: 18s; + } +} + +/* 减少动画以节省电池 */ +@media (prefers-reduced-motion: reduce) { + .green-gradient, + .green-gradient::before { + animation: none; + } + + .green-gradient { + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.2) 0%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.15) 100% + ); + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css b/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css new file mode 100644 index 00000000..39624d2f --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css @@ -0,0 +1,291 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; + color: #333; + background-color: #f0f8f0; + position: relative; + min-height: 100vh; +} + +.container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + position: relative; + z-index: 1; + background-color: rgba(255, 255, 255, 0.9); + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 128, 0, 0.1); +} + +header { + text-align: center; + margin-bottom: 25px; + padding-bottom: 20px; + border-bottom: 2px solid #e8f5e8; +} + +header h1 { + color: #2d8f47; + margin-bottom: 12px; + font-size: 2.2rem; + font-weight: 600; + text-shadow: 0 2px 4px rgba(45, 143, 71, 0.1); +} + +.update-time { + color: #6b8e6b; + font-size: 0.95rem; + background-color: #f0f8f0; + padding: 8px 16px; + border-radius: 20px; + display: inline-block; +} + +.hot-list { + list-style: none; +} + +.hot-item { + padding: 18px; + margin-bottom: 12px; + border-radius: 10px; + background-color: white; + box-shadow: 0 3px 8px rgba(0, 128, 0, 0.08); + transition: all 0.3s ease; + display: flex; + align-items: center; + border-left: 4px solid transparent; + position: relative; +} + +.hot-item:hover { + transform: translateY(-3px); + box-shadow: 0 6px 16px rgba(0, 128, 0, 0.15); + border-left-color: #4caf50; +} + +.hot-rank { + font-size: 1.3rem; + font-weight: bold; + color: #4caf50; + margin-right: 18px; + min-width: 35px; + text-align: center; + background-color: #f0f8f0; + border-radius: 50%; + width: 35px; + height: 35px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.hot-rank.top-1 { + background: linear-gradient(135deg, #ff6b6b, #ff8e8e); + color: white; +} + +.hot-rank.top-2 { + background: linear-gradient(135deg, #ffa726, #ffb74d); + color: white; +} + +.hot-rank.top-3 { + background: linear-gradient(135deg, #ffca28, #ffd54f); + color: white; +} + +.hot-content { + flex: 1; + display: flex; + flex-direction: column; +} + +.hot-title { + font-size: 1.15rem; + margin-bottom: 6px; + color: #2c3e2c; + text-decoration: none; + display: block; + line-height: 1.4; + font-weight: 500; +} + +.hot-title:hover { + color: #2d8f47; + text-decoration: underline; +} + +.hot-stats { + display: flex; + align-items: center; + gap: 15px; + font-size: 0.85rem; + color: #888; + margin-top: 5px; +} + +.stat-item { + display: flex; + align-items: center; + gap: 4px; +} + +.hot-value { + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + padding: 4px 8px; + border-radius: 12px; + font-weight: 500; + font-size: 0.8rem; +} + +.hot-tag { + background-color: #e8f5e8; + color: #2d8f47; + padding: 2px 6px; + border-radius: 8px; + font-size: 0.75rem; + font-weight: 500; +} + +.loading { + text-align: center; + padding: 40px; + color: #6b8e6b; + font-size: 1.1rem; +} + +footer { + text-align: center; + margin-top: 30px; + padding-top: 20px; + border-top: 1px solid #e8f5e8; + color: #6b8e6b; + font-size: 0.9rem; +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + max-width: 90%; + padding: 18px; + } + + header h1 { + font-size: 2rem; + } + + .hot-item { + padding: 16px; + } + + .hot-title { + font-size: 1.1rem; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + body { + background-color: #f8fdf8; + } + + .container { + max-width: 95%; + margin: 10px auto; + padding: 15px; + border-radius: 8px; + } + + header { + margin-bottom: 20px; + padding-bottom: 15px; + } + + header h1 { + font-size: 1.8rem; + margin-bottom: 10px; + } + + .update-time { + font-size: 0.85rem; + padding: 6px 12px; + } + + .hot-item { + padding: 14px; + margin-bottom: 10px; + border-radius: 8px; + flex-direction: row; + align-items: flex-start; + } + + .hot-rank { + font-size: 1.1rem; + margin-right: 12px; + min-width: 30px; + width: 30px; + height: 30px; + margin-top: 2px; + } + + .hot-title { + font-size: 1rem; + line-height: 1.5; + margin-bottom: 4px; + } + + .hot-stats { + flex-wrap: wrap; + gap: 10px; + font-size: 0.8rem; + } + + footer { + margin-top: 20px; + padding-top: 15px; + font-size: 0.8rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .container { + margin: 5px auto; + padding: 12px; + } + + header h1 { + font-size: 1.6rem; + } + + .hot-item { + padding: 12px; + margin-bottom: 8px; + } + + .hot-rank { + font-size: 1rem; + margin-right: 10px; + min-width: 28px; + width: 28px; + height: 28px; + } + + .hot-title { + font-size: 0.95rem; + } + + .update-time { + font-size: 0.8rem; + padding: 5px 10px; + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/index.html b/frontend/60sapi/热搜榜单/头条热搜榜/index.html new file mode 100644 index 00000000..0c77ee74 --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/index.html @@ -0,0 +1,34 @@ + + + + + + 头条热搜榜 + + + + +
+
+
+ +
+
+

头条热搜榜

+
+
+ +
+
+
加载中...
+
+
+ +
+

数据来源于头条热搜榜

+
+
+ + + + \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js b/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js new file mode 100644 index 00000000..cf7f0f6b --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js @@ -0,0 +1,156 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s.viki.moe/v2/toutiao", + "https://60s-cf.viki.moe/v2/toutiao", + "https://60s.b23.run/v2/toutiao", + "https://60s.114128.xyz/v2/toutiao", + "https://60s-cf.114128.xyz/v2/toutiao" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const hotListElement = document.getElementById('hotList'); +const updateTimeElement = document.getElementById('updateTime'); + +// 格式化时间 +function formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + +// 格式化数字 +function formatNumber(num) { + if (num >= 10000) { + return (num / 10000).toFixed(1) + '万'; + } + return num.toString(); +} + +// 渲染热搜列表 +function renderHotList(data) { + hotListElement.innerHTML = ''; + + data.forEach((item, index) => { + const hotItem = document.createElement('div'); + hotItem.className = 'hot-item'; + + const rankClass = index < 3 ? `top-${index + 1}` : ''; + + // 处理热度值显示 + const hotValueDisplay = item.hot_value ? + `
${formatNumber(item.hot_value)} 热度
` : ''; + + // 处理标签显示 + const tagDisplay = item.tag ? + `
${item.tag}
` : ''; + + hotItem.innerHTML = ` +
${index + 1}
+
+ ${item.title} +
+ ${hotValueDisplay} + ${tagDisplay} + ${item.source ? `
📰 ${item.source}
` : ''} + ${item.time ? `
🕒 ${item.time}
` : ''} +
+
+ `; + + hotListElement.appendChild(hotItem); + }); + + // 更新时间 + updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; +} + +// 显示加载状态 +function showLoading() { + hotListElement.innerHTML = '
加载中...
'; +} + +// 显示错误状态 +function showError(message) { + hotListElement.innerHTML = `
${message}
`; +} + +// 获取头条热搜数据 +async function fetchToutiaoHotList() { + showLoading(); + + try { + const response = await fetch(API_ENDPOINTS[currentApiIndex]); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const result = await response.json(); + + if (result.code === 200 && result.data && Array.isArray(result.data)) { + if (result.data.length > 0) { + renderHotList(result.data); + } else { + showError('暂无热搜数据'); + } + } else { + throw new Error('数据格式错误或无数据'); + } + } catch (error) { + console.error('获取数据失败:', error); + + // 尝试切换到下一个API + const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (nextApiIndex !== 0) { + // 还有其他API可以尝试 + currentApiIndex = nextApiIndex; + showError('获取数据失败,正在尝试其他接口...'); + + // 延迟后重试 + setTimeout(fetchToutiaoHotList, 2000); + } else { + // 所有API都尝试过了 + currentApiIndex = 0; + showError('所有接口都无法访问,请稍后再试'); + } + } +} + +// 手动刷新数据 +function refreshData() { + currentApiIndex = 0; // 重置API索引 + fetchToutiaoHotList(); +} + +// 页面加载完成后获取数据 +document.addEventListener('DOMContentLoaded', () => { + fetchToutiaoHotList(); + + // 每隔5分钟刷新一次数据 + setInterval(fetchToutiaoHotList, 5 * 60 * 1000); + + // 添加键盘快捷键支持(按R键刷新) + document.addEventListener('keydown', (event) => { + if (event.key === 'r' || event.key === 'R') { + event.preventDefault(); + refreshData(); + } + }); +}); + +// 页面可见性变化时的处理 +document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + // 页面重新可见时刷新数据 + refreshData(); + } +}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json new file mode 100644 index 00000000..547b2771 --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json @@ -0,0 +1,3 @@ +[ + "https://60s.api.shumengya.top" +] diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json new file mode 100644 index 00000000..778e5e45 --- /dev/null +++ b/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json @@ -0,0 +1,30 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "title": "九三阅兵具体安排公布", + "hot_value": 11821633, + "tag": "热", + "source": "头条新闻", + "time": "2小时前", + "link": "https://www.toutiao.com/article/7404567890123456789/" + }, + { + "title": "九月第一天", + "hot_value": 11327170, + "tag": "新", + "source": "今日头条", + "time": "1小时前", + "link": "https://www.toutiao.com/article/7404567890123456790/" + }, + { + "title": "遇见上合共享津彩", + "hot_value": 11222444, + "tag": "推荐", + "source": "头条资讯", + "time": "3小时前", + "link": "https://www.toutiao.com/article/7404567890123456791/" + } + ] +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json +++ b/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js b/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js index 5e57415c..03931e5d 100644 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js +++ b/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js @@ -1,4 +1,7 @@ -// API接口列表 +// 本地后端API接口 +const LOCAL_API_BASE = 'http://localhost:5000/api/60s'; + +// API接口列表(备用) const API_ENDPOINTS = [ "https://60s-cf.viki.moe", "https://60s.viki.moe", @@ -9,6 +12,7 @@ const API_ENDPOINTS = [ // 当前使用的API索引 let currentApiIndex = 0; +let useLocalApi = true; // DOM元素 const loadingElement = document.getElementById('loading'); @@ -46,6 +50,30 @@ async function loadHotList() { // 获取数据 async function fetchData() { + // 优先尝试本地API + if (useLocalApi) { + try { + const response = await fetch(`${LOCAL_API_BASE}/douyin`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + timeout: 10000 + }); + + if (response.ok) { + const data = await response.json(); + if (data.code === 200 && data.data) { + return data; + } + } + } catch (error) { + console.warn('本地API请求失败,切换到外部API:', error); + useLocalApi = false; + } + } + + // 使用外部API作为备用 for (let i = 0; i < API_ENDPOINTS.length; i++) { const apiUrl = API_ENDPOINTS[currentApiIndex]; diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json +++ b/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json b/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json +++ b/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css b/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css new file mode 100644 index 00000000..a7d0b453 --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css @@ -0,0 +1,107 @@ +.background-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + overflow: hidden; +} + +.green-gradient { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.3) 0%, + rgba(129, 199, 132, 0.2) 25%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.2) 75%, + rgba(76, 175, 80, 0.3) 100% + ); + animation: green-flow 20s ease-in-out infinite; +} + +.green-gradient::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient( + circle at 30% 70%, + rgba(139, 195, 74, 0.4) 0%, + transparent 50% + ), radial-gradient( + circle at 70% 30%, + rgba(102, 187, 106, 0.3) 0%, + transparent 50% + ); + animation: green-pulse 15s ease-in-out infinite alternate; +} + +@keyframes green-flow { + 0%, 100% { + transform: rotate(0deg) scale(1); + opacity: 0.8; + } + 25% { + transform: rotate(90deg) scale(1.1); + opacity: 0.6; + } + 50% { + transform: rotate(180deg) scale(0.9); + opacity: 0.9; + } + 75% { + transform: rotate(270deg) scale(1.05); + opacity: 0.7; + } +} + +@keyframes green-pulse { + 0% { + transform: scale(1) rotate(0deg); + opacity: 0.5; + } + 50% { + transform: scale(1.2) rotate(180deg); + opacity: 0.8; + } + 100% { + transform: scale(1) rotate(360deg); + opacity: 0.6; + } +} + +/* 手机端背景优化 */ +@media (max-width: 768px) { + .green-gradient { + animation-duration: 25s; + } + + .green-gradient::before { + animation-duration: 18s; + } +} + +/* 减少动画以节省电池 */ +@media (prefers-reduced-motion: reduce) { + .green-gradient, + .green-gradient::before { + animation: none; + } + + .green-gradient { + background: linear-gradient( + 135deg, + rgba(76, 175, 80, 0.2) 0%, + rgba(165, 214, 167, 0.1) 50%, + rgba(200, 230, 201, 0.15) 100% + ); + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css b/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css new file mode 100644 index 00000000..f53380d4 --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css @@ -0,0 +1,331 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; + color: #333; + background-color: #f0f8f0; + position: relative; + min-height: 100vh; +} + +.container { + max-width: 900px; + margin: 0 auto; + padding: 20px; + position: relative; + z-index: 1; + background-color: rgba(255, 255, 255, 0.9); + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 128, 0, 0.1); +} + +header { + text-align: center; + margin-bottom: 25px; + padding-bottom: 20px; + border-bottom: 2px solid #e8f5e8; +} + +header h1 { + color: #2d8f47; + margin-bottom: 12px; + font-size: 2.2rem; + font-weight: 600; + text-shadow: 0 2px 4px rgba(45, 143, 71, 0.1); +} + +.update-time { + color: #6b8e6b; + font-size: 0.95rem; + background-color: #f0f8f0; + padding: 8px 16px; + border-radius: 20px; + display: inline-block; +} + +.topic-list { + list-style: none; +} + +.topic-item { + padding: 20px; + margin-bottom: 15px; + border-radius: 12px; + background-color: white; + box-shadow: 0 3px 10px rgba(0, 128, 0, 0.08); + transition: all 0.3s ease; + border-left: 4px solid transparent; + position: relative; +} + +.topic-item:hover { + transform: translateY(-3px); + box-shadow: 0 6px 20px rgba(0, 128, 0, 0.15); + border-left-color: #4caf50; +} + +.topic-header { + display: flex; + align-items: flex-start; + margin-bottom: 12px; +} + +.topic-rank { + font-size: 1.3rem; + font-weight: bold; + color: #4caf50; + margin-right: 18px; + min-width: 35px; + text-align: center; + background-color: #f0f8f0; + border-radius: 50%; + width: 35px; + height: 35px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.topic-rank.top-1 { + background: linear-gradient(135deg, #ff6b6b, #ff8e8e); + color: white; +} + +.topic-rank.top-2 { + background: linear-gradient(135deg, #ffa726, #ffb74d); + color: white; +} + +.topic-rank.top-3 { + background: linear-gradient(135deg, #ffca28, #ffd54f); + color: white; +} + +.topic-content { + flex: 1; +} + +.topic-title { + font-size: 1.2rem; + margin-bottom: 8px; + color: #2c3e2c; + text-decoration: none; + display: block; + line-height: 1.4; + font-weight: 600; +} + +.topic-title:hover { + color: #2d8f47; + text-decoration: underline; +} + +.topic-detail { + font-size: 0.95rem; + color: #666; + line-height: 1.5; + margin-bottom: 10px; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.topic-stats { + display: flex; + align-items: center; + gap: 15px; + font-size: 0.85rem; + color: #888; + margin-top: 10px; +} + +.stat-item { + display: flex; + align-items: center; + gap: 4px; +} + +.hot-value { + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + padding: 4px 8px; + border-radius: 12px; + font-weight: 500; + font-size: 0.8rem; +} + +.topic-cover { + width: 80px; + height: 60px; + border-radius: 8px; + object-fit: cover; + margin-left: 15px; + flex-shrink: 0; +} + +.loading { + text-align: center; + padding: 40px; + color: #6b8e6b; + font-size: 1.1rem; +} + +footer { + text-align: center; + margin-top: 30px; + padding-top: 20px; + border-top: 1px solid #e8f5e8; + color: #6b8e6b; + font-size: 0.9rem; +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + max-width: 90%; + padding: 18px; + } + + header h1 { + font-size: 2rem; + } + + .topic-item { + padding: 18px; + } + + .topic-title { + font-size: 1.15rem; + } + + .topic-cover { + width: 70px; + height: 50px; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + body { + background-color: #f8fdf8; + } + + .container { + max-width: 95%; + margin: 10px auto; + padding: 15px; + border-radius: 8px; + } + + header { + margin-bottom: 20px; + padding-bottom: 15px; + } + + header h1 { + font-size: 1.8rem; + margin-bottom: 10px; + } + + .update-time { + font-size: 0.85rem; + padding: 6px 12px; + } + + .topic-item { + padding: 16px; + margin-bottom: 12px; + border-radius: 8px; + } + + .topic-header { + flex-direction: column; + align-items: stretch; + } + + .topic-rank { + font-size: 1.1rem; + margin-right: 0; + margin-bottom: 10px; + width: 30px; + height: 30px; + align-self: flex-start; + } + + .topic-title { + font-size: 1.05rem; + line-height: 1.5; + margin-bottom: 6px; + } + + .topic-detail { + font-size: 0.9rem; + margin-bottom: 8px; + } + + .topic-stats { + flex-wrap: wrap; + gap: 10px; + font-size: 0.8rem; + } + + .topic-cover { + width: 60px; + height: 45px; + margin-left: 10px; + } + + footer { + margin-top: 20px; + padding-top: 15px; + font-size: 0.8rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .container { + margin: 5px auto; + padding: 12px; + } + + header h1 { + font-size: 1.6rem; + } + + .topic-item { + padding: 14px; + margin-bottom: 10px; + } + + .topic-rank { + font-size: 1rem; + width: 28px; + height: 28px; + } + + .topic-title { + font-size: 1rem; + } + + .topic-detail { + font-size: 0.85rem; + } + + .topic-cover { + width: 50px; + height: 38px; + margin-left: 8px; + } + + .update-time { + font-size: 0.8rem; + padding: 5px 10px; + } +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/index.html b/frontend/60sapi/热搜榜单/知乎热门话题/index.html new file mode 100644 index 00000000..82c7302d --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/index.html @@ -0,0 +1,34 @@ + + + + + + 知乎热门话题 + + + + +
+
+
+ +
+
+

知乎热门话题

+
+
+ +
+
+
加载中...
+
+
+ +
+

数据来源于知乎热门话题

+
+
+ + + + \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js b/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js new file mode 100644 index 00000000..8b0558f8 --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js @@ -0,0 +1,155 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s.viki.moe/v2/zhihu", + "https://60s-cf.viki.moe/v2/zhihu", + "https://60s.b23.run/v2/zhihu", + "https://60s.114128.xyz/v2/zhihu", + "https://60s-cf.114128.xyz/v2/zhihu" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const topicListElement = document.getElementById('topicList'); +const updateTimeElement = document.getElementById('updateTime'); + +// 格式化时间 +function formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + +// 格式化数字 +function formatNumber(num) { + if (num >= 10000) { + return (num / 10000).toFixed(1) + '万'; + } + return num.toString(); +} + +// 渲染话题列表 +function renderTopicList(data) { + topicListElement.innerHTML = ''; + + data.forEach((item, index) => { + const topicItem = document.createElement('div'); + topicItem.className = 'topic-item'; + + const rankClass = index < 3 ? `top-${index + 1}` : ''; + + // 处理封面图片 + const coverImg = item.cover ? + `话题封面` : ''; + + topicItem.innerHTML = ` +
+
${index + 1}
+
+ ${item.title} + ${item.detail ? `
${item.detail}
` : ''} +
+ ${item.hot_value_desc ? `
${item.hot_value_desc}
` : ''} + ${item.answer_cnt ? `
💬 ${formatNumber(item.answer_cnt)} 回答
` : ''} + ${item.follower_cnt ? `
👥 ${formatNumber(item.follower_cnt)} 关注
` : ''} +
+
+ ${coverImg} +
+ `; + + topicListElement.appendChild(topicItem); + }); + + // 更新时间 + updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; +} + +// 显示加载状态 +function showLoading() { + topicListElement.innerHTML = '
加载中...
'; +} + +// 显示错误状态 +function showError(message) { + topicListElement.innerHTML = `
${message}
`; +} + +// 获取知乎热门话题数据 +async function fetchZhihuTopics() { + showLoading(); + + try { + const response = await fetch(API_ENDPOINTS[currentApiIndex]); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const result = await response.json(); + + if (result.code === 200 && result.data && Array.isArray(result.data)) { + if (result.data.length > 0) { + renderTopicList(result.data); + } else { + showError('暂无热门话题数据'); + } + } else { + throw new Error('数据格式错误或无数据'); + } + } catch (error) { + console.error('获取数据失败:', error); + + // 尝试切换到下一个API + const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (nextApiIndex !== 0) { + // 还有其他API可以尝试 + currentApiIndex = nextApiIndex; + showError('获取数据失败,正在尝试其他接口...'); + + // 延迟后重试 + setTimeout(fetchZhihuTopics, 2000); + } else { + // 所有API都尝试过了 + currentApiIndex = 0; + showError('所有接口都无法访问,请稍后再试'); + } + } +} + +// 手动刷新数据 +function refreshData() { + currentApiIndex = 0; // 重置API索引 + fetchZhihuTopics(); +} + +// 页面加载完成后获取数据 +document.addEventListener('DOMContentLoaded', () => { + fetchZhihuTopics(); + + // 每隔5分钟刷新一次数据 + setInterval(fetchZhihuTopics, 5 * 60 * 1000); + + // 添加键盘快捷键支持(按R键刷新) + document.addEventListener('keydown', (event) => { + if (event.key === 'r' || event.key === 'R') { + event.preventDefault(); + refreshData(); + } + }); +}); + +// 页面可见性变化时的处理 +document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + // 页面重新可见时刷新数据 + refreshData(); + } +}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json b/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json b/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json new file mode 100644 index 00000000..a9acef11 --- /dev/null +++ b/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json @@ -0,0 +1,30 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "title": "你是什么时候意识到抗日战争很艰难的?", + "detail": "就不像抗日神剧", + "cover": "https://picx.zhimg.com/v2-a07a53b2e23887c7a2440cc3f1984122.png", + "hot_value_desc": "1311 万热度", + "answer_cnt": 739, + "follower_cnt": 1739, + "comment_cnt": 0, + "created_at": 1622774952000, + "created": "2021/06/04 10:49:12", + "link": "https://api.zhihu.com/questions/463076881" + }, + { + "title": "为什么中国在很多领域都要求自主研发?", + "detail": "中国在很多领域都要求自主研发,似乎确认很多东西都有个中国版本,真有这个必要吗?", + "cover": "https://pic3.zhimg.com/80/v2-bb4dfa56f138980078da003df436e661_hd.png", + "hot_value_desc": "816 万热度", + "answer_cnt": 2476, + "follower_cnt": 12545, + "comment_cnt": 0, + "created_at": 1352205751000, + "created": "2012/11/06 20:42:31", + "link": "https://api.zhihu.com/questions/20579464" + } + ] +} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单列表/接口集合.json b/frontend/60sapi/热搜榜单/网易云榜单列表/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/热搜榜单/网易云榜单列表/接口集合.json +++ b/frontend/60sapi/热搜榜单/网易云榜单列表/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/热搜榜单/网易云榜单详情/接口集合.json b/frontend/60sapi/热搜榜单/网易云榜单详情/接口集合.json index 04e92b7f..547b2771 100644 --- a/frontend/60sapi/热搜榜单/网易云榜单详情/接口集合.json +++ b/frontend/60sapi/热搜榜单/网易云榜单详情/接口集合.json @@ -1,7 +1,3 @@ [ - "https://60s-cf.viki.moe", - "https://60s.viki.moe", - "https://60s.b23.run", - "https://60s.114128.xyz", - "https://60s-cf.114128.xyz" + "https://60s.api.shumengya.top" ] diff --git a/frontend/60sapi/生成要求模板.txt b/frontend/60sapi/生成要求模板.txt index 0a3addc7..91b7c04d 100644 --- a/frontend/60sapi/生成要求模板.txt +++ b/frontend/60sapi/生成要求模板.txt @@ -5,4 +5,4 @@ 5.返回接口.json储存了网页api返回的数据格式 6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...” 7.接口集合.json保存了所有已知的后端API接口,一个访问不了尝试自动切换另一个 -8.在css中有关背景的css单独一个css文件,方便我直接迁移 \ No newline at end of file +8.在css中有关背景的css单独一个css文件,方便我直接迁移 diff --git a/frontend/assets/App Logo 设计 (2).png b/frontend/assets/App Logo 设计 (2).png new file mode 100644 index 00000000..2e50c34c Binary files /dev/null and b/frontend/assets/App Logo 设计 (2).png differ diff --git a/frontend/assets/logo.png b/frontend/assets/logo.png new file mode 100644 index 00000000..71b4c1e6 Binary files /dev/null and b/frontend/assets/logo.png differ diff --git a/frontend/react-app/package-lock.json b/frontend/react-app/package-lock.json new file mode 100644 index 00000000..e2ee0482 --- /dev/null +++ b/frontend/react-app/package-lock.json @@ -0,0 +1,20652 @@ +{ + "name": "infogenie-frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "infogenie-frontend", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^14.5.2", + "axios": "^1.5.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-hot-toast": "^2.4.1", + "react-icons": "^4.11.0", + "react-router-dom": "^6.15.0", + "react-scripts": "5.0.1", + "styled-components": "^6.0.7", + "web-vitals": "^2.1.4" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "license": "MIT" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", + "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.3", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2", + "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.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz", + "integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==", + "license": "MIT", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@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.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@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.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "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.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "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.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "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.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "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.npmjs.org/@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.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", + "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", + "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-decorators": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", + "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", + "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "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.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", + "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz", + "integrity": "sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", + "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-flow": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", + "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", + "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", + "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", + "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz", + "integrity": "sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz", + "integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.27.1.tgz", + "integrity": "sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.27.1", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", + "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "license": "MIT" + }, + "node_modules/@csstools/normalize.css": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", + "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==", + "license": "CC0-1.0" + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "license": "CC0-1.0", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "license": "CC0-1.0", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "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.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "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/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "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.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "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/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "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.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/console/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/core/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/environment/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/environment/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.1.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.1.2.tgz", + "integrity": "sha512-HXy1qT/bfdjCv7iC336ExbqqYtZvljrV8odNdso7dWK9bSeHtLlvwWWC3YSybSPL03Gg5rug6WLCZAZFH72m0A==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/fake-timers/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/globals/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/globals/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/reporters/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/test-result/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/transform/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@jest/transform/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", + "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "license": "MIT", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "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.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz", + "integrity": "sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ==", + "license": "MIT", + "dependencies": { + "ansi-html": "^0.0.9", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^4.2.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x || 5.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", + "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "license": "Apache-2.0", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "license": "MIT", + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz", + "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.24", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.24.tgz", + "integrity": "sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "license": "MIT", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "license": "BSD-3-Clause" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", + "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz", + "integrity": "sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "is-string": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "license": "MIT" + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "license": "MIT", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-jest/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/babel-loader": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", + "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.4", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "license": "MIT", + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "license": "MIT" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.1.0.tgz", + "integrity": "sha512-f9B1xMdnkCIqe+2dHrJsoQFRz7reChaAHE/65SdaykPklQqhme2WaC08oD3is77x9ff98/9EazAKFDZv5rFEQg==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "license": "MIT", + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "license": "BSD-2-Clause" + }, + "node_modules/browserslist": { + "version": "4.25.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", + "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "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": { + "caniuse-lite": "^1.0.30001737", + "electron-to-chromium": "^1.5.211", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/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/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001739", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz", + "integrity": "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==", + "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/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "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/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", + "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "license": "MIT", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/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/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.1.tgz", + "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", + "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.45.1.tgz", + "integrity": "sha512-OHnWFKgTUshEU8MK+lOs1H8kC8GkTi9Z1tvNkxrCcw9wl3MJIO7q2ld77wjWn4/xuGrVu2X+nME1iIIPBSdyEQ==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "license": "MIT", + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "license": "CC0-1.0", + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "license": "MIT" + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, + "node_modules/cssdb": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "CC0-1.0" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "license": "MIT", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "license": "MIT", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "license": "BSD-2-Clause" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "license": "MIT" + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "license": "MIT", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "license": "BSD-2-Clause" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/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/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.211", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.211.tgz", + "integrity": "sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==", + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/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.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/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.npmjs.org/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/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/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.", + "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-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "license": "BSD-3-Clause", + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "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.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "license": "MIT", + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "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/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "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/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.1.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.1.2.tgz", + "integrity": "sha512-xvHszRavo28ejws8FpemjhwswGj4w/BetHIL8cU49u4sGyXDw2+p3YbeDbj6xzlxi6kWTjIRSTJ+9sNXPnF0Zg==", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.1.2", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.1.2", + "jest-message-util": "30.1.0", + "jest-mock": "30.0.5", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "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.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "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.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/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/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "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/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "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.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/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-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/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": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "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/goober": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", + "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "license": "MIT", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/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.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "license": "(Apache-2.0 OR MPL-1.1)" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.4.tgz", + "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "license": "MIT", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/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.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "license": "MIT" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "license": "MIT", + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-changed-files/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-circus/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "license": "MIT", + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-cli/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-config/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-diff": { + "version": "30.1.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.1.2.tgz", + "integrity": "sha512-4+prq+9J61mOVXCa4Qp8ZjavdxzrWQXrI80GNxP8f4tkI2syPuPrJgdRPZRrfUTRvIoUwcmNLbqEJy9W800+NQ==", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-diff/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-each/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-environment-jsdom/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-node/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-environment-node/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-haste-map/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-haste-map/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-haste-map/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-jasmine2/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "license": "MIT", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.1.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.1.2.tgz", + "integrity": "sha512-7ai16hy4rSbDjvPTuUhuV8nyPBd6EX34HkBsBcBX2lENCuAQ0qKCPb/+lt8OSWUa9WWmGYLy41PrEzkwRwoGZQ==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.1.2", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-matcher-utils/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/jest-message-util": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.1.0.tgz", + "integrity": "sha512-HizKDGG98cYkWmaLUHChq4iN+oCENohQLb7Z5guBPumYs+/etonmNFlg1Ps6yN9LTPyZn+M+b/9BbnHx3WTMDg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.0.5", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.0.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-message-util/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/jest-mock": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", + "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-resolve/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-runner/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-runtime/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-snapshot/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-util": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.0.5.tgz", + "integrity": "sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "license": "MIT", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "license": "MIT" + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-watch-typeahead/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "license": "MIT", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "license": "MIT", + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "license": "MIT", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", + "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-watcher/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", + "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", + "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.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "license": "MIT", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.11.1.tgz", + "integrity": "sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/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.npmjs.org/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/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", + "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/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.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.21", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", + "integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", + "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", + "license": "MIT", + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "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/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "license": "CC0-1.0", + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "license": "CC0-1.0", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "license": "CC0-1.0", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "license": "MIT", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "license": "MIT", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "license": "MIT", + "dependencies": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "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/react-dev-utils/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-overlay": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz", + "integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==", + "license": "MIT" + }, + "node_modules/react-hot-toast": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz", + "integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3", + "goober": "^2.1.16" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "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-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=8.9" + }, + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" + }, + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } + } + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "license": "ISC" + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "license": "MIT", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==", + "license": "CC0-1.0" + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "license": "MIT", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "license": "ISC" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/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/source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "license": "MIT" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "license": "MIT", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/styled-components": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", + "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.49", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "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.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "license": "BSD-2-Clause" + }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/tapable": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", + "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", + "license": "MIT" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "license": "MIT" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "license": "MIT" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "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.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "license": "ISC", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.101.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz", + "integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "license": "MIT", + "dependencies": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "license": "MIT", + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "license": "MIT", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "deprecated": "The work that was done in this beta branch won't be included in future versions", + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", + "license": "MIT" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "license": "MIT", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "license": "MIT", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "license": "MIT", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==", + "license": "MIT" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "license": "MIT", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "license": "MIT", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "license": "Apache-2.0" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/frontend/react-app/package.json b/frontend/react-app/package.json new file mode 100644 index 00000000..7016236e --- /dev/null +++ b/frontend/react-app/package.json @@ -0,0 +1,49 @@ +{ + "name": "infogenie-frontend", + "version": "1.0.0", + "description": "✨ 神奇万事通 - 前端React应用", + "keywords": ["react", "api", "mobile-first", "responsive"], + "author": "神奇万事通", + "license": "MIT", + "private": true, + "dependencies": { + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^14.5.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.15.0", + "react-scripts": "5.0.1", + "axios": "^1.5.0", + "styled-components": "^6.0.7", + "react-icons": "^4.11.0", + "react-hot-toast": "^2.4.1", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "dev": "react-scripts start" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://localhost:5000" +} diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css new file mode 100644 index 00000000..7a44dec9 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css @@ -0,0 +1,190 @@ +/* 背景样式文件 */ + +/* 主体背景 */ +body { + background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 50%, #a5d6a7 100%); + background-attachment: fixed; + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; +} + +/* 背景动画 */ +@keyframes gradientShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 装饰性背景元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(129, 199, 132, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(165, 214, 167, 0.08) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +/* 浮动装饰圆点 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + animation: float 20s linear infinite; + pointer-events: none; + z-index: -1; + opacity: 0.6; +} + +@keyframes float { + 0% { + transform: translateY(0px); + } + 50% { + transform: translateY(-10px); + } + 100% { + transform: translateY(0px); + } +} + +/* 题目容器背景增强 */ +.question-container { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 8px 32px rgba(26, 77, 26, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +/* 错误容器背景 */ +.error-container { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} + +/* 结果容器背景 */ +.result-container { + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); +} + +/* 代码块背景 */ +.code-block { + background: rgba(248, 249, 250, 0.9); + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); +} + +/* 选项背景 */ +.option { + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); +} + +.option:hover { + background: rgba(76, 175, 80, 0.05); +} + +.option.selected { + background: linear-gradient(135deg, rgba(76, 175, 80, 0.15), rgba(76, 175, 80, 0.08)); +} + +/* 按钮背景增强 */ +.submit-btn { + background: linear-gradient(135deg, #4caf50, #45a049); + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2); +} + +.show-answer-btn { + background: linear-gradient(135deg, #2196f3, #1976d2); + box-shadow: 0 4px 15px rgba(33, 150, 243, 0.2); +} + +.retry-btn { + background: linear-gradient(135deg, #ff9800, #f57c00); + box-shadow: 0 4px 15px rgba(255, 152, 0, 0.2); +} + +.refresh-btn { + background: linear-gradient(135deg, #4caf50, #45a049); + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2); +} + +/* 移动端背景优化 */ +@media (max-width: 768px) { + body { + background-attachment: scroll; + } + + body::after { + opacity: 0.4; + background-size: 150px 75px; + } + + .question-container { + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + } +} + +/* 高对比度模式支持 */ +@media (prefers-contrast: high) { + body { + background: #f0f8f0; + } + + body::before, + body::after { + display: none; + } + + .question-container { + background: #ffffff; + border: 2px solid #4caf50; + } +} + +/* 减少动画模式支持 */ +@media (prefers-reduced-motion: reduce) { + body { + animation: none; + background: #e8f5e8; + } + + body::after { + animation: none; + } + + .refresh-btn:hover { + transform: scale(1.1); + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css new file mode 100644 index 00000000..2ad05653 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css @@ -0,0 +1,597 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; + line-height: 1.6; + color: #2d5a27; + min-height: 100vh; + overflow-x: hidden; +} + +/* 容器布局 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + padding: 30px 0; +} + +.header h1 { + font-size: 2.5rem; + color: #1a4d1a; + margin-bottom: 10px; + font-weight: 700; + text-shadow: 0 2px 4px rgba(26, 77, 26, 0.1); +} + +.subtitle { + font-size: 1.1rem; + color: #4a7c59; + opacity: 0.8; +} + +/* 主内容区域 */ +.main-content { + flex: 1; + display: flex; + justify-content: center; + align-items: flex-start; +} + +/* 加载动画 */ +.loading { + text-align: center; + padding: 60px 20px; +} + +.spinner { + width: 50px; + height: 50px; + border: 4px solid #e8f5e8; + border-top: 4px solid #4caf50; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading p { + color: #4a7c59; + font-size: 1.1rem; +} + +/* 题目容器 */ +.question-container { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 40px; + box-shadow: 0 10px 30px rgba(26, 77, 26, 0.1); + border: 2px solid rgba(76, 175, 80, 0.2); + width: 100%; + max-width: 800px; + backdrop-filter: blur(10px); +} + +/* 题目头部 */ +.question-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + padding-bottom: 15px; + border-bottom: 2px solid #e8f5e8; +} + +.question-id { + font-size: 1.1rem; + color: #4caf50; + font-weight: 600; + background: linear-gradient(135deg, #e8f5e8, #c8e6c9); + padding: 8px 16px; + border-radius: 20px; +} + +.refresh-btn { + background: linear-gradient(135deg, #4caf50, #45a049); + border: none; + border-radius: 50%; + width: 45px; + height: 45px; + color: white; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; +} + +.refresh-btn:hover { + transform: rotate(180deg) scale(1.1); + box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3); +} + +/* 题目文本 */ +.question-text h2 { + font-size: 1.5rem; + color: #1a4d1a; + margin-bottom: 25px; + text-align: center; +} + +/* 代码块 */ +.code-block { + background: #f8f9fa; + border: 2px solid #e8f5e8; + border-radius: 12px; + margin: 25px 0; + overflow-x: auto; + position: relative; +} + +.code-block pre { + margin: 0; + padding: 25px; + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; + font-size: 0.95rem; + line-height: 1.5; + color: #2d5a27; + white-space: pre-wrap; + word-wrap: break-word; + background: transparent !important; +} + +.code-block code { + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; + background: transparent !important; +} + +/* 代码高亮自定义样式 - 丰富的语法高亮 */ +.code-block .hljs { + background: transparent !important; + color: #333333 !important; +} + +/* JavaScript 关键字 - 蓝色 */ +.code-block .hljs-keyword { + color: #0066cc !important; + font-weight: 600; +} + +/* 字符串 - 绿色 */ +.code-block .hljs-string { + color: #22aa22 !important; +} + +/* 数字 - 橙色 */ +.code-block .hljs-number { + color: #ff6600 !important; +} + +/* 函数名 - 紫色 */ +.code-block .hljs-function, +.code-block .hljs-title.function_ { + color: #9933cc !important; + font-weight: 600; +} + +/* 变量名 - 深蓝色 */ +.code-block .hljs-variable, +.code-block .hljs-name { + color: #0066aa !important; +} + +/* 注释 - 灰色 */ +.code-block .hljs-comment { + color: #888888 !important; + font-style: italic; +} + +/* 内置对象和方法 - 深紫色 */ +.code-block .hljs-built_in { + color: #663399 !important; + font-weight: 500; +} + +/* 字面量 (true, false, null) - 红色 */ +.code-block .hljs-literal { + color: #cc0000 !important; + font-weight: 600; +} + +/* 操作符 - 深灰色 */ +.code-block .hljs-operator { + color: #666666 !important; +} + +/* 标点符号 - 深灰色 */ +.code-block .hljs-punctuation { + color: #666666 !important; +} + +/* 属性名 - 深蓝色 */ +.code-block .hljs-property, +.code-block .hljs-attr { + color: #0066aa !important; +} + +/* 类名和构造函数 - 深绿色 */ +.code-block .hljs-title.class_, +.code-block .hljs-title { + color: #228833 !important; + font-weight: 600; +} + +/* 参数 - 深蓝色 */ +.code-block .hljs-params { + color: #0066aa !important; +} + +/* 正则表达式 - 深红色 */ +.code-block .hljs-regexp { + color: #aa0066 !important; +} + +/* 模板字符串 - 深绿色 */ +.code-block .hljs-template-variable, +.code-block .hljs-template-tag { + color: #228833 !important; +} + +/* 选项容器 */ +.options-container { + margin: 30px 0; +} + +.option { + background: rgba(255, 255, 255, 0.8); + border: 2px solid #e8f5e8; + border-radius: 12px; + padding: 15px 20px; + margin: 12px 0; + cursor: pointer; + transition: all 0.3s ease; + font-size: 1rem; + position: relative; + overflow: hidden; +} + +.option:hover { + border-color: #4caf50; + background: rgba(76, 175, 80, 0.05); + transform: translateX(5px); +} + +.option.selected { + border-color: #4caf50; + background: linear-gradient(135deg, rgba(76, 175, 80, 0.1), rgba(76, 175, 80, 0.05)); + color: #1a4d1a; + font-weight: 600; +} + +.option.correct { + border-color: #4caf50; + background: linear-gradient(135deg, rgba(76, 175, 80, 0.2), rgba(76, 175, 80, 0.1)); + color: #1a4d1a; +} + +.option.incorrect { + border-color: #f44336; + background: linear-gradient(135deg, rgba(244, 67, 54, 0.1), rgba(244, 67, 54, 0.05)); + color: #c62828; +} + +/* 按钮样式 */ +.action-buttons { + display: flex; + gap: 15px; + margin: 30px 0; + justify-content: center; + flex-wrap: wrap; +} + +.submit-btn, .show-answer-btn, .retry-btn, .export-btn { + padding: 12px 30px; + border: none; + border-radius: 25px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + min-width: 120px; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.submit-btn { + background: linear-gradient(135deg, #4caf50, #45a049); + color: white; +} + +.submit-btn:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3); +} + +.submit-btn:disabled { + background: #cccccc; + cursor: not-allowed; + transform: none; + box-shadow: none; +} + +.show-answer-btn { + background: linear-gradient(135deg, #2196f3, #1976d2); + color: white; +} + +.show-answer-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(33, 150, 243, 0.3); +} + +.retry-btn { + background: linear-gradient(135deg, #ff9800, #f57c00); + color: white; +} + +.retry-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(255, 152, 0, 0.3); +} + +.export-btn { + background: linear-gradient(135deg, #9c27b0, #7b1fa2); + color: white; +} + +.export-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(156, 39, 176, 0.3); +} + +.export-btn svg { + width: 16px; + height: 16px; +} + +/* 结果容器 */ +.result-container { + margin-top: 30px; + padding: 25px; + background: rgba(255, 255, 255, 0.9); + border-radius: 15px; + border: 2px solid #e8f5e8; +} + +.result-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding-bottom: 15px; + border-bottom: 1px solid #e8f5e8; +} + +.result-status { + font-size: 1.2rem; + font-weight: 600; +} + +.result-status.correct { + color: #4caf50; +} + +.result-status.incorrect { + color: #f44336; +} + +.correct-answer { + font-weight: 600; + color: #4caf50; + background: rgba(76, 175, 80, 0.1); + padding: 5px 12px; + border-radius: 15px; +} + +.explanation { + color: #2d5a27; + line-height: 1.7; + font-size: 1rem; +} + +.explanation pre { + background: #f8f9fa; + border: 1px solid #e8f5e8; + border-radius: 8px; + padding: 15px; + margin: 15px 0; + overflow-x: auto; + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; +} + +/* 错误容器 */ +.error-container { + text-align: center; + padding: 60px 20px; + background: rgba(255, 255, 255, 0.9); + border-radius: 20px; + border: 2px solid rgba(244, 67, 54, 0.2); + max-width: 500px; + margin: 0 auto; +} + +.error-icon { + font-size: 3rem; + margin-bottom: 20px; +} + +.error-container h3 { + color: #f44336; + margin-bottom: 15px; + font-size: 1.5rem; +} + +.error-container p { + color: #666; + margin-bottom: 25px; + font-size: 1.1rem; +} + +/* 底部 */ +.footer { + text-align: center; + padding: 30px 0; + margin-top: 40px; + color: #4a7c59; + opacity: 0.7; + border-top: 1px solid rgba(76, 175, 80, 0.2); +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2.2rem; + } + + .question-container { + padding: 30px; + } + + .action-buttons { + flex-wrap: wrap; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + .container { + padding: 10px; + } + + .header { + margin-bottom: 25px; + padding: 20px 0; + } + + .header h1 { + font-size: 1.8rem; + } + + .subtitle { + font-size: 1rem; + } + + .question-container { + padding: 20px; + border-radius: 15px; + } + + .question-header { + flex-direction: column; + gap: 15px; + text-align: center; + } + + .question-text h2 { + font-size: 1.3rem; + } + + .code-block pre { + padding: 15px; + font-size: 0.85rem; + } + + .option { + padding: 12px 15px; + font-size: 0.95rem; + } + + .action-buttons { + flex-direction: column; + align-items: center; + } + + .submit-btn, .show-answer-btn, .retry-btn { + width: 100%; + max-width: 200px; + } + + .result-header { + flex-direction: column; + gap: 10px; + text-align: center; + } + + .explanation { + font-size: 0.95rem; + } + + .explanation pre { + padding: 10px; + font-size: 0.8rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .container { + padding: 8px; + } + + .header h1 { + font-size: 1.6rem; + } + + .question-container { + padding: 15px; + } + + .question-id { + font-size: 1rem; + padding: 6px 12px; + } + + .refresh-btn { + width: 40px; + height: 40px; + } + + .code-block pre { + font-size: 0.8rem; + padding: 12px; + } + + .option { + padding: 10px 12px; + font-size: 0.9rem; + } + + .submit-btn, .show-answer-btn, .retry-btn { + padding: 10px 20px; + font-size: 0.95rem; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/index.html b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/index.html new file mode 100644 index 00000000..310880a4 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/index.html @@ -0,0 +1,89 @@ + + + + + + 随机JavaScript趣味题 + + + + + + + +
+
+

JavaScript趣味题

+

测试你的JavaScript知识

+
+ +
+
+
+

正在加载题目...

+
+ + + + +
+ +
+

JavaScript趣味题集合

+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js new file mode 100644 index 00000000..dd4812c0 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js @@ -0,0 +1,565 @@ +// JavaScript趣味题应用 +class JSQuizApp { + constructor() { + this.apiEndpoints = [ + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run', + 'https://60s.114128.xyz', + 'https://60s-cf.114128.xyz' + ]; + this.currentApiIndex = 0; + this.currentQuestion = null; + this.selectedOption = null; + this.isAnswered = false; + + this.initElements(); + this.bindEvents(); + this.loadQuestion(); + } + + // 初始化DOM元素 + initElements() { + this.elements = { + loading: document.getElementById('loading'), + questionContainer: document.getElementById('questionContainer'), + errorContainer: document.getElementById('errorContainer'), + questionId: document.getElementById('questionId'), + questionText: document.getElementById('questionText'), + codeContent: document.getElementById('codeContent'), + optionsContainer: document.getElementById('optionsContainer'), + submitBtn: document.getElementById('submitBtn'), + showAnswerBtn: document.getElementById('showAnswerBtn'), + refreshBtn: document.getElementById('refreshBtn'), + retryBtn: document.getElementById('retryBtn'), + exportBtn: document.getElementById('exportBtn'), + resultContainer: document.getElementById('resultContainer'), + resultStatus: document.getElementById('resultStatus'), + correctAnswer: document.getElementById('correctAnswer'), + explanation: document.getElementById('explanation'), + errorMessage: document.getElementById('errorMessage') + }; + } + + // 绑定事件 + bindEvents() { + this.elements.submitBtn.addEventListener('click', () => this.submitAnswer()); + this.elements.showAnswerBtn.addEventListener('click', () => this.showAnswer()); + this.elements.refreshBtn.addEventListener('click', () => this.loadQuestion()); + this.elements.retryBtn.addEventListener('click', () => this.loadQuestion()); + this.elements.exportBtn.addEventListener('click', () => this.exportToMarkdown()); + } + + // 显示加载状态 + showLoading() { + this.elements.loading.style.display = 'block'; + this.elements.questionContainer.style.display = 'none'; + this.elements.errorContainer.style.display = 'none'; + } + + // 显示题目 + showQuestion() { + this.elements.loading.style.display = 'none'; + this.elements.questionContainer.style.display = 'block'; + this.elements.errorContainer.style.display = 'none'; + } + + // 显示错误 + showError(message) { + this.elements.loading.style.display = 'none'; + this.elements.questionContainer.style.display = 'none'; + this.elements.errorContainer.style.display = 'block'; + this.elements.errorMessage.textContent = message; + } + + // 获取当前API地址 + getCurrentApiUrl() { + return `${this.apiEndpoints[this.currentApiIndex]}/v2/awesome-js`; + } + + // 切换到下一个API + switchToNextApi() { + this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length; + } + + // 加载题目 + async loadQuestion() { + this.showLoading(); + this.resetQuestion(); + + let attempts = 0; + const maxAttempts = this.apiEndpoints.length; + + while (attempts < maxAttempts) { + try { + const response = await fetch(this.getCurrentApiUrl(), { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + timeout: 10000 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + this.currentQuestion = data.data; + this.displayQuestion(); + return; + } else { + throw new Error(data.message || '数据格式错误'); + } + + } catch (error) { + console.warn(`API ${this.getCurrentApiUrl()} 请求失败:`, error.message); + attempts++; + + if (attempts < maxAttempts) { + this.switchToNextApi(); + console.log(`切换到备用API: ${this.getCurrentApiUrl()}`); + } else { + this.showError(`所有API接口都无法访问,请检查网络连接后重试。\n最后尝试的错误: ${error.message}`); + return; + } + } + } + } + + // 重置题目状态 + resetQuestion() { + this.selectedOption = null; + this.isAnswered = false; + this.elements.resultContainer.style.display = 'none'; + this.elements.submitBtn.disabled = true; + this.elements.submitBtn.textContent = '提交答案'; + this.elements.showAnswerBtn.style.display = 'inline-block'; + + // 清空选项容器,防止重复显示 + this.elements.optionsContainer.innerHTML = ''; + + // 移除所有选项的事件监听器 + const existingOptions = document.querySelectorAll('.option'); + existingOptions.forEach(option => { + option.removeEventListener('click', this.selectOption); + }); + } + + // 显示题目内容 + displayQuestion() { + const question = this.currentQuestion; + + console.log('显示题目:', question); + + // 设置题目ID + this.elements.questionId.textContent = `题目 #${question.id}`; + + // 设置题目文本 + this.elements.questionText.innerHTML = `

${this.escapeHtml(question.question)}

`; + + // 设置代码内容并应用语法高亮 + this.elements.codeContent.textContent = question.code; + + // 应用语法高亮 + if (typeof hljs !== 'undefined') { + hljs.highlightElement(this.elements.codeContent); + } + + // 确保选项容器已清空 + this.elements.optionsContainer.innerHTML = ''; + + // 生成选项 + this.generateOptions(question.options); + + this.showQuestion(); + } + + // 生成选项 + generateOptions(options) { + // 确保清空容器 + this.elements.optionsContainer.innerHTML = ''; + + // 验证选项数据 + if (!Array.isArray(options) || options.length === 0) { + console.error('选项数据无效:', options); + return; + } + + // 移除可能存在的重复选项 + const uniqueOptions = [...new Set(options)]; + + uniqueOptions.forEach((option, index) => { + const optionElement = document.createElement('div'); + optionElement.className = 'option'; + optionElement.textContent = option; + optionElement.dataset.index = index; + optionElement.dataset.value = option.charAt(0); // A, B, C, D + + optionElement.addEventListener('click', () => this.selectOption(optionElement)); + + this.elements.optionsContainer.appendChild(optionElement); + }); + + console.log('生成选项:', uniqueOptions); + } + + // 选择选项 + selectOption(optionElement) { + if (this.isAnswered) return; + + // 移除之前的选中状态 + document.querySelectorAll('.option.selected').forEach(el => { + el.classList.remove('selected'); + }); + + // 设置当前选中 + optionElement.classList.add('selected'); + this.selectedOption = optionElement.dataset.value; + + // 启用提交按钮 + this.elements.submitBtn.disabled = false; + } + + // 提交答案 + submitAnswer() { + if (!this.selectedOption || this.isAnswered) return; + + this.isAnswered = true; + this.elements.submitBtn.disabled = true; + this.elements.submitBtn.textContent = '已提交'; + this.elements.showAnswerBtn.style.display = 'none'; + + const isCorrect = this.selectedOption === this.currentQuestion.answer; + + // 显示结果 + this.showResult(isCorrect); + + // 标记选项 + this.markOptions(); + } + + // 显示答案 + showAnswer() { + this.isAnswered = true; + this.elements.submitBtn.disabled = true; + this.elements.submitBtn.textContent = '已显示答案'; + this.elements.showAnswerBtn.style.display = 'none'; + + // 显示结果(不判断对错) + this.showResult(null); + + // 标记正确答案 + this.markCorrectAnswer(); + } + + // 显示结果 + showResult(isCorrect) { + const resultContainer = this.elements.resultContainer; + const resultStatus = this.elements.resultStatus; + const correctAnswer = this.elements.correctAnswer; + const explanation = this.elements.explanation; + + // 设置结果状态 + if (isCorrect === true) { + resultStatus.textContent = '✅ 回答正确!'; + resultStatus.className = 'result-status correct'; + } else if (isCorrect === false) { + resultStatus.textContent = '❌ 回答错误'; + resultStatus.className = 'result-status incorrect'; + } else { + resultStatus.textContent = '💡 答案解析'; + resultStatus.className = 'result-status'; + } + + // 设置正确答案 + correctAnswer.textContent = `正确答案: ${this.currentQuestion.answer}`; + + // 设置解析内容 + explanation.innerHTML = this.formatExplanation(this.currentQuestion.explanation); + + // 显示结果容器 + resultContainer.style.display = 'block'; + + // 滚动到结果区域 + setTimeout(() => { + resultContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + }, 100); + } + + // 标记选项 + markOptions() { + const options = document.querySelectorAll('.option'); + const correctAnswer = this.currentQuestion.answer; + + options.forEach(option => { + const optionValue = option.dataset.value; + + if (optionValue === correctAnswer) { + option.classList.add('correct'); + } else if (option.classList.contains('selected')) { + option.classList.add('incorrect'); + } + + // 禁用点击 + option.style.pointerEvents = 'none'; + }); + } + + // 标记正确答案 + markCorrectAnswer() { + const options = document.querySelectorAll('.option'); + const correctAnswer = this.currentQuestion.answer; + + options.forEach(option => { + const optionValue = option.dataset.value; + + if (optionValue === correctAnswer) { + option.classList.add('correct'); + } + + // 禁用点击 + option.style.pointerEvents = 'none'; + }); + } + + // 格式化解析内容 + formatExplanation(explanation) { + // 转义HTML + let formatted = this.escapeHtml(explanation); + + // 处理代码块 + formatted = formatted.replace(/```js\n([\s\S]*?)\n```/g, '
$1
'); + formatted = formatted.replace(/```javascript\n([\s\S]*?)\n```/g, '
$1
'); + formatted = formatted.replace(/```([\s\S]*?)```/g, '
$1
'); + + // 处理行内代码 + formatted = formatted.replace(/`([^`]+)`/g, '$1'); + + // 处理换行 + formatted = formatted.replace(/\n\n/g, '

'); + formatted = formatted.replace(/\n/g, '
'); + + // 包装段落 + if (!formatted.includes('

')) { + formatted = '

' + formatted + '

'; + } + + return formatted; + } + + // HTML转义 + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + // 导出为Markdown + exportToMarkdown() { + if (!this.currentQuestion) { + alert('请先加载题目后再导出!'); + return; + } + + const question = this.currentQuestion; + const timestamp = new Date().toLocaleString('zh-CN'); + + // 构建Markdown内容 + let markdown = `# JavaScript趣味题 #${question.id}\n\n`; + markdown += `> 导出时间: ${timestamp}\n\n`; + + // 题目部分 + markdown += `## 题目\n\n`; + markdown += `${question.question}\n\n`; + + // 代码部分 + markdown += `## 代码\n\n`; + markdown += `\`\`\`javascript\n${question.code}\n\`\`\`\n\n`; + + // 选项部分 + markdown += `## 选项\n\n`; + question.options.forEach((option, index) => { + const letter = String.fromCharCode(65 + index); // A, B, C, D + const isCorrect = letter === question.answer; + markdown += `${letter}. ${option}${isCorrect ? ' ✅' : ''}\n`; + }); + markdown += `\n`; + + // 答案部分 + markdown += `## 正确答案\n\n`; + markdown += `**${question.answer}**\n\n`; + + // 解析部分 + markdown += `## 答案解析\n\n`; + // 清理解析内容中的HTML标签,转换为Markdown格式 + let explanation = question.explanation; + explanation = explanation.replace(//gi, '\n'); + explanation = explanation.replace(/

/gi, '\n'); + explanation = explanation.replace(/<\/p>/gi, '\n'); + explanation = explanation.replace(/]*>/gi, '`'); + explanation = explanation.replace(/<\/code>/gi, '`'); + explanation = explanation.replace(/

/gi, '\n```javascript\n');
+        explanation = explanation.replace(/<\/code><\/pre>/gi, '\n```\n');
+        explanation = explanation.replace(/<[^>]*>/g, ''); // 移除其他HTML标签
+        explanation = explanation.replace(/\n\s*\n/g, '\n\n'); // 清理多余空行
+        markdown += explanation.trim() + '\n\n';
+        
+        // 添加页脚
+        markdown += `---\n\n`;
+        markdown += `*本题目来源于JavaScript趣味题集合*\n`;
+        markdown += `*导出工具: JavaScript趣味题网页版*\n`;
+        
+        // 创建下载
+        this.downloadMarkdown(markdown, `JavaScript趣味题_${question.id}_${new Date().getTime()}.md`);
+    }
+    
+    // 下载Markdown文件
+    downloadMarkdown(content, filename) {
+        const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' });
+        const url = URL.createObjectURL(blob);
+        
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = filename;
+        link.style.display = 'none';
+        
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        
+        // 清理URL对象
+        setTimeout(() => {
+            URL.revokeObjectURL(url);
+        }, 100);
+        
+        // 显示成功提示
+        this.showExportSuccess(filename);
+    }
+    
+    // 显示导出成功提示
+    showExportSuccess(filename) {
+        // 创建临时提示元素
+        const toast = document.createElement('div');
+        toast.style.cssText = `
+            position: fixed;
+            top: 20px;
+            right: 20px;
+            background: linear-gradient(135deg, #4caf50, #45a049);
+            color: white;
+            padding: 15px 20px;
+            border-radius: 8px;
+            box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
+            z-index: 10000;
+            font-size: 14px;
+            max-width: 300px;
+            word-wrap: break-word;
+            animation: slideInRight 0.3s ease-out;
+        `;
+        
+        toast.innerHTML = `
+            
+ + + +
+
导出成功!
+
${filename}
+
+
+ `; + + // 添加动画样式 + const style = document.createElement('style'); + style.textContent = ` + @keyframes slideInRight { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } + } + @keyframes slideOutRight { + from { + transform: translateX(0); + opacity: 1; + } + to { + transform: translateX(100%); + opacity: 0; + } + } + `; + document.head.appendChild(style); + + document.body.appendChild(toast); + + // 3秒后自动消失 + setTimeout(() => { + toast.style.animation = 'slideOutRight 0.3s ease-in'; + setTimeout(() => { + if (toast.parentNode) { + document.body.removeChild(toast); + } + if (style.parentNode) { + document.head.removeChild(style); + } + }, 300); + }, 3000); + } +} + +// 页面加载完成后初始化应用 +document.addEventListener('DOMContentLoaded', () => { + new JSQuizApp(); +}); + +// 添加键盘快捷键支持 +document.addEventListener('keydown', (e) => { + // 按R键刷新题目 + if (e.key.toLowerCase() === 'r' && !e.ctrlKey && !e.metaKey) { + const refreshBtn = document.getElementById('refreshBtn'); + if (refreshBtn && !document.querySelector('.loading').style.display !== 'none') { + refreshBtn.click(); + } + } + + // 按数字键1-4选择选项 + if (['1', '2', '3', '4'].includes(e.key)) { + const options = document.querySelectorAll('.option'); + const index = parseInt(e.key) - 1; + if (options[index] && !options[index].style.pointerEvents) { + options[index].click(); + } + } + + // 按Enter键提交答案 + if (e.key === 'Enter') { + const submitBtn = document.getElementById('submitBtn'); + if (submitBtn && !submitBtn.disabled) { + submitBtn.click(); + } + } +}); + +// 添加触摸设备支持 +if ('ontouchstart' in window) { + document.addEventListener('touchstart', () => {}, { passive: true }); +} + +// 添加网络状态监听 +if ('navigator' in window && 'onLine' in navigator) { + window.addEventListener('online', () => { + console.log('网络连接已恢复'); + }); + + window.addEventListener('offline', () => { + console.log('网络连接已断开'); + }); +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json new file mode 100644 index 00000000..d6592cc8 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json @@ -0,0 +1,17 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "id": 11, + "question": "输出是什么?", + "code": "function Person(firstName, lastName) {\n this.firstName = firstName;\n this.lastName = lastName;\n}\n\nconst member = new Person(\"Lydia\", \"Hallie\");\nPerson.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n\nconsole.log(member.getFullName());", + "options": [ + "A: `TypeError`", + "B: `SyntaxError`", + "C: `Lydia Hallie`", + "D: `undefined` `undefined`" + ], + "answer": "A", + "explanation": "你不能像常规对象那样,给构造函数添加属性。如果你想一次性给所有实例添加特性,你应该使用原型。因此本例中,使用如下方式:\n\n```js\nPerson.prototype.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n```\n\n这才会使 `member.getFullName()` 起作用。为什么这么做有益的?假设我们将这个方法添加到构造函数本身里。也许不是每个 `Person` 实例都需要这个方法。这将浪费大量内存空间,因为它们仍然具有该属性,这将占用每个实例的内存空间。相反,如果我们只将它添加到原型中,那么它只存在于内存中的一个位置,但是所有实例都可以访问它!" + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/background.css b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/background.css new file mode 100644 index 00000000..84d3b43d --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/background.css @@ -0,0 +1,81 @@ +/* 背景样式文件 */ +body { + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 25%, #ffd3a5 50%, #a8e6cf 75%, #88d8a3 100%); + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; + position: relative; +} + +/* 背景动画 */ +@keyframes gradientShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 背景装饰元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 80%, rgba(39, 174, 96, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(46, 204, 113, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(26, 188, 156, 0.05) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +/* 浮动装饰圆点 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(39, 174, 96, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(46, 204, 113, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(26, 188, 156, 0.3), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(39, 174, 96, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(46, 204, 113, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + animation: floatDots 20s linear infinite; + pointer-events: none; + z-index: -1; +} + +@keyframes floatDots { + 0% { + transform: translateY(0px); + } + 100% { + transform: translateY(-100px); + } +} + +/* 响应式背景调整 */ +@media (max-width: 768px) { + body::after { + background-size: 150px 75px; + animation-duration: 25s; + } +} + +@media (max-width: 480px) { + body::after { + background-size: 100px 50px; + animation-duration: 30s; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/style.css b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/style.css new file mode 100644 index 00000000..b1bef2cc --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/css/style.css @@ -0,0 +1,339 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2c3e50; + min-height: 100vh; + overflow-x: hidden; +} + +/* 容器布局 */ +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + padding: 30px 0; +} + +.title { + font-size: 2.5rem; + font-weight: 700; + color: #27ae60; + margin-bottom: 10px; + text-shadow: 0 2px 4px rgba(39, 174, 96, 0.2); +} + +.subtitle { + font-size: 1.1rem; + color: #7f8c8d; + font-weight: 400; +} + +/* 主要内容区域 */ +.main { + flex: 1; + display: flex; + justify-content: center; + align-items: center; +} + +.content-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 40px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + border: 1px solid rgba(39, 174, 96, 0.1); + width: 100%; + max-width: 600px; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.content-card:hover { + transform: translateY(-5px); + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15); +} + +/* KFC文案内容 */ +.kfc-content { + min-height: 200px; + padding: 30px; + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + border-radius: 15px; + border-left: 5px solid #27ae60; + margin-bottom: 30px; + position: relative; + overflow: hidden; +} + +.kfc-content::before { + content: '"'; + position: absolute; + top: 10px; + left: 15px; + font-size: 3rem; + color: #27ae60; + opacity: 0.3; + font-family: serif; +} + +.kfc-content p { + font-size: 1.1rem; + line-height: 1.8; + color: #2c3e50; + margin-left: 20px; + position: relative; + z-index: 1; +} + +.loading-text { + text-align: center; + color: #7f8c8d; + font-style: italic; +} + +/* 按钮组 */ +.button-group { + display: flex; + gap: 15px; + justify-content: center; + margin-bottom: 20px; +} + +.generate-btn, .copy-btn { + padding: 15px 30px; + border: none; + border-radius: 50px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.generate-btn { + background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%); + color: white; + box-shadow: 0 4px 15px rgba(39, 174, 96, 0.3); +} + +.generate-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(39, 174, 96, 0.4); +} + +.generate-btn:active { + transform: translateY(0); +} + +.generate-btn:disabled { + opacity: 0.7; + cursor: not-allowed; + transform: none; +} + +.copy-btn { + background: linear-gradient(135deg, #3498db 0%, #5dade2 100%); + color: white; + box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); +} + +.copy-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4); +} + +/* 编号信息 */ +.index-info { + text-align: center; + padding: 10px; + background: rgba(39, 174, 96, 0.1); + border-radius: 10px; + border: 1px solid rgba(39, 174, 96, 0.2); +} + +.index-text { + color: #27ae60; + font-weight: 600; + font-size: 0.9rem; +} + +#indexNumber { + color: #2c3e50; + font-weight: 700; +} + +/* 底部 */ +.footer { + text-align: center; + padding: 20px 0; + color: #7f8c8d; + font-size: 0.9rem; + margin-top: 40px; +} + +/* 提示框 */ +.toast { + position: fixed; + top: 20px; + right: 20px; + background: #27ae60; + color: white; + padding: 15px 25px; + border-radius: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + transform: translateX(400px); + transition: transform 0.3s ease; + z-index: 1000; + font-weight: 600; +} + +.toast.show { + transform: translateX(0); +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + padding: 15px; + } + + .title { + font-size: 2.2rem; + } + + .content-card { + padding: 35px; + max-width: 550px; + } + + .kfc-content { + padding: 25px; + min-height: 180px; + } + + .button-group { + flex-direction: row; + gap: 12px; + } + + .generate-btn, .copy-btn { + padding: 12px 25px; + font-size: 0.95rem; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + .container { + padding: 10px; + } + + .header { + margin-bottom: 30px; + padding: 20px 0; + } + + .title { + font-size: 1.8rem; + margin-bottom: 8px; + } + + .subtitle { + font-size: 1rem; + } + + .content-card { + padding: 25px; + margin: 0 5px; + border-radius: 15px; + } + + .kfc-content { + padding: 20px; + min-height: 150px; + margin-bottom: 25px; + } + + .kfc-content::before { + font-size: 2.5rem; + top: 5px; + left: 10px; + } + + .kfc-content p { + font-size: 1rem; + line-height: 1.7; + margin-left: 15px; + } + + .button-group { + flex-direction: column; + gap: 10px; + } + + .generate-btn, .copy-btn { + padding: 12px 20px; + font-size: 0.9rem; + width: 100%; + } + + .footer { + font-size: 0.8rem; + margin-top: 30px; + } + + .toast { + right: 10px; + left: 10px; + transform: translateY(-100px); + font-size: 0.9rem; + } + + .toast.show { + transform: translateY(0); + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .title { + font-size: 1.6rem; + } + + .content-card { + padding: 20px; + margin: 0; + } + + .kfc-content { + padding: 15px; + min-height: 120px; + } + + .kfc-content p { + font-size: 0.95rem; + margin-left: 10px; + } + + .generate-btn, .copy-btn { + padding: 10px 15px; + font-size: 0.85rem; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/index.html b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/index.html new file mode 100644 index 00000000..72ab0627 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/index.html @@ -0,0 +1,46 @@ + + + + + + 随机KFC文案生成器 + + + + +
+
+

🍗 随机KFC文案生成器

+

疯狂星期四,文案来一套!

+
+ +
+
+
+

点击按钮获取随机KFC文案...

+
+ +
+ + +
+ + +
+
+ +
+

© 2024 KFC文案生成器 | 让每个星期四都疯狂起来

+
+
+ +
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/js/main.js b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/js/main.js new file mode 100644 index 00000000..526c4750 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/js/main.js @@ -0,0 +1,240 @@ +// KFC文案生成器主要功能 +class KFCGenerator { + constructor() { + this.apiEndpoints = []; + this.currentApiIndex = 0; + this.isLoading = false; + + this.init(); + } + + // 初始化 + async init() { + await this.loadApiEndpoints(); + this.bindEvents(); + } + + // 加载API接口列表 + async loadApiEndpoints() { + try { + const response = await fetch('./接口集合.json'); + this.apiEndpoints = await response.json(); + } catch (error) { + console.error('加载API接口列表失败:', error); + this.showToast('加载接口配置失败', 'error'); + } + } + + // 绑定事件 + bindEvents() { + const generateBtn = document.getElementById('generateBtn'); + const copyBtn = document.getElementById('copyBtn'); + + generateBtn.addEventListener('click', () => this.generateKFC()); + copyBtn.addEventListener('click', () => this.copyContent()); + } + + // 生成KFC文案 + async generateKFC() { + if (this.isLoading) return; + + this.setLoadingState(true); + + let success = false; + let attempts = 0; + const maxAttempts = this.apiEndpoints.length; + + while (!success && attempts < maxAttempts) { + try { + const apiUrl = this.apiEndpoints[this.currentApiIndex]; + const data = await this.fetchKFCData(apiUrl); + + if (data && data.code === 200 && data.data && data.data.kfc) { + this.displayKFC(data.data); + success = true; + } else { + throw new Error('API返回数据格式错误'); + } + } catch (error) { + console.error(`API ${this.currentApiIndex + 1} 请求失败:`, error); + this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length; + attempts++; + } + } + + if (!success) { + this.showError('所有API接口都无法访问,请稍后重试'); + } + + this.setLoadingState(false); + } + + // 请求KFC数据 + async fetchKFCData(apiUrl) { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 + + try { + const response = await fetch(`${apiUrl}/v2/kfc`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + signal: controller.signal + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + return await response.json(); + } catch (error) { + clearTimeout(timeoutId); + throw error; + } + } + + // 显示KFC文案 + displayKFC(data) { + const contentElement = document.getElementById('kfcContent'); + const indexElement = document.getElementById('indexNumber'); + const indexInfo = document.getElementById('indexInfo'); + const copyBtn = document.getElementById('copyBtn'); + + // 显示文案内容 + contentElement.innerHTML = `

${this.escapeHtml(data.kfc)}

`; + + // 显示编号信息 + if (data.index) { + indexElement.textContent = data.index; + indexInfo.style.display = 'block'; + } else { + indexInfo.style.display = 'none'; + } + + // 显示复制按钮 + copyBtn.style.display = 'inline-block'; + + // 添加显示动画 + contentElement.style.opacity = '0'; + contentElement.style.transform = 'translateY(20px)'; + + setTimeout(() => { + contentElement.style.transition = 'all 0.5s ease'; + contentElement.style.opacity = '1'; + contentElement.style.transform = 'translateY(0)'; + }, 100); + } + + // 显示错误信息 + showError(message) { + const contentElement = document.getElementById('kfcContent'); + contentElement.innerHTML = `

${this.escapeHtml(message)}

`; + + const copyBtn = document.getElementById('copyBtn'); + const indexInfo = document.getElementById('indexInfo'); + copyBtn.style.display = 'none'; + indexInfo.style.display = 'none'; + } + + // 复制文案内容 + async copyContent() { + const contentElement = document.getElementById('kfcContent'); + const textContent = contentElement.querySelector('p')?.textContent; + + if (!textContent || textContent.includes('点击按钮获取') || textContent.includes('失败')) { + this.showToast('没有可复制的内容', 'error'); + return; + } + + try { + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(textContent); + } else { + // 降级方案 + const textArea = document.createElement('textarea'); + textArea.value = textContent; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + document.execCommand('copy'); + textArea.remove(); + } + + this.showToast('文案已复制到剪贴板', 'success'); + } catch (error) { + console.error('复制失败:', error); + this.showToast('复制失败,请手动选择复制', 'error'); + } + } + + // 设置加载状态 + setLoadingState(loading) { + this.isLoading = loading; + const generateBtn = document.getElementById('generateBtn'); + const btnText = generateBtn.querySelector('.btn-text'); + const btnLoading = generateBtn.querySelector('.btn-loading'); + + if (loading) { + generateBtn.disabled = true; + btnText.style.display = 'none'; + btnLoading.style.display = 'inline'; + } else { + generateBtn.disabled = false; + btnText.style.display = 'inline'; + btnLoading.style.display = 'none'; + } + } + + // 显示提示消息 + showToast(message, type = 'success') { + const toast = document.getElementById('toast'); + toast.textContent = message; + toast.className = `toast ${type}`; + toast.classList.add('show'); + + setTimeout(() => { + toast.classList.remove('show'); + }, 3000); + } + + // HTML转义 + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } +} + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', () => { + const generator = new KFCGenerator(); + // 页面加载完成后自动生成一条文案 + setTimeout(() => { + generator.generateKFC(); + }, 1000); +}); + +// 添加键盘快捷键支持 +document.addEventListener('keydown', (event) => { + // 按空格键生成文案 + if (event.code === 'Space' && event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') { + event.preventDefault(); + document.getElementById('generateBtn').click(); + } + + // Ctrl+C 复制文案 + if (event.ctrlKey && event.key === 'c' && event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') { + const copyBtn = document.getElementById('copyBtn'); + if (copyBtn.style.display !== 'none') { + event.preventDefault(); + copyBtn.click(); + } + } +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/接口集合.json b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/返回接口.json b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/返回接口.json new file mode 100644 index 00000000..0f729ba8 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机KFC文案/返回接口.json @@ -0,0 +1 @@ +{"code":200,"message":"获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841","data":{"index":369,"kfc":"我不想你带着情绪过夜,这样会把你推的越来越远,我不想你离开我,我希望你可以多爱我一点,我不想因为一点点小问题就让我们两之间的感情产生隔阂。对我来说,双向奔赴的感情相处才有意义,看不到希望的事情我没办法坚持太久,我不想浪费时间在一些无意义无结果的事情上,时间应该用来做我该做的事情。很多人走不到最后,是因为理解不同步,但我跟你在一起,我知道你什样的人,我了解你甚至比了解自己还多,我和你在一起,不是因为其他,而是因为今天肯德基疯狂星期四,我希望你能请我吃!"}} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/background.css b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/background.css new file mode 100644 index 00000000..3a10cfda --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/background.css @@ -0,0 +1,167 @@ +/* 背景样式文件 - 金色光辉主题 */ + +/* 主背景 */ +body { + background: linear-gradient( + 135deg, + #fff8dc 0%, + #ffeaa7 25%, + #fdcb6e 50%, + #e17055 75%, + #d63031 100% + ); + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; + position: relative; +} + +/* 背景装饰层 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 80%, rgba(255, 215, 0, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 223, 0, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(212, 175, 55, 0.05) 0%, transparent 50%); + pointer-events: none; + z-index: 1; +} + +/* 动态光点效果 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(255, 215, 0, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(255, 223, 0, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(212, 175, 55, 0.4), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(255, 215, 0, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(255, 223, 0, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + animation: sparkle 20s linear infinite; + pointer-events: none; + z-index: 2; +} + +/* 背景动画 */ +@keyframes gradientShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +@keyframes sparkle { + 0% { + transform: translateY(0); + opacity: 1; + } + 100% { + transform: translateY(-100vh); + opacity: 0; + } +} + +/* 响应式背景调整 */ + +/* 平板端背景 */ +@media (min-width: 768px) and (max-width: 1024px) { + body::after { + background-size: 250px 120px; + } +} + +/* 电脑端背景 */ +@media (min-width: 1024px) { + body { + background-size: 300% 300%; + } + + body::after { + background-size: 300px 150px; + animation-duration: 25s; + } +} + +/* 手机端背景优化 */ +@media (max-width: 767px) { + body { + background-size: 200% 200%; + animation-duration: 10s; + } + + body::before { + background: + radial-gradient(circle at 30% 70%, rgba(255, 215, 0, 0.08) 0%, transparent 40%), + radial-gradient(circle at 70% 30%, rgba(255, 223, 0, 0.08) 0%, transparent 40%); + } + + body::after { + background-size: 150px 80px; + animation-duration: 15s; + } +} + +/* 超小屏幕背景 */ +@media (max-width: 479px) { + body { + background: linear-gradient( + 135deg, + #fff8dc 0%, + #ffeaa7 50%, + #fdcb6e 100% + ); + background-size: 150% 150%; + } + + body::after { + background-size: 120px 60px; + } +} + +/* 深色模式支持 */ +@media (prefers-color-scheme: dark) { + body { + background: linear-gradient( + 135deg, + #2c1810 0%, + #3d2914 25%, + #4a3319 50%, + #5c3e1f 75%, + #6b4423 100% + ); + } + + body::before { + background: + radial-gradient(circle at 20% 80%, rgba(255, 215, 0, 0.05) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 223, 0, 0.05) 0%, transparent 50%); + } +} + +/* 减少动画效果(用户偏好) */ +@media (prefers-reduced-motion: reduce) { + body, + body::before, + body::after { + animation: none; + } + + body { + background: linear-gradient(135deg, #fff8dc 0%, #ffeaa7 50%, #fdcb6e 100%); + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/style.css b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/style.css new file mode 100644 index 00000000..b84b1125 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/css/style.css @@ -0,0 +1,357 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2c1810; + overflow-x: hidden; +} + +/* 容器布局 */ +.container { + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 20px; + position: relative; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + z-index: 10; +} + +.title { + font-size: 3rem; + font-weight: 700; + color: #d4af37; + text-shadow: + 0 0 10px rgba(212, 175, 55, 0.8), + 0 0 20px rgba(212, 175, 55, 0.6), + 0 0 30px rgba(212, 175, 55, 0.4); + margin-bottom: 10px; + animation: titleGlow 3s ease-in-out infinite alternate; +} + +.subtitle { + font-size: 1.2rem; + color: #b8860b; + opacity: 0.9; + text-shadow: 0 0 5px rgba(184, 134, 11, 0.5); +} + +/* 主内容区域 */ +.main-content { + width: 100%; + max-width: 800px; + z-index: 10; +} + +/* 一言容器 */ +.quote-container { + background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 223, 0, 0.05)); + border: 2px solid rgba(212, 175, 55, 0.3); + border-radius: 20px; + padding: 40px; + margin-bottom: 30px; + backdrop-filter: blur(10px); + box-shadow: + 0 8px 32px rgba(212, 175, 55, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + position: relative; + overflow: hidden; +} + +.quote-container::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, #ffd700, #ffed4e, #ffd700, #ffed4e); + border-radius: 22px; + z-index: -1; + animation: borderGlow 4s linear infinite; +} + +/* 加载状态 */ +.loading { + display: none; + text-align: center; + color: #d4af37; +} + +.loading.show { + display: block; +} + +.loading-spinner { + width: 40px; + height: 40px; + border: 4px solid rgba(212, 175, 55, 0.3); + border-top: 4px solid #d4af37; + border-radius: 50%; + margin: 0 auto 15px; + animation: spin 1s linear infinite; +} + +/* 一言显示 */ +.quote-display { + display: block; + text-align: center; +} + +.quote-display.hide { + display: none; +} + +.quote-text { + font-size: 1.8rem; + line-height: 1.8; + color: #2c1810; + margin-bottom: 20px; + text-shadow: 0 1px 2px rgba(212, 175, 55, 0.1); + font-weight: 500; +} + +.quote-index { + font-size: 0.9rem; + color: #b8860b; + opacity: 0.8; +} + +/* 错误信息 */ +.error-message { + display: none; + text-align: center; + color: #cd853f; +} + +.error-message.show { + display: block; +} + +.error-icon { + font-size: 2rem; + margin-bottom: 10px; +} + +.error-text { + font-size: 1.1rem; + line-height: 1.5; +} + +/* 控制按钮 */ +.controls { + text-align: center; +} + +.refresh-btn { + background: linear-gradient(135deg, #ffd700, #ffed4e); + border: none; + border-radius: 50px; + padding: 15px 30px; + font-size: 1.1rem; + font-weight: 600; + color: #2c1810; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 10px; + transition: all 0.3s ease; + box-shadow: + 0 4px 15px rgba(212, 175, 55, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + position: relative; + overflow: hidden; +} + +.refresh-btn:hover { + transform: translateY(-2px); + box-shadow: + 0 6px 20px rgba(212, 175, 55, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.refresh-btn:active { + transform: translateY(0); +} + +.refresh-btn:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none; +} + +.btn-icon { + font-size: 1.2rem; + transition: transform 0.3s ease; +} + +.refresh-btn:hover .btn-icon { + transform: rotate(180deg); +} + +/* 底部 */ +.footer { + margin-top: 40px; + text-align: center; + color: #b8860b; + opacity: 0.8; + font-size: 0.9rem; +} + +/* 动画效果 */ +@keyframes titleGlow { + 0% { + text-shadow: + 0 0 10px rgba(212, 175, 55, 0.8), + 0 0 20px rgba(212, 175, 55, 0.6), + 0 0 30px rgba(212, 175, 55, 0.4); + } + 100% { + text-shadow: + 0 0 15px rgba(212, 175, 55, 1), + 0 0 25px rgba(212, 175, 55, 0.8), + 0 0 35px rgba(212, 175, 55, 0.6); + } +} + +@keyframes borderGlow { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 平板端适配 (768px - 1024px) */ +@media (min-width: 768px) and (max-width: 1024px) { + .container { + padding: 30px; + } + + .title { + font-size: 3.5rem; + } + + .subtitle { + font-size: 1.3rem; + } + + .quote-container { + padding: 50px; + } + + .quote-text { + font-size: 2rem; + } +} + +/* 电脑端适配 (1024px+) */ +@media (min-width: 1024px) { + .container { + padding: 40px; + } + + .title { + font-size: 4rem; + } + + .subtitle { + font-size: 1.4rem; + } + + .quote-container { + padding: 60px; + max-width: 900px; + } + + .quote-text { + font-size: 2.2rem; + line-height: 1.9; + } + + .refresh-btn { + padding: 18px 36px; + font-size: 1.2rem; + } +} + +/* 手机端适配 (小于768px) */ +@media (max-width: 767px) { + .container { + padding: 15px; + } + + .header { + margin-bottom: 30px; + } + + .title { + font-size: 2.5rem; + } + + .subtitle { + font-size: 1rem; + } + + .quote-container { + padding: 25px; + border-radius: 15px; + } + + .quote-text { + font-size: 1.4rem; + line-height: 1.6; + } + + .refresh-btn { + padding: 12px 24px; + font-size: 1rem; + } + + .footer { + margin-top: 30px; + font-size: 0.8rem; + } +} + +/* 超小屏幕适配 (小于480px) */ +@media (max-width: 479px) { + .title { + font-size: 2rem; + } + + .quote-container { + padding: 20px; + } + + .quote-text { + font-size: 1.2rem; + } + + .refresh-btn { + padding: 10px 20px; + font-size: 0.9rem; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/index.html b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/index.html new file mode 100644 index 00000000..4ef88f30 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/index.html @@ -0,0 +1,52 @@ + + + + + + 随机一言 - 金色光辉 + + + + +
+
+

随机一言

+

每一句话都是心灵的光芒

+
+ +
+
+
+
+

正在获取一言...

+
+ +
+
+ 点击下方按钮获取一言 +
+
+
+ +
+
⚠️
+
+
+
+ +
+ +
+
+ +
+

愿每一句话都能温暖你的心

+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/js/script.js b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/js/script.js new file mode 100644 index 00000000..5ce4546a --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/js/script.js @@ -0,0 +1,225 @@ +// 随机一言 JavaScript 功能实现 + +class HitokotoApp { + constructor() { + // API接口列表 + this.apiEndpoints = [ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" + ]; + + this.currentEndpointIndex = 0; + this.isLoading = false; + + // DOM 元素 + this.elements = { + loading: document.getElementById('loading'), + quoteDisplay: document.getElementById('quoteDisplay'), + quoteText: document.getElementById('quoteText'), + quoteIndex: document.getElementById('quoteIndex'), + errorMessage: document.getElementById('errorMessage'), + errorText: document.getElementById('errorText'), + refreshBtn: document.getElementById('refreshBtn') + }; + + this.init(); + } + + // 初始化应用 + init() { + this.bindEvents(); + this.hideAllStates(); + this.showQuoteDisplay(); + } + + // 绑定事件 + bindEvents() { + this.elements.refreshBtn.addEventListener('click', () => { + this.fetchHitokoto(); + }); + + // 键盘快捷键支持 + document.addEventListener('keydown', (e) => { + if (e.code === 'Space' && !this.isLoading) { + e.preventDefault(); + this.fetchHitokoto(); + } + }); + } + + // 隐藏所有状态 + hideAllStates() { + this.elements.loading.classList.remove('show'); + this.elements.quoteDisplay.classList.remove('hide'); + this.elements.errorMessage.classList.remove('show'); + } + + // 显示加载状态 + showLoading() { + this.hideAllStates(); + this.elements.loading.classList.add('show'); + this.elements.quoteDisplay.classList.add('hide'); + this.elements.refreshBtn.disabled = true; + this.isLoading = true; + } + + // 显示一言内容 + showQuoteDisplay() { + this.hideAllStates(); + this.elements.quoteDisplay.classList.remove('hide'); + this.elements.refreshBtn.disabled = false; + this.isLoading = false; + } + + // 显示错误信息 + showError(message) { + this.hideAllStates(); + this.elements.errorMessage.classList.add('show'); + this.elements.errorText.textContent = message; + this.elements.refreshBtn.disabled = false; + this.isLoading = false; + } + + // 获取一言数据 + async fetchHitokoto() { + if (this.isLoading) return; + + this.showLoading(); + + // 尝试所有API接口 + for (let i = 0; i < this.apiEndpoints.length; i++) { + const endpointIndex = (this.currentEndpointIndex + i) % this.apiEndpoints.length; + const endpoint = this.apiEndpoints[endpointIndex]; + + try { + const result = await this.tryFetchFromEndpoint(endpoint); + if (result.success) { + this.currentEndpointIndex = endpointIndex; + this.displayHitokoto(result.data); + return; + } + } catch (error) { + console.warn(`接口 ${endpoint} 请求失败:`, error.message); + continue; + } + } + + // 所有接口都失败 + this.showError('所有接口都无法访问,请检查网络连接或稍后重试'); + } + + // 尝试从指定接口获取数据 + async tryFetchFromEndpoint(endpoint) { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 + + try { + const response = await fetch(`${endpoint}/v2/hitokoto?encoding=text`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + signal: controller.signal + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + // 验证返回数据格式 + if (data.code === 200 && data.data && data.data.hitokoto) { + return { + success: true, + data: data.data + }; + } else { + throw new Error('返回数据格式不正确'); + } + + } catch (error) { + clearTimeout(timeoutId); + + if (error.name === 'AbortError') { + throw new Error('请求超时'); + } + + throw error; + } + } + + // 显示一言内容 + displayHitokoto(data) { + // 更新一言文本 + this.elements.quoteText.textContent = data.hitokoto; + + // 更新序号信息 + if (data.index) { + this.elements.quoteIndex.textContent = `第 ${data.index} 条`; + } else { + this.elements.quoteIndex.textContent = ''; + } + + // 添加淡入动画效果 + this.elements.quoteText.style.opacity = '0'; + this.elements.quoteIndex.style.opacity = '0'; + + setTimeout(() => { + this.elements.quoteText.style.transition = 'opacity 0.5s ease'; + this.elements.quoteIndex.style.transition = 'opacity 0.5s ease'; + this.elements.quoteText.style.opacity = '1'; + this.elements.quoteIndex.style.opacity = '1'; + }, 100); + + this.showQuoteDisplay(); + + // 控制台输出调试信息 + console.log('一言获取成功:', { + content: data.hitokoto, + index: data.index, + endpoint: this.apiEndpoints[this.currentEndpointIndex] + }); + } + + // 获取随机接口(用于负载均衡) + getRandomEndpoint() { + const randomIndex = Math.floor(Math.random() * this.apiEndpoints.length); + return this.apiEndpoints[randomIndex]; + } +} + +// 页面加载完成后初始化应用 +document.addEventListener('DOMContentLoaded', () => { + const app = new HitokotoApp(); + + // 添加全局错误处理 + window.addEventListener('error', (event) => { + console.error('页面发生错误:', event.error); + }); + + window.addEventListener('unhandledrejection', (event) => { + console.error('未处理的Promise拒绝:', event.reason); + }); + + // 页面可见性变化时的处理 + document.addEventListener('visibilitychange', () => { + if (!document.hidden && !app.isLoading) { + // 页面重新可见时,可以选择刷新内容 + console.log('页面重新可见'); + } + }); + + console.log('随机一言应用初始化完成'); +}); + +// 导出应用类(如果需要在其他地方使用) +if (typeof module !== 'undefined' && module.exports) { + module.exports = HitokotoApp; +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/接口集合.json b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机一言/返回接口.json b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/返回接口.json new file mode 100644 index 00000000..29342ebc --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机一言/返回接口.json @@ -0,0 +1,8 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "index": 2862, + "hitokoto": "你带上罪恶之冠,即使背负上所有罪恶和孤独,绝不让你受伤" + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/css/style.css b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/css/style.css new file mode 100644 index 00000000..c6b6f0d6 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/css/style.css @@ -0,0 +1,251 @@ +/* 随机唱歌音频 - 淡绿色清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 900px; + margin: 0 auto; + padding: 20px; +} + +/* 头部 */ +.header { + text-align: center; + margin-bottom: 20px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 24px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; +} + +.header p { + color: #5a7c65; + font-size: 1rem; +} + +/* 用户卡片 */ +.user-card { + display: flex; + align-items: center; + justify-content: center; + gap: 15px; + background: rgba(255, 255, 255, 0.9); + padding: 16px; + border-radius: 15px; + box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08); + margin-bottom: 15px; + text-align: center; +} + +.avatar { + width: 56px; + height: 56px; + border-radius: 50%; + object-fit: cover; + border: 3px solid rgba(129, 199, 132, 0.5); +} + +.user-info { + display: flex; + flex-direction: column; +} + +.nickname { + font-weight: 700; + font-size: 1.1rem; + color: #2d5016; +} + +.meta { + color: #5a7c65; + font-size: 0.9rem; +} + +/* 歌曲信息 */ +.song-card { + background: rgba(255, 255, 255, 0.9); + padding: 16px; + border-radius: 15px; + box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08); + margin-bottom: 15px; + text-align: center; +} + +.song-title { + font-size: 1.2rem; + font-weight: 700; + margin-bottom: 8px; + color: #1b5e20; +} + +.song-meta { + color: #5a7c65; + font-size: 0.95rem; + margin-bottom: 10px; +} + +/* 歌词 */ +.lyrics { + background: rgba(129, 199, 132, 0.1); + border-radius: 12px; + padding: 12px; + max-height: 220px; + overflow: auto; +} + +.lyrics p { + margin-bottom: 6px; +} + +/* 音频播放器卡片 */ +.audio-card { + background: rgba(255, 255, 255, 0.9); + padding: 16px; + border-radius: 15px; + box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08); + margin-bottom: 15px; +} + +.audio-actions { + display: flex; + flex-direction: column; + gap: 12px; + align-items: center; + margin-top: 10px; +} + +.btn { + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + border: none; + padding: 10px 18px; + border-radius: 10px; + font-size: 0.95rem; + font-weight: 600; + cursor: pointer; + transition: all 0.25s ease; + box-shadow: 0 4px 12px rgba(129, 199, 132, 0.35); + text-decoration: none; +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 18px rgba(129, 199, 132, 0.45); +} + +.info { + color: #5a7c65; + font-size: 0.9rem; +} + +/* 加载与错误 */ +.loading, .error { + text-align: center; + padding: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 36px; + height: 36px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 18px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 动画 */ +.fade-in { + animation: fadeIn 0.5s ease-in-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* 平板端适配 */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { padding: 16px; } + .header h1 { font-size: 1.8rem; } +} + +/* 手机端优先优化 */ +@media (max-width: 767px) { + .container { padding: 12px; } + .header { padding: 18px; } + .header h1 { font-size: 1.6rem; gap: 8px; } + + .user-card { + padding: 16px; + flex-direction: column; + text-align: center; + } + + .avatar { + width: 80px; + height: 80px; + margin-bottom: 8px; + } + + .song-card, .audio-card { + padding: 16px; + } + + .lyrics { + max-height: 180px; + text-align: left; + padding: 16px; + } + + .audio-actions { + flex-direction: column; + gap: 15px; + align-items: center; + } + + .info { + text-align: center; + line-height: 1.8; + } + + .btn { + width: 100%; + max-width: 200px; + text-align: center; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/index.html b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/index.html new file mode 100644 index 00000000..3134b76d --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/index.html @@ -0,0 +1,67 @@ + + + + + + + 随机唱歌音频 - 60s API 集合 + + + + + +
+
+

+ 🎵 随机唱歌音频 +

+

数据来自官方/权威源头,以确保稳定与实时 · 支持本地数据回退

+
+ + +
+
+

正在加载中,请稍候…

+
+ + + + +
+ +
+ 用户头像 + +
+ + +
+
-
+
-
+
+
+ + +
+ +
+ +
+ ❤ 喜欢:- + · ⏱ 时长:--:-- + · 🗓 发布:- + · 🔗 查看原帖 +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/js/script.js b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/js/script.js new file mode 100644 index 00000000..598eb5d6 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/js/script.js @@ -0,0 +1,252 @@ +// 随机唱歌音频 页面脚本 +(function () { + 'use strict'; + + const API = { + endpoints: [], + currentIndex: 0, + params: { + encoding: 'json' + }, + localFallback: '返回接口.json', + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/changya`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/changya']; + } + }, + // 获取当前接口URL + getCurrentUrl() { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v)); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } + }; + + // DOM 元素引用 + const els = { + loading: null, + error: null, + container: null, + avatar: null, + nickname: null, + gender: null, + songTitle: null, + songMeta: null, + lyrics: null, + audio: null, + likeCount: null, + publishTime: null, + link: null, + refreshBtn: null, + }; + + function initDom() { + els.loading = document.getElementById('loading'); + els.error = document.getElementById('error'); + els.container = document.getElementById('content'); + + els.avatar = document.getElementById('avatar'); + els.nickname = document.getElementById('nickname'); + els.gender = document.getElementById('gender'); + els.songTitle = document.getElementById('song-title'); + els.songMeta = document.getElementById('song-meta'); + els.lyrics = document.getElementById('lyrics'); + + els.audio = document.getElementById('audio'); + els.likeCount = document.getElementById('like-count'); + els.publishTime = document.getElementById('publish-time'); + els.link = document.getElementById('link'); + els.refreshBtn = document.getElementById('refresh-btn'); + } + + function showLoading() { + els.loading.style.display = 'block'; + els.error.style.display = 'none'; + els.container.style.display = 'none'; + } + + function showError(msg) { + els.loading.style.display = 'none'; + els.error.style.display = 'block'; + els.container.style.display = 'none'; + els.error.querySelector('p').textContent = msg || '获取数据失败,请稍后重试'; + } + + function showContent() { + els.loading.style.display = 'none'; + els.error.style.display = 'none'; + els.container.style.display = 'block'; + } + + function formatDuration(ms) { + if (!ms && ms !== 0) return ''; + const totalSeconds = Math.floor(ms / 1000); + const m = Math.floor(totalSeconds / 60).toString().padStart(2, '0'); + const s = (totalSeconds % 60).toString().padStart(2, '0'); + return `${m}:${s}`; + } + + function safeText(text) { + const div = document.createElement('div'); + div.textContent = text == null ? '' : String(text); + return div.innerHTML; + } + + async function fetchFromAPI() { + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const resp = await fetch(url, { + cache: 'no-store', + timeout: 10000 // 10秒超时 + }); + + if (!resp.ok) { + throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); + } + + const data = await resp.json(); + + if (data && data.code === 200) { + console.log(`接口 ${i + 1} 请求成功`); + return data; + } + + throw new Error(data && data.message ? data.message : '接口返回异常'); + + } catch (e) { + console.warn(`接口 ${i + 1} 失败:`, e.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了 + console.warn('所有远程接口都失败,尝试本地数据'); + return null; + } + } + } + + async function fetchFromLocal() { + try { + const resp = await fetch(API.localFallback + `?t=${Date.now()}`); + if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`); + const data = await resp.json(); + return data; + } catch (e) { + console.error('读取本地返回接口.json失败:', e); + return null; + } + } + + function render(data) { + const d = data?.data || {}; + const user = d.user || {}; + const song = d.song || {}; + const audio = d.audio || {}; + + // 用户信息 + els.avatar.src = user.avatar_url || ''; + els.avatar.alt = (user.nickname || '用户') + ' 头像'; + els.nickname.textContent = user.nickname || '未知用户'; + els.gender.textContent = user.gender === 'female' ? '女' : user.gender === 'male' ? '男' : '未知'; + + // 歌曲信息 + els.songTitle.textContent = song.name || '未知歌曲'; + els.songMeta.textContent = song.singer ? `演唱:${song.singer}` : ''; + + els.lyrics.innerHTML = ''; + if (Array.isArray(song.lyrics)) { + const frag = document.createDocumentFragment(); + song.lyrics.forEach(line => { + const p = document.createElement('p'); + p.innerHTML = safeText(line); + frag.appendChild(p); + }); + els.lyrics.appendChild(frag); + } + + // 音频 + els.audio.src = audio.url || ''; + els.audio.preload = 'none'; + + // 其他信息 + els.likeCount.textContent = typeof audio.like_count === 'number' ? audio.like_count : '-'; + const publish = audio.publish || (audio.publish_at ? new Date(audio.publish_at).toLocaleString() : ''); + els.publishTime.textContent = publish; + els.link.href = audio.link || '#'; + els.link.target = '_blank'; + + // 时长信息 + const durationEl = document.getElementById('duration'); + durationEl.textContent = formatDuration(audio.duration); + + showContent(); + } + + async function load() { + showLoading(); + try { + // 先尝试远程API + const data = await fetchFromAPI(); + if (data) { + render(data); + return; + } + + // 远程API失败,尝试本地数据 + const localData = await fetchFromLocal(); + if (localData) { + render(localData); + return; + } + + // 都失败了 + showError('获取数据失败,请稍后重试'); + } catch (e) { + console.error('加载数据时发生错误:', e); + showError('获取数据失败,请稍后重试'); + } + } + + function bindEvents() { + if (els.refreshBtn) { + els.refreshBtn.addEventListener('click', load); + } + // 快捷键 Ctrl+R 刷新(不拦截浏览器默认刷新) + } + + document.addEventListener('DOMContentLoaded', () => { + initDom(); + bindEvents(); + load(); + }); +})(); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/接口集合.json b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/返回接口.json b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/返回接口.json new file mode 100644 index 00000000..d364f524 --- /dev/null +++ b/frontend/react-app/public/60sapi/娱乐消遣/随机唱歌音频/返回接口.json @@ -0,0 +1,32 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "user": { + "nickname": "𝑮𝑺_迷鹿_", + "gender": "female", + "avatar_url": "http://img-cdn.api.singduck.cn/user-img/6afbebcfae6144478c150d0c1d0d5899.jpg" + }, + "song": { + "name": "恶作剧", + "singer": "王蓝茵", + "lyrics": [ + "我想我会开始想念你", + "可是我刚刚才遇见了你", + "我怀疑这奇遇只是个恶作剧", + "我想我已慢慢喜欢你", + "因为我拥有爱情的勇气", + "我任性投入你给的恶作剧", + "你给的恶作剧" + ] + }, + "audio": { + "url": "http://audio-cdn.api.singduck.cn/ugc/220929_965696173_b822a290c553.wav?auth_key=1755845643-0-0-4029539b73e17337dcac49cc4e0ecfcc", + "duration": 35050, + "like_count": 955, + "link": "https://m.api.singduck.cn/user-piece/toGZlBfZbukck2sHb", + "publish": "2022/09/29 18:33:51", + "publish_at": 1664447631000 + } + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/css/style.css b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/css/style.css new file mode 100644 index 00000000..30d4f120 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/css/style.css @@ -0,0 +1,330 @@ +/* Epic Games 免费游戏 - 淡绿色清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部 */ +.header { + text-align: center; + margin-bottom: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 24px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2.2rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; +} + +.header p { + color: #5a7c65; + font-size: 1rem; +} + +/* 统计信息 */ +.stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; + margin-bottom: 25px; +} + +.stat-card { + background: rgba(255, 255, 255, 0.9); + padding: 16px; + border-radius: 15px; + text-align: center; + box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08); +} + +.stat-number { + font-size: 1.8rem; + font-weight: 700; + color: #1b5e20; + margin-bottom: 5px; +} + +.stat-label { + color: #5a7c65; + font-size: 0.9rem; +} + +/* 游戏网格 */ +.games-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 20px; + margin-bottom: 20px; +} + +/* 游戏卡片 */ +.game-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 18px; + overflow: hidden; + box-shadow: 0 6px 25px rgba(45, 80, 22, 0.1); + transition: all 0.3s ease; + position: relative; +} + +.game-card:hover { + transform: translateY(-5px); + box-shadow: 0 12px 35px rgba(45, 80, 22, 0.15); +} + +.game-cover { + width: 100%; + height: 180px; + object-fit: cover; + border-radius: 0; +} + +.game-info { + padding: 18px; +} + +.game-title { + font-size: 1.1rem; + font-weight: 700; + color: #1b5e20; + margin-bottom: 8px; + line-height: 1.3; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.game-description { + color: #5a7c65; + font-size: 0.9rem; + margin-bottom: 12px; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + line-height: 1.4; +} + +.game-meta { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.game-price { + font-size: 1rem; + font-weight: 600; +} + +.original-price { + color: #81c784; + text-decoration: line-through; +} + +.free-price { + color: #2e7d32; + font-weight: 700; +} + +.game-seller { + color: #5a7c65; + font-size: 0.85rem; +} + +.game-dates { + background: rgba(129, 199, 132, 0.1); + padding: 10px; + border-radius: 10px; + margin-bottom: 12px; + font-size: 0.85rem; + color: #2d5016; +} + +.free-period { + display: flex; + justify-content: space-between; + margin-bottom: 4px; +} + +.game-actions { + display: flex; + gap: 10px; +} + +.btn { + flex: 1; + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + border: none; + padding: 10px 16px; + border-radius: 10px; + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + transition: all 0.25s ease; + box-shadow: 0 4px 12px rgba(129, 199, 132, 0.35); + text-decoration: none; + text-align: center; + display: inline-block; +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 18px rgba(129, 199, 132, 0.45); +} + +.btn-secondary { + background: linear-gradient(135deg, #a5d6a7 0%, #81c784 100%); +} + +/* 状态标签 */ +.status-badge { + position: absolute; + top: 12px; + right: 12px; + padding: 6px 12px; + border-radius: 20px; + font-size: 0.8rem; + font-weight: 600; + color: white; + text-shadow: 0 1px 2px rgba(0,0,0,0.2); +} + +.status-free { + background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%); +} + +.status-upcoming { + background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%); +} + +/* 加载与错误 */ +.loading, .error { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 动画 */ +.fade-in { + animation: fadeIn 0.6s ease-in-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +/* 平板端适配 */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { padding: 16px; } + .header h1 { font-size: 2rem; } + .games-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); } +} + +/* 手机端优化 */ +@media (max-width: 767px) { + .container { padding: 12px; } + .header { padding: 18px; } + .header h1 { font-size: 1.8rem; gap: 8px; } + + .stats { + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 8px; + } + + .stat-card { + padding: 10px 8px; + flex: 1; + min-width: 0; + } + .stat-number { font-size: 1.4rem; } + .stat-label { font-size: 0.75rem; } + + .games-grid { + grid-template-columns: 1fr; + gap: 16px; + } + + .game-card { margin: 0 4px; } + .game-cover { height: 160px; } + .game-info { padding: 14px; } + + .game-actions { + flex-direction: column; + } + + .btn { + width: 100%; + padding: 12px; + } +} + +/* 小屏手机优化 */ +@media (max-width: 480px) { + .stats { + grid-template-columns: 1fr; + } + + .game-meta { + flex-direction: column; + align-items: flex-start; + gap: 6px; + } +} + +/* 高分辨率显示器优化 */ +@media (min-width: 1400px) { + .games-grid { + grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/index.html b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/index.html new file mode 100644 index 00000000..c29c106f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/index.html @@ -0,0 +1,63 @@ + + + + + + + Epic Games 免费游戏 - 60s API 集合 + + + + + +
+
+

+ 🎮 Epic Games 免费游戏 +

+
+ + +
+
+

正在加载游戏数据,请稍候…

+
+ + + + +
+ +
+
+
0
+
总游戏数
+
+
+
0
+
当前免费
+
+
+
0
+
即将免费
+
+
+ + +
+ +
+ + +
+ +
+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/js/script.js b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/js/script.js new file mode 100644 index 00000000..c9592876 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/js/script.js @@ -0,0 +1,266 @@ +// Epic Games 免费游戏 页面脚本 +(function () { + 'use strict'; + + const API = { + endpoints: [], + currentIndex: 0, + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/epic`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s-api.viki.moe/v2/epic']; + } + }, + // 获取当前接口URL + getCurrentUrl(encoding) { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + if (encoding) url.searchParams.set('encoding', encoding); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } + }; + + // DOM 元素引用 + const els = { + loading: null, + error: null, + container: null, + gamesGrid: null, + totalGames: null, + freeNow: null, + upcoming: null, + refreshBtn: null, + }; + + function initDom() { + els.loading = document.getElementById('loading'); + els.error = document.getElementById('error'); + els.container = document.getElementById('content'); + els.gamesGrid = document.getElementById('games-grid'); + els.totalGames = document.getElementById('total-games'); + els.freeNow = document.getElementById('free-now'); + els.upcoming = document.getElementById('upcoming'); + els.refreshBtn = document.getElementById('refresh-btn'); + } + + function showLoading() { + els.loading.style.display = 'block'; + els.error.style.display = 'none'; + els.container.style.display = 'none'; + } + + function showError(msg) { + els.loading.style.display = 'none'; + els.error.style.display = 'block'; + els.container.style.display = 'none'; + els.error.querySelector('p').textContent = msg || '获取数据失败,请稍后重试'; + } + + function showContent() { + els.loading.style.display = 'none'; + els.error.style.display = 'none'; + els.container.style.display = 'block'; + } + + function safeText(text) { + const div = document.createElement('div'); + div.textContent = text == null ? '' : String(text); + return div.innerHTML; + } + + function formatDate(dateStr) { + if (!dateStr) return ''; + try { + const date = new Date(dateStr); + return date.toLocaleDateString('zh-CN', { + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + } catch (e) { + return dateStr; + } + } + + async function fetchData(preferLocal = false) { + if (preferLocal) { + try { + const res = await fetch('./返回接口.json', { cache: 'no-store' }); + const json = await res.json(); + return json; + } catch (e) { + throw new Error('本地数据加载失败'); + } + } + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const res = await fetch(url, { + cache: 'no-store', + timeout: 10000 // 10秒超时 + }); + + if (!res.ok) { + throw new Error(`HTTP ${res.status}: ${res.statusText}`); + } + + const json = await res.json(); + + if (json && json.code === 200) { + console.log(`接口 ${i + 1} 请求成功`); + return json; + } + + throw new Error(json && json.message ? json.message : '接口返回异常'); + + } catch (e) { + console.warn(`接口 ${i + 1} 失败:`, e.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了,尝试本地数据 + console.warn('所有远程接口都失败,尝试本地数据'); + try { + const res = await fetch('./返回接口.json', { cache: 'no-store' }); + const json = await res.json(); + return json; + } catch (e2) { + throw new Error('所有接口和本地数据都无法访问'); + } + } + } + } + + function createGameCard(game) { + const isFree = game.is_free_now; + const statusClass = isFree ? 'status-free' : 'status-upcoming'; + const statusText = isFree ? '限时免费' : '即将免费'; + + return ` +
+
${statusText}
+ ${safeText(game.title)} 封面 +
+

${safeText(game.title)}

+

${safeText(game.description)}

+ +
+
+ ${safeText(game.original_price_desc)} + 免费 +
+
${safeText(game.seller)}
+
+ +
+
+ 开始:${formatDate(game.free_start)} + 结束:${formatDate(game.free_end)} +
+
+ + +
+
+ `; + } + + function updateStats(games) { + const total = games.length; + const freeNow = games.filter(game => game.is_free_now).length; + const upcoming = total - freeNow; + + els.totalGames.textContent = total; + els.freeNow.textContent = freeNow; + els.upcoming.textContent = upcoming; + } + + function renderGames(games) { + if (!Array.isArray(games) || games.length === 0) { + els.gamesGrid.innerHTML = '
暂无游戏数据
'; + return; + } + + // 按状态排序:免费的在前 + const sortedGames = [...games].sort((a, b) => { + if (a.is_free_now && !b.is_free_now) return -1; + if (!a.is_free_now && b.is_free_now) return 1; + return 0; + }); + + const html = sortedGames.map(game => createGameCard(game)).join(''); + els.gamesGrid.innerHTML = html; + + updateStats(games); + } + + function render(data) { + const games = data?.data || []; + renderGames(games); + showContent(); + } + + async function load() { + showLoading(); + + // 初始化API接口列表 + await API.init(); + + try { + const data = await fetchData(false); + render(data); + } catch (e) { + console.error('数据获取失败:', e); + showError(e.message || '获取数据失败,请稍后重试'); + } + } + + function bindEvents() { + if (els.refreshBtn) { + els.refreshBtn.addEventListener('click', load); + } + + // 快捷键 Ctrl+R 刷新(不拦截浏览器默认刷新) + document.addEventListener('keydown', (e) => { + if (e.ctrlKey && e.key === 'r' && !e.defaultPrevented) { + // 不阻止默认行为,让浏览器正常刷新 + } + }); + } + + document.addEventListener('DOMContentLoaded', () => { + initDom(); + bindEvents(); + load(); + }); +})(); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/接口集合.json b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/返回接口.json b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/返回接口.json new file mode 100644 index 00000000..7804d62a --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/EpicGames免费游戏/返回接口.json @@ -0,0 +1,66 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "id": "9aa227e2ba294bb1a95c95fde892eb31", + "title": "《Totally Reliable Delivery Service》 Standard Edition", + "cover": "https://cdn1.epicgames.com/52b90f9a982a404781b189f6a7903226/offer/EGS_TotallyReliableDeliveryService_WereFiveGames_S1-2560x1440-47e6e9562d62705a75ea7b7096d0b8dc.jpg", + "original_price": 52, + "original_price_desc": "¥52.00", + "description": "穿好护腰护具,发动货车,送货的时间到啦!在一个高度互动的沙盒世界中,与最多三位好友一起随意地完成送货。货物已试投,这就是我们靠谱快递(Totally Reliable Delivery Service)的品质保证!", + "seller": "Infogrames LLC", + "is_free_now": true, + "free_start": "2025/08/14 23:00:00", + "free_start_at": 1755183600000, + "free_end": "2025/08/21 23:00:00", + "free_end_at": 1755788400000, + "link": "https://store.epicgames.com/store/zh-CN/p/totally-reliable-delivery-service/home" + }, + { + "id": "8ea3500dc38e4f429702bf889c172d3d", + "title": "Hidden Folks", + "cover": "https://cdn1.epicgames.com/spt-assets/7bfd56b0586348dcb139945d9e59f988/hidden-folks-1b7hh.png", + "original_price": 47, + "original_price_desc": "¥47.00", + "description": "Search for hidden folks in hand-drawn, interactive, miniature landscapes. Unfurl tent flaps, cut through bushes, slam doors, and poke some crocodiles! Rooooaaaarrrr!!!!!", + "seller": "Adriaan de Jongh", + "is_free_now": true, + "free_start": "2025/08/14 23:00:00", + "free_start_at": 1755183600000, + "free_end": "2025/08/21 23:00:00", + "free_end_at": 1755788400000, + "link": "https://store.epicgames.com/store/zh-CN/p/hidden-folks-239d16" + }, + { + "id": "4cbb6c3704d240f19c3dd5f5cb2b0cb4", + "title": "Kamaeru", + "cover": "https://cdn1.epicgames.com/spt-assets/44313cfbb62b4df5801d0c8d541c2624/kamaeru-40asc.png", + "original_price": 62, + "original_price_desc": "¥62.00", + "description": "Foster a sanctuary for frogs and restore the biodiversity of the wetlands in Kamaeru, a cozy frog collecting game, where you take pictures of frogs, play mini-games and decorate your habitat. Hop right to it!", + "seller": "Armor Games Studios", + "is_free_now": false, + "free_start": "2025/08/21 23:00:00", + "free_start_at": 1755788400000, + "free_end": "2025/08/28 23:00:00", + "free_end_at": 1756393200000, + "link": "https://store.epicgames.com/store/zh-CN/p/kamaeru-0c301e" + }, + { + "id": "0d9a533f0e684cc18620a8f408e8e72c", + "title": "Strange Horticulture", + "cover": "https://cdn1.epicgames.com/spt-assets/15e8e3eba65a4763a815d6eae1d763b2/strange-horticulture-offer-2wghv.png", + "original_price": 45, + "original_price_desc": "¥45.00", + "description": "款神秘学解谜游戏,你将扮演当地植物商店的店主,寻找并识别新的植物,悠闲撸猫,与女巫团体交谈,或加入异教。收集各种强大的植物,用它们来影响故事走向,揭开昂德米尔镇的黑暗谜团。", + "seller": "Iceberg Interactive", + "is_free_now": false, + "free_start": "2025/08/21 23:00:00", + "free_start_at": 1755788400000, + "free_end": "2025/08/28 23:00:00", + "free_end_at": 1756393200000, + "link": "https://store.epicgames.com/store/zh-CN/p/strange-horticulture-360e80" + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/css/background.css b/frontend/react-app/public/60sapi/实用功能/农历信息/css/background.css new file mode 100644 index 00000000..254496c1 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/css/background.css @@ -0,0 +1,89 @@ +/* 玻璃拟态背景相关样式 */ +body { + background: linear-gradient(135deg, + #667eea 0%, + #764ba2 25%, + #f093fb 50%, + #f5576c 75%, + #4facfe 100% + ); + background-size: 400% 400%; + animation: gradientShift 20s ease infinite; + background-attachment: fixed; + min-height: 100vh; + position: relative; +} + +@keyframes gradientShift { + 0% { background-position: 0% 50%; } + 25% { background-position: 100% 50%; } + 50% { background-position: 100% 100%; } + 75% { background-position: 0% 100%; } + 100% { background-position: 0% 50%; } +} + +/* 玻璃拟态装饰层 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 40%), + radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.08) 0%, transparent 40%), + radial-gradient(circle at 40% 60%, rgba(255, 255, 255, 0.06) 0%, transparent 30%), + radial-gradient(circle at 60% 30%, rgba(255, 255, 255, 0.05) 0%, transparent 35%); + pointer-events: none; + z-index: -1; + animation: glassFloat 25s ease-in-out infinite alternate; +} + +/* 毛玻璃气泡效果 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 10% 20%, rgba(255, 255, 255, 0.3) 2px, transparent 2px), + radial-gradient(circle at 30% 40%, rgba(255, 255, 255, 0.25) 3px, transparent 3px), + radial-gradient(circle at 50% 60%, rgba(255, 255, 255, 0.2) 1.5px, transparent 1.5px), + radial-gradient(circle at 70% 80%, rgba(255, 255, 255, 0.3) 2.5px, transparent 2.5px), + radial-gradient(circle at 90% 10%, rgba(255, 255, 255, 0.25) 2px, transparent 2px), + radial-gradient(circle at 20% 90%, rgba(255, 255, 255, 0.2) 1px, transparent 1px); + background-size: 300px 300px, 250px 250px, 400px 400px, 200px 200px, 350px 350px, 150px 150px; + animation: bubbleFloat 30s linear infinite; + pointer-events: none; + z-index: -1; + opacity: 0.7; +} + +@keyframes glassFloat { + 0% { + transform: translateY(0px) rotate(0deg); + opacity: 0.7; + } + 100% { + transform: translateY(-20px) rotate(2deg); + opacity: 0.9; + } +} + +@keyframes bubbleFloat { + 0%, 100% { + transform: translateX(0) translateY(0); + } + 25% { + transform: translateX(-15px) translateY(-10px); + } + 50% { + transform: translateX(10px) translateY(-20px); + } + 75% { + transform: translateX(-5px) translateY(-15px); + } +} diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/css/style.css b/frontend/react-app/public/60sapi/实用功能/农历信息/css/style.css new file mode 100644 index 00000000..1c679c5f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/css/style.css @@ -0,0 +1,1105 @@ +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2c3e50; + overflow-x: hidden; +} + +/* 容器 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + animation: containerFadeIn 1s ease-out; +} + +@keyframes containerFadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 玻璃拟态基础样式 */ +.glass-morphism { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border-radius: 20px; +} + +/* 头部 */ +.header { + text-align: center; + margin-bottom: 40px; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + padding: 40px 30px; + border-radius: 25px; + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.4); + position: relative; + overflow: hidden; +} + +.header::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent, + rgba(255, 255, 255, 0.1), + transparent + ); + animation: headerShimmer 6s ease-in-out infinite; +} + +@keyframes headerShimmer { + 0% { left: -100%; } + 50% { left: 100%; } + 100% { left: 100%; } +} + +.header-icon { + font-size: 4em; + margin-bottom: 15px; + animation: iconFloat 3s ease-in-out infinite; + text-shadow: 0 0 20px rgba(255, 255, 255, 0.5); +} + +@keyframes iconFloat { + 0%, 100% { + transform: translateY(0) scale(1); + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); + } + 50% { + transform: translateY(-10px) scale(1.05); + filter: drop-shadow(0 5px 15px rgba(255, 255, 255, 0.5)); + } +} + +.title { + font-size: 3.2em; + font-weight: 800; + color: rgba(255, 255, 255, 0.95); + margin-bottom: 10px; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + letter-spacing: 2px; + animation: titleGlow 4s ease-in-out infinite alternate; +} + +@keyframes titleGlow { + 0% { + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + color: rgba(255, 255, 255, 0.95); + } + 100% { + text-shadow: 0 0 20px rgba(255, 255, 255, 0.8), 0 2px 10px rgba(0, 0, 0, 0.3); + color: rgba(255, 255, 255, 1); + } +} + +.subtitle { + font-size: 1.3em; + color: rgba(255, 255, 255, 0.8); + margin-bottom: 30px; + font-weight: 500; + text-shadow: 0 1px 5px rgba(0, 0, 0, 0.2); +} + +/* 日期选择器 */ +.date-selector { + display: flex; + align-items: flex-end; + justify-content: center; + gap: 20px; + margin-bottom: 25px; + flex-wrap: wrap; +} + +.input-group { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 200px; +} + +.input-label { + display: flex; + align-items: center; + gap: 8px; + color: rgba(255, 255, 255, 0.9); + font-weight: 600; + font-size: 1em; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +.label-icon { + font-size: 1.2em; +} + +.date-input { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 15px; + padding: 12px 16px; + color: rgba(255, 255, 255, 0.95); + font-size: 1em; + font-weight: 500; + transition: all 0.3s ease; + box-shadow: + 0 4px 15px rgba(31, 38, 135, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.date-input:focus { + outline: none; + border-color: rgba(255, 255, 255, 0.5); + background: rgba(255, 255, 255, 0.15); + box-shadow: + 0 6px 20px rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.3), + 0 0 0 3px rgba(255, 255, 255, 0.1); + transform: translateY(-2px); +} + +.date-input::-webkit-calendar-picker-indicator { + filter: invert(1); + opacity: 0.8; + cursor: pointer; +} + +.query-btn { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(15px); + -webkit-backdrop-filter: blur(15px); + color: rgba(255, 255, 255, 0.95); + border: 1px solid rgba(255, 255, 255, 0.3); + padding: 12px 28px; + border-radius: 20px; + cursor: pointer; + font-size: 1em; + font-weight: 600; + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + display: flex; + align-items: center; + gap: 8px; + position: relative; + overflow: hidden; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: + 0 4px 15px rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.query-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent, + rgba(255, 255, 255, 0.2), + transparent + ); + transition: left 0.6s ease; +} + +.query-btn:hover::before { + left: 100%; +} + +.query-btn:hover { + background: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.4); + transform: translateY(-3px); + box-shadow: + 0 8px 25px rgba(31, 38, 135, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.btn-icon { + font-size: 1.2em; + transition: transform 0.3s ease; +} + +.query-btn:hover .btn-icon { + transform: scale(1.1) rotate(5deg); +} + +.update-time { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + color: rgba(255, 255, 255, 0.8); + font-size: 1em; + padding: 10px 20px; + background: rgba(255, 255, 255, 0.08); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.15); + display: inline-flex; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +.time-icon { + font-size: 1.2em; + animation: clockTick 2s infinite; +} + +@keyframes clockTick { + 0%, 50% { transform: rotate(0deg); } + 25% { transform: rotate(15deg); } + 75% { transform: rotate(-15deg); } +} + +/* 玻璃拟态加载动画 */ +.loading { + text-align: center; + padding: 60px 40px; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + border-radius: 25px; + margin-bottom: 25px; + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.loading-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 25px; +} + +.glass-spinner { + width: 60px; + height: 60px; + border: 4px solid rgba(255, 255, 255, 0.1); + border-top: 4px solid rgba(255, 255, 255, 0.8); + border-radius: 50%; + animation: glassSpinnerRotate 1.5s linear infinite; + position: relative; + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); +} + +.glass-spinner::before { + content: ''; + position: absolute; + top: -4px; + left: -4px; + right: -4px; + bottom: -4px; + border: 2px solid rgba(255, 255, 255, 0.05); + border-top: 2px solid rgba(255, 255, 255, 0.3); + border-radius: 50%; + animation: glassSpinnerRotate 2s linear infinite reverse; +} + +@keyframes glassSpinnerRotate { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading-text { + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; +} + +.loading-emoji { + font-size: 2.5em; + animation: mysticalPulse 2s ease-in-out infinite alternate; + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)); +} + +@keyframes mysticalPulse { + 0% { + transform: scale(1); + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)); + } + 100% { + transform: scale(1.1); + filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.8)); + } +} + +.loading-text p { + font-size: 1.2em; + color: rgba(255, 255, 255, 0.9); + font-weight: 600; + margin: 0; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +.loading-dots { + display: flex; + gap: 8px; +} + +.loading-dots span { + width: 10px; + height: 10px; + background: rgba(255, 255, 255, 0.7); + border-radius: 50%; + animation: glassDotsFloat 1.4s ease-in-out infinite both; + backdrop-filter: blur(2px); + -webkit-backdrop-filter: blur(2px); + box-shadow: 0 2px 8px rgba(255, 255, 255, 0.3); +} + +.loading-dots span:nth-child(1) { animation-delay: -0.32s; } +.loading-dots span:nth-child(2) { animation-delay: -0.16s; } +.loading-dots span:nth-child(3) { animation-delay: 0s; } + +@keyframes glassDotsFloat { + 0%, 80%, 100% { + transform: scale(0.8); + opacity: 0.5; + } + 40% { + transform: scale(1.2); + opacity: 1; + } +} + +/* 农历信息展示 */ +.lunar-info { + display: grid; + gap: 25px; + animation: infoFadeIn 0.8s ease-out; +} + +@keyframes infoFadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.info-card { + background: rgba(255, 255, 255, 0.12); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 20px; + padding: 30px; + position: relative; + overflow: hidden; + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.info-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 3px; + background: linear-gradient(90deg, + rgba(255, 255, 255, 0.3), + rgba(255, 255, 255, 0.6), + rgba(255, 255, 255, 0.3) + ); + transform: scaleX(0); + transition: transform 0.4s ease; +} + +.info-card:hover::before { + transform: scaleX(1); +} + +.info-card:hover { + transform: translateY(-5px); + background: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.3); + box-shadow: + 0 12px 40px 0 rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.card-header { + display: flex; + align-items: center; + gap: 15px; + margin-bottom: 20px; +} + +.card-icon { + font-size: 2.5em; + animation: cardIconFloat 3s ease-in-out infinite; +} + +@keyframes cardIconFloat { + 0%, 100% { transform: translateY(0) rotate(0deg); } + 50% { transform: translateY(-5px) rotate(5deg); } +} + +.card-title { + font-size: 1.5em; + font-weight: 700; + color: rgba(255, 255, 255, 0.95); + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +.card-content { + display: grid; + gap: 15px; +} + +.info-item { + display: flex; + align-items: center; + gap: 12px; + padding: 15px; + background: rgba(255, 255, 255, 0.08); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-radius: 15px; + border: 1px solid rgba(255, 255, 255, 0.15); + transition: all 0.3s ease; +} + +.info-item:hover { + background: rgba(255, 255, 255, 0.12); + transform: scale(1.02); +} + +.item-icon { + font-size: 1.3em; + min-width: 30px; + text-align: center; +} + +.item-label { + font-weight: 600; + color: rgba(255, 255, 255, 0.9); + min-width: 80px; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +.item-value { + font-weight: 700; + color: rgba(255, 255, 255, 0.95); + font-size: 1.1em; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +/* 错误信息 */ +.error-message { + text-align: center; + padding: 60px 40px; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + border-radius: 25px; + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.error-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 25px; +} + +.error-icon { + font-size: 4em; + animation: errorFloat 2s ease-in-out infinite alternate; + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); +} + +@keyframes errorFloat { + 0% { transform: translateY(0) rotate(-5deg); } + 100% { transform: translateY(-10px) rotate(5deg); } +} + +.error-content h3 { + font-size: 1.6em; + color: rgba(255, 255, 255, 0.95); + margin: 0; + font-weight: 700; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +.error-content p { + color: rgba(255, 255, 255, 0.8); + font-size: 1.1em; + margin: 0; + line-height: 1.6; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +.retry-btn { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(15px); + -webkit-backdrop-filter: blur(15px); + color: rgba(255, 255, 255, 0.95); + border: 1px solid rgba(255, 255, 255, 0.3); + padding: 12px 25px; + border-radius: 20px; + cursor: pointer; + font-size: 1em; + font-weight: 600; + transition: all 0.4s ease; + display: inline-flex; + align-items: center; + gap: 8px; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: + 0 4px 15px rgba(31, 38, 135, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.retry-btn:hover { + background: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.4); + transform: translateY(-2px); + box-shadow: + 0 6px 20px rgba(31, 38, 135, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.retry-btn span { + font-size: 1.1em; + transition: transform 0.3s ease; +} + +.retry-btn:hover span { + transform: rotate(180deg); +} + +/* 功能提示 */ +.feature-tips { + margin-top: 40px; +} + +.tip-card { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 20px; + padding: 30px; + text-align: center; + box-shadow: + 0 8px 32px 0 rgba(31, 38, 135, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.tip-icon { + font-size: 3em; + margin-bottom: 15px; + animation: tipBlink 3s ease-in-out infinite; +} + +@keyframes tipBlink { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.7; transform: scale(1.05); } +} + +.tip-card h3 { + font-size: 1.4em; + font-weight: 700; + color: rgba(255, 255, 255, 0.95); + margin-bottom: 20px; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); +} + +.tip-card ul { + list-style: none; + display: grid; + gap: 12px; + text-align: left; +} + +.tip-card li { + color: rgba(255, 255, 255, 0.9); + font-size: 1em; + padding: 10px 15px; + background: rgba(255, 255, 255, 0.08); + backdrop-filter: blur(5px); + -webkit-backdrop-filter: blur(5px); + border-radius: 10px; + border: 1px solid rgba(255, 255, 255, 0.15); + transition: all 0.3s ease; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +.tip-card li:hover { + background: rgba(255, 255, 255, 0.12); + transform: translateX(5px); +} + +/* 平板端适配 (768px - 1024px) */ +@media (min-width: 768px) and (max-width: 1024px) { + .container { + padding: 25px; + } + + .header { + padding: 35px 25px; + } + + .header-icon { + font-size: 3.5em; + } + + .title { + font-size: 2.8em; + letter-spacing: 1.5px; + } + + .subtitle { + font-size: 1.2em; + } + + .date-selector { + gap: 15px; + } + + .input-group { + min-width: 180px; + } + + .lunar-info { + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); + gap: 20px; + } + + .info-card { + padding: 25px; + } +} + +/* 电脑端适配 (1025px+) */ +@media (min-width: 1025px) { + .container { + padding: 40px; + } + + .header { + padding: 50px 40px; + margin-bottom: 50px; + } + + .header-icon { + font-size: 4.5em; + } + + .title { + font-size: 3.8em; + letter-spacing: 3px; + } + + .subtitle { + font-size: 1.4em; + } + + .date-selector { + gap: 25px; + } + + .input-group { + min-width: 220px; + } + + .date-input { + padding: 14px 18px; + font-size: 1.05em; + } + + .query-btn { + padding: 14px 32px; + font-size: 1.05em; + } + + .lunar-info { + grid-template-columns: repeat(auto-fit, minmax(500px, 1fr)); + gap: 30px; + } + + .info-card { + padding: 35px; + } + + .card-title { + font-size: 1.6em; + } + + .item-label { + min-width: 100px; + } + + .item-value { + font-size: 1.15em; + } + + /* 电脑端特殊效果 */ + .info-card:hover { + transform: translateY(-8px) scale(1.02); + } +} + +/* 手机端适配 (767px以下) */ +@media (max-width: 767px) { + .container { + padding: 15px; + } + + .header { + padding: 25px 20px; + margin-bottom: 25px; + } + + .header-icon { + font-size: 2.8em; + } + + .title { + font-size: 2.2em; + letter-spacing: 1px; + } + + .subtitle { + font-size: 1em; + } + + .date-selector { + flex-direction: column; + gap: 15px; + align-items: center; + } + + .input-group { + width: 100%; + max-width: 300px; + min-width: auto; + } + + .date-input { + padding: 10px 14px; + font-size: 0.95em; + } + + .query-btn { + padding: 10px 24px; + font-size: 0.95em; + width: 100%; + max-width: 200px; + justify-content: center; + } + + .update-time { + font-size: 0.9em; + padding: 8px 16px; + } + + .info-card { + padding: 20px; + border-radius: 15px; + } + + .card-header { + gap: 12px; + margin-bottom: 15px; + } + + .card-icon { + font-size: 2em; + } + + .card-title { + font-size: 1.3em; + } + + .info-item { + padding: 12px; + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + + .item-icon { + font-size: 1.2em; + } + + .item-label { + min-width: auto; + font-size: 0.9em; + } + + .item-value { + font-size: 1em; + } + + .tip-card { + padding: 20px; + } + + .tip-card ul { + gap: 10px; + } + + .tip-card li { + padding: 8px 12px; + font-size: 0.9em; + } +} + +/* 超小屏幕适配 (480px以下) */ +@media (max-width: 480px) { + .container { + padding: 12px; + } + + .header { + padding: 20px 15px; + margin-bottom: 20px; + } + + .header-icon { + font-size: 2.5em; + } + + .title { + font-size: 1.9em; + letter-spacing: 0.5px; + } + + .subtitle { + font-size: 0.95em; + } + + .date-selector { + gap: 12px; + } + + .input-group { + max-width: 280px; + } + + .date-input { + padding: 8px 12px; + font-size: 0.9em; + } + + .query-btn { + padding: 8px 20px; + font-size: 0.9em; + max-width: 180px; + } + + .update-time { + font-size: 0.85em; + padding: 6px 12px; + flex-direction: column; + gap: 4px; + } + + .lunar-info { + gap: 15px; + } + + .info-card { + padding: 18px 15px; + border-radius: 12px; + } + + .card-header { + gap: 10px; + margin-bottom: 12px; + } + + .card-icon { + font-size: 1.8em; + } + + .card-title { + font-size: 1.2em; + } + + .info-item { + padding: 10px; + gap: 6px; + } + + .item-icon { + font-size: 1.1em; + } + + .item-label { + font-size: 0.85em; + } + + .item-value { + font-size: 0.95em; + } + + .tip-card { + padding: 15px; + } + + .tip-icon { + font-size: 2.5em; + } + + .tip-card h3 { + font-size: 1.2em; + } + + .tip-card li { + padding: 6px 10px; + font-size: 0.85em; + } + + /* 超小屏幕性能优化 */ + .info-card { + transition: transform 0.2s ease, background 0.2s ease; + } + + .info-card::before { + display: none; + } + + .loading-content { + gap: 15px; + } + + .loading-emoji { + font-size: 2em; + } + + .error-icon { + font-size: 3em; + } +} + +/* 时辰宜忌特殊样式 */ +.hours-card { + grid-column: 1 / -1; /* 占满整行 */ +} + +.hours-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; + margin-top: 15px; +} + +.hour-item { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 12px; + padding: 12px; + transition: all 0.3s ease; +} + +.hour-item:hover { + background: rgba(255, 255, 255, 0.15); + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); +} + +.hour-name { + font-size: 14px; + font-weight: 600; + color: #ffffff; + text-align: center; + margin-bottom: 8px; + padding: 4px 8px; + background: rgba(255, 255, 255, 0.1); + border-radius: 6px; +} + +.hour-content { + font-size: 12px; + line-height: 1.4; +} + +.hour-recommends, +.hour-avoids { + margin: 4px 0; +} + +.hour-label { + font-weight: 600; + color: #ffffff; + margin-right: 4px; +} + +.hour-recommends .hour-label { + color: #4ade80; +} + +.hour-avoids .hour-label { + color: #f87171; +} + +.hour-text { + color: rgba(255, 255, 255, 0.9); +} + +/* 时辰宜忌响应式优化 */ +@media (max-width: 768px) { + .hours-grid { + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 10px; + } + + .hour-item { + padding: 8px; + } + + .hour-name { + font-size: 12px; + margin-bottom: 6px; + } + + .hour-content { + font-size: 11px; + } +} diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/index.html b/frontend/react-app/public/60sapi/实用功能/农历信息/index.html new file mode 100644 index 00000000..0e8aace3 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/index.html @@ -0,0 +1,71 @@ + + + + + + 🌙 农历信息查询 + + + + +
+
+
🏮
+

🌙 农历信息查询 📅

+

传统文化 · 时光转换 · 节气查询

+ +
+
+ + +
+ +
+ +
+ + 等待查询... +
+
+ + + + + + + + + + + diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/js/script.js b/frontend/react-app/public/60sapi/实用功能/农历信息/js/script.js new file mode 100644 index 00000000..a2fb42cc --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/js/script.js @@ -0,0 +1,485 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const loadingElement = document.getElementById('loading'); +const lunarInfoElement = document.getElementById('lunarInfo'); +const errorMessageElement = document.getElementById('errorMessage'); +const updateTimeElement = document.getElementById('updateTime'); +const dateInput = document.getElementById('dateInput'); +const queryBtn = document.getElementById('queryBtn'); + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', function() { + initializePage(); +}); + +// 初始化页面 +function initializePage() { + // 设置默认日期为今天 + const today = new Date(); + const dateString = today.toISOString().split('T')[0]; + dateInput.value = dateString; + + // 绑定事件 + queryBtn.addEventListener('click', queryLunarInfo); + dateInput.addEventListener('change', queryLunarInfo); + + // 自动查询当天信息 + queryLunarInfo(); +} + +// 查询农历信息 +async function queryLunarInfo() { + const selectedDate = dateInput.value; + if (!selectedDate) { + showError('请选择查询日期'); + return; + } + + showLoading(); + hideError(); + hideLunarInfo(); + + try { + const data = await fetchLunarData(selectedDate); + displayLunarInfo(data.data); + updateQueryTime(); + } catch (error) { + console.error('查询失败:', error); + showError('查询农历信息失败,请稍后重试'); + } + + hideLoading(); +} + +// 获取农历数据 +async function fetchLunarData(date) { + for (let i = 0; i < API_ENDPOINTS.length; i++) { + const apiUrl = API_ENDPOINTS[currentApiIndex]; + + try { + const response = await fetch(`${apiUrl}/v2/lunar?date=${date}`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + timeout: 10000 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + return data; + } else { + throw new Error('数据格式错误'); + } + } catch (error) { + console.error(`API ${apiUrl} 请求失败:`, error); + currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (i === API_ENDPOINTS.length - 1) { + throw new Error('所有API接口都无法访问'); + } + } + } +} + +// 显示农历信息 +function displayLunarInfo(lunarData) { + lunarInfoElement.innerHTML = ` +
+
+
📅
+
公历信息
+
+
+
+
🗓️
+
公历日期
+
${lunarData.solar.year}年${String(lunarData.solar.month).padStart(2, '0')}月${String(lunarData.solar.day).padStart(2, '0')}日
+
+
+
🌍
+
星期
+
${lunarData.solar.week_desc}
+
+
+
+
季节
+
${lunarData.solar.season_name_desc}
+
+
+
+
星座
+
${lunarData.constellation.name}
+
+
+
+ +
+
+
🌙
+
农历信息
+
+
+
+
🏮
+
农历日期
+
${lunarData.lunar.desc_short}
+
+
+
🐲
+
生肖年
+
${lunarData.zodiac.year}年
+
+
+
+
天干地支
+
${lunarData.sixty_cycle.year.name}
+
+
+
🌙
+
月相
+
${lunarData.phase.name}
+
+
+
+ +
+
+
🌸
+
节气节日
+
+
+
+
🍃
+
当前节气
+
${lunarData.term.stage ? lunarData.term.stage.name : '无节气'}
+
+
+
🎊
+
法定假日
+
${lunarData.legal_holiday ? lunarData.legal_holiday.name : '无假日'}
+
+
+
+
传统节日
+
${lunarData.festival.both_desc || '无特殊节日'}
+
+
+
🔢
+
一年第几天
+
第${lunarData.stats.day_of_year}天
+
+
+
+ +
+
+
+
时辰干支
+
+
+
+
🕐
+
当前时辰
+
${lunarData.lunar.hour_desc}
+
+
+
+
时辰干支
+
${lunarData.sixty_cycle.hour.name}
+
+
+
🐓
+
时辰生肖
+
${lunarData.zodiac.hour}
+
+
+
🎵
+
纳音
+
${lunarData.nayin.hour}
+
+
+
+ +
+
+
🔮
+
黄历宜忌
+
+
+
+
+
+
${formatTabooText(lunarData.taboo.day.recommends)}
+
+
+
+
+
${formatTabooText(lunarData.taboo.day.avoids)}
+
+
+
🕐
+
时辰宜
+
${formatTabooText(lunarData.taboo.hour.recommends)}
+
+
+
🚫
+
时辰忌
+
${formatTabooText(lunarData.taboo.hour.avoids)}
+
+
+
+ +
+
+
🌟
+
运势财运
+
+
+
+
🎯
+
今日运势
+
${lunarData.fortune.today_luck}
+
+
+
💼
+
事业运
+
${lunarData.fortune.career}
+
+
+
💰
+
财运
+
${lunarData.fortune.money}
+
+
+
💕
+
感情运
+
${lunarData.fortune.love}
+
+
+
+ +
+
+
📊
+
年度统计
+
+
+
+
📈
+
年度进度
+
${lunarData.stats.percents_formatted.year}
+
+
+
📅
+
本月进度
+
${lunarData.stats.percents_formatted.month}
+
+
+
🗓️
+
本周第几天
+
第${lunarData.stats.week_of_month}周
+
+
+
+
今日进度
+
${lunarData.stats.percents_formatted.day}
+
+
+
+ + ${generateHourlyTaboo(lunarData.taboo.hours)} + `; + + showLunarInfo(); +} + +// 格式化宜忌文本 +function formatTabooText(text) { + if (!text) return '无'; + return text.replace(/\./g, '、'); +} + +// 生成十二时辰宜忌 +function generateHourlyTaboo(hours) { + if (!hours || hours.length === 0) return ''; + + const hourCards = hours.map(hour => ` +
+
${hour.hour}
+
+
+ 宜: + ${formatTabooText(hour.recommends) || '无'} +
+
+ 忌: + ${formatTabooText(hour.avoids) || '无'} +
+
+
+ `).join(''); + + return ` +
+
+
+
十二时辰宜忌
+
+
+
+ ${hourCards} +
+
+
+ `; +} + +// 更新查询时间 +function updateQueryTime() { + const now = new Date(); + const timeStr = now.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + updateTimeElement.textContent = `查询时间: ${timeStr}`; + + // 添加成功提示 + showSuccessMessage('🌙 农历信息已更新'); +} + +// 显示成功消息 +function showSuccessMessage(message) { + // 移除之前的提示 + const existingToast = document.querySelector('.success-toast'); + if (existingToast) { + existingToast.remove(); + } + + const toast = document.createElement('div'); + toast.className = 'success-toast'; + toast.textContent = message; + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(15px); + -webkit-backdrop-filter: blur(15px); + color: rgba(255, 255, 255, 0.95); + padding: 12px 20px; + border-radius: 25px; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2); + z-index: 1000; + font-weight: 600; + font-size: 0.9em; + animation: glassToastSlide 0.5s ease-out; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + `; + + document.body.appendChild(toast); + + // 3秒后自动移除 + setTimeout(() => { + toast.style.animation = 'glassToastSlideOut 0.5s ease-in forwards'; + setTimeout(() => toast.remove(), 500); + }, 3000); +} + +// 显示加载状态 +function showLoading() { + loadingElement.style.display = 'block'; +} + +// 隐藏加载状态 +function hideLoading() { + loadingElement.style.display = 'none'; +} + +// 显示农历信息 +function showLunarInfo() { + lunarInfoElement.style.display = 'block'; +} + +// 隐藏农历信息 +function hideLunarInfo() { + lunarInfoElement.style.display = 'none'; +} + +// 显示错误信息 +function showError(message = '查询失败,请稍后重试') { + errorMessageElement.style.display = 'block'; + const errorContent = errorMessageElement.querySelector('.error-content p'); + if (errorContent) { + errorContent.textContent = message; + } +} + +// 隐藏错误信息 +function hideError() { + errorMessageElement.style.display = 'none'; +} + +// 添加CSS动画到页面 +if (!document.querySelector('#toast-styles')) { + const style = document.createElement('style'); + style.id = 'toast-styles'; + style.textContent = ` + @keyframes glassToastSlide { + from { + opacity: 0; + transform: translateX(100px) scale(0.8); + } + to { + opacity: 1; + transform: translateX(0) scale(1); + } + } + + @keyframes glassToastSlideOut { + from { + opacity: 1; + transform: translateX(0) scale(1); + } + to { + opacity: 0; + transform: translateX(100px) scale(0.8); + } + } + `; + document.head.appendChild(style); +} + +// 键盘快捷键支持 +document.addEventListener('keydown', function(e) { + if (e.key === 'Enter') { + e.preventDefault(); + queryLunarInfo(); + } + + if (e.key === 'r' && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + queryLunarInfo(); + } +}); diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/接口集合.json b/frontend/react-app/public/60sapi/实用功能/农历信息/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/实用功能/农历信息/返回接口.json b/frontend/react-app/public/60sapi/实用功能/农历信息/返回接口.json new file mode 100644 index 00000000..910981d4 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/农历信息/返回接口.json @@ -0,0 +1,647 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "solar": { + "year": 2025, + "month": 9, + "day": 1, + "hour": 17, + "minute": 58, + "second": 47, + "full": "2025-09-01", + "full_with_time": "2025-09-01 17:58:47", + "week": 1, + "week_desc": "星期一", + "week_desc_short": "一", + "season": 3, + "season_desc": "三季度", + "season_desc_short": "三", + "season_name": "秋", + "season_name_desc": "秋天", + "is_leap_year": false + }, + "lunar": { + "year": "乙巳", + "month": "七", + "day": "初十", + "hour": "酉", + "full_with_hour": "农历乙巳年七月初十酉时", + "desc_short": "农历乙巳年七月初十", + "year_desc": "农历乙巳年", + "month_desc": "七月", + "day_desc": "初十", + "hour_desc": "酉时", + "is_leap_month": false + }, + "stats": { + "day_of_year": 244, + "week_of_year": 36, + "week_of_month": 1, + "percents": { + "year": 0.665753424657534, + "month": 0.0333333333333333, + "week": 0.142857142857143, + "day": 0.749161909722222 + }, + "percents_formatted": { + "year": "66.58%", + "month": "3.33%", + "week": "14.29%", + "day": "74.92%" + } + }, + "term": { + "today": null, + "stage": { + "name": "处暑", + "position": 10, + "is_jie": false, + "is_qi": true + } + }, + "zodiac": { + "year": "蛇", + "month": "鸡", + "day": "鸡", + "hour": "鸡" + }, + "sixty_cycle": { + "year": { + "heaven_stem": "乙", + "earth_branch": "巳", + "name": "乙巳年", + "name_short": "乙巳" + }, + "month": { + "heaven_stem": "乙", + "earth_branch": "酉", + "name": "乙酉月", + "name_short": "乙酉" + }, + "day": { + "heaven_stem": "癸", + "earth_branch": "酉", + "name": "癸酉日", + "name_short": "癸酉" + }, + "hour": { + "heaven_stem": "辛", + "earth_branch": "酉", + "name": "辛酉时", + "name_short": "辛酉" + } + }, + "legal_holiday": null, + "festival": { + "solar": null, + "lunar": null, + "both_desc": null + }, + "phase": { + "name": "宵月", + "position": 10 + }, + "constellation": { + "name": "处女座", + "name_short": "处女" + }, + "taboo": { + "day": { + "recommends": "解除.祭祀.祈福.求嗣.修造.动土.竖柱.上梁.安床.纳畜.盖屋.合脊.起基.入殓.破土.安葬", + "avoids": "出火.嫁娶.开光.进人口.出行.词讼.开市.入宅.移徙.赴任" + }, + "hour": { + "hour": "酉时", + "hour_short": "酉", + "avoids": "乘船.造桥", + "recommends": "嫁娶.出行.移徙.入宅.开市.赴任.祈福.安床.开仓.盖屋.修造.求财" + }, + "hours": [ + { + "hour": "酉时", + "hour_short": "酉", + "recommends": "嫁娶.出行.移徙.入宅.开市.赴任.祈福.安床.开仓.盖屋.修造.求财", + "avoids": "乘船.造桥" + }, + { + "hour": "戌时", + "hour_short": "戌", + "recommends": "嫁娶.移徙.安葬.进人口.求财", + "avoids": "出行.赴任.祈福.祭祀.开光.斋醮" + }, + { + "hour": "亥时", + "hour_short": "亥", + "recommends": "嫁娶.移徙.交易.入宅.开市.安葬.求嗣.求财", + "avoids": "出行.赴任.动土.祈福.祭祀.修造.开光.斋醮" + }, + { + "hour": "子时", + "hour_short": "子", + "recommends": "嫁娶.交易.入宅.开市.祈福.安葬.求嗣.求财", + "avoids": "出行.移徙.赴任.词讼.修造" + }, + { + "hour": "丑时", + "hour_short": "丑", + "recommends": "嫁娶.祈福.安葬.祭祀.酬神.求财", + "avoids": "出行.赴任.动土.修造" + }, + { + "hour": "寅时", + "hour_short": "寅", + "recommends": "嫁娶.出行.交易.开市.赴任.祈福.安床.祭祀.求嗣.求财", + "avoids": "盖屋.入殓.上梁" + }, + { + "hour": "卯时", + "hour_short": "卯", + "recommends": "嫁娶.交易.入宅.开市.祈福.安床.安葬.求嗣.求财", + "avoids": "出行.赴任.修造" + }, + { + "hour": "辰时", + "hour_short": "辰", + "recommends": "", + "avoids": "诸事不宜" + }, + { + "hour": "巳时", + "hour_short": "巳", + "recommends": "嫁娶.出行.移徙.入宅.开市.祈福.安床.盖屋.祭祀.作灶", + "avoids": "安葬.修造.开光" + }, + { + "hour": "午时", + "hour_short": "午", + "recommends": "嫁娶.出行.交易.开市.祈福.安床.求嗣.求财", + "avoids": "赴任.动土.词讼.修造" + }, + { + "hour": "未时", + "hour_short": "未", + "recommends": "嫁娶.入宅.祈福.安葬.祭祀.修造.酬神.求财", + "avoids": "出行.赴任" + }, + { + "hour": "申时", + "hour_short": "申", + "recommends": "嫁娶.出行.开市.赴任.安葬.求财", + "avoids": "祈福.祭祀.酬神.斋醮" + } + ] + }, + "julian_day": 2460919.5, + "nayin": { + "year": "覆灯火", + "month": "泉中水", + "day": "剑锋金", + "hour": "石榴木" + }, + "baizi": { + "year_baizi": "性格温和,为人正直诚信。", + "day_baizi": "性格温和,为人正直诚信。" + }, + "fortune": { + "today_luck": "今日学习运好,适合进修", + "career": "领导能力突出,升职有望", + "money": "偏财运不错,可小试投资", + "love": "感情需要沟通,避免误会" + }, + "constants": { + "legal_holiday_list": [ + { + "name": "元旦节", + "date": "2025-01-01", + "start": "2025-01-01", + "end": "2025-01-01" + }, + { + "name": "春节", + "date": "2025-01-29", + "start": "2025-01-26", + "end": "2025-02-08" + }, + { + "name": "清明节", + "date": "2025-04-04", + "start": "2025-04-04", + "end": "2025-04-06" + }, + { + "name": "劳动节", + "date": "2025-05-01", + "start": "2025-04-27", + "end": "2025-05-05" + }, + { + "name": "端午节", + "date": "2025-05-31", + "start": "2025-05-31", + "end": "2025-06-02" + }, + { + "name": "国庆中秋", + "date": "2025-10-01", + "start": "2025-09-28", + "end": "2025-10-11" + } + ], + "phase_list": [ + { + "name": "朔月", + "lunar_day": 1 + }, + { + "name": "既朔月", + "lunar_day": 2 + }, + { + "name": "蛾眉新月", + "lunar_day": 3 + }, + { + "name": "蛾眉新月", + "lunar_day": 4 + }, + { + "name": "蛾眉月", + "lunar_day": 5 + }, + { + "name": "夕月", + "lunar_day": 6 + }, + { + "name": "上弦月", + "lunar_day": 7 + }, + { + "name": "上弦月", + "lunar_day": 8 + }, + { + "name": "九夜月", + "lunar_day": 9 + }, + { + "name": "宵月", + "lunar_day": 10 + }, + { + "name": "宵月", + "lunar_day": 11 + }, + { + "name": "宵月", + "lunar_day": 12 + }, + { + "name": "渐盈凸月", + "lunar_day": 13 + }, + { + "name": "小望月", + "lunar_day": 14 + }, + { + "name": "望月", + "lunar_day": 15 + }, + { + "name": "既望月", + "lunar_day": 16 + }, + { + "name": "立待月", + "lunar_day": 17 + }, + { + "name": "居待月", + "lunar_day": 18 + }, + { + "name": "寝待月", + "lunar_day": 19 + }, + { + "name": "更待月", + "lunar_day": 20 + }, + { + "name": "渐亏凸月", + "lunar_day": 21 + }, + { + "name": "下弦月", + "lunar_day": 22 + }, + { + "name": "下弦月", + "lunar_day": 23 + }, + { + "name": "有明月", + "lunar_day": 24 + }, + { + "name": "有明月", + "lunar_day": 25 + }, + { + "name": "蛾眉残月", + "lunar_day": 26 + }, + { + "name": "蛾眉残月", + "lunar_day": 27 + }, + { + "name": "残月", + "lunar_day": 28 + }, + { + "name": "晓月", + "lunar_day": 29 + }, + { + "name": "晦月", + "lunar_day": 30 + } + ], + "zodiac_list": [ + "鼠", + "牛", + "虎", + "兔", + "龙", + "蛇", + "马", + "羊", + "猴", + "鸡", + "狗", + "猪" + ], + "constellation_list": [ + { + "name": "白羊", + "desc": "白羊座", + "start": "3月21日", + "end": "4月19日", + "range": "3月21日~4月19日", + "start_month": 3, + "start_day": 21, + "end_month": 4, + "end_day": 19 + }, + { + "name": "金牛", + "desc": "金牛座", + "start": "4月20日", + "end": "5月20日", + "range": "4月20日~5月20日", + "start_month": 4, + "start_day": 20, + "end_month": 5, + "end_day": 20 + }, + { + "name": "双子", + "desc": "双子座", + "start": "5月21日", + "end": "6月21日", + "range": "5月21日~6月21日", + "start_month": 5, + "start_day": 21, + "end_month": 6, + "end_day": 21 + }, + { + "name": "巨蟹", + "desc": "巨蟹座", + "start": "6月22日", + "end": "7月22日", + "range": "6月22日~7月22日", + "start_month": 6, + "start_day": 22, + "end_month": 7, + "end_day": 22 + }, + { + "name": "狮子", + "desc": "狮子座", + "start": "7月23日", + "end": "8月22日", + "range": "7月23日~8月22日", + "start_month": 7, + "start_day": 23, + "end_month": 8, + "end_day": 22 + }, + { + "name": "处女", + "desc": "处女座", + "start": "8月23日", + "end": "9月22日", + "range": "8月23日~9月22日", + "start_month": 8, + "start_day": 23, + "end_month": 9, + "end_day": 22 + }, + { + "name": "天秤", + "desc": "天秤座", + "start": "9月23日", + "end": "10月23日", + "range": "9月23日~10月23日", + "start_month": 9, + "start_day": 23, + "end_month": 10, + "end_day": 23 + }, + { + "name": "天蝎", + "desc": "天蝎座", + "start": "10月24日", + "end": "11月22日", + "range": "10月24日~11月22日", + "start_month": 10, + "start_day": 24, + "end_month": 11, + "end_day": 22 + }, + { + "name": "射手", + "desc": "射手座", + "start": "11月23日", + "end": "12月21日", + "range": "11月23日~12月21日", + "start_month": 11, + "start_day": 23, + "end_month": 12, + "end_day": 21 + }, + { + "name": "摩羯", + "desc": "摩羯座", + "start": "12月22日", + "end": "1月19日", + "range": "12月22日~1月19日", + "start_month": 12, + "start_day": 22, + "end_month": 1, + "end_day": 19 + }, + { + "name": "水瓶", + "desc": "水瓶座", + "start": "1月20日", + "end": "2月18日", + "range": "1月20日~2月18日", + "start_month": 1, + "start_day": 20, + "end_month": 2, + "end_day": 18 + }, + { + "name": "双鱼", + "desc": "双鱼座", + "start": "2月19日", + "end": "3月20日", + "range": "2月19日~3月20日", + "start_month": 2, + "start_day": 19, + "end_month": 3, + "end_day": 20 + } + ], + "heaven_stems": [ + "甲", + "乙", + "丙", + "丁", + "戊", + "己", + "庚", + "辛", + "壬", + "癸" + ], + "earth_branches": [ + "子", + "丑", + "寅", + "卯", + "辰", + "巳", + "午", + "未", + "申", + "酉", + "戌", + "亥" + ], + "solar_terms": [ + { + "name": "立春", + "desc": "春季开始" + }, + { + "name": "雨水", + "desc": "降雨增多" + }, + { + "name": "惊蛰", + "desc": "春雷乍响" + }, + { + "name": "春分", + "desc": "昼夜等长" + }, + { + "name": "清明", + "desc": "天清地明" + }, + { + "name": "谷雨", + "desc": "雨生百谷" + }, + { + "name": "立夏", + "desc": "夏季开始" + }, + { + "name": "小满", + "desc": "麦粒渐满" + }, + { + "name": "芒种", + "desc": "麦类收割" + }, + { + "name": "夏至", + "desc": "白昼最长" + }, + { + "name": "小暑", + "desc": "天气渐热" + }, + { + "name": "大暑", + "desc": "一年最热" + }, + { + "name": "立秋", + "desc": "秋季开始" + }, + { + "name": "处暑", + "desc": "暑热结束" + }, + { + "name": "白露", + "desc": "露水增多" + }, + { + "name": "秋分", + "desc": "昼夜等长" + }, + { + "name": "寒露", + "desc": "露水渐凉" + }, + { + "name": "霜降", + "desc": "开始降霜" + }, + { + "name": "立冬", + "desc": "冬季开始" + }, + { + "name": "小雪", + "desc": "开始降雪" + }, + { + "name": "大雪", + "desc": "降雪增多" + }, + { + "name": "冬至", + "desc": "白昼最短" + }, + { + "name": "小寒", + "desc": "天气渐冷" + }, + { + "name": "大寒", + "desc": "一年最冷" + } + ] + } + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/css/background.css b/frontend/react-app/public/60sapi/实用功能/实时天气/css/background.css new file mode 100644 index 00000000..a9872b38 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/css/background.css @@ -0,0 +1,145 @@ +/* 背景样式文件 */ +body { + background: linear-gradient(135deg, #e8f5e8 0%, #d4f1d4 25%, #c8ecc8 50%, #b8e6b8 75%, #a8d5ba 100%); + background-attachment: fixed; + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; + position: relative; + overflow-x: hidden; +} + +/* 背景渐变动画 */ +@keyframes gradientShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 背景装饰元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 80%, rgba(168, 213, 186, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(107, 183, 123, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(200, 236, 200, 0.1) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +/* 浮动装饰圆点 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(168, 213, 186, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(107, 183, 123, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(200, 236, 200, 0.4), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(168, 213, 186, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(107, 183, 123, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + animation: float 20s linear infinite; + pointer-events: none; + z-index: -1; +} + +@keyframes float { + 0% { + transform: translateY(0px); + } + 50% { + transform: translateY(-10px); + } + 100% { + transform: translateY(0px); + } +} + +/* 云朵装饰效果 */ +.container::before { + content: ''; + position: absolute; + top: -50px; + right: -50px; + width: 200px; + height: 100px; + background: rgba(255, 255, 255, 0.1); + border-radius: 50px; + box-shadow: + -30px 20px 0 rgba(255, 255, 255, 0.08), + 30px 40px 0 rgba(255, 255, 255, 0.06); + animation: cloudFloat 25s ease-in-out infinite; + pointer-events: none; + z-index: -1; +} + +.container::after { + content: ''; + position: absolute; + bottom: -30px; + left: -30px; + width: 150px; + height: 80px; + background: rgba(255, 255, 255, 0.08); + border-radius: 40px; + box-shadow: + 20px 15px 0 rgba(255, 255, 255, 0.06), + -20px 25px 0 rgba(255, 255, 255, 0.04); + animation: cloudFloat 30s ease-in-out infinite reverse; + pointer-events: none; + z-index: -1; +} + +@keyframes cloudFloat { + 0%, 100% { + transform: translateX(0px) translateY(0px); + } + 25% { + transform: translateX(20px) translateY(-10px); + } + 50% { + transform: translateX(-10px) translateY(-20px); + } + 75% { + transform: translateX(15px) translateY(-5px); + } +} + +/* 响应式背景调整 */ +@media (max-width: 768px) { + body::after { + background-size: 150px 75px; + } + + .container::before, + .container::after { + display: none; + } +} + +@media (max-width: 480px) { + body { + background: linear-gradient(135deg, #e8f5e8 0%, #d4f1d4 50%, #a8d5ba 100%); + animation: none; + } + + body::before, + body::after { + display: none; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/css/style.css b/frontend/react-app/public/60sapi/实用功能/实时天气/css/style.css new file mode 100644 index 00000000..8a1e29f0 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/css/style.css @@ -0,0 +1,409 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Microsoft YaHei', Arial, sans-serif; + line-height: 1.6; + color: #333; + min-height: 100vh; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 30px; +} + +.header h1 { + color: #2d5a3d; + font-size: 2.5rem; + font-weight: 300; + margin-bottom: 10px; +} + +/* 搜索区域 */ +.search-section { + margin-bottom: 30px; +} + +.search-box { + display: flex; + justify-content: center; + gap: 10px; + max-width: 500px; + margin: 0 auto; +} + +#cityInput { + flex: 1; + padding: 12px 16px; + border: 2px solid #a8d5ba; + border-radius: 25px; + font-size: 16px; + outline: none; + transition: all 0.3s ease; + background: rgba(255, 255, 255, 0.9); +} + +#cityInput:focus { + border-color: #6bb77b; + box-shadow: 0 0 10px rgba(107, 183, 123, 0.3); +} + +#searchBtn { + padding: 12px 24px; + background: linear-gradient(135deg, #6bb77b, #5a9f6a); + color: white; + border: none; + border-radius: 25px; + font-size: 16px; + cursor: pointer; + transition: all 0.3s ease; + white-space: nowrap; +} + +#searchBtn:hover { + background: linear-gradient(135deg, #5a9f6a, #4a8759); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(107, 183, 123, 0.4); +} + +/* 加载动画 */ +.loading { + text-align: center; + padding: 40px; +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #6bb77b; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 天气容器 */ +.weather-container { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + border: 1px solid rgba(168, 213, 186, 0.3); +} + +/* 位置信息 */ +.location-info { + text-align: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e8f5e8; +} + +.location-info h2 { + color: #2d5a3d; + font-size: 2rem; + margin-bottom: 5px; +} + +.location-info p { + color: #666; + font-size: 14px; +} + +/* 当前天气 */ +.current-weather { + margin-bottom: 30px; +} + +.weather-main { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 25px; +} + +.temperature { + font-size: 4rem; + font-weight: 300; + color: #2d5a3d; +} + +.unit { + font-size: 2rem; + color: #6bb77b; +} + +.weather-desc p:first-child { + font-size: 1.5rem; + color: #2d5a3d; + margin-bottom: 5px; +} + +.weather-desc p:last-child { + color: #666; + font-size: 14px; +} + +/* 天气详情 */ +.weather-details { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 15px; +} + +.detail-item { + background: rgba(168, 213, 186, 0.1); + padding: 15px; + border-radius: 12px; + text-align: center; + border: 1px solid rgba(168, 213, 186, 0.2); +} + +.detail-item .label { + display: block; + color: #666; + font-size: 12px; + margin-bottom: 5px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.detail-item span:last-child { + color: #2d5a3d; + font-weight: 600; + font-size: 16px; +} + +/* 生活指数 */ +.life-index { + margin-top: 30px; +} + +.life-index h3 { + color: #2d5a3d; + font-size: 1.5rem; + margin-bottom: 20px; + text-align: center; +} + +.index-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 20px; +} + +.index-item { + display: flex; + align-items: center; + background: rgba(168, 213, 186, 0.05); + padding: 20px; + border-radius: 15px; + border: 1px solid rgba(168, 213, 186, 0.2); + transition: all 0.3s ease; +} + +.index-item:hover { + background: rgba(168, 213, 186, 0.1); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(168, 213, 186, 0.2); +} + +.index-icon { + font-size: 2rem; + margin-right: 15px; + width: 50px; + text-align: center; +} + +.index-content h4 { + color: #2d5a3d; + font-size: 16px; + margin-bottom: 5px; +} + +.index-content p { + color: #6bb77b; + font-weight: 600; + margin-bottom: 3px; +} + +.index-content span { + color: #666; + font-size: 13px; + line-height: 1.4; +} + +/* 更新时间 */ +.update-time { + text-align: center; + margin-top: 30px; + padding-top: 20px; + border-top: 1px solid #e8f5e8; + color: #666; + font-size: 14px; +} + +/* 错误信息 */ +.error-message { + text-align: center; + padding: 40px; + background: rgba(255, 107, 107, 0.1); + border-radius: 15px; + border: 1px solid rgba(255, 107, 107, 0.2); + color: #d63031; +} + +/* 平板端适配 (768px - 1024px) */ +@media (min-width: 768px) and (max-width: 1024px) { + .container { + padding: 25px; + } + + .header h1 { + font-size: 2.2rem; + } + + .temperature { + font-size: 3.5rem; + } + + .weather-details { + grid-template-columns: repeat(3, 1fr); + } + + .index-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +/* 电脑端适配 (1024px+) */ +@media (min-width: 1024px) { + .container { + padding: 40px; + } + + .weather-container { + padding: 40px; + } + + .weather-main { + justify-content: space-around; + } + + .weather-details { + grid-template-columns: repeat(6, 1fr); + } + + .index-grid { + grid-template-columns: repeat(3, 1fr); + } + + .search-box { + max-width: 600px; + } +} + +/* 手机端适配 (768px以下) */ +@media (max-width: 767px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2rem; + } + + .search-box { + flex-direction: column; + gap: 15px; + } + + #searchBtn { + padding: 14px 24px; + } + + .weather-container { + padding: 20px; + margin: 0 -5px; + } + + .weather-main { + flex-direction: column; + text-align: center; + gap: 20px; + } + + .temperature { + font-size: 3rem; + } + + .weather-details { + grid-template-columns: repeat(2, 1fr); + gap: 10px; + } + + .detail-item { + padding: 12px; + } + + .index-grid { + grid-template-columns: 1fr; + gap: 15px; + } + + .index-item { + padding: 15px; + } + + .index-icon { + font-size: 1.5rem; + width: 40px; + margin-right: 12px; + } +} + +/* 超小屏幕适配 (480px以下) */ +@media (max-width: 480px) { + .container { + padding: 10px; + } + + .header h1 { + font-size: 1.8rem; + } + + .weather-container { + padding: 15px; + border-radius: 15px; + } + + .temperature { + font-size: 2.5rem; + } + + .weather-details { + grid-template-columns: 1fr; + } + + .detail-item { + padding: 10px; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/index.html b/frontend/react-app/public/60sapi/实用功能/实时天气/index.html new file mode 100644 index 00000000..474571a4 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/index.html @@ -0,0 +1,140 @@ + + + + + + 实时天气查询 + + + + +
+
+

实时天气查询

+
+ +
+ +
+ + + + + + +
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/js/script.js b/frontend/react-app/public/60sapi/实用功能/实时天气/js/script.js new file mode 100644 index 00000000..a3aaacda --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/js/script.js @@ -0,0 +1,252 @@ +// 天气查询应用 +class WeatherApp { + constructor() { + this.apiEndpoints = [ + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run', + 'https://60s.114128.xyz', + 'https://60s-cf.114128.xyz' + ]; + this.currentEndpointIndex = 0; + this.init(); + } + + init() { + this.bindEvents(); + // 页面加载时自动查询北京天气 + this.searchWeather('北京'); + } + + bindEvents() { + const searchBtn = document.getElementById('searchBtn'); + const cityInput = document.getElementById('cityInput'); + + searchBtn.addEventListener('click', () => { + const city = cityInput.value.trim(); + if (city) { + this.searchWeather(city); + } else { + this.showError('请输入城市名称'); + } + }); + + cityInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + const city = cityInput.value.trim(); + if (city) { + this.searchWeather(city); + } else { + this.showError('请输入城市名称'); + } + } + }); + + // 防止输入框为空时查询 + cityInput.addEventListener('input', () => { + const searchBtn = document.getElementById('searchBtn'); + searchBtn.disabled = !cityInput.value.trim(); + }); + } + + async searchWeather(city) { + this.showLoading(); + + for (let i = 0; i < this.apiEndpoints.length; i++) { + try { + const endpoint = this.apiEndpoints[this.currentEndpointIndex]; + const response = await this.fetchWeatherData(endpoint, city); + + if (response && response.code === 200) { + this.displayWeatherData(response.data); + return; + } + } catch (error) { + console.warn(`API ${this.apiEndpoints[this.currentEndpointIndex]} 请求失败:`, error); + } + + // 切换到下一个API端点 + this.currentEndpointIndex = (this.currentEndpointIndex + 1) % this.apiEndpoints.length; + } + + // 所有API都失败了 + this.showError('获取天气信息失败,请检查网络连接或稍后重试'); + } + + async fetchWeatherData(endpoint, city) { + const url = `${endpoint}/v2/weather?query=${encodeURIComponent(city)}`; + + const response = await fetch(url, { + method: 'GET', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + timeout: 10000 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + return await response.json(); + } + + displayWeatherData(data) { + const { location, realtime } = data; + + // 显示位置信息 + document.getElementById('locationName').textContent = location.formatted; + document.getElementById('locationDetail').textContent = + `${location.province} ${location.city} | 邮编: ${location.zip_code}`; + + // 显示当前天气 + document.getElementById('temperature').textContent = realtime.temperature; + document.getElementById('weatherCondition').textContent = realtime.weather; + + // 体感温度转换(API返回的是华氏度,需要转换为摄氏度) + const feelsLikeCelsius = this.fahrenheitToCelsius(realtime.temperature_feels_like); + document.getElementById('feelsLike').textContent = + `体感温度 ${feelsLikeCelsius}°C`; + + // 显示天气详情 + document.getElementById('humidity').textContent = `${realtime.humidity}%`; + document.getElementById('windDirection').textContent = realtime.wind_direction; + document.getElementById('windStrength').textContent = realtime.wind_strength; + document.getElementById('pressure').textContent = `${realtime.pressure} hPa`; + document.getElementById('visibility').textContent = realtime.visibility; + + // 空气质量显示 + const aqiElement = document.getElementById('aqi'); + aqiElement.textContent = `${realtime.aqi} (PM2.5: ${realtime.pm25})`; + aqiElement.className = this.getAQIClass(realtime.aqi); + + // 显示生活指数 + const lifeIndex = realtime.life_index; + this.displayLifeIndex('comfort', lifeIndex.comfort); + this.displayLifeIndex('clothing', lifeIndex.clothing); + this.displayLifeIndex('umbrella', lifeIndex.umbrella); + this.displayLifeIndex('uv', lifeIndex.uv); + this.displayLifeIndex('travel', lifeIndex.travel); + this.displayLifeIndex('sport', lifeIndex.sport); + + // 显示更新时间 + document.getElementById('updateTime').textContent = + `${realtime.updated} (${realtime.updated_at})`; + + this.showWeatherContainer(); + } + + displayLifeIndex(type, indexData) { + const levelElement = document.getElementById(`${type}Level`); + const descElement = document.getElementById(`${type}Desc`); + + if (levelElement && descElement && indexData) { + levelElement.textContent = indexData.level; + descElement.textContent = indexData.desc; + + // 根据指数级别设置颜色 + levelElement.className = this.getIndexLevelClass(indexData.level); + } + } + + getAQIClass(aqi) { + if (aqi <= 50) return 'aqi-good'; + if (aqi <= 100) return 'aqi-moderate'; + if (aqi <= 150) return 'aqi-unhealthy-sensitive'; + if (aqi <= 200) return 'aqi-unhealthy'; + if (aqi <= 300) return 'aqi-very-unhealthy'; + return 'aqi-hazardous'; + } + + getIndexLevelClass(level) { + const levelMap = { + '优': 'level-excellent', + '良': 'level-good', + '适宜': 'level-suitable', + '舒适': 'level-comfortable', + '较适宜': 'level-fairly-suitable', + '不宜': 'level-unsuitable', + '较不宜': 'level-fairly-unsuitable', + '带伞': 'level-bring-umbrella', + '最弱': 'level-weakest', + '弱': 'level-weak', + '中等': 'level-moderate', + '强': 'level-strong', + '很强': 'level-very-strong' + }; + + return levelMap[level] || 'level-default'; + } + + // 华氏度转摄氏度 + fahrenheitToCelsius(fahrenheit) { + const celsius = (fahrenheit - 32) * 5 / 9; + return Math.round(celsius * 10) / 10; // 保留一位小数 + } + + showLoading() { + document.getElementById('loading').style.display = 'block'; + document.getElementById('weatherContainer').style.display = 'none'; + document.getElementById('errorMessage').style.display = 'none'; + } + + showWeatherContainer() { + document.getElementById('loading').style.display = 'none'; + document.getElementById('weatherContainer').style.display = 'block'; + document.getElementById('errorMessage').style.display = 'none'; + } + + showError(message) { + document.getElementById('loading').style.display = 'none'; + document.getElementById('weatherContainer').style.display = 'none'; + const errorElement = document.getElementById('errorMessage'); + errorElement.style.display = 'block'; + errorElement.querySelector('p').textContent = message; + } +} + +// 添加生活指数级别样式 +const style = document.createElement('style'); +style.textContent = ` + .aqi-good { color: #52c41a; } + .aqi-moderate { color: #faad14; } + .aqi-unhealthy-sensitive { color: #fa8c16; } + .aqi-unhealthy { color: #f5222d; } + .aqi-very-unhealthy { color: #a0206e; } + .aqi-hazardous { color: #722ed1; } + + .level-excellent, .level-suitable, .level-comfortable { color: #52c41a; } + .level-good, .level-fairly-suitable { color: #1890ff; } + .level-bring-umbrella, .level-moderate { color: #faad14; } + .level-unsuitable, .level-fairly-unsuitable { color: #f5222d; } + .level-weakest, .level-weak { color: #52c41a; } + .level-strong, .level-very-strong { color: #fa8c16; } + .level-default { color: #666; } +`; +document.head.appendChild(style); + +// 页面加载完成后初始化应用 +document.addEventListener('DOMContentLoaded', () => { + new WeatherApp(); +}); + +// 添加页面可见性检测,当页面重新可见时刷新数据 +document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + const cityInput = document.getElementById('cityInput'); + const city = cityInput.value.trim() || '北京'; + // 延迟1秒刷新,避免频繁请求 + setTimeout(() => { + if (window.weatherApp) { + window.weatherApp.searchWeather(city); + } + }, 1000); + } +}); + +// 将应用实例暴露到全局,方便调试和其他功能调用 +window.weatherApp = null; +document.addEventListener('DOMContentLoaded', () => { + window.weatherApp = new WeatherApp(); +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/接口集合.json b/frontend/react-app/public/60sapi/实用功能/实时天气/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/实用功能/实时天气/返回接口.json b/frontend/react-app/public/60sapi/实用功能/实时天气/返回接口.json new file mode 100644 index 00000000..a0243aa1 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/实时天气/返回接口.json @@ -0,0 +1,68 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "location": { + "province": "北京", + "city": "北京", + "town": "北京", + "formatted": "北京", + "location_id": "101010100", + "detail_url": "http://www.weather.com.cn/weather/101010100.shtml", + "is_province": true, + "is_city": false, + "is_town": false, + "area_code": "10", + "zip_code": "100000" + }, + "realtime": { + "weather": "小雨转多云", + "weather_desc": "未知", + "weather_code": "d7", + "temperature": 26, + "temperature_feels_like": 81.1, + "humidity": 78, + "wind_direction": "南风转北风", + "wind_strength": "\u003C3级", + "wind_speed": "5km/h", + "pressure": 1008, + "visibility": "8km", + "aqi": 37, + "pm25": 37, + "rainfall": 0, + "rainfall_24h": 0, + "updated": "2025-08-29 08:00:00", + "updated_at": "15:10", + "life_index": { + "comfort": { + "level": "舒适", + "desc": "白天温度宜人,风力不大。" + }, + "clothing": { + "level": "舒适", + "desc": "建议穿长袖衬衫单裤等服装。" + }, + "umbrella": { + "level": "带伞", + "desc": "有降水,带雨伞,短期外出可收起雨伞。" + }, + "uv": { + "level": "最弱", + "desc": "辐射弱,涂擦SPF8-12防晒护肤品。" + }, + "car_wash": { + "level": "不宜", + "desc": "有雨,雨水和泥水会弄脏爱车。" + }, + "travel": { + "level": "适宜", + "desc": "较弱降水和微风将伴您共赴旅程。" + }, + "sport": { + "level": "较不宜", + "desc": "有降水,推荐您在室内进行休闲运动。" + } + } + } + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/css/background.css b/frontend/react-app/public/60sapi/实用功能/生成二维码/css/background.css new file mode 100644 index 00000000..f0cd4e04 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/css/background.css @@ -0,0 +1,132 @@ +/* 背景样式文件 - 独立分离便于迁移 */ + +/* 主背景渐变 */ +body { + background: linear-gradient(135deg, + #e8f5e8 0%, + #f1f8e9 25%, + #e8f5e8 50%, + #c8e6c9 75%, + #e8f5e8 100%); + background-size: 400% 400%; + animation: backgroundShift 15s ease-in-out infinite; + position: relative; +} + +/* 背景动画 */ +@keyframes backgroundShift { + 0%, 100% { + background-position: 0% 50%; + } + 25% { + background-position: 100% 50%; + } + 50% { + background-position: 50% 100%; + } + 75% { + background-position: 50% 0%; + } +} + +/* 背景装饰元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 20%, rgba(76, 175, 80, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 80%, rgba(129, 199, 132, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 60%, rgba(165, 214, 167, 0.08) 0%, transparent 50%); + pointer-events: none; + z-index: -1; + animation: floatingBubbles 20s ease-in-out infinite; +} + +@keyframes floatingBubbles { + 0%, 100% { + transform: translateY(0px) rotate(0deg); + opacity: 1; + } + 33% { + transform: translateY(-20px) rotate(120deg); + opacity: 0.8; + } + 66% { + transform: translateY(10px) rotate(240deg); + opacity: 0.9; + } +} + +/* 背景粒子效果 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + pointer-events: none; + z-index: -1; + animation: particleFloat 25s linear infinite; +} + +@keyframes particleFloat { + 0% { + transform: translateY(0px); + } + 100% { + transform: translateY(-100px); + } +} + +/* 响应式背景调整 */ +@media (max-width: 768px) { + body::after { + background-size: 150px 75px; + animation-duration: 20s; + } + + body::before { + animation-duration: 15s; + } +} + +@media (max-width: 480px) { + body::after { + background-size: 100px 50px; + animation-duration: 15s; + } + + body::before { + animation-duration: 12s; + } + + body { + animation-duration: 12s; + } +} + +/* 高性能模式 - 减少动画 */ +@media (prefers-reduced-motion: reduce) { + body, + body::before, + body::after { + animation: none; + } + + body { + background: linear-gradient(135deg, #e8f5e8 0%, #f1f8e9 50%, #c8e6c9 100%); + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/css/style.css b/frontend/react-app/public/60sapi/实用功能/生成二维码/css/style.css new file mode 100644 index 00000000..ca4dd96c --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/css/style.css @@ -0,0 +1,468 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + color: #2d5a3d; + min-height: 100vh; + overflow-x: hidden; +} + +/* 容器样式 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + min-height: 100vh; + display: flex; + flex-direction: column; + position: relative; + z-index: 1; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + padding: 40px 20px; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 20px; + box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1); + border: 1px solid rgba(76, 175, 80, 0.2); + position: relative; + overflow: hidden; +} + +.header::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 4px; + background: linear-gradient(90deg, transparent, #4caf50, transparent); + animation: headerGlow 3s ease-in-out infinite; +} + +@keyframes headerGlow { + 0% { left: -100%; } + 50% { left: 100%; } + 100% { left: 100%; } +} + +.header h1 { + font-size: 2.5rem; + font-weight: 700; + background: linear-gradient(135deg, #4caf50, #81c784, #4caf50); + background-size: 200% 200%; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 10px; + animation: titleGradient 4s ease-in-out infinite; +} + +@keyframes titleGradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.header p { + font-size: 1.1rem; + color: #66bb6a; + opacity: 0.9; +} + +/* 主要内容区域 */ +.main { + flex: 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; + align-items: start; +} + +/* 表单容器 */ +.form-container { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + padding: 35px; + border-radius: 20px; + box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1); + border: 1px solid rgba(76, 175, 80, 0.2); + transition: all 0.3s ease; +} + +.form-container:hover { + transform: translateY(-5px); + box-shadow: 0 12px 40px rgba(76, 175, 80, 0.15); +} + +/* 表单样式 */ +.qr-form { + display: flex; + flex-direction: column; + gap: 25px; +} + +.input-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.input-group label { + font-weight: 600; + color: #2d5a3d; + font-size: 0.95rem; +} + +textarea, select { + padding: 12px 16px; + border: 2px solid rgba(76, 175, 80, 0.3); + border-radius: 12px; + font-size: 1rem; + background: rgba(255, 255, 255, 0.9); + transition: all 0.3s ease; + resize: vertical; +} + +textarea { + min-height: 100px; + font-family: inherit; +} + +textarea:focus, select:focus { + outline: none; + border-color: #4caf50; + box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); + background: rgba(255, 255, 255, 1); +} + +.options-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 20px; +} + +/* 按钮样式 */ +.generate-btn { + padding: 15px 30px; + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + border: none; + border-radius: 12px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + letter-spacing: 0.5px; +} + +.generate-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: left 0.5s ease; +} + +.generate-btn:hover::before { + left: 100%; +} + +.generate-btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(76, 175, 80, 0.3); +} + +.generate-btn:active { + transform: translateY(0); +} + +.generate-btn.loading .btn-text { + display: none; +} + +.generate-btn.loading .btn-loading { + display: inline; +} + +.btn-loading { + display: none; +} + +/* 结果容器 */ +.result-container { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + padding: 35px; + border-radius: 20px; + box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1); + border: 1px solid rgba(76, 175, 80, 0.2); + min-height: 400px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +/* 加载动画 */ +.loading { + text-align: center; + color: #4caf50; +} + +.loading-spinner { + width: 50px; + height: 50px; + border: 4px solid rgba(76, 175, 80, 0.2); + border-top: 4px solid #4caf50; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 错误样式 */ +.error { + text-align: center; + color: #d32f2f; +} + +.error-icon { + font-size: 3rem; + margin-bottom: 15px; +} + +.error-message { + font-size: 1.1rem; + margin-bottom: 20px; + color: #666; +} + +.retry-btn { + padding: 10px 20px; + background: #4caf50; + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.retry-btn:hover { + background: #45a049; + transform: translateY(-1px); +} + +/* 结果显示 */ +.result { + width: 100%; + text-align: center; +} + +.qr-display { + margin-bottom: 25px; +} + +.qr-display img { + max-width: 100%; + height: auto; + border-radius: 12px; + box-shadow: 0 4px 20px rgba(76, 175, 80, 0.2); + transition: all 0.3s ease; +} + +.qr-display img:hover { + transform: scale(1.05); + box-shadow: 0 8px 30px rgba(76, 175, 80, 0.3); +} + +.result-info { + display: flex; + flex-direction: column; + gap: 20px; +} + +.result-text { + font-size: 1rem; + color: #666; + word-break: break-all; + background: rgba(76, 175, 80, 0.1); + padding: 12px; + border-radius: 8px; + border-left: 4px solid #4caf50; +} + +.result-actions { + display: flex; + gap: 10px; + justify-content: center; + flex-wrap: wrap; +} + +.download-btn, .copy-btn, .new-btn { + padding: 10px 16px; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 0.9rem; + font-weight: 500; + transition: all 0.3s ease; +} + +.download-btn { + background: #4caf50; + color: white; +} + +.copy-btn { + background: #2196f3; + color: white; +} + +.new-btn { + background: #ff9800; + color: white; +} + +.download-btn:hover, .copy-btn:hover, .new-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); +} + +/* 隐藏类 */ +.hidden { + display: none !important; +} + +/* 页脚样式 */ +.footer { + text-align: center; + margin-top: 40px; + padding: 25px; + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(15px); + border-radius: 15px; + color: #66bb6a; + font-size: 0.9rem; + border: 1px solid rgba(76, 175, 80, 0.1); +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + max-width: 95%; + padding: 15px; + } + + .main { + gap: 30px; + } + + .header h1 { + font-size: 2.2rem; + } + + .form-container, .result-container { + padding: 25px; + } + + .options-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + .container { + padding: 10px; + } + + .header { + margin-bottom: 25px; + padding: 25px 15px; + } + + .header h1 { + font-size: 1.8rem; + } + + .header p { + font-size: 1rem; + } + + .main { + grid-template-columns: 1fr; + gap: 25px; + } + + .form-container, .result-container { + padding: 20px; + } + + .options-grid { + grid-template-columns: 1fr; + gap: 15px; + } + + .result-actions { + flex-direction: column; + align-items: center; + } + + .download-btn, .copy-btn, .new-btn { + width: 100%; + max-width: 200px; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .container { + padding: 8px; + } + + .header { + padding: 20px 10px; + margin-bottom: 20px; + } + + .header h1 { + font-size: 1.6rem; + } + + .form-container, .result-container { + padding: 15px; + border-radius: 15px; + } + + .generate-btn { + padding: 12px 20px; + font-size: 1rem; + } + + textarea { + min-height: 80px; + } + + .qr-display img { + max-width: 90%; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/index.html b/frontend/react-app/public/60sapi/实用功能/生成二维码/index.html new file mode 100644 index 00000000..f9366891 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/index.html @@ -0,0 +1,98 @@ + + + + + + 二维码生成器 + + + + +
+
+

🔗 二维码生成器

+

快速生成高质量二维码

+
+ +
+
+
+
+ + +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+
+ +
+ + + + + +
+
+ +
+

© 2024 二维码生成器 - 简单快捷的二维码生成工具

+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/js/script.js b/frontend/react-app/public/60sapi/实用功能/生成二维码/js/script.js new file mode 100644 index 00000000..f09ff5a6 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/js/script.js @@ -0,0 +1,417 @@ +// 二维码生成器 JavaScript +class QRCodeGenerator { + constructor() { + this.apiEndpoints = []; + this.currentApiIndex = 0; + this.init(); + } + + // 初始化 + async init() { + await this.loadApiEndpoints(); + this.bindEvents(); + this.setupFormValidation(); + } + + // 加载API接口列表 + async loadApiEndpoints() { + try { + const response = await fetch('./接口集合.json'); + this.apiEndpoints = await response.json(); + console.log('已加载API接口:', this.apiEndpoints); + } catch (error) { + console.error('加载API接口失败:', error); + this.showError('加载配置失败,请刷新页面重试'); + } + } + + // 绑定事件 + bindEvents() { + const form = document.getElementById('qrForm'); + const retryBtn = document.querySelector('.retry-btn'); + const downloadBtn = document.querySelector('.download-btn'); + const copyBtn = document.querySelector('.copy-btn'); + const newBtn = document.querySelector('.new-btn'); + + form.addEventListener('submit', (e) => this.handleSubmit(e)); + retryBtn.addEventListener('click', () => this.retryGeneration()); + downloadBtn.addEventListener('click', () => this.downloadQRCode()); + copyBtn.addEventListener('click', () => this.copyImageLink()); + newBtn.addEventListener('click', () => this.resetForm()); + + // 实时字符计数 + const textArea = document.getElementById('text'); + textArea.addEventListener('input', () => this.updateCharCount()); + } + + // 设置表单验证 + setupFormValidation() { + const textArea = document.getElementById('text'); + const form = document.getElementById('qrForm'); + + textArea.addEventListener('blur', () => { + if (textArea.value.trim() === '') { + this.showFieldError(textArea, '请输入要生成二维码的内容'); + } else { + this.clearFieldError(textArea); + } + }); + } + + // 显示字段错误 + showFieldError(field, message) { + this.clearFieldError(field); + field.style.borderColor = '#d32f2f'; + const errorDiv = document.createElement('div'); + errorDiv.className = 'field-error'; + errorDiv.style.color = '#d32f2f'; + errorDiv.style.fontSize = '0.8rem'; + errorDiv.style.marginTop = '5px'; + errorDiv.textContent = message; + field.parentNode.appendChild(errorDiv); + } + + // 清除字段错误 + clearFieldError(field) { + field.style.borderColor = ''; + const errorDiv = field.parentNode.querySelector('.field-error'); + if (errorDiv) { + errorDiv.remove(); + } + } + + // 更新字符计数 + updateCharCount() { + const textArea = document.getElementById('text'); + const text = textArea.value; + const length = text.length; + + // 移除旧的计数显示 + const oldCounter = textArea.parentNode.querySelector('.char-counter'); + if (oldCounter) oldCounter.remove(); + + // 添加新的计数显示 + if (length > 0) { + const counter = document.createElement('div'); + counter.className = 'char-counter'; + counter.style.fontSize = '0.8rem'; + counter.style.color = '#666'; + counter.style.textAlign = 'right'; + counter.style.marginTop = '5px'; + counter.textContent = `${length} 个字符`; + textArea.parentNode.appendChild(counter); + } + } + + // 处理表单提交 + async handleSubmit(e) { + e.preventDefault(); + + const formData = new FormData(e.target); + const params = { + text: formData.get('text').trim(), + size: formData.get('size'), + level: formData.get('level'), + encoding: formData.get('encoding') + }; + + // 验证输入 + if (!params.text) { + this.showFieldError(document.getElementById('text'), '请输入要生成二维码的内容'); + return; + } + + this.showLoading(); + await this.generateQRCode(params); + } + + // 生成二维码 + async generateQRCode(params) { + let success = false; + let lastError = null; + + // 尝试所有API接口 + for (let i = 0; i < this.apiEndpoints.length; i++) { + const apiIndex = (this.currentApiIndex + i) % this.apiEndpoints.length; + const apiUrl = this.apiEndpoints[apiIndex]; + + try { + console.log(`尝试API ${apiIndex + 1}:`, apiUrl); + const result = await this.callAPI(apiUrl, params); + + if (result.success) { + this.currentApiIndex = apiIndex; // 记录成功的API + this.showResult(result.data, params); + success = true; + break; + } + } catch (error) { + console.warn(`API ${apiIndex + 1} 失败:`, error); + lastError = error; + } + } + + if (!success) { + this.showError(lastError?.message || '所有API接口都无法访问,请稍后重试'); + } + } + + // 调用API + async callAPI(baseUrl, params) { + const url = new URL('/v2/qrcode', baseUrl); + + // 添加查询参数 + Object.entries(params).forEach(([key, value]) => { + if (value) { + url.searchParams.append(key, value); + } + }); + + console.log('请求URL:', url.toString()); + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 + + try { + const response = await fetch(url.toString(), { + method: 'GET', + signal: controller.signal, + headers: { + 'Accept': 'application/json, image/*' + } + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + // 根据返回格式处理 + if (params.encoding === 'image') { + const blob = await response.blob(); + const imageUrl = URL.createObjectURL(blob); + return { + success: true, + data: { + imageUrl: imageUrl, + text: params.text, + size: params.size, + level: params.level, + format: 'image' + } + }; + } else { + const jsonData = await response.json(); + if (jsonData.code === 0 && jsonData.data) { + return { + success: true, + data: { + imageUrl: jsonData.data.data_uri, + text: params.text, + size: params.size, + level: params.level, + format: 'json', + base64: jsonData.data.base64, + mimeType: jsonData.data.mime_type + } + }; + } else { + throw new Error(jsonData.message || '生成失败'); + } + } + } catch (error) { + clearTimeout(timeoutId); + if (error.name === 'AbortError') { + throw new Error('请求超时,请重试'); + } + throw error; + } + } + + // 显示加载状态 + showLoading() { + this.hideAllStates(); + document.getElementById('loading').classList.remove('hidden'); + + const btn = document.querySelector('.generate-btn'); + btn.classList.add('loading'); + btn.disabled = true; + } + + // 显示错误 + showError(message) { + this.hideAllStates(); + const errorDiv = document.getElementById('error'); + const errorMessage = errorDiv.querySelector('.error-message'); + errorMessage.textContent = message; + errorDiv.classList.remove('hidden'); + + this.resetButton(); + } + + // 显示结果 + showResult(data, params) { + this.hideAllStates(); + + const resultDiv = document.getElementById('result'); + const qrImage = document.getElementById('qrImage'); + const resultText = document.querySelector('.result-text'); + + qrImage.src = data.imageUrl; + qrImage.alt = `二维码: ${data.text}`; + + resultText.innerHTML = ` + 内容: ${this.escapeHtml(data.text)}
+ 尺寸: ${data.size}x${data.size}
+ 容错级别: ${data.level}
+ 格式: ${data.format.toUpperCase()} + `; + + resultDiv.classList.remove('hidden'); + this.resetButton(); + + // 保存数据供下载使用 + this.currentQRData = data; + } + + // 隐藏所有状态 + hideAllStates() { + document.getElementById('loading').classList.add('hidden'); + document.getElementById('error').classList.add('hidden'); + document.getElementById('result').classList.add('hidden'); + } + + // 重置按钮状态 + resetButton() { + const btn = document.querySelector('.generate-btn'); + btn.classList.remove('loading'); + btn.disabled = false; + } + + // 重试生成 + async retryGeneration() { + const form = document.getElementById('qrForm'); + const formData = new FormData(form); + const params = { + text: formData.get('text').trim(), + size: formData.get('size'), + level: formData.get('level'), + encoding: formData.get('encoding') + }; + + this.showLoading(); + await this.generateQRCode(params); + } + + // 下载二维码 + downloadQRCode() { + if (!this.currentQRData) return; + + const link = document.createElement('a'); + link.href = this.currentQRData.imageUrl; + link.download = `qrcode_${Date.now()}.png`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + this.showToast('二维码已下载'); + } + + // 复制图片链接 + async copyImageLink() { + if (!this.currentQRData) return; + + try { + await navigator.clipboard.writeText(this.currentQRData.imageUrl); + this.showToast('链接已复制到剪贴板'); + } catch (error) { + console.error('复制失败:', error); + this.showToast('复制失败,请手动复制'); + } + } + + // 重置表单 + resetForm() { + document.getElementById('qrForm').reset(); + this.hideAllStates(); + this.currentQRData = null; + + // 清除字符计数 + const counter = document.querySelector('.char-counter'); + if (counter) counter.remove(); + + // 清除字段错误 + document.querySelectorAll('input, textarea, select').forEach(field => { + this.clearFieldError(field); + }); + + // 聚焦到文本框 + document.getElementById('text').focus(); + } + + // 显示提示消息 + showToast(message) { + // 移除旧的toast + const oldToast = document.querySelector('.toast'); + if (oldToast) oldToast.remove(); + + const toast = document.createElement('div'); + toast.className = 'toast'; + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: #4caf50; + color: white; + padding: 12px 20px; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0,0,0,0.2); + z-index: 1000; + animation: slideIn 0.3s ease; + `; + toast.textContent = message; + + document.body.appendChild(toast); + + setTimeout(() => { + toast.style.animation = 'slideOut 0.3s ease'; + setTimeout(() => toast.remove(), 300); + }, 3000); + } + + // HTML转义 + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } +} + +// 添加CSS动画 +const style = document.createElement('style'); +style.textContent = ` + @keyframes slideIn { + from { transform: translateX(100%); opacity: 0; } + to { transform: translateX(0); opacity: 1; } + } + @keyframes slideOut { + from { transform: translateX(0); opacity: 1; } + to { transform: translateX(100%); opacity: 0; } + } +`; +document.head.appendChild(style); + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', () => { + new QRCodeGenerator(); +}); + +// 错误处理 +window.addEventListener('error', (e) => { + console.error('全局错误:', e.error); +}); + +window.addEventListener('unhandledrejection', (e) => { + console.error('未处理的Promise拒绝:', e.reason); +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/接口集合.json b/frontend/react-app/public/60sapi/实用功能/生成二维码/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/实用功能/生成二维码/返回接口.json b/frontend/react-app/public/60sapi/实用功能/生成二维码/返回接口.json new file mode 100644 index 00000000..8cea87e9 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/生成二维码/返回接口.json @@ -0,0 +1,10 @@ +{ + "code": 0, + "message": "success", + "data": { + "base64": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z15fBTV...", + "data_uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z15fBTV...", + "mime_type": "image/png", + "text": "https://example.com" + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/background.css b/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/background.css new file mode 100644 index 00000000..04fcd858 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/background.css @@ -0,0 +1,192 @@ +/* 彩虹渐变背景样式 */ + +/* 主背景渐变 */ +body { + background: linear-gradient( + 135deg, + rgba(255, 107, 107, 0.3) 0%, + rgba(255, 165, 0, 0.3) 14.28%, + rgba(255, 255, 0, 0.25) 28.56%, + rgba(50, 205, 50, 0.3) 42.84%, + rgba(0, 191, 255, 0.3) 57.12%, + rgba(65, 105, 225, 0.3) 71.4%, + rgba(147, 112, 219, 0.3) 85.68%, + rgba(255, 105, 180, 0.3) 100% + ); + background-size: 400% 400%; + animation: rainbowShift 20s ease infinite; + min-height: 100vh; +} + +/* 彩虹渐变动画 */ +@keyframes rainbowShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 半透明覆盖层,增强可读性 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.4); + backdrop-filter: blur(2px); + z-index: -1; + pointer-events: none; +} + +/* 搜索按钮彩虹渐变 */ +.search-btn { + background: linear-gradient( + 45deg, + rgba(255, 107, 107, 0.8), + rgba(255, 165, 0, 0.8), + rgba(255, 255, 0, 0.7), + rgba(50, 205, 50, 0.8), + rgba(0, 191, 255, 0.8), + rgba(65, 105, 225, 0.8), + rgba(147, 112, 219, 0.8) + ); + background-size: 300% 300%; + animation: buttonRainbow 12s ease infinite; +} + +@keyframes buttonRainbow { + 0%, 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } +} + +/* 结果卡片边框彩虹渐变 */ +.result-card { + position: relative; + overflow: hidden; +} + +.result-card::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient( + 45deg, + rgba(255, 107, 107, 0.4), + rgba(255, 165, 0, 0.4), + rgba(255, 255, 0, 0.3), + rgba(50, 205, 50, 0.4), + rgba(0, 191, 255, 0.4), + rgba(65, 105, 225, 0.4), + rgba(147, 112, 219, 0.4), + rgba(255, 107, 107, 0.4) + ); + background-size: 400% 400%; + animation: borderRainbow 15s linear infinite; + border-radius: inherit; + z-index: -1; +} + +@keyframes borderRainbow { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 400% 50%; + } +} + +/* 加载动画彩虹效果 */ +.loading-spinner { + border: 4px solid rgba(255, 255, 255, 0.3); + border-top: 4px solid transparent; + border-image: linear-gradient( + 45deg, + #ff6b6b, + #ffa500, + #ffff00, + #32cd32, + #00bfff, + #4169e1, + #9370db + ) 1; + animation: spin 1s linear infinite, colorShift 3s ease infinite; +} + +@keyframes colorShift { + 0%, 100% { + filter: hue-rotate(0deg); + } + 50% { + filter: hue-rotate(180deg); + } +} + +/* 链接悬停彩虹效果 */ +.result-link:hover { + background: linear-gradient( + 90deg, + rgba(255, 107, 107, 0.7), + rgba(255, 165, 0, 0.7), + rgba(255, 255, 0, 0.6), + rgba(50, 205, 50, 0.7), + rgba(0, 191, 255, 0.7), + rgba(65, 105, 225, 0.7), + rgba(147, 112, 219, 0.7) + ); + background-size: 200% 200%; + animation: linkRainbow 3s ease infinite; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +@keyframes linkRainbow { + 0%, 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } +} + +/* 标题彩虹文字效果 */ +.title { + background: linear-gradient( + 90deg, + rgba(255, 107, 107, 0.8), + rgba(255, 165, 0, 0.8), + rgba(255, 255, 0, 0.7), + rgba(50, 205, 50, 0.8), + rgba(0, 191, 255, 0.8), + rgba(65, 105, 225, 0.8), + rgba(147, 112, 219, 0.8) + ); + background-size: 200% 200%; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + animation: titleRainbow 8s ease infinite; +} + +@keyframes titleRainbow { + 0%, 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/style.css b/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/style.css new file mode 100644 index 00000000..8de2ae2c --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/css/style.css @@ -0,0 +1,530 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #333; + overflow-x: hidden; +} + +/* 容器布局 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + padding: 20px 0; +} + +.title { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.subtitle { + font-size: 1.1rem; + color: rgba(255, 255, 255, 0.9); + font-weight: 300; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); +} + +/* 主内容区域 */ +.main { + flex: 1; + display: flex; + flex-direction: column; + gap: 30px; +} + +/* 搜索区域 */ +.search-section { + display: flex; + justify-content: center; + align-items: center; +} + +.search-container { + display: flex; + width: 100%; + max-width: 600px; + background: rgba(255, 255, 255, 0.95); + border-radius: 50px; + padding: 8px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(10px); + transition: all 0.3s ease; +} + +.search-container:focus-within { + transform: translateY(-2px); + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3); +} + +.search-input { + flex: 1; + border: none; + outline: none; + padding: 15px 25px; + font-size: 1.1rem; + background: transparent; + color: #333; + border-radius: 50px; +} + +.search-input::placeholder { + color: #999; + font-weight: 300; +} + +.search-btn { + border: none; + outline: none; + padding: 15px 25px; + border-radius: 50px; + color: white; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + transition: all 0.3s ease; + min-width: 120px; + justify-content: center; +} + +.search-btn:hover { + transform: scale(1.05); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); +} + +.search-btn:active { + transform: scale(0.98); +} + +.search-icon { + font-size: 1.2rem; +} + +/* 结果区域 */ +.result-section { + flex: 1; + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 400px; +} + +/* 加载动画 */ +.loading { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + padding: 40px; + color: rgba(255, 255, 255, 0.9); +} + +.loading-spinner { + width: 50px; + height: 50px; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 结果卡片 */ +.result-card { + width: 100%; + max-width: 800px; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 30px; + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(10px); + animation: slideUp 0.5s ease; +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.result-header { + margin-bottom: 25px; + text-align: center; +} + +.result-title { + font-size: 2rem; + font-weight: 700; + color: #333; + margin-bottom: 10px; +} + +.result-description { + font-size: 1.1rem; + color: #666; + font-weight: 400; +} + +.result-content { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 30px; + align-items: start; +} + +.result-image-container { + display: flex; + justify-content: center; +} + +.result-image { + width: 100%; + max-width: 250px; + height: auto; + border-radius: 15px; + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); + transition: transform 0.3s ease; +} + +.result-image:hover { + transform: scale(1.05); +} + +.result-text { + display: flex; + flex-direction: column; + gap: 20px; +} + +.result-abstract h3 { + font-size: 1.3rem; + color: #333; + margin-bottom: 10px; + font-weight: 600; +} + +.result-abstract p { + font-size: 1rem; + line-height: 1.8; + color: #555; + text-align: justify; +} + +.result-actions { + display: flex; + justify-content: flex-end; +} + +.result-link { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 12px 24px; + background: rgba(0, 123, 255, 0.1); + color: #007bff; + text-decoration: none; + border-radius: 25px; + font-weight: 600; + transition: all 0.3s ease; + border: 2px solid transparent; +} + +.result-link:hover { + background: rgba(0, 123, 255, 0.2); + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 123, 255, 0.3); +} + +.link-icon { + font-size: 1.2rem; + transition: transform 0.3s ease; +} + +.result-link:hover .link-icon { + transform: translateX(5px); +} + +/* 错误消息 */ +.error-message { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + padding: 40px; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(10px); + text-align: center; + max-width: 500px; + width: 100%; +} + +.error-icon { + font-size: 3rem; +} + +.error-message h3 { + color: #e74c3c; + font-size: 1.5rem; + margin-bottom: 10px; +} + +.error-message p { + color: #666; + font-size: 1rem; + line-height: 1.6; +} + +.retry-btn { + padding: 12px 24px; + background: #e74c3c; + color: white; + border: none; + border-radius: 25px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; +} + +.retry-btn:hover { + background: #c0392b; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(231, 76, 60, 0.3); +} + +/* 欢迎消息 */ +.welcome-message { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + padding: 60px 40px; + background: rgba(255, 255, 255, 0.9); + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + text-align: center; + max-width: 600px; + width: 100%; +} + +.welcome-icon { + font-size: 4rem; + opacity: 0.8; +} + +.welcome-message h3 { + color: #333; + font-size: 1.8rem; + font-weight: 600; + margin-bottom: 10px; +} + +.welcome-message p { + color: #666; + font-size: 1.1rem; + line-height: 1.6; + max-width: 400px; +} + +/* 页脚 */ +.footer { + text-align: center; + padding: 20px 0; + margin-top: 40px; + color: rgba(255, 255, 255, 0.8); + font-size: 0.9rem; +} + +/* 平板端适配 (768px - 1024px) */ +@media (max-width: 1024px) and (min-width: 768px) { + .container { + padding: 15px; + } + + .title { + font-size: 2.2rem; + } + + .result-content { + grid-template-columns: 1fr 1.5fr; + gap: 25px; + } + + .result-card { + padding: 25px; + } +} + +/* 手机端适配 (最大768px) */ +@media (max-width: 768px) { + .container { + padding: 10px; + } + + .header { + margin-bottom: 30px; + padding: 15px 0; + } + + .title { + font-size: 1.8rem; + } + + .subtitle { + font-size: 1rem; + } + + .search-container { + max-width: 100%; + padding: 6px; + } + + .search-input { + padding: 12px 20px; + font-size: 1rem; + } + + .search-btn { + padding: 12px 20px; + min-width: 100px; + font-size: 0.9rem; + } + + .search-text { + display: none; + } + + .result-card { + padding: 20px; + border-radius: 15px; + } + + .result-title { + font-size: 1.5rem; + } + + .result-description { + font-size: 1rem; + } + + .result-content { + grid-template-columns: 1fr; + gap: 20px; + } + + .result-image { + max-width: 200px; + } + + .result-abstract h3 { + font-size: 1.2rem; + } + + .result-abstract p { + font-size: 0.95rem; + line-height: 1.7; + } + + .result-actions { + justify-content: center; + } + + .welcome-message { + padding: 40px 20px; + } + + .welcome-icon { + font-size: 3rem; + } + + .welcome-message h3 { + font-size: 1.5rem; + } + + .welcome-message p { + font-size: 1rem; + } + + .error-message { + padding: 30px 20px; + } + + .error-icon { + font-size: 2.5rem; + } + + .error-message h3 { + font-size: 1.3rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media (max-width: 480px) { + .title { + font-size: 1.6rem; + } + + .search-container { + flex-direction: column; + gap: 10px; + padding: 15px; + border-radius: 20px; + } + + .search-input { + border-radius: 15px; + text-align: center; + } + + .search-btn { + border-radius: 15px; + justify-content: center; + } + + .search-text { + display: inline; + } + + .result-card { + padding: 15px; + } + + .result-title { + font-size: 1.3rem; + } + + .result-image { + max-width: 150px; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/index.html b/frontend/react-app/public/60sapi/实用功能/百度百科词条/index.html new file mode 100644 index 00000000..6b52b446 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/index.html @@ -0,0 +1,83 @@ + + + + + + 百度百科词条查询 + + + + +
+
+

百度百科词条查询

+

探索知识的彩虹世界

+
+ +
+
+
+ + +
+
+ +
+ + + + + + +
+
📚
+

欢迎使用百度百科词条查询

+

在上方搜索框中输入您想了解的词条,开始探索知识的海洋

+
+
+
+ +
+

数据来源:百度百科

+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/js/script.js b/frontend/react-app/public/60sapi/实用功能/百度百科词条/js/script.js new file mode 100644 index 00000000..6dbc4939 --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/js/script.js @@ -0,0 +1,324 @@ +// 百度百科词条查询应用 +class BaikeApp { + constructor() { + // API接口列表 + this.apiEndpoints = [ + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run', + 'https://60s.114128.xyz', + 'https://60s-cf.114128.xyz' + ]; + + this.currentApiIndex = 0; + this.isLoading = false; + + this.initElements(); + this.bindEvents(); + } + + // 初始化DOM元素 + initElements() { + this.searchInput = document.getElementById('searchInput'); + this.searchBtn = document.getElementById('searchBtn'); + this.resultSection = document.getElementById('resultSection'); + this.loading = document.getElementById('loading'); + this.resultCard = document.getElementById('resultCard'); + this.errorMessage = document.getElementById('errorMessage'); + this.welcomeMessage = document.getElementById('welcomeMessage'); + this.retryBtn = document.getElementById('retryBtn'); + + // 结果显示元素 + this.resultTitle = document.getElementById('resultTitle'); + this.resultDescription = document.getElementById('resultDescription'); + this.resultImage = document.getElementById('resultImage'); + this.resultAbstract = document.getElementById('resultAbstract'); + this.resultLink = document.getElementById('resultLink'); + this.errorText = document.getElementById('errorText'); + } + + // 绑定事件 + bindEvents() { + // 搜索按钮点击事件 + this.searchBtn.addEventListener('click', () => { + this.handleSearch(); + }); + + // 输入框回车事件 + this.searchInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + this.handleSearch(); + } + }); + + // 重试按钮事件 + this.retryBtn.addEventListener('click', () => { + this.handleSearch(); + }); + + // 输入框焦点事件 + this.searchInput.addEventListener('focus', () => { + this.searchInput.select(); + }); + } + + // 处理搜索 + async handleSearch() { + const query = this.searchInput.value.trim(); + + if (!query) { + this.showError('请输入要查询的词条'); + this.searchInput.focus(); + return; + } + + if (this.isLoading) { + return; + } + + await this.searchBaike(query); + } + + // 搜索百科词条 + async searchBaike(query) { + this.showLoading(); + this.isLoading = true; + + // 重置API索引 + this.currentApiIndex = 0; + + const success = await this.tryApiCall(query); + + if (!success) { + this.showError('所有API接口都无法访问,请稍后重试'); + } + + this.isLoading = false; + } + + // 尝试API调用 + async tryApiCall(query) { + for (let i = 0; i < this.apiEndpoints.length; i++) { + const endpoint = this.apiEndpoints[this.currentApiIndex]; + + try { + const result = await this.callApi(endpoint, query); + if (result) { + this.showResult(result); + return true; + } + } catch (error) { + console.warn(`API ${endpoint} 调用失败:`, error.message); + } + + // 切换到下一个API + this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length; + } + + return false; + } + + // 调用API + async callApi(endpoint, query) { + const url = `${endpoint}/v2/baike?word=${encodeURIComponent(query)}`; + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 + + try { + const response = await fetch(url, { + method: 'GET', + signal: controller.signal, + headers: { + 'Accept': 'application/json', + } + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + return data.data; + } else { + throw new Error(data.message || '未找到相关词条'); + } + + } catch (error) { + clearTimeout(timeoutId); + + if (error.name === 'AbortError') { + throw new Error('请求超时'); + } + + throw error; + } + } + + // 显示加载状态 + showLoading() { + this.hideAllSections(); + this.loading.style.display = 'flex'; + } + + // 显示搜索结果 + showResult(data) { + this.hideAllSections(); + + // 填充数据 + this.resultTitle.textContent = data.title || '未知标题'; + this.resultDescription.textContent = data.description || '暂无描述'; + this.resultAbstract.textContent = data.abstract || '暂无摘要信息'; + + // 处理图片 + if (data.cover) { + this.resultImage.src = data.cover; + this.resultImage.style.display = 'block'; + this.resultImage.onerror = () => { + this.resultImage.style.display = 'none'; + }; + } else { + this.resultImage.style.display = 'none'; + } + + // 处理链接 + if (data.link) { + this.resultLink.href = data.link; + this.resultLink.style.display = 'inline-flex'; + } else { + this.resultLink.style.display = 'none'; + } + + this.resultCard.style.display = 'block'; + + // 滚动到结果区域 + this.resultCard.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + + // 显示错误信息 + showError(message) { + this.hideAllSections(); + this.errorText.textContent = message; + this.errorMessage.style.display = 'flex'; + } + + // 隐藏所有区域 + hideAllSections() { + this.loading.style.display = 'none'; + this.resultCard.style.display = 'none'; + this.errorMessage.style.display = 'none'; + this.welcomeMessage.style.display = 'none'; + } + + // 显示欢迎信息 + showWelcome() { + this.hideAllSections(); + this.welcomeMessage.style.display = 'flex'; + } +} + +// 工具函数 +class Utils { + // 防抖函数 + static debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + } + + // 节流函数 + static throttle(func, limit) { + let inThrottle; + return function() { + const args = arguments; + const context = this; + if (!inThrottle) { + func.apply(context, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + }; + } + + // 格式化文本长度 + static truncateText(text, maxLength) { + if (text.length <= maxLength) { + return text; + } + return text.substring(0, maxLength) + '...'; + } + + // 检查是否为移动设备 + static isMobile() { + return window.innerWidth <= 768; + } +} + +// 页面加载完成后初始化应用 +document.addEventListener('DOMContentLoaded', () => { + // 初始化应用 + const app = new BaikeApp(); + + // 添加页面可见性变化监听 + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible') { + // 页面重新可见时,聚焦搜索框 + if (!app.isLoading) { + app.searchInput.focus(); + } + } + }); + + // 添加窗口大小变化监听 + window.addEventListener('resize', Utils.throttle(() => { + // 响应式调整 + if (Utils.isMobile()) { + // 移动端特殊处理 + document.body.classList.add('mobile'); + } else { + document.body.classList.remove('mobile'); + } + }, 250)); + + // 初始检查设备类型 + if (Utils.isMobile()) { + document.body.classList.add('mobile'); + } + + // 页面加载完成后聚焦搜索框 + setTimeout(() => { + app.searchInput.focus(); + }, 500); + + // 添加键盘快捷键支持 + document.addEventListener('keydown', (e) => { + // Ctrl/Cmd + K 聚焦搜索框 + if ((e.ctrlKey || e.metaKey) && e.key === 'k') { + e.preventDefault(); + app.searchInput.focus(); + app.searchInput.select(); + } + + // ESC 清空搜索框 + if (e.key === 'Escape') { + app.searchInput.value = ''; + app.showWelcome(); + app.searchInput.focus(); + } + }); + + console.log('百度百科词条查询应用已初始化'); +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/接口集合.json b/frontend/react-app/public/60sapi/实用功能/百度百科词条/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/实用功能/百度百科词条/返回接口.json b/frontend/react-app/public/60sapi/实用功能/百度百科词条/返回接口.json new file mode 100644 index 00000000..55ec21dc --- /dev/null +++ b/frontend/react-app/public/60sapi/实用功能/百度百科词条/返回接口.json @@ -0,0 +1,12 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "title": "西游记", + "description": "明代吴承恩创作的章回体长篇神魔小说", + "abstract": "《西游记》又名《西游释厄传》,是中国古代第一部浪漫主义章回体长篇神魔小说。最早的《西游记》版本是明代万历二十年金陵世德堂《新刻出像官板大字西游记》,未署作者姓名。鲁迅、董作宾等人根据《淮安府志》“吴承恩《西游记》”的记载予以最终论定“吴承恩原著”。该小说主要讲述了孙悟空出世,并寻菩提祖师学艺及大闹天宫后,与猪八戒、沙僧和白龙马一同护送唐僧西天取经,于路上历经险阻,降妖除魔,渡过了九九八十一难,成功...", + "cover": "https://bkimg.cdn.bcebos.com/pic/b7fd5266d01609248d763e43db0735fae6cd3412?x-bce-process=image/format,f_auto", + "has_other": true, + "link": "http://baike.baidu.com/subview/2583/5315045.htm" + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/历史上的今天/css/style.css b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/css/style.css new file mode 100644 index 00000000..93fb1485 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/css/style.css @@ -0,0 +1,388 @@ +/* 历史上的今天 - 手机端优先的响应式设计 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + color: #2c3e50; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 100%; + margin: 0 auto; + padding: 10px; +} + +/* 头部样式 - 手机端优先 */ +.header { + text-align: center; + margin-bottom: 20px; + background: rgba(255, 255, 255, 0.95); + border-radius: 15px; + padding: 20px 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 1.8rem; + color: #2c3e50; + margin-bottom: 8px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + flex-wrap: wrap; +} + +.header p { + color: #7f8c8d; + font-size: 0.9rem; + line-height: 1.4; +} + +/* 日期显示 */ +.date-info { + background: rgba(255, 255, 255, 0.95); + border-radius: 12px; + padding: 15px; + margin-bottom: 15px; + text-align: center; + box-shadow: 0 3px 15px rgba(0, 0, 0, 0.08); +} + +.date-info h2 { + font-size: 1.3rem; + color: #2c3e50; + margin-bottom: 5px; +} + +.date-info .date-text { + color: #7f8c8d; + font-size: 0.9rem; +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 30px 15px; + background: rgba(255, 255, 255, 0.95); + border-radius: 12px; + box-shadow: 0 3px 15px rgba(0, 0, 0, 0.08); +} + +.spinner { + width: 35px; + height: 35px; + border: 3px solid #ecf0f1; + border-top: 3px solid #667eea; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 15px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 历史事件容器 */ +.events-container { + background: rgba(255, 255, 255, 0.95); + border-radius: 15px; + padding: 15px; + margin-bottom: 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + backdrop-filter: blur(10px); +} + +/* 统计信息 */ +.stats { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 8px; + margin-bottom: 20px; +} + +.stat-item { + background: rgba(102, 126, 234, 0.1); + border-radius: 10px; + padding: 12px; + text-align: center; +} + +.stat-number { + font-size: 1.4rem; + font-weight: 700; + color: #667eea; + display: block; +} + +.stat-label { + color: #7f8c8d; + font-size: 0.8rem; + margin-top: 3px; +} + +/* 事件列表 */ +.events-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.event-card { + background: rgba(255, 255, 255, 0.9); + border-radius: 12px; + padding: 15px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; + border-left: 4px solid #667eea; + position: relative; +} + +.event-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); +} + +/* 事件类型标签 */ +.event-type { + position: absolute; + top: 10px; + right: 10px; + padding: 4px 8px; + border-radius: 12px; + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; +} + +.event-type.birth { + background: #e8f5e8; + color: #27ae60; +} + +.event-type.death { + background: #fdf2e9; + color: #e67e22; +} + +.event-type.event { + background: #ebf3fd; + color: #3498db; +} + +/* 事件年份 */ +.event-year { + font-size: 1.1rem; + font-weight: 700; + color: #667eea; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 8px; +} + +.event-year::before { + content: "📅"; + font-size: 1rem; +} + +/* 事件标题 */ +.event-title { + font-size: 1rem; + font-weight: 600; + color: #2c3e50; + margin-bottom: 8px; + line-height: 1.4; +} + +/* 事件描述 */ +.event-description { + color: #7f8c8d; + font-size: 0.85rem; + line-height: 1.5; + margin-bottom: 10px; +} + +/* 链接按钮 */ +.event-link { + display: inline-flex; + align-items: center; + gap: 5px; + color: #667eea; + text-decoration: none; + font-size: 0.8rem; + font-weight: 500; + padding: 6px 12px; + background: rgba(102, 126, 234, 0.1); + border-radius: 15px; + transition: all 0.3s ease; +} + +.event-link:hover { + background: rgba(102, 126, 234, 0.2); + transform: translateX(2px); +} + +.event-link::after { + content: "🔗"; + font-size: 0.7rem; +} + +/* 错误提示 */ +.error { + background: #fed7d7; + color: #c53030; + padding: 15px; + border-radius: 12px; + text-align: center; + border: 1px solid #feb2b2; + margin: 15px 0; + font-size: 0.9rem; +} + +/* 隐藏类 */ +.hidden { + display: none; +} + +/* 淡入动画 */ +.fade-in { + animation: fadeIn 0.6s ease-in; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 平板端适配 (768px+) */ +@media (min-width: 768px) { + .container { + max-width: 750px; + padding: 20px; + } + + .header { + padding: 30px 25px; + } + + .header h1 { + font-size: 2.2rem; + } + + .header p { + font-size: 1rem; + } + + .date-info { + padding: 20px; + } + + .date-info h2 { + font-size: 1.5rem; + } + + .events-container { + padding: 25px; + } + + .stats { + gap: 15px; + } + + .event-card { + padding: 20px; + } + + .event-title { + font-size: 1.1rem; + } + + .event-description { + font-size: 0.9rem; + } +} + +/* 电脑端适配 (1024px+) */ +@media (min-width: 1024px) { + .container { + max-width: 1000px; + padding: 30px; + } + + .header { + padding: 40px 35px; + } + + .header h1 { + font-size: 2.5rem; + } + + .events-list { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; + } + + .event-card { + padding: 25px; + } + + .event-title { + font-size: 1.2rem; + } + + .event-description { + font-size: 0.95rem; + } +} + +/* 大屏幕优化 (1200px+) */ +@media (min-width: 1200px) { + .container { + max-width: 1200px; + padding: 40px; + } + + .events-list { + grid-template-columns: repeat(3, 1fr); + gap: 25px; + } +} + +/* 滚动条样式 */ +::-webkit-scrollbar { + width: 6px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); +} + +::-webkit-scrollbar-thumb { + background: rgba(102, 126, 234, 0.5); + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(102, 126, 234, 0.7); +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/历史上的今天/index.html b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/index.html new file mode 100644 index 00000000..2f941a44 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/index.html @@ -0,0 +1,83 @@ + + + + + + + + 历史上的今天 - 60s API集合 + + + + + + + + + + + + + +
+ +
+

📚 历史上的今天

+

探索历史,了解今天在历史上发生的重要事件

+
+ + +
+
+ 加载中... +
+
+ + +
+
+

正在加载历史数据...

+
+ + +
+ + + +
+

历史事件

+
+
+ +
+
+
+
+ +
+ + + + + + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/历史上的今天/js/script.js b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/js/script.js new file mode 100644 index 00000000..986eac74 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/js/script.js @@ -0,0 +1,295 @@ +// 历史上的今天 - JavaScript 功能实现 + +// API 配置 +const API = { + endpoints: [], + currentIndex: 0, + encoding: 'utf-8', + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/today_in_history`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/today_in_history']; + } + }, + // 获取当前接口URL + getCurrentUrl() { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + url.searchParams.append('encoding', this.encoding); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } +}; + +// 事件类型映射 +const EVENT_TYPE_MAP = { + 'birth': { name: '诞生', icon: '🎂', color: '#27ae60' }, + 'death': { name: '逝世', icon: '🕊️', color: '#e67e22' }, + 'event': { name: '事件', icon: '📰', color: '#3498db' } +}; + +// DOM 元素 +let elements = {}; +let currentData = null; + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', function() { + initElements(); + loadTodayInHistory(); +}); + +// 初始化 DOM 元素 +function initElements() { + elements = { + loading: document.getElementById('loading'), + content: document.getElementById('history-content'), + dateInfo: document.getElementById('date-info'), + dateText: document.getElementById('date-text'), + totalEvents: document.getElementById('total-events'), + birthEvents: document.getElementById('birth-events'), + deathEvents: document.getElementById('death-events'), + otherEvents: document.getElementById('other-events'), + eventsList: document.getElementById('events-list') + }; +} + +// 加载历史上的今天数据 +async function loadTodayInHistory() { + try { + showLoading(true); + + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const response = await fetch(url, { + cache: 'no-store', + timeout: 10000 // 10秒超时 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + console.log('API响应数据:', data); + + if (data.code === 200 && data.data) { + console.log(`接口 ${i + 1} 请求成功`); + currentData = data.data; + displayHistoryData(data.data); + return; + } else { + throw new Error(data.message || '获取数据失败'); + } + + } catch (error) { + console.warn(`接口 ${i + 1} 失败:`, error.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了,抛出错误 + throw new Error('所有接口都无法访问'); + } + } + + } catch (error) { + console.error('加载历史数据失败:', error); + showError(`加载失败: ${error.message}`); + } finally { + showLoading(false); + } +} + +// 显示历史数据 +function displayHistoryData(data) { + if (!data || !data.items) { + showError('没有获取到历史数据'); + return; + } + + // 更新日期信息 + updateDateInfo(data); + + // 更新统计信息 + updateStats(data.items); + + // 显示事件列表 + renderEventsList(data.items); + + // 显示内容区域 + if (elements.content) { + elements.content.classList.add('fade-in'); + elements.content.style.display = 'block'; + } +} + +// 更新日期信息 +function updateDateInfo(data) { + if (elements.dateText && data.date) { + const today = new Date(); + const year = today.getFullYear(); + elements.dateText.textContent = `${year}年${data.month}月${data.day}日`; + } +} + +// 更新统计信息 +function updateStats(items) { + const stats = { + total: items.length, + birth: items.filter(item => item.event_type === 'birth').length, + death: items.filter(item => item.event_type === 'death').length, + event: items.filter(item => item.event_type === 'event').length + }; + + if (elements.totalEvents) { + elements.totalEvents.textContent = stats.total; + } + + if (elements.birthEvents) { + elements.birthEvents.textContent = stats.birth; + } + + if (elements.deathEvents) { + elements.deathEvents.textContent = stats.death; + } + + if (elements.otherEvents) { + elements.otherEvents.textContent = stats.event; + } +} + +// 渲染事件列表 +function renderEventsList(items) { + if (!elements.eventsList || !items) return; + + // 按年份排序(从今到古) + const sortedItems = [...items].sort((a, b) => { + return parseInt(b.year) - parseInt(a.year); + }); + + elements.eventsList.innerHTML = ''; + + sortedItems.forEach(item => { + const eventCard = createEventCard(item); + elements.eventsList.appendChild(eventCard); + }); +} + +// 创建事件卡片 +function createEventCard(item) { + const card = document.createElement('div'); + card.className = 'event-card'; + + const eventType = EVENT_TYPE_MAP[item.event_type] || EVENT_TYPE_MAP['event']; + + card.innerHTML = ` +
${eventType.name}
+
${formatYear(item.year)}
+
${escapeHtml(item.title)}
+
${escapeHtml(item.description)}
+ ${item.link ? `了解更多` : ''} + `; + + return card; +} + +// 格式化年份显示 +function formatYear(year) { + const yearNum = parseInt(year); + if (yearNum < 0) { + return `公元前${Math.abs(yearNum)}年`; + } else if (yearNum < 1000) { + return `公元${yearNum}年`; + } else { + return `${yearNum}年`; + } +} + +// 显示加载状态 +function showLoading(show) { + if (elements.loading) { + elements.loading.style.display = show ? 'block' : 'none'; + } + + if (elements.content) { + elements.content.style.display = show ? 'none' : 'block'; + } +} + +// 显示错误信息 +function showError(message) { + if (elements.content) { + elements.content.innerHTML = ` +
+

😔 加载失败

+

${escapeHtml(message)}

+ +
+ `; + elements.content.style.display = 'block'; + } +} + +// HTML 转义 +function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +// 错误处理 +window.addEventListener('error', function(event) { + console.error('页面错误:', event.error); +}); + +// 网络状态监听 +window.addEventListener('online', function() { + console.log('网络已连接'); +}); + +window.addEventListener('offline', function() { + console.log('网络已断开'); + showError('网络连接已断开,请检查网络设置'); +}); + +// 导出全局方法 +window.TodayInHistory = { + loadTodayInHistory, + showError, + showLoading +}; \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/历史上的今天/接口集合.json b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/日更资讯/历史上的今天/返回接口.json b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/返回接口.json new file mode 100644 index 00000000..8531e735 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/历史上的今天/返回接口.json @@ -0,0 +1,102 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "date": "8-19", + "month": 8, + "day": 19, + "items": [ + { + "title": "罗马帝国开国皇帝奥古斯都逝世", + "year": "14", + "description": "奥古斯都(拉丁文 Augustus的中译,复数型 Augusti)的原意为“神圣的”、“高贵的”,带有宗教与神学式的意味。", + "event_type": "death", + "link": "https://baike.baidu.com/item/%E5%A5%A5%E5%8F%A4%E6%96%AF%E9%83%BD/14291" + }, + { + "title": "近代概率论的奠基者帕斯卡逝世", + "year": "1662", + "description": "布莱士·帕斯卡(Blaise Pascal ,1623-1662)是法国数学家、物理学家、哲学家、散文家。", + "event_type": "death", + "link": "https://baike.baidu.com/item/%E5%B8%83%E8%8E%B1%E5%A3%AB%C2%B7%E5%B8%95%E6%96%AF%E5%8D%A1" + }, + { + "title": "瑞典国王古斯塔夫三世发动政变夺取权力", + "year": "1772", + "description": "古斯塔夫三世(Gustavus III,1746-1792)是瑞典历史上褒贬最多的国王(1771-1792)。阿道夫·弗里德里克国王的儿子和继承者。", + "event_type": "event", + "link": "https://baike.baidu.com/item/%E5%8F%A4%E6%96%AF%E5%A1%94%E5%A4%AB%E4%B8%89%E4%B8%96" + }, + { + "title": "美国飞机设计师奥维尔·莱特诞生", + "year": "1871", + "description": "奥威尔莱特(公元1871~公元1948)。 奥维尔·莱特1871年生于美国俄亥俄州代顿市。上过中学,但实际上未获得毕业文凭。", + "event_type": "birth", + "link": "https://baike.baidu.com/item/%E5%A5%A5%E7%BB%B4%E5%B0%94%C2%B7%E8%8E%B1%E7%89%B9" + }, + { + "title": "法国著名时装设计师、香奈儿品牌创始人加布里埃·香奈儿出生", + "year": "1883", + "description": "香奈儿儿时入读修女院学校学得一手针线活。后来她与许多上流社会男士有过交往。1910年,毅然放弃嫁入豪门做阔太太的她在巴黎开设了一家女装帽子店,从此开创了香奈儿时尚帝国。", + "event_type": "birth", + "link": "https://baike.baidu.com/item/%E5%8A%A0%E5%B8%83%E9%87%8C%E5%9F%83%C2%B7%E9%A6%99%E5%A5%88%E5%84%BF/9480318" + }, + { + "title": "美国宇航员斯托里·马斯格雷夫出生", + "year": "1935", + "description": "斯托里·马斯格雷夫(Franklin Story Musgrave,1935年8月19日-),美国宇航员,拥有医学、数学、文学等六个学位,入选美国国家航空航天局(NASA)科学家宇航员。", + "event_type": "birth", + "link": "https://baike.baidu.com/item/%E6%96%AF%E6%89%98%E9%87%8C%C2%B7%E9%A9%AC%E6%96%AF%E6%A0%BC%E9%9B%B7%E5%A4%AB" + }, + { + "title": "纳粹德国陆军元帅京特·冯·克鲁格畏罪自杀", + "year": "1944", + "description": "汉斯·京特·冯·克卢格(Günther·von·Kluge, 1882年10月30日-1944年8月19日),纳粹德国陆军元帅(1940.7.19),著名军事家、统帅。", + "event_type": "death", + "link": "https://baike.baidu.com/item/%E4%BA%AC%E7%89%B9%C2%B7%E5%86%AF%C2%B7%E5%85%8B%E9%B2%81%E6%A0%BC" + }, + { + "title": "美国第42任总统克林顿出生", + "year": "1946", + "description": "威廉·杰斐逊·克林顿,美国律师、政治家,美国民主党成员,曾任阿肯色州州长和第42任美国总统。克林顿基金会主席 。", + "event_type": "birth", + "link": "https://baike.baidu.com/item/%E5%A8%81%E5%BB%89%C2%B7%E6%9D%B0%E6%96%90%E9%80%8A%C2%B7%E5%85%8B%E6%9E%97%E9%A1%BF" + }, + { + "title": "美国演员马修·派瑞出生", + "year": "1969", + "description": "马修·派瑞(Matthew Perry,1969年8月19日—2023年10月28日),出生于美国马萨诸塞州普利茅斯,美国、加拿大籍男演员、编剧。", + "event_type": "birth", + "link": "https://baike.baidu.com/item/%E9%A9%AC%E4%BF%AE%C2%B7%E6%B4%BE%E7%91%9E" + }, + { + "title": "北回归线标志塔在广州落成", + "year": "1985", + "description": "北回归线标志塔,是标志地理学上北回归线经过地方的建筑物。", + "event_type": "event", + "link": "https://baike.baidu.com/item/%E5%8C%97%E5%9B%9E%E5%BD%92%E7%BA%BF%E6%A0%87%E5%BF%97%E5%A1%94" + }, + { + "title": "“八一九事件”,苏联八月政变", + "year": "1991", + "description": "八一九事件,又称“苏联政变”、“八月政变”,指1991年8月19日-8月21日在苏联发生的一次政变。", + "event_type": "event", + "link": "https://baike.baidu.com/item/%E5%85%AB%E4%B8%80%E4%B9%9D%E4%BA%8B%E4%BB%B6" + }, + { + "title": "量子化学家莱纳斯·卡尔·鲍林逝世", + "year": "1994", + "description": "莱纳斯·卡尔·鲍林(Linus Carl Pauling,1901年2月28日—1994年8月19日),出生于美国俄勒冈州波特兰,化学家、美国国家科学院院士、美国艺术与科学院院士,1954年诺贝尔化学奖获得者。", + "event_type": "death", + "link": "https://baike.baidu.com/item/%E8%8E%B1%E7%BA%B3%E6%96%AF%C2%B7%E5%8D%A1%E5%B0%94%C2%B7%E9%B2%8D%E6%9E%97" + }, + { + "title": "中国三江源自然保护区成立", + "year": "2000", + "description": "青海三江源国家级自然保护区位于青藏高原腹地,青海省南部,地理位置介于东经89°24′~102°23′,北纬31°39′~36°16′之间,青海三江源国家级自然保护区属湿地类型的自然保护区。", + "event_type": "event", + "link": "https://baike.baidu.com/item/%E4%B8%89%E6%B1%9F%E6%BA%90%E8%87%AA%E7%84%B6%E4%BF%9D%E6%8A%A4%E5%8C%BA" + } + ] + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/css/style.css b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/css/style.css new file mode 100644 index 00000000..ac8ca0e5 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/css/style.css @@ -0,0 +1,326 @@ +/* 必应每日壁纸 - 淡绿色清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2.5rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 15px; +} + +.header p { + color: #5a7c65; + font-size: 1.1rem; +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 壁纸容器 */ +.wallpaper-container { + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); + margin-bottom: 20px; +} + +/* 壁纸信息 */ +.wallpaper-info { + text-align: center; + margin-bottom: 25px; +} + +.wallpaper-title { + font-size: 1.8rem; + font-weight: 700; + color: #2d5016; + margin-bottom: 10px; +} + +.wallpaper-date { + color: #5a7c65; + font-size: 1rem; + margin-bottom: 15px; +} + +.wallpaper-description { + color: #2d5016; + font-size: 1.1rem; + line-height: 1.6; + max-width: 800px; + margin: 0 auto; +} + +/* 壁纸图片 */ +.wallpaper-image { + position: relative; + border-radius: 15px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(45, 80, 22, 0.15); + margin: 20px 0; +} + +.wallpaper-image img { + width: 100%; + height: auto; + display: block; + transition: transform 0.3s ease; +} + +.wallpaper-image:hover img { + transform: scale(1.02); +} + +/* 下载按钮 */ +.download-section { + text-align: center; + margin-top: 25px; +} + +.download-btn { + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + border: none; + padding: 15px 30px; + border-radius: 25px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3); + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 10px; +} + +.download-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4); +} + +.download-btn:active { + transform: translateY(0); +} + +/* 错误提示 */ +.error { + background: #fed7d7; + color: #c53030; + padding: 20px; + border-radius: 15px; + text-align: center; + border: 1px solid #feb2b2; + margin: 20px 0; +} + +/* 版权信息 */ +.copyright { + background: rgba(255, 255, 255, 0.7); + border-radius: 15px; + padding: 20px; + text-align: center; + color: #5a7c65; + font-size: 0.9rem; + margin-top: 20px; +} + +/* 响应式设计 */ + +/* 平板端 */ +@media (max-width: 768px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2rem; + flex-direction: column; + gap: 10px; + } + + .header { + padding: 20px; + } + + .wallpaper-container { + padding: 20px; + } + + .wallpaper-title { + font-size: 1.5rem; + } + + .wallpaper-description { + font-size: 1rem; + } +} + +/* 手机端 */ +@media (max-width: 480px) { + .container { + padding: 10px; + } + + .header { + padding: 15px; + margin-bottom: 20px; + } + + .header h1 { + font-size: 1.8rem; + } + + .wallpaper-container { + padding: 15px; + } + + .wallpaper-title { + font-size: 1.3rem; + } + + .wallpaper-description { + font-size: 0.95rem; + } + + .download-btn { + padding: 12px 25px; + font-size: 1rem; + width: 100%; + justify-content: center; + } + + .copyright { + padding: 15px; + font-size: 0.8rem; + } +} + +/* 大屏幕优化 */ +@media (min-width: 1200px) { + .container { + padding: 40px; + } + + .header { + padding: 40px; + } + + .wallpaper-container { + padding: 40px; + } + + .wallpaper-image { + max-height: 70vh; + overflow: hidden; + } + + .wallpaper-image img { + width: 100%; + height: 100%; + object-fit: cover; + } +} + +/* 特殊效果 */ +.fade-in { + animation: fadeIn 0.6s ease-in; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 图片加载效果 */ +.wallpaper-image img { + opacity: 0; + transition: opacity 0.3s ease; +} + +.wallpaper-image img.loaded { + opacity: 1; +} + +/* 滚动条样式 */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); +} + +::-webkit-scrollbar-thumb { + background: rgba(129, 199, 132, 0.5); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(129, 199, 132, 0.7); +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/index.html b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/index.html new file mode 100644 index 00000000..ac3ecb85 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/index.html @@ -0,0 +1,42 @@ + + + + + + + + 必应每日壁纸 + + + + + + + + +
+ +
+

+ 🖼️ + 必应每日壁纸 +

+

每天为您呈现精美的必应壁纸,发现世界之美

+
+ + +
+
+

正在加载今日壁纸...

+
+ + +
+ +
+
+ + + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/js/script.js b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/js/script.js new file mode 100644 index 00000000..9e231288 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/js/script.js @@ -0,0 +1,315 @@ +// 必应每日壁纸 JavaScript 功能 + +// API配置 +const API = { + endpoints: [], + currentIndex: 0, + params: { + encoding: 'json' + }, + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/bing`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/bing']; + } + }, + // 获取当前接口URL + getCurrentUrl() { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + Object.keys(this.params).forEach(key => { + url.searchParams.append(key, this.params[key]); + }); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } +}; + +// DOM元素 +let elements = {}; + +// 初始化 +document.addEventListener('DOMContentLoaded', function() { + initElements(); + loadWallpaper(); +}); + +// 初始化DOM元素 +function initElements() { + elements = { + container: document.getElementById('wallpaper-content'), + loading: document.getElementById('loading') + }; +} + +// 加载壁纸数据 +async function loadWallpaper() { + try { + showLoading(true); + + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const response = await fetch(url, { + cache: 'no-store', + timeout: 10000 // 10秒超时 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + console.log('API响应数据:', data); + + // 检查数据有效性 + if (data && (data.code === 200 || data.data)) { + console.log(`接口 ${i + 1} 请求成功`); + displayWallpaper(data); + return; + } + + throw new Error(data && data.message ? data.message : '接口返回异常'); + + } catch (error) { + console.warn(`接口 ${i + 1} 失败:`, error.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了,抛出错误 + throw new Error('所有接口都无法访问'); + } + } + + } catch (error) { + console.error('加载壁纸失败:', error); + showError('加载壁纸失败,请稍后重试'); + } finally { + showLoading(false); + } +} + +// 显示壁纸 +function displayWallpaper(data) { + if (!data) { + showError('没有获取到壁纸数据'); + return; + } + + // 提取壁纸信息 + const wallpaperInfo = extractWallpaperInfo(data); + + if (!wallpaperInfo || !wallpaperInfo.imageUrl) { + showError('壁纸图片链接无效'); + return; + } + + // 生成HTML内容 + const html = generateWallpaperHTML(wallpaperInfo); + + // 显示内容 + elements.container.innerHTML = html; + elements.container.classList.add('fade-in'); + + // 绑定图片加载事件 + bindImageEvents(); +} + +// 提取壁纸信息 +function extractWallpaperInfo(data) { + // 根据API响应结构提取信息 + let imageUrl = ''; + let title = '必应每日壁纸'; + let description = ''; + let date = new Date().toLocaleDateString('zh-CN'); + let copyright = ''; + + // 处理新的API响应格式 + if (data.data) { + const wallpaperData = data.data; + title = wallpaperData.title || title; + description = wallpaperData.description || wallpaperData.main_text || ''; + copyright = wallpaperData.copyright || ''; + date = wallpaperData.update_date || date; + + // 提取图片URL,去除反引号 + if (wallpaperData.cover) { + imageUrl = wallpaperData.cover.replace(/`/g, '').trim(); + } + } + // 处理其他可能的API响应格式 + else if (data.url) { + imageUrl = data.url; + } else if (data.image_url) { + imageUrl = data.image_url; + } else if (data.images && data.images.length > 0) { + imageUrl = data.images[0].url || data.images[0].image_url; + title = data.images[0].title || title; + description = data.images[0].description || data.images[0].copyright || ''; + copyright = data.images[0].copyright || ''; + } + + // 如果是相对路径,转换为完整URL + if (imageUrl && imageUrl.startsWith('/')) { + imageUrl = 'https://www.bing.com' + imageUrl; + } + + // 确保图片URL有效 + if (!imageUrl || imageUrl === '') { + console.error('无法提取图片URL,原始数据:', data); + return null; + } + + return { + imageUrl, + title, + description: description || copyright, + date, + copyright + }; +} + +// 生成壁纸HTML +function generateWallpaperHTML(info) { + return ` +
+
+

${escapeHtml(info.title)}

+
${info.date}
+ ${info.description ? `
${escapeHtml(info.description)}
` : ''} +
+ +
+ ${escapeHtml(info.title)} +
+ + +
+ + ${info.copyright ? ` + + ` : ''} + `; +} + +// 绑定图片事件 +function bindImageEvents() { + const images = elements.container.querySelectorAll('img'); + + images.forEach(img => { + img.addEventListener('load', function() { + this.classList.add('loaded'); + }); + + img.addEventListener('error', function() { + console.error('图片加载失败:', this.src); + this.parentElement.innerHTML = ` +
+

🖼️ 图片加载失败

+

请检查网络连接或稍后重试

+
+ `; + }); + }); +} + +// 显示/隐藏加载状态 +function showLoading(show) { + if (elements.loading) { + elements.loading.style.display = show ? 'block' : 'none'; + } + if (elements.container) { + elements.container.style.display = show ? 'none' : 'block'; + } +} + +// 显示错误信息 +function showError(message) { + if (elements.container) { + elements.container.innerHTML = ` +
+

⚠️ 加载失败

+

${escapeHtml(message)}

+

请检查网络连接或稍后重试

+
+ `; + elements.container.style.display = 'block'; + } +} + +// HTML转义 +function escapeHtml(text) { + if (!text) return ''; + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +// 格式化日期 +function formatDate(dateString) { + try { + const date = new Date(dateString); + return date.toLocaleDateString('zh-CN', { + year: 'numeric', + month: 'long', + day: 'numeric' + }); + } catch (error) { + return dateString; + } +} + +// 错误处理 +window.addEventListener('error', function(event) { + console.error('页面错误:', event.error); +}); + +// 网络状态监听 +window.addEventListener('online', function() { + console.log('网络已连接'); +}); + +window.addEventListener('offline', function() { + console.log('网络已断开'); + showError('网络连接已断开,请检查网络设置'); +}); + +// 导出函数供外部调用 +window.BingWallpaper = { + loadWallpaper, + showError, + showLoading +}; \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/接口集合.json b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/返回接口.json b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/返回接口.json new file mode 100644 index 00000000..2c6a72a4 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/必应每日壁纸/返回接口.json @@ -0,0 +1,15 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "title": "瑟沃格湖,瓦加尔岛,法罗群岛", + "headline": "海洋上方的湖泊", + "description": "大自然自有其奇妙之处,瑟沃格湖(Sørvágsvatn)便是其中最精彩的之一。世界湖泊日是探索法罗群岛(丹麦王国的一个自治行政区)这片视错觉的绝佳时机。这座位于沃格岛上的湖泊也被称为莱蒂斯湖(Leitisvatn),看似漂浮在海平面之上。实际上,它的海拔不到100英尺。索尔瓦格斯湖是法罗群岛最大的湖泊,面积约1.3平方英里,为Bøsdalafossur瀑布Bøsdalafossur提供水源,瀑布的湖水在那里奔腾而下,最终倾泻而入大海。", + "main_text": "该湖位于瓦加尔岛南部,通过Bøsdalafossur瀑布与大西洋相连,形成了壮丽的“悬湖”景观。", + "cover": "https://bing.com/th?id=OHR.FaroeLake_ZH-CN3977660997_1920x1080.jpg", + "cover_4k": "https://bing.com/th?id=OHR.FaroeLake_ZH-CN3977660997_UHD.jpg", + "copyright": "© Anton Petrus/Getty Images", + "update_date": "2025-08-27 13:24:37", + "update_date_at": 1756301077809 + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/css/style.css b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/css/style.css new file mode 100644 index 00000000..9bd66ac6 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/css/style.css @@ -0,0 +1,327 @@ +/* 每天60s读懂世界 - 清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2.5rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; +} + +.header p { + color: #5a7c65; + font-size: 1.1rem; +} + +/* 控制面板 */ +.controls { + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + padding: 20px; + margin-bottom: 30px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.date-selector { + display: flex; + align-items: center; + gap: 15px; + margin-bottom: 20px; + flex-wrap: wrap; +} + +.date-selector label { + font-weight: 600; + color: #4a5568; +} + +.date-selector input { + padding: 10px 15px; + border: 2px solid #e2e8f0; + border-radius: 10px; + font-size: 1rem; + transition: all 0.3s ease; +} + +.date-selector input:focus { + outline: none; + border-color: #81c784; + box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.1); +} + +.btn { + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + border: none; + padding: 12px 25px; + border-radius: 10px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3); +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4); +} + +.btn:active { + transform: translateY(0); +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 内容区域 */ +.content { + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.news-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 25px; + flex-wrap: wrap; + gap: 15px; +} + +.news-date { + font-size: 1.5rem; + font-weight: 700; + color: #2d5016; +} + +.lunar-date { + color: #5a7c65; + font-size: 1rem; +} + +/* 新闻图片 */ +.news-image { + width: 100%; + max-width: 600px; + height: auto; + border-radius: 15px; + margin: 20px auto; + display: block; + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); +} + +/* 新闻列表 */ +.news-list { + margin: 25px 0; +} + +.news-item { + background: #f1f8e9; + border-left: 4px solid #81c784; + padding: 15px 20px; + margin-bottom: 15px; + border-radius: 0 10px 10px 0; + transition: all 0.3s ease; + position: relative; +} + +.news-item:hover { + background: #e8f5e8; + transform: translateX(5px); + box-shadow: 0 4px 15px rgba(45, 80, 22, 0.1); +} + +.news-item::before { + content: counter(news-counter); + counter-increment: news-counter; + position: absolute; + left: -15px; + top: 50%; + transform: translateY(-50%); + background: #81c784; + color: white; + width: 25px; + height: 25px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.8rem; + font-weight: bold; +} + +.news-list { + counter-reset: news-counter; +} + +/* 每日一句 */ +.daily-tip { + background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); + padding: 20px; + border-radius: 15px; + margin: 25px 0; + text-align: center; + font-style: italic; + font-size: 1.1rem; + color: #744210; + box-shadow: 0 5px 20px rgba(252, 182, 159, 0.3); +} + +/* 错误提示 */ +.error { + background: #fed7d7; + color: #c53030; + padding: 20px; + border-radius: 10px; + text-align: center; + border: 1px solid #feb2b2; +} + +/* 响应式设计 */ + +/* 平板端 */ +@media (max-width: 768px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2rem; + } + + .header { + padding: 20px; + } + + .content { + padding: 20px; + } + + .date-selector { + flex-direction: column; + align-items: stretch; + } + + .news-header { + flex-direction: column; + align-items: flex-start; + } +} + +/* 手机端 */ +@media (max-width: 480px) { + .container { + padding: 10px; + } + + .header { + padding: 15px; + margin-bottom: 20px; + } + + .header h1 { + font-size: 1.8rem; + } + + .controls { + padding: 15px; + } + + .content { + padding: 15px; + } + + .news-item { + padding: 12px 15px; + margin-left: 10px; + } + + .news-item::before { + left: -10px; + width: 20px; + height: 20px; + font-size: 0.7rem; + } + + .daily-tip { + padding: 15px; + font-size: 1rem; + } + + .btn { + width: 100%; + padding: 15px; + } +} + +/* 大屏幕优化 */ +@media (min-width: 1200px) { + .container { + padding: 40px; + } + + .header { + padding: 40px; + } + + .content { + padding: 40px; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/index.html b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/index.html new file mode 100644 index 00000000..3240ff17 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/index.html @@ -0,0 +1,49 @@ + + + + + + + + 每天60秒读懂世界 | 最新资讯 + + + + + + + + + + + + + +
+ +
+

📰 每天60秒读懂世界

+

获取最新资讯,了解天下大事

+
+ + + + +
+ +
+
+

正在加载今日资讯...

+
+
+
+ + +
+

Made with ❤️ | 数据来源:每天60秒读懂世界API

+
+ + + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/js/script.js b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/js/script.js new file mode 100644 index 00000000..63c2d19f --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/js/script.js @@ -0,0 +1,305 @@ +// 每天60s读懂世界 - JavaScript功能实现 + +const API = { + endpoints: [], + currentIndex: 0, + params: { + encoding: 'json' + }, + localFallback: '返回接口.json', + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/60s`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/60s']; + } + }, + // 获取当前接口URL + getCurrentUrl() { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v)); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } +}; + +class NewsApp { + constructor() { + this.apiUrl = 'https://60s.viki.moe/v2/60s'; + this.init(); + } + + init() { + this.bindEvents(); + this.loadTodayNews(); + } + + bindEvents() { + // 移除了刷新按钮,不需要绑定事件 + } + + formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + } + + showLoading() { + const contentDiv = document.getElementById('content'); + if (contentDiv) { + contentDiv.innerHTML = ` +
+
+

正在获取最新资讯...

+
+ `; + } + } + + showError(message) { + const contentDiv = document.getElementById('content'); + if (contentDiv) { + contentDiv.innerHTML = ` +
+

😔 获取失败

+

${message}

+
+ `; + } + } + + async loadNews() { + try { + this.showLoading(); + + // 尝试从API获取数据 + let data = await this.fetchFromAPI(); + + // 如果API失败,尝试本地数据 + if (!data) { + data = await this.fetchFromLocal(); + } + + if (!data) { + throw new Error('无法获取数据,请检查网络连接或稍后重试'); + } + + if (data.code !== 200) { + throw new Error(data.message || '获取数据失败'); + } + + this.renderNews(data.data); + + } catch (error) { + console.error('获取新闻失败:', error); + this.showError(error.message || '网络连接失败,请检查网络后重试'); + } + } + + async fetchFromAPI() { + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const resp = await fetch(url, { + cache: 'no-store' + }); + + if (!resp.ok) { + throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); + } + + const data = await resp.json(); + + if (data && data.code === 200) { + console.log(`接口 ${i + 1} 请求成功`); + return data; + } + + throw new Error(data && data.message ? data.message : '接口返回异常'); + + } catch (e) { + console.warn(`接口 ${i + 1} 失败:`, e.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了 + console.warn('所有远程接口都失败,尝试本地数据'); + return null; + } + } + } + + async fetchFromLocal() { + try { + const resp = await fetch(API.localFallback + `?t=${Date.now()}`); + if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`); + const data = await resp.json(); + return data; + } catch (e) { + console.error('读取本地返回接口.json失败:', e); + return null; + } + } + + loadTodayNews() { + this.loadNews(); + } + + renderNews(newsData) { + const contentDiv = document.getElementById('content'); + if (!contentDiv || !newsData) return; + + const { + date, + day_of_week, + lunar_date, + news, + tip, + link + } = newsData; + + let newsListHtml = ''; + if (news && news.length > 0) { + newsListHtml = news.map(item => ` +
+ ${this.escapeHtml(item)} +
+ `).join(''); + } + + // 移除图片显示功能 + + const tipHtml = tip ? ` +
+ 💡 ${this.escapeHtml(tip)} +
+ ` : ''; + + const linkHtml = link ? ` + + ` : ''; + + contentDiv.innerHTML = ` +
+
+
${this.escapeHtml(date)} ${this.escapeHtml(day_of_week || '')}
+ ${lunar_date ? `
${this.escapeHtml(lunar_date)}
` : ''} +
+
+ + ${tipHtml} + +
+

📰 今日要闻

+ ${newsListHtml} +
+ + ${linkHtml} + +
+

数据来源:每天60秒读懂世界

+

更新时间:${newsData.api_updated || '未知'}

+
+ `; + } + + escapeHtml(text) { + if (typeof text !== 'string') return text; + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } +} + +// 页面加载完成后初始化应用 +document.addEventListener('DOMContentLoaded', function() { + window.newsApp = new NewsApp(); +}); + +// 添加一些实用功能 +function copyToClipboard(text) { + navigator.clipboard.writeText(text).then(() => { + showToast('已复制到剪贴板'); + }).catch(() => { + showToast('复制失败,请手动复制'); + }); +} + +function showToast(message) { + // 创建提示框 + const toast = document.createElement('div'); + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: #4a5568; + color: white; + padding: 12px 20px; + border-radius: 8px; + z-index: 1000; + font-size: 14px; + box-shadow: 0 4px 12px rgba(0,0,0,0.3); + animation: slideIn 0.3s ease; + `; + toast.textContent = message; + + // 添加动画样式 + const style = document.createElement('style'); + style.textContent = ` + @keyframes slideIn { + from { transform: translateX(100%); opacity: 0; } + to { transform: translateX(0); opacity: 1; } + } + `; + document.head.appendChild(style); + + document.body.appendChild(toast); + + // 3秒后自动移除 + setTimeout(() => { + toast.remove(); + style.remove(); + }, 3000); +} + +// 添加键盘快捷键支持 +document.addEventListener('keydown', function(e) { + // Ctrl/Cmd + R 刷新数据 + if ((e.ctrlKey || e.metaKey) && e.key === 'r') { + e.preventDefault(); + if (window.newsApp) { + window.newsApp.loadNews(); + } + } +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/接口集合.json b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/返回接口.json b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/返回接口.json new file mode 100644 index 00000000..7804d62a --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每天60s读懂世界/返回接口.json @@ -0,0 +1,66 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "id": "9aa227e2ba294bb1a95c95fde892eb31", + "title": "《Totally Reliable Delivery Service》 Standard Edition", + "cover": "https://cdn1.epicgames.com/52b90f9a982a404781b189f6a7903226/offer/EGS_TotallyReliableDeliveryService_WereFiveGames_S1-2560x1440-47e6e9562d62705a75ea7b7096d0b8dc.jpg", + "original_price": 52, + "original_price_desc": "¥52.00", + "description": "穿好护腰护具,发动货车,送货的时间到啦!在一个高度互动的沙盒世界中,与最多三位好友一起随意地完成送货。货物已试投,这就是我们靠谱快递(Totally Reliable Delivery Service)的品质保证!", + "seller": "Infogrames LLC", + "is_free_now": true, + "free_start": "2025/08/14 23:00:00", + "free_start_at": 1755183600000, + "free_end": "2025/08/21 23:00:00", + "free_end_at": 1755788400000, + "link": "https://store.epicgames.com/store/zh-CN/p/totally-reliable-delivery-service/home" + }, + { + "id": "8ea3500dc38e4f429702bf889c172d3d", + "title": "Hidden Folks", + "cover": "https://cdn1.epicgames.com/spt-assets/7bfd56b0586348dcb139945d9e59f988/hidden-folks-1b7hh.png", + "original_price": 47, + "original_price_desc": "¥47.00", + "description": "Search for hidden folks in hand-drawn, interactive, miniature landscapes. Unfurl tent flaps, cut through bushes, slam doors, and poke some crocodiles! Rooooaaaarrrr!!!!!", + "seller": "Adriaan de Jongh", + "is_free_now": true, + "free_start": "2025/08/14 23:00:00", + "free_start_at": 1755183600000, + "free_end": "2025/08/21 23:00:00", + "free_end_at": 1755788400000, + "link": "https://store.epicgames.com/store/zh-CN/p/hidden-folks-239d16" + }, + { + "id": "4cbb6c3704d240f19c3dd5f5cb2b0cb4", + "title": "Kamaeru", + "cover": "https://cdn1.epicgames.com/spt-assets/44313cfbb62b4df5801d0c8d541c2624/kamaeru-40asc.png", + "original_price": 62, + "original_price_desc": "¥62.00", + "description": "Foster a sanctuary for frogs and restore the biodiversity of the wetlands in Kamaeru, a cozy frog collecting game, where you take pictures of frogs, play mini-games and decorate your habitat. Hop right to it!", + "seller": "Armor Games Studios", + "is_free_now": false, + "free_start": "2025/08/21 23:00:00", + "free_start_at": 1755788400000, + "free_end": "2025/08/28 23:00:00", + "free_end_at": 1756393200000, + "link": "https://store.epicgames.com/store/zh-CN/p/kamaeru-0c301e" + }, + { + "id": "0d9a533f0e684cc18620a8f408e8e72c", + "title": "Strange Horticulture", + "cover": "https://cdn1.epicgames.com/spt-assets/15e8e3eba65a4763a815d6eae1d763b2/strange-horticulture-offer-2wghv.png", + "original_price": 45, + "original_price_desc": "¥45.00", + "description": "款神秘学解谜游戏,你将扮演当地植物商店的店主,寻找并识别新的植物,悠闲撸猫,与女巫团体交谈,或加入异教。收集各种强大的植物,用它们来影响故事走向,揭开昂德米尔镇的黑暗谜团。", + "seller": "Iceberg Interactive", + "is_free_now": false, + "free_start": "2025/08/21 23:00:00", + "free_start_at": 1755788400000, + "free_end": "2025/08/28 23:00:00", + "free_end_at": 1756393200000, + "link": "https://store.epicgames.com/store/zh-CN/p/strange-horticulture-360e80" + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/css/style.css b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/css/style.css new file mode 100644 index 00000000..5bb68371 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/css/style.css @@ -0,0 +1,409 @@ +/* 每日国际汇率 - 淡绿色清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2.5rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 15px; +} + +.header p { + color: #5a7c65; + font-size: 1.1rem; +} + +/* 货币选择器 */ +.currency-selector { + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + padding: 20px; + margin-bottom: 20px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); + text-align: center; +} + +.currency-selector label { + display: block; + margin-bottom: 10px; + font-weight: 600; + color: #2d5016; +} + +.currency-selector select { + padding: 12px 20px; + border: 2px solid #c8e6c9; + border-radius: 25px; + background: white; + color: #2d5016; + font-size: 1rem; + min-width: 200px; + cursor: pointer; + transition: all 0.3s ease; +} + +.currency-selector select:focus { + outline: none; + border-color: #81c784; + box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.2); +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 汇率信息容器 */ +.exchange-info { + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 25px; + margin-bottom: 20px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.base-currency { + text-align: center; + margin-bottom: 20px; +} + +.base-currency h2 { + font-size: 1.8rem; + color: #2d5016; + margin-bottom: 10px; +} + +.update-time { + color: #5a7c65; + font-size: 0.9rem; +} + +/* 汇率网格 */ +.rates-grid { + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 10px; + margin-top: 20px; +} + +.rate-card { + background: rgba(255, 255, 255, 0.9); + border-radius: 10px; + padding: 12px; + box-shadow: 0 3px 10px rgba(45, 80, 22, 0.06); + transition: all 0.3s ease; + border: 1px solid rgba(200, 230, 201, 0.5); + text-align: center; +} + +.rate-card:hover { + transform: translateY(-1px); + box-shadow: 0 4px 15px rgba(45, 80, 22, 0.1); + border-color: #81c784; +} + +.currency-code { + font-size: 1rem; + font-weight: 700; + color: #2d5016; + margin-bottom: 6px; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; +} + +.currency-flag { + font-size: 1.2rem; +} + +.exchange-rate { + font-size: 1.1rem; + font-weight: 600; + color: #388e3c; + margin-bottom: 4px; +} + +.currency-name { + color: #5a7c65; + font-size: 0.8rem; + line-height: 1.2; +} + +/* 搜索框 */ +.search-container { + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + padding: 20px; + margin-bottom: 20px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.search-input { + width: 100%; + padding: 12px 20px; + border: 2px solid #c8e6c9; + border-radius: 25px; + background: white; + color: #2d5016; + font-size: 1rem; + transition: all 0.3s ease; +} + +.search-input:focus { + outline: none; + border-color: #81c784; + box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.2); +} + +.search-input::placeholder { + color: #81c784; +} + +/* 错误提示 */ +.error { + background: #fed7d7; + color: #c53030; + padding: 20px; + border-radius: 15px; + text-align: center; + border: 1px solid #feb2b2; + margin: 20px 0; +} + +/* 统计信息 */ +.stats { + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + padding: 20px; + margin-bottom: 20px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); + text-align: center; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 20px; + margin-top: 15px; +} + +.stat-item { + padding: 15px; + background: rgba(129, 199, 132, 0.1); + border-radius: 10px; +} + +.stat-number { + font-size: 1.5rem; + font-weight: 700; + color: #2d5016; +} + +.stat-label { + color: #5a7c65; + font-size: 0.9rem; + margin-top: 5px; +} + +/* 响应式设计 */ + +/* 平板端 */ +@media (max-width: 768px) and (min-width: 481px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2rem; + flex-direction: column; + gap: 10px; + } + + .header { + padding: 20px; + } + + .rates-grid { + grid-template-columns: repeat(6, 1fr); + gap: 8px; + } + + .rate-card { + padding: 10px; + } + + .currency-selector select { + min-width: 180px; + } +} + +/* 手机端 */ +@media (max-width: 480px) { + .container { + padding: 10px; + } + + .header { + padding: 15px; + margin-bottom: 20px; + } + + .header h1 { + font-size: 1.8rem; + } + + .rates-grid { + grid-template-columns: repeat(4, 1fr); + gap: 6px; + } + + .rate-card { + padding: 8px; + border-radius: 8px; + } + + .currency-code { + font-size: 0.85rem; + margin-bottom: 4px; + gap: 4px; + } + + .currency-flag { + font-size: 1rem; + } + + .exchange-rate { + font-size: 0.9rem; + margin-bottom: 3px; + } + + .currency-name { + font-size: 0.7rem; + line-height: 1.1; + } + + .currency-selector { + padding: 15px; + } + + .currency-selector select { + min-width: 100%; + padding: 10px 15px; + } + + .search-input { + padding: 10px 15px; + } + + .stats-grid { + grid-template-columns: repeat(2, 1fr); + gap: 10px; + } +} + +/* 大屏幕优化 */ +@media (min-width: 1200px) { + .container { + padding: 40px; + } + + .header { + padding: 40px; + } +} + +/* 特殊效果 */ +.fade-in { + animation: fadeIn 0.6s ease-in; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 滚动条样式 */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); +} + +::-webkit-scrollbar-thumb { + background: rgba(129, 199, 132, 0.5); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(129, 199, 132, 0.7); +} + +/* 隐藏类 */ +.hidden { + display: none; +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/index.html b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/index.html new file mode 100644 index 00000000..644740d2 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/index.html @@ -0,0 +1,86 @@ + + + + + + + + 每日国际汇率 + + + + + + + + +
+ +
+

+ 💱 + 每日国际汇率 +

+

实时获取全球货币汇率信息,助您掌握汇率动态

+
+ + +
+ + +
+ + +
+ +
+ + +
+
+

正在加载汇率数据...

+
+ + +
+ +
+
+

基础货币

+
更新时间: --
+
+ + +
+

汇率统计

+
+
+
--
+
货币总数
+
+
+
--
+
最后更新
+
+
+
+ + +
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/js/script.js b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/js/script.js new file mode 100644 index 00000000..d7d217b3 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/js/script.js @@ -0,0 +1,520 @@ +// 每日国际汇率 JavaScript 功能 + +// API配置 +const API = { + endpoints: [], + currentIndex: 0, + defaultCurrency: 'CNY', + localFallback: '返回接口.json', + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/exchange_rate`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/exchange_rate']; + } + }, + // 获取当前接口URL + getCurrentUrl(currency) { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + url.searchParams.append('currency', currency); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } +}; + +// 常用货币列表 +const POPULAR_CURRENCIES = [ + { code: 'CNY', name: '人民币', flag: '🇨🇳' }, + { code: 'USD', name: '美元', flag: '🇺🇸' }, + { code: 'EUR', name: '欧元', flag: '🇪🇺' }, + { code: 'JPY', name: '日元', flag: '🇯🇵' }, + { code: 'GBP', name: '英镑', flag: '🇬🇧' }, + { code: 'AUD', name: '澳元', flag: '🇦🇺' }, + { code: 'CAD', name: '加元', flag: '🇨🇦' }, + { code: 'CHF', name: '瑞士法郎', flag: '🇨🇭' }, + { code: 'HKD', name: '港币', flag: '🇭🇰' }, + { code: 'SGD', name: '新加坡元', flag: '🇸🇬' }, + { code: 'KRW', name: '韩元', flag: '🇰🇷' }, + { code: 'THB', name: '泰铢', flag: '🇹🇭' } +]; + +// 货币优先级排序 - 经济发达、交易频繁的国家货币优先 +const CURRENCY_PRIORITY = { + // 第一梯队:全球主要储备货币和交易货币 + 'USD': 1, // 美元 - 全球储备货币 + 'EUR': 2, // 欧元 - 欧盟统一货币 + 'JPY': 3, // 日元 - 亚洲主要货币 + 'GBP': 4, // 英镑 - 传统储备货币 + 'CNY': 5, // 人民币 - 中国货币 + + // 第二梯队:发达国家货币 + 'CHF': 10, // 瑞士法郎 - 避险货币 + 'CAD': 11, // 加拿大元 + 'AUD': 12, // 澳大利亚元 + 'NZD': 13, // 新西兰元 + 'SEK': 14, // 瑞典克朗 + 'NOK': 15, // 挪威克朗 + 'DKK': 16, // 丹麦克朗 + + // 第三梯队:亚洲发达经济体 + 'HKD': 20, // 港币 + 'SGD': 21, // 新加坡元 + 'KRW': 22, // 韩元 + 'TWD': 23, // 新台币 + + // 第四梯队:重要新兴市场货币 + 'RUB': 30, // 俄罗斯卢布 + 'INR': 31, // 印度卢比 + 'BRL': 32, // 巴西雷亚尔 + 'MXN': 33, // 墨西哥比索 + 'ZAR': 34, // 南非兰特 + 'TRY': 35, // 土耳其里拉 + + // 第五梯队:亚洲重要货币 + 'THB': 40, // 泰铢 + 'MYR': 41, // 马来西亚林吉特 + 'IDR': 42, // 印尼盾 + 'PHP': 43, // 菲律宾比索 + 'VND': 44, // 越南盾 + + // 第六梯队:中东石油国家货币 + 'SAR': 50, // 沙特里亚尔 + 'AED': 51, // 阿联酋迪拉姆 + 'QAR': 52, // 卡塔尔里亚尔 + 'KWD': 53, // 科威特第纳尔 + + // 第七梯队:欧洲其他货币 + 'PLN': 60, // 波兰兹罗提 + 'CZK': 61, // 捷克克朗 + 'HUF': 62, // 匈牙利福林 + 'RON': 63, // 罗马尼亚列伊 + 'BGN': 64, // 保加利亚列弗 + 'HRK': 65, // 克罗地亚库纳 + + // 第八梯队:拉美货币 + 'ARS': 70, // 阿根廷比索 + 'CLP': 71, // 智利比索 + 'COP': 72, // 哥伦比亚比索 + 'PEN': 73, // 秘鲁索尔 + 'UYU': 74, // 乌拉圭比索 + + // 其他货币默认优先级为 999 +}; + +// 货币名称映射 +const CURRENCY_NAMES = { + 'CNY': '人民币', 'USD': '美元', 'EUR': '欧元', 'JPY': '日元', 'GBP': '英镑', + 'AUD': '澳元', 'CAD': '加元', 'CHF': '瑞士法郎', 'HKD': '港币', 'SGD': '新加坡元', + 'KRW': '韩元', 'THB': '泰铢', 'AED': '阿联酋迪拉姆', 'AFN': '阿富汗尼', + 'ALL': '阿尔巴尼亚列克', 'AMD': '亚美尼亚德拉姆', 'ANG': '荷属安的列斯盾', + 'AOA': '安哥拉宽扎', 'ARS': '阿根廷比索', 'AWG': '阿鲁巴弗罗林', + 'AZN': '阿塞拜疆马纳特', 'BAM': '波黑马克', 'BBD': '巴巴多斯元', + 'BDT': '孟加拉塔卡', 'BGN': '保加利亚列弗', 'BHD': '巴林第纳尔', + 'BIF': '布隆迪法郎', 'BMD': '百慕大元', 'BND': '文莱元', 'BOB': '玻利维亚诺', + 'BRL': '巴西雷亚尔', 'BSD': '巴哈马元', 'BTN': '不丹努尔特鲁姆', + 'BWP': '博茨瓦纳普拉', 'BYN': '白俄罗斯卢布', 'BZD': '伯利兹元', + 'CDF': '刚果法郎', 'CLP': '智利比索', 'COP': '哥伦比亚比索', 'CRC': '哥斯达黎加科朗', + 'CUP': '古巴比索', 'CVE': '佛得角埃斯库多', 'CZK': '捷克克朗', 'DJF': '吉布提法郎', + 'DKK': '丹麦克朗', 'DOP': '多米尼加比索', 'DZD': '阿尔及利亚第纳尔', 'EGP': '埃及镑', + 'ERN': '厄立特里亚纳克法', 'ETB': '埃塞俄比亚比尔', 'FJD': '斐济元', 'FKP': '福克兰群岛镑', + 'FOK': '法罗群岛克朗', 'GEL': '格鲁吉亚拉里', 'GGP': '根西岛镑', 'GHS': '加纳塞地', + 'GIP': '直布罗陀镑', 'GMD': '冈比亚达拉西', 'GNF': '几内亚法郎', 'GTQ': '危地马拉格查尔', + 'GYD': '圭亚那元', 'HNL': '洪都拉斯伦皮拉', 'HRK': '克罗地亚库纳', 'HTG': '海地古德', + 'HUF': '匈牙利福林', 'IDR': '印尼盾', 'ILS': '以色列新谢克尔', 'IMP': '马恩岛镑', + 'INR': '印度卢比', 'IQD': '伊拉克第纳尔', 'IRR': '伊朗里亚尔', 'ISK': '冰岛克朗', + 'JEP': '泽西岛镑', 'JMD': '牙买加元', 'JOD': '约旦第纳尔', 'KES': '肯尼亚先令', + 'KGS': '吉尔吉斯斯坦索姆', 'KHR': '柬埔寨瑞尔', 'KID': '基里巴斯元', 'KMF': '科摩罗法郎', + 'KWD': '科威特第纳尔', 'KYD': '开曼群岛元', 'KZT': '哈萨克斯坦坚戈', 'LAK': '老挝基普', + 'LBP': '黎巴嫩镑', 'LKR': '斯里兰卡卢比', 'LRD': '利比里亚元', 'LSL': '莱索托洛蒂', + 'LYD': '利比亚第纳尔', 'MAD': '摩洛哥迪拉姆', 'MDL': '摩尔多瓦列伊', 'MGA': '马达加斯加阿里亚里', + 'MKD': '北马其顿第纳尔', 'MMK': '缅甸缅元', 'MNT': '蒙古图格里克', 'MOP': '澳门帕塔卡', + 'MRU': '毛里塔尼亚乌吉亚', 'MUR': '毛里求斯卢比', 'MVR': '马尔代夫拉菲亚', 'MWK': '马拉维克瓦查', + 'MXN': '墨西哥比索', 'MYR': '马来西亚林吉特', 'MZN': '莫桑比克梅蒂卡尔', 'NAD': '纳米比亚元', + 'NGN': '尼日利亚奈拉', 'NIO': '尼加拉瓜科多巴', 'NOK': '挪威克朗', 'NPR': '尼泊尔卢比', + 'NZD': '新西兰元', 'OMR': '阿曼里亚尔', 'PAB': '巴拿马巴波亚', 'PEN': '秘鲁索尔', + 'PGK': '巴布亚新几内亚基那', 'PHP': '菲律宾比索', 'PKR': '巴基斯坦卢比', 'PLN': '波兰兹罗提', + 'PYG': '巴拉圭瓜拉尼', 'QAR': '卡塔尔里亚尔', 'RON': '罗马尼亚列伊', 'RSD': '塞尔维亚第纳尔', + 'RUB': '俄罗斯卢布', 'RWF': '卢旺达法郎', 'SAR': '沙特里亚尔', 'SBD': '所罗门群岛元', + 'SCR': '塞舌尔卢比', 'SDG': '苏丹镑', 'SEK': '瑞典克朗', 'SHP': '圣赫勒拿镑', + 'SLE': '塞拉利昂利昂', 'SLL': '塞拉利昂利昂(旧)', 'SOS': '索马里先令', 'SRD': '苏里南元', + 'SSP': '南苏丹镑', 'STN': '圣多美和普林西比多布拉', 'SYP': '叙利亚镑', 'SZL': '斯威士兰里兰吉尼', + 'TJS': '塔吉克斯坦索莫尼', 'TMT': '土库曼斯坦马纳特', 'TND': '突尼斯第纳尔', 'TOP': '汤加潘加', + 'TRY': '土耳其里拉', 'TTD': '特立尼达和多巴哥元', 'TVD': '图瓦卢元', 'TWD': '新台币', + 'TZS': '坦桑尼亚先令', 'UAH': '乌克兰格里夫纳', 'UGX': '乌干达先令', 'UYU': '乌拉圭比索', + 'UZS': '乌兹别克斯坦苏姆', 'VES': '委内瑞拉玻利瓦尔', 'VND': '越南盾', 'VUV': '瓦努阿图瓦图', + 'WST': '萨摩亚塔拉', 'XAF': '中非法郎', 'XCD': '东加勒比元', 'XCG': '加勒比盾', + 'XDR': '特别提款权', 'XOF': '西非法郎', 'XPF': '太平洋法郎', 'YER': '也门里亚尔', + 'ZAR': '南非兰特', 'ZMW': '赞比亚克瓦查', 'ZWL': '津巴布韦元' +}; + +// 货币旗帜映射 +const CURRENCY_FLAGS = { + 'CNY': '🇨🇳', 'USD': '🇺🇸', 'EUR': '🇪🇺', 'JPY': '🇯🇵', 'GBP': '🇬🇧', + 'AUD': '🇦🇺', 'CAD': '🇨🇦', 'CHF': '🇨🇭', 'HKD': '🇭🇰', 'SGD': '🇸🇬', + 'KRW': '🇰🇷', 'THB': '🇹🇭', 'AED': '🇦🇪', 'AFN': '🇦🇫', 'ALL': '🇦🇱', + 'AMD': '🇦🇲', 'ANG': '🇳🇱', 'AOA': '🇦🇴', 'ARS': '🇦🇷', 'AWG': '🇦🇼', + 'AZN': '🇦🇿', 'BAM': '🇧🇦', 'BBD': '🇧🇧', 'BDT': '🇧🇩', 'BGN': '🇧🇬', + 'BHD': '🇧🇭', 'BIF': '🇧🇮', 'BMD': '🇧🇲', 'BND': '🇧🇳', 'BOB': '🇧🇴', + 'BRL': '🇧🇷', 'BSD': '🇧🇸', 'BTN': '🇧🇹', 'BWP': '🇧🇼', 'BYN': '🇧🇾', + 'BZD': '🇧🇿', 'CDF': '🇨🇩', 'CLP': '🇨🇱', 'COP': '🇨🇴', 'CRC': '🇨🇷', + 'CUP': '🇨🇺', 'CVE': '🇨🇻', 'CZK': '🇨🇿', 'DJF': '🇩🇯', 'DKK': '🇩🇰', + 'DOP': '🇩🇴', 'DZD': '🇩🇿', 'EGP': '🇪🇬', 'ERN': '🇪🇷', 'ETB': '🇪🇹', + 'FJD': '🇫🇯', 'FKP': '🇫🇰', 'FOK': '🇫🇴', 'GEL': '🇬🇪', 'GGP': '🇬🇬', + 'GHS': '🇬🇭', 'GIP': '🇬🇮', 'GMD': '🇬🇲', 'GNF': '🇬🇳', 'GTQ': '🇬🇹', + 'GYD': '🇬🇾', 'HNL': '🇭🇳', 'HRK': '🇭🇷', 'HTG': '🇭🇹', 'HUF': '🇭🇺', + 'IDR': '🇮🇩', 'ILS': '🇮🇱', 'IMP': '🇮🇲', 'INR': '🇮🇳', 'IQD': '🇮🇶', + 'IRR': '🇮🇷', 'ISK': '🇮🇸', 'JEP': '🇯🇪', 'JMD': '🇯🇲', 'JOD': '🇯🇴', + 'KES': '🇰🇪', 'KGS': '🇰🇬', 'KHR': '🇰🇭', 'KID': '🇰🇮', 'KMF': '🇰🇲', + 'KWD': '🇰🇼', 'KYD': '🇰🇾', 'KZT': '🇰🇿', 'LAK': '🇱🇦', 'LBP': '🇱🇧', + 'LKR': '🇱🇰', 'LRD': '🇱🇷', 'LSL': '🇱🇸', 'LYD': '🇱🇾', 'MAD': '🇲🇦', + 'MDL': '🇲🇩', 'MGA': '🇲🇬', 'MKD': '🇲🇰', 'MMK': '🇲🇲', 'MNT': '🇲🇳', + 'MOP': '🇲🇴', 'MRU': '🇲🇷', 'MUR': '🇲🇺', 'MVR': '🇲🇻', 'MWK': '🇲🇼', + 'MXN': '🇲🇽', 'MYR': '🇲🇾', 'MZN': '🇲🇿', 'NAD': '🇳🇦', 'NGN': '🇳🇬', + 'NIO': '🇳🇮', 'NOK': '🇳🇴', 'NPR': '🇳🇵', 'NZD': '🇳🇿', 'OMR': '🇴🇲', + 'PAB': '🇵🇦', 'PEN': '🇵🇪', 'PGK': '🇵🇬', 'PHP': '🇵🇭', 'PKR': '🇵🇰', + 'PLN': '🇵🇱', 'PYG': '🇵🇾', 'QAR': '🇶🇦', 'RON': '🇷🇴', 'RSD': '🇷🇸', + 'RUB': '🇷🇺', 'RWF': '🇷🇼', 'SAR': '🇸🇦', 'SBD': '🇸🇧', 'SCR': '🇸🇨', + 'SDG': '🇸🇩', 'SEK': '🇸🇪', 'SHP': '🇸🇭', 'SLE': '🇸🇱', 'SLL': '🇸🇱', + 'SOS': '🇸🇴', 'SRD': '🇸🇷', 'SSP': '🇸🇸', 'STN': '🇸🇹', 'SYP': '🇸🇾', + 'SZL': '🇸🇿', 'TJS': '🇹🇯', 'TMT': '🇹🇲', 'TND': '🇹🇳', 'TOP': '🇹🇴', + 'TRY': '🇹🇷', 'TTD': '🇹🇹', 'TVD': '🇹🇻', 'TWD': '🇹🇼', 'TZS': '🇹🇿', + 'UAH': '🇺🇦', 'UGX': '🇺🇬', 'UYU': '🇺🇾', 'UZS': '🇺🇿', 'VES': '🇻🇪', + 'VND': '🇻🇳', 'VUV': '🇻🇺', 'WST': '🇼🇸', 'XAF': '🌍', 'XCD': '🏝️', + 'XCG': '🏝️', 'XDR': '🌐', 'XOF': '🌍', 'XPF': '🌊', 'YER': '🇾🇪', + 'ZAR': '🇿🇦', 'ZMW': '🇿🇲', 'ZWL': '🇿🇼' +}; + +// DOM元素 +let elements = {}; +let currentRates = []; +let filteredRates = []; + +// 初始化 +document.addEventListener('DOMContentLoaded', function() { + initElements(); + initCurrencySelector(); + bindEvents(); + loadExchangeRates(); +}); + +// 初始化DOM元素 +function initElements() { + elements = { + currencySelect: document.getElementById('currency-select'), + searchInput: document.getElementById('search-input'), + loading: document.getElementById('loading'), + content: document.getElementById('exchange-content'), + baseCurrency: document.getElementById('base-currency'), + updateTime: document.getElementById('update-time'), + ratesGrid: document.getElementById('rates-grid'), + totalCurrencies: document.getElementById('total-currencies'), + lastUpdate: document.getElementById('last-update') + }; +} + +// 初始化货币选择器 +function initCurrencySelector() { + if (!elements.currencySelect) return; + + // 添加常用货币选项 + POPULAR_CURRENCIES.forEach(currency => { + const option = document.createElement('option'); + option.value = currency.code; + option.textContent = `${currency.flag} ${currency.code} - ${currency.name}`; + if (currency.code === API.defaultCurrency) { + option.selected = true; + } + elements.currencySelect.appendChild(option); + }); +} + +// 绑定事件 +function bindEvents() { + // 货币选择变化 + if (elements.currencySelect) { + elements.currencySelect.addEventListener('change', function() { + loadExchangeRates(this.value); + }); + } + + // 搜索功能 + if (elements.searchInput) { + elements.searchInput.addEventListener('input', function() { + filterRates(this.value); + }); + } +} + +// 加载汇率数据 +async function loadExchangeRates(currency = API.defaultCurrency) { + try { + showLoading(true); + + // 尝试从API获取数据 + const data = await fetchFromAPI(currency); + + if (data && data.code === 200 && data.data) { + currentRates = data.data.rates || []; + displayExchangeRates(data.data); + } else { + // 尝试从本地获取数据 + const localData = await fetchFromLocal(); + if (localData && localData.code === 200 && localData.data) { + currentRates = localData.data.rates || []; + displayExchangeRates(localData.data); + showError('使用本地数据,可能不是最新汇率'); + } else { + throw new Error('无法获取汇率数据'); + } + } + + } catch (error) { + console.error('加载汇率失败:', error); + showError('加载汇率数据失败,请稍后重试'); + } finally { + showLoading(false); + } +} + +// 从API获取数据 +async function fetchFromAPI(currency) { + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(currency); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const response = await fetch(url, { + cache: 'no-store' + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data && data.code === 200) { + console.log(`接口 ${i + 1} 请求成功`); + return data; + } + + throw new Error(data && data.message ? data.message : '接口返回异常'); + + } catch (e) { + console.warn(`接口 ${i + 1} 失败:`, e.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了 + console.warn('所有远程接口都失败,尝试本地数据'); + return null; + } + } +} + +// 从本地获取数据 +async function fetchFromLocal() { + try { + const response = await fetch(API.localFallback + `?t=${Date.now()}`); + if (!response.ok) throw new Error(`本地文件HTTP ${response.status}`); + const data = await response.json(); + return data; + } catch (e) { + console.error('读取本地返回接口.json失败:', e); + return null; + } +} + +// 显示汇率数据 +function displayExchangeRates(data) { + if (!data || !data.rates) { + showError('没有获取到汇率数据'); + return; + } + + // 更新基础货币信息 + if (elements.baseCurrency) { + const baseCurrencyName = CURRENCY_NAMES[data.base_code] || data.base_code; + const baseCurrencyFlag = CURRENCY_FLAGS[data.base_code] || '💱'; + elements.baseCurrency.textContent = `${baseCurrencyFlag} ${data.base_code} - ${baseCurrencyName}`; + } + + // 更新时间信息 + if (elements.updateTime && data.updated) { + elements.updateTime.textContent = `更新时间: ${data.updated}`; + } + + // 更新统计信息 + updateStats(data); + + // 显示汇率列表 + filteredRates = data.rates; + renderRates(filteredRates); + + // 显示内容区域 + if (elements.content) { + elements.content.classList.add('fade-in'); + elements.content.style.display = 'block'; + } +} + +// 更新统计信息 +function updateStats(data) { + if (elements.totalCurrencies) { + elements.totalCurrencies.textContent = data.rates ? data.rates.length : 0; + } + + if (elements.lastUpdate && data.updated) { + elements.lastUpdate.textContent = data.updated; + } +} + +// 渲染汇率列表 +function renderRates(rates) { + if (!elements.ratesGrid || !rates) return; + + // 按优先级排序货币 + const sortedRates = [...rates].sort((a, b) => { + const priorityA = CURRENCY_PRIORITY[a.currency] || 999; + const priorityB = CURRENCY_PRIORITY[b.currency] || 999; + + // 优先级相同时按货币代码字母顺序排序 + if (priorityA === priorityB) { + return a.currency.localeCompare(b.currency); + } + + return priorityA - priorityB; + }); + + elements.ratesGrid.innerHTML = ''; + + sortedRates.forEach(rate => { + const rateCard = createRateCard(rate); + elements.ratesGrid.appendChild(rateCard); + }); +} + +// 创建汇率卡片 +function createRateCard(rate) { + const card = document.createElement('div'); + card.className = 'rate-card'; + + const currencyName = CURRENCY_NAMES[rate.currency] || rate.currency; + const currencyFlag = CURRENCY_FLAGS[rate.currency] || '💱'; + + card.innerHTML = ` +
+ ${currencyFlag} + ${rate.currency} +
+
${formatRate(rate.rate)}
+
${currencyName}
+ `; + + return card; +} + +// 格式化汇率 +function formatRate(rate) { + if (rate >= 1) { + return rate.toFixed(4); + } else if (rate >= 0.01) { + return rate.toFixed(6); + } else { + return rate.toFixed(8); + } +} + +// 过滤汇率数据 +function filterRates(searchTerm) { + if (!searchTerm.trim()) { + renderRates(currentRates); + return; + } + + const filtered = currentRates.filter(rate => { + const currencyName = CURRENCY_NAMES[rate.currency] || rate.currency; + return rate.currency.toLowerCase().includes(searchTerm.toLowerCase()) || + currencyName.toLowerCase().includes(searchTerm.toLowerCase()); + }); + + renderRates(filtered); +} + +// 显示/隐藏加载状态 +function showLoading(show) { + if (elements.loading) { + elements.loading.style.display = show ? 'block' : 'none'; + } + if (elements.content) { + elements.content.style.display = show ? 'none' : 'block'; + } +} + +// 显示错误信息 +function showError(message) { + if (elements.content) { + elements.content.innerHTML = ` +
+

⚠️ 加载失败

+

${escapeHtml(message)}

+

请检查网络连接或稍后重试

+
+ `; + elements.content.style.display = 'block'; + } +} + +// HTML转义 +function escapeHtml(text) { + if (!text) return ''; + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +// 错误处理 +window.addEventListener('error', function(event) { + console.error('页面错误:', event.error); +}); + +// 网络状态监听 +window.addEventListener('online', function() { + console.log('网络已连接'); +}); + +window.addEventListener('offline', function() { + console.log('网络已断开'); + showError('网络连接已断开,请检查网络设置'); +}); + +// 导出函数供外部调用 +window.ExchangeRate = { + loadExchangeRates, + showError, + showLoading +}; \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/接口集合.json b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/返回接口.json b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/返回接口.json new file mode 100644 index 00000000..b376d9c2 --- /dev/null +++ b/frontend/react-app/public/60sapi/日更资讯/每日国际汇率/返回接口.json @@ -0,0 +1 @@ +{"code":200,"message":"获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841","data":{"base_code":"CNY","updated":"2025/08/19 08:02:31","updated_at":1755561751000,"next_updated":"2025/08/20 08:11:41","next_updated_at":1755648701000,"rates":[{"currency":"CNY","rate":1},{"currency":"AED","rate":0.511124},{"currency":"AFN","rate":9.517171},{"currency":"ALL","rate":11.591448},{"currency":"AMD","rate":53.380737},{"currency":"ANG","rate":0.249125},{"currency":"AOA","rate":130.082117},{"currency":"ARS","rate":180.766035},{"currency":"AUD","rate":0.214039},{"currency":"AWG","rate":0.249125},{"currency":"AZN","rate":0.236907},{"currency":"BAM","rate":0.233194},{"currency":"BBD","rate":0.278352},{"currency":"BDT","rate":16.911823},{"currency":"BGN","rate":0.233216},{"currency":"BHD","rate":0.05233},{"currency":"BIF","rate":416.872549},{"currency":"BMD","rate":0.139176},{"currency":"BND","rate":0.178681},{"currency":"BOB","rate":0.962893},{"currency":"BRL","rate":0.752907},{"currency":"BSD","rate":0.139176},{"currency":"BTN","rate":12.167157},{"currency":"BWP","rate":1.952087},{"currency":"BYN","rate":0.44452},{"currency":"BZD","rate":0.278352},{"currency":"CAD","rate":0.19212},{"currency":"CDF","rate":404.961905},{"currency":"CHF","rate":0.112314},{"currency":"CLP","rate":134.245001},{"currency":"COP","rate":560.180139},{"currency":"CRC","rate":70.415535},{"currency":"CUP","rate":3.340225},{"currency":"CVE","rate":13.146924},{"currency":"CZK","rate":2.918414},{"currency":"DJF","rate":24.734508},{"currency":"DKK","rate":0.889716},{"currency":"DOP","rate":8.582359},{"currency":"DZD","rate":18.079862},{"currency":"EGP","rate":6.734271},{"currency":"ERN","rate":2.087641},{"currency":"ETB","rate":19.722171},{"currency":"EUR","rate":0.119223},{"currency":"FJD","rate":0.314391},{"currency":"FKP","rate":0.102914},{"currency":"FOK","rate":0.889734},{"currency":"GBP","rate":0.102909},{"currency":"GEL","rate":0.375537},{"currency":"GGP","rate":0.102914},{"currency":"GHS","rate":1.578239},{"currency":"GIP","rate":0.102914},{"currency":"GMD","rate":10.138575},{"currency":"GNF","rate":1210.235138},{"currency":"GTQ","rate":1.068254},{"currency":"GYD","rate":29.143934},{"currency":"HKD","rate":1.088795},{"currency":"HNL","rate":3.652528},{"currency":"HRK","rate":0.89834},{"currency":"HTG","rate":18.225889},{"currency":"HUF","rate":47.111579},{"currency":"IDR","rate":2251.38752},{"currency":"ILS","rate":0.471627},{"currency":"IMP","rate":0.102914},{"currency":"INR","rate":12.167163},{"currency":"IQD","rate":182.493562},{"currency":"IRR","rate":5947.331641},{"currency":"ISK","rate":17.059481},{"currency":"JEP","rate":0.102914},{"currency":"JMD","rate":22.284011},{"currency":"JOD","rate":0.098676},{"currency":"JPY","rate":20.560161},{"currency":"KES","rate":18.001838},{"currency":"KGS","rate":12.154697},{"currency":"KHR","rate":559.486842},{"currency":"KID","rate":0.213953},{"currency":"KMF","rate":58.657438},{"currency":"KRW","rate":193.082196},{"currency":"KWD","rate":0.042467},{"currency":"KYD","rate":0.11598},{"currency":"KZT","rate":75.044843},{"currency":"LAK","rate":3020.068103},{"currency":"LBP","rate":12456.256905},{"currency":"LKR","rate":41.92144},{"currency":"LRD","rate":27.931467},{"currency":"LSL","rate":2.453056},{"currency":"LYD","rate":0.753251},{"currency":"MAD","rate":1.256183},{"currency":"MDL","rate":2.318865},{"currency":"MGA","rate":616.246377},{"currency":"MKD","rate":7.330199},{"currency":"MMK","rate":292.821503},{"currency":"MNT","rate":496.284455},{"currency":"MOP","rate":1.121431},{"currency":"MRU","rate":5.575062},{"currency":"MUR","rate":6.322278},{"currency":"MVR","rate":2.152859},{"currency":"MWK","rate":242.759976},{"currency":"MXN","rate":2.615768},{"currency":"MYR","rate":0.587931},{"currency":"MZN","rate":8.897355},{"currency":"NAD","rate":2.453056},{"currency":"NGN","rate":213.548738},{"currency":"NIO","rate":5.126446},{"currency":"NOK","rate":1.418768},{"currency":"NPR","rate":19.467451},{"currency":"NZD","rate":0.234779},{"currency":"OMR","rate":0.053513},{"currency":"PAB","rate":0.139176},{"currency":"PEN","rate":0.494927},{"currency":"PGK","rate":0.582729},{"currency":"PHP","rate":7.93572},{"currency":"PKR","rate":39.46328},{"currency":"PLN","rate":0.506978},{"currency":"PYG","rate":1027.399127},{"currency":"QAR","rate":0.506601},{"currency":"RON","rate":0.603459},{"currency":"RSD","rate":13.970729},{"currency":"RUB","rate":11.172399},{"currency":"RWF","rate":202.11696},{"currency":"SAR","rate":0.52191},{"currency":"SBD","rate":1.166597},{"currency":"SCR","rate":2.048212},{"currency":"SDG","rate":62.256223},{"currency":"SEK","rate":1.330729},{"currency":"SGD","rate":0.178681},{"currency":"SHP","rate":0.102914},{"currency":"SLE","rate":3.233657},{"currency":"SLL","rate":3233.656465},{"currency":"SOS","rate":79.627341},{"currency":"SRD","rate":5.237221},{"currency":"SSP","rate":656.433807},{"currency":"STN","rate":2.921141},{"currency":"SYP","rate":1797.905083},{"currency":"SZL","rate":2.453056},{"currency":"THB","rate":4.522448},{"currency":"TJS","rate":1.304898},{"currency":"TMT","rate":0.487573},{"currency":"TND","rate":0.400111},{"currency":"TOP","rate":0.334775},{"currency":"TRY","rate":5.692494},{"currency":"TTD","rate":0.944407},{"currency":"TVD","rate":0.213953},{"currency":"TWD","rate":4.180337},{"currency":"TZS","rate":362.491953},{"currency":"UAH","rate":5.749996},{"currency":"UGX","rate":495.482314},{"currency":"USD","rate":0.139189},{"currency":"UYU","rate":5.574},{"currency":"UZS","rate":1755.559577},{"currency":"VES","rate":19.06244},{"currency":"VND","rate":3651.953637},{"currency":"VUV","rate":16.614981},{"currency":"WST","rate":0.37355},{"currency":"XAF","rate":78.209917},{"currency":"XCD","rate":0.375775},{"currency":"XCG","rate":0.249125},{"currency":"XDR","rate":0.101791},{"currency":"XOF","rate":78.209917},{"currency":"XPF","rate":14.227984},{"currency":"YER","rate":33.479791},{"currency":"ZAR","rate":2.453082},{"currency":"ZMW","rate":3.244378},{"currency":"ZWL","rate":3.727233}]}} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/background.css b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/background.css new file mode 100644 index 00000000..b889760c --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/background.css @@ -0,0 +1,106 @@ +/* 彩虹背景相关样式 */ +body { + background: linear-gradient( + 135deg, + #ff6b6b 0%, + #4ecdc4 12.5%, + #45b7d1 25%, + #96ceb4 37.5%, + #feca57 50%, + #ff9ff3 62.5%, + #54a0ff 75%, + #5f27cd 87.5%, + #00d2d3 100% + ); + background-size: 400% 400%; + animation: rainbowGradient 15s ease infinite; + background-attachment: fixed; + min-height: 100vh; + position: relative; +} + +@keyframes rainbowGradient { + 0% { + background-position: 0% 50%; + } + 25% { + background-position: 100% 50%; + } + 50% { + background-position: 100% 100%; + } + 75% { + background-position: 0% 100%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 彩虹装饰层 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + radial-gradient(circle at 20% 20%, rgba(255, 107, 107, 0.15) 0%, transparent 50%), + radial-gradient(circle at 80% 80%, rgba(78, 205, 196, 0.15) 0%, transparent 50%), + radial-gradient(circle at 40% 80%, rgba(69, 183, 209, 0.12) 0%, transparent 40%), + radial-gradient(circle at 60% 20%, rgba(150, 206, 180, 0.12) 0%, transparent 40%), + radial-gradient(circle at 80% 40%, rgba(254, 202, 87, 0.1) 0%, transparent 35%); + pointer-events: none; + z-index: -1; + animation: float 20s ease-in-out infinite alternate; +} + +/* 彩虹粒子效果 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 10% 10%, rgba(255, 107, 107, 0.8) 2px, transparent 2px), + radial-gradient(circle at 30% 20%, rgba(78, 205, 196, 0.8) 1.5px, transparent 1.5px), + radial-gradient(circle at 50% 30%, rgba(69, 183, 209, 0.8) 1px, transparent 1px), + radial-gradient(circle at 70% 40%, rgba(150, 206, 180, 0.8) 2px, transparent 2px), + radial-gradient(circle at 90% 50%, rgba(254, 202, 87, 0.8) 1.5px, transparent 1.5px), + radial-gradient(circle at 20% 60%, rgba(255, 159, 243, 0.8) 1px, transparent 1px), + radial-gradient(circle at 40% 70%, rgba(84, 160, 255, 0.8) 2px, transparent 2px), + radial-gradient(circle at 60% 80%, rgba(95, 39, 205, 0.8) 1.5px, transparent 1.5px), + radial-gradient(circle at 80% 90%, rgba(0, 210, 211, 0.8) 1px, transparent 1px); + background-size: 200px 200px, 250px 250px, 180px 180px, 300px 300px, 220px 220px, 160px 160px, 280px 280px, 240px 240px, 200px 200px; + animation: sparkle 25s linear infinite; + pointer-events: none; + z-index: -1; + opacity: 0.6; +} + +@keyframes float { + 0% { + transform: translateY(0px) rotate(0deg); + } + 100% { + transform: translateY(-15px) rotate(2deg); + } +} + +@keyframes sparkle { + 0%, 100% { + transform: translateX(0) translateY(0) scale(1); + } + 25% { + transform: translateX(-10px) translateY(-5px) scale(1.1); + } + 50% { + transform: translateX(10px) translateY(-10px) scale(0.9); + } + 75% { + transform: translateX(-5px) translateY(-15px) scale(1.05); + } +} diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/style.css b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/style.css new file mode 100644 index 00000000..caf27e8e --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/css/style.css @@ -0,0 +1,1037 @@ +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2c3e50; + overflow-x: hidden; +} + +/* 容器 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + animation: containerFadeIn 1s ease-out; +} + +@keyframes containerFadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 头部 */ +.header { + text-align: center; + margin-bottom: 40px; + background: rgba(255, 255, 255, 0.95); + padding: 40px 30px; + border-radius: 25px; + box-shadow: + 0 10px 40px rgba(0, 0, 0, 0.1), + 0 0 0 1px rgba(255, 255, 255, 0.5); + backdrop-filter: blur(20px); + border: 2px solid transparent; + background-clip: padding-box; + position: relative; + overflow: hidden; +} + +.header::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, + rgba(255, 107, 107, 0.1), + rgba(78, 205, 196, 0.1), + rgba(69, 183, 209, 0.1), + rgba(150, 206, 180, 0.1) + ); + animation: headerShimmer 4s ease-in-out infinite; + z-index: -1; +} + +@keyframes headerShimmer { + 0%, 100% { opacity: 0.3; } + 50% { opacity: 0.7; } +} + +.header-icon { + font-size: 4em; + margin-bottom: 15px; + animation: rainbowBounce 3s ease-in-out infinite; + text-shadow: 0 0 20px rgba(255, 255, 255, 0.8); +} + +@keyframes rainbowBounce { + 0%, 100% { + transform: translateY(0) scale(1); + filter: hue-rotate(0deg); + } + 25% { + transform: translateY(-10px) scale(1.05); + filter: hue-rotate(90deg); + } + 50% { + transform: translateY(-15px) scale(1.1); + filter: hue-rotate(180deg); + } + 75% { + transform: translateY(-5px) scale(1.05); + filter: hue-rotate(270deg); + } +} + +.title { + font-size: 3.2em; + font-weight: 800; + background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff9ff3); + background-size: 400% 400%; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + animation: rainbowText 3s ease-in-out infinite; + margin-bottom: 10px; + text-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + letter-spacing: 2px; +} + +@keyframes rainbowText { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.subtitle { + font-size: 1.3em; + color: #34495e; + margin-bottom: 25px; + font-weight: 600; + opacity: 0.9; +} + +/* 标签切换 */ +.tab-container { + display: flex; + justify-content: center; + gap: 15px; + margin-bottom: 25px; + flex-wrap: wrap; +} + +.tab-btn { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.7)); + border: 2px solid transparent; + padding: 12px 24px; + border-radius: 25px; + cursor: pointer; + font-size: 1em; + font-weight: 600; + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + position: relative; + overflow: hidden; + display: flex; + align-items: center; + gap: 8px; + color: #2c3e50; + backdrop-filter: blur(10px); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); +} + +.tab-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transition: left 0.5s ease; +} + +.tab-btn:hover::before { + left: 100%; +} + +.tab-btn.active { + background: linear-gradient(135deg, #ff6b6b, #4ecdc4); + color: white; + transform: translateY(-3px) scale(1.05); + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4); +} + +.tab-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); +} + +.tab-icon { + font-size: 1.2em; + transition: transform 0.3s ease; +} + +.tab-btn:hover .tab-icon { + transform: scale(1.2) rotate(10deg); +} + +.update-time { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + color: #34495e; + font-size: 1em; + margin-bottom: 20px; + padding: 10px 20px; + background: rgba(52, 73, 94, 0.1); + border-radius: 25px; + display: inline-flex; + backdrop-filter: blur(5px); +} + +.time-icon { + font-size: 1.2em; + animation: tick 2s infinite; +} + +@keyframes tick { + 0%, 50% { transform: rotate(0deg); } + 25% { transform: rotate(20deg); } + 75% { transform: rotate(-20deg); } +} + +.refresh-btn { + background: linear-gradient(135deg, #ff6b6b, #4ecdc4, #45b7d1); + background-size: 200% 200%; + color: white; + border: none; + padding: 15px 35px; + border-radius: 30px; + cursor: pointer; + font-size: 1.1em; + font-weight: 700; + transition: all 0.4s ease; + box-shadow: 0 6px 20px rgba(255, 107, 107, 0.3); + display: inline-flex; + align-items: center; + gap: 10px; + position: relative; + overflow: hidden; + animation: buttonRainbow 3s ease-in-out infinite; +} + +@keyframes buttonRainbow { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.refresh-btn::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(255, 255, 255, 0.3); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.6s ease; +} + +.refresh-btn:hover::before { + width: 300px; + height: 300px; +} + +.refresh-btn:hover { + transform: translateY(-4px) scale(1.05); + box-shadow: 0 10px 30px rgba(255, 107, 107, 0.5); +} + +.btn-icon { + font-size: 1.3em; + transition: transform 0.4s ease; +} + +.refresh-btn:hover .btn-icon { + transform: rotate(360deg); +} + +/* 彩虹加载动画 */ +.loading { + text-align: center; + padding: 70px 40px; + background: rgba(255, 255, 255, 0.95); + border-radius: 25px; + margin-bottom: 25px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(20px); +} + +.loading-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 25px; +} + +.rainbow-spinner { + width: 60px; + height: 60px; + border: 6px solid transparent; + border-radius: 50%; + background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff9ff3) border-box; + background-clip: padding-box; + position: relative; + animation: rainbowSpin 2s linear infinite; +} + +.rainbow-spinner::before { + content: ''; + position: absolute; + top: -6px; + left: -6px; + right: -6px; + bottom: -6px; + background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff9ff3); + border-radius: 50%; + z-index: -1; + animation: rainbowSpin 2s linear infinite reverse; +} + +@keyframes rainbowSpin { + 0% { transform: rotate(0deg); filter: hue-rotate(0deg); } + 100% { transform: rotate(360deg); filter: hue-rotate(360deg); } +} + +.loading-text { + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; +} + +.loading-emoji { + font-size: 3em; + animation: rocketPulse 1.5s ease-in-out infinite alternate; +} + +@keyframes rocketPulse { + 0% { transform: scale(1) rotate(-10deg); } + 100% { transform: scale(1.2) rotate(10deg); } +} + +.loading-text p { + font-size: 1.2em; + color: #34495e; + font-weight: 600; + margin: 0; +} + +.loading-dots { + display: flex; + gap: 8px; +} + +.loading-dots span { + width: 10px; + height: 10px; + border-radius: 50%; + animation: dotRainbow 1.4s ease-in-out infinite both; +} + +.loading-dots span:nth-child(1) { + background: #ff6b6b; + animation-delay: -0.32s; +} +.loading-dots span:nth-child(2) { + background: #4ecdc4; + animation-delay: -0.16s; +} +.loading-dots span:nth-child(3) { + background: #45b7d1; + animation-delay: 0s; +} + +@keyframes dotRainbow { + 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; } + 40% { transform: scale(1.3); opacity: 1; } +} + +/* 新闻列表 */ +.news-list { + display: grid; + gap: 25px; + animation: listFadeIn 0.8s ease-out; +} + +@keyframes listFadeIn { + from { + opacity: 0; + transform: translateY(40px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.news-item { + background: rgba(255, 255, 255, 0.98); + border-radius: 20px; + padding: 30px; + box-shadow: 0 5px 25px rgba(0, 0, 0, 0.08); + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + border: 2px solid transparent; + backdrop-filter: blur(15px); + position: relative; + overflow: hidden; + animation: itemSlideIn 0.6s ease-out; + animation-fill-mode: both; +} + +.news-item:nth-child(odd) { + animation-delay: 0.1s; +} + +.news-item:nth-child(even) { + animation-delay: 0.2s; +} + +@keyframes itemSlideIn { + from { + opacity: 0; + transform: translateX(-60px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.news-item::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 6px; + height: 100%; + background: linear-gradient(to bottom, #ff6b6b, #4ecdc4, #45b7d1); + transform: scaleY(0); + transition: transform 0.4s ease; +} + +.news-item:hover::before { + transform: scaleY(1); +} + +.news-item:hover { + box-shadow: 0 10px 50px rgba(0, 0, 0, 0.12); + transform: translateY(-8px) scale(1.02); + border-color: rgba(255, 107, 107, 0.3); +} + +.news-header { + display: flex; + align-items: center; + margin-bottom: 20px; + gap: 15px; +} + +.news-rank { + background: linear-gradient(135deg, #ff6b6b, #4ecdc4); + color: white; + min-width: 45px; + height: 45px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 1.1em; + flex-shrink: 0; + position: relative; + box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3); + animation: rankGlow 3s ease-in-out infinite; +} + +@keyframes rankGlow { + 0%, 100% { + box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3); + background: linear-gradient(135deg, #ff6b6b, #4ecdc4); + } + 33% { + box-shadow: 0 4px 20px rgba(78, 205, 196, 0.4); + background: linear-gradient(135deg, #4ecdc4, #45b7d1); + } + 66% { + box-shadow: 0 4px 20px rgba(69, 183, 209, 0.4); + background: linear-gradient(135deg, #45b7d1, #96ceb4); + } +} + +.news-rank.top-5 { + background: linear-gradient(135deg, #feca57, #ff9ff3, #54a0ff); + animation: topRankGlow 2s ease-in-out infinite alternate; +} + +@keyframes topRankGlow { + 0% { + box-shadow: 0 4px 20px rgba(254, 202, 87, 0.5); + transform: scale(1); + } + 100% { + box-shadow: 0 6px 30px rgba(255, 159, 243, 0.6), 0 0 40px rgba(84, 160, 255, 0.3); + transform: scale(1.05); + } +} + +.news-rank.top-5::before { + content: '⭐'; + position: absolute; + top: -10px; + right: -8px; + font-size: 0.8em; + animation: starTwinkle 1s ease-in-out infinite alternate; +} + +@keyframes starTwinkle { + 0% { transform: translateY(0) rotate(-10deg) scale(1); } + 100% { transform: translateY(-3px) rotate(10deg) scale(1.1); } +} + +.news-score { + background: linear-gradient(135deg, #ff6b6b, #feca57); + color: white; + padding: 8px 16px; + border-radius: 20px; + font-weight: 700; + font-size: 1em; + box-shadow: 0 3px 10px rgba(255, 107, 107, 0.3); + animation: scoreFloat 2s ease-in-out infinite alternate; +} + +@keyframes scoreFloat { + 0% { transform: translateY(0); } + 100% { transform: translateY(-2px); } +} + +.news-title { + font-size: 1.3em; + font-weight: 700; + color: #2c3e50; + line-height: 1.4; + margin-bottom: 15px; + position: relative; +} + +.news-meta { + display: flex; + align-items: center; + gap: 20px; + margin-bottom: 15px; + flex-wrap: wrap; +} + +.news-author { + color: #7f8c8d; + font-size: 1em; + font-weight: 600; + display: flex; + align-items: center; + gap: 6px; +} + +.news-author::before { + content: '👤'; + font-size: 1.1em; +} + +.news-time { + color: #95a5a6; + font-size: 0.95em; + display: flex; + align-items: center; + gap: 6px; +} + +.news-time::before { + content: '🕒'; + font-size: 1em; +} + +.news-link { + display: inline-flex; + align-items: center; + gap: 8px; + color: white; + text-decoration: none; + font-size: 1em; + font-weight: 600; + padding: 12px 24px; + background: linear-gradient(135deg, #ff6b6b, #4ecdc4); + background-size: 200% 200%; + border-radius: 30px; + transition: all 0.4s ease; + position: relative; + overflow: hidden; + animation: linkRainbow 4s ease-in-out infinite; + box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3); +} + +@keyframes linkRainbow { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.news-link::before { + content: '🚀'; + font-size: 1.1em; +} + +.news-link::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); + transition: left 0.6s ease; +} + +.news-link:hover::after { + left: 100%; +} + +.news-link:hover { + transform: scale(1.05) translateY(-2px); + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.5); +} + +/* 错误信息 */ +.error-message { + text-align: center; + padding: 70px 40px; + background: rgba(255, 255, 255, 0.95); + border-radius: 25px; + box-shadow: 0 10px 40px rgba(231, 76, 60, 0.1); + backdrop-filter: blur(20px); +} + +.error-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 25px; +} + +.error-icon { + font-size: 5em; + animation: errorShake 1.5s ease-in-out infinite alternate; +} + +@keyframes errorShake { + 0% { transform: translateX(0) rotate(0deg); } + 25% { transform: translateX(-8px) rotate(-8deg); } + 50% { transform: translateX(8px) rotate(8deg); } + 75% { transform: translateX(-5px) rotate(-5deg); } + 100% { transform: translateX(0) rotate(0deg); } +} + +.error-content h3 { + font-size: 1.8em; + color: #e74c3c; + margin: 0; + font-weight: 700; +} + +.error-content p { + color: #7f8c8d; + font-size: 1.1em; + margin: 0; + line-height: 1.6; +} + +.retry-btn { + background: linear-gradient(135deg, #ff6b6b, #4ecdc4); + color: white; + border: none; + padding: 15px 30px; + border-radius: 30px; + cursor: pointer; + font-size: 1.1em; + font-weight: 700; + transition: all 0.4s ease; + box-shadow: 0 6px 20px rgba(255, 107, 107, 0.3); + display: inline-flex; + align-items: center; + gap: 10px; +} + +.retry-btn:hover { + background: linear-gradient(135deg, #e74c3c, #3498db); + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.5); + transform: translateY(-3px); +} + +.retry-btn span { + font-size: 1.2em; + transition: transform 0.4s ease; +} + +.retry-btn:hover span { + transform: rotate(360deg); +} + +/* 平板端适配 (768px - 1024px) */ +@media (min-width: 768px) and (max-width: 1024px) { + .container { + padding: 25px; + } + + .header { + padding: 35px 25px; + } + + .header-icon { + font-size: 3.5em; + } + + .title { + font-size: 2.8em; + letter-spacing: 1.5px; + } + + .subtitle { + font-size: 1.2em; + } + + .news-list { + grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); + gap: 30px; + } + + .news-item { + padding: 25px; + } + + .news-rank { + min-width: 42px; + height: 42px; + font-size: 1.05em; + } + + .news-title { + font-size: 1.25em; + } + + .tab-container { + gap: 12px; + } + + .tab-btn { + padding: 10px 20px; + font-size: 0.95em; + } +} + +/* 电脑端适配 (1025px+) */ +@media (min-width: 1025px) { + .container { + padding: 40px; + } + + .header { + padding: 50px 40px; + margin-bottom: 50px; + } + + .header-icon { + font-size: 4.5em; + } + + .title { + font-size: 3.8em; + letter-spacing: 3px; + } + + .subtitle { + font-size: 1.4em; + } + + .news-list { + grid-template-columns: repeat(auto-fit, minmax(550px, 1fr)); + gap: 35px; + } + + .news-item { + padding: 35px; + } + + .news-rank { + min-width: 50px; + height: 50px; + font-size: 1.2em; + } + + .news-title { + font-size: 1.4em; + } + + .news-meta { + gap: 25px; + } + + .news-author { + font-size: 1.05em; + } + + .news-time { + font-size: 1em; + } + + .news-link { + font-size: 1.05em; + padding: 14px 28px; + } + + /* 电脑端特殊效果 */ + .news-item:hover { + transform: translateY(-10px) scale(1.03); + } + + .tab-btn { + padding: 14px 28px; + font-size: 1.05em; + } +} + +/* 手机端适配 (767px以下) */ +@media (max-width: 767px) { + .container { + padding: 15px; + } + + .header { + padding: 25px 20px; + margin-bottom: 25px; + } + + .header-icon { + font-size: 2.8em; + } + + .title { + font-size: 2.2em; + letter-spacing: 1px; + } + + .subtitle { + font-size: 1em; + } + + .tab-container { + gap: 8px; + justify-content: center; + } + + .tab-btn { + padding: 8px 16px; + font-size: 0.85em; + flex-direction: column; + gap: 4px; + } + + .update-time { + font-size: 0.9em; + padding: 8px 16px; + } + + .refresh-btn { + padding: 12px 24px; + font-size: 0.95em; + } + + .news-item { + padding: 20px; + border-radius: 15px; + } + + .news-rank { + min-width: 38px; + height: 38px; + font-size: 0.95em; + } + + .news-title { + font-size: 1.15em; + line-height: 1.3; + } + + .news-meta { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + + .news-author { + font-size: 0.9em; + } + + .news-time { + font-size: 0.85em; + } + + .news-link { + font-size: 0.9em; + padding: 10px 20px; + align-self: flex-start; + } + + /* 手机端动画优化 */ + .news-item { + animation-duration: 0.4s; + } + + .news-item:hover { + transform: translateY(-3px) scale(1.01); + } +} + +/* 超小屏幕适配 (480px以下) */ +@media (max-width: 480px) { + .container { + padding: 12px; + } + + .header { + padding: 20px 15px; + margin-bottom: 20px; + } + + .header-icon { + font-size: 2.5em; + } + + .title { + font-size: 1.9em; + letter-spacing: 0.5px; + } + + .subtitle { + font-size: 0.95em; + } + + .tab-container { + gap: 6px; + } + + .tab-btn { + padding: 6px 12px; + font-size: 0.8em; + min-width: auto; + } + + .tab-icon { + font-size: 1em; + } + + .update-time { + font-size: 0.85em; + padding: 6px 12px; + flex-direction: column; + gap: 4px; + } + + .refresh-btn { + padding: 10px 20px; + font-size: 0.9em; + } + + .news-list { + gap: 15px; + } + + .news-item { + padding: 18px 15px; + border-radius: 12px; + } + + .news-header { + gap: 12px; + margin-bottom: 15px; + } + + .news-rank { + min-width: 35px; + height: 35px; + font-size: 0.9em; + } + + .news-title { + font-size: 1.05em; + line-height: 1.25; + } + + .news-meta { + gap: 8px; + } + + .news-author { + font-size: 0.85em; + } + + .news-time { + font-size: 0.8em; + } + + .news-link { + font-size: 0.85em; + padding: 8px 16px; + } + + /* 超小屏幕性能优化 */ + .news-item { + transition: transform 0.2s ease, box-shadow 0.2s ease; + } + + .news-item::before, + .news-item::after, + .news-link::after { + display: none; + } + + .loading-content { + gap: 15px; + } + + .loading-emoji { + font-size: 2.5em; + } + + .error-icon { + font-size: 3.5em; + } + + .error-content h3 { + font-size: 1.4em; + } + + .error-content p { + font-size: 0.95em; + } +} diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/index.html b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/index.html new file mode 100644 index 00000000..765583af --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/index.html @@ -0,0 +1,77 @@ + + + + + + 🔥 HackerNews 热门榜单 + + + + +
+
+
🌈
+

🔥 HackerNews 热门榜单 💻

+

全球技术社区 · 实时热门话题

+ +
+ + + +
+ +
+ + 加载中... +
+ + +
+ +
+
+
+
+ 🚀 +

正在获取最新榜单...

+
+ + + +
+
+
+
+ +
+ +
+ + +
+ + + + diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/js/script.js b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/js/script.js new file mode 100644 index 00000000..33d90bed --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/js/script.js @@ -0,0 +1,338 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; +let currentType = 'top'; + +// DOM元素 +const loadingElement = document.getElementById('loading'); +const newsListElement = document.getElementById('newsList'); +const errorMessageElement = document.getElementById('errorMessage'); +const updateTimeElement = document.getElementById('updateTime'); +const refreshBtn = document.getElementById('refreshBtn'); +const tabBtns = document.querySelectorAll('.tab-btn'); + +// 页面加载完成后自动加载数据 +document.addEventListener('DOMContentLoaded', function() { + loadNewsList(); + initTabEvents(); +}); + +// 初始化标签事件 +function initTabEvents() { + tabBtns.forEach(btn => { + btn.addEventListener('click', function() { + const type = this.getAttribute('data-type'); + if (type !== currentType) { + currentType = type; + updateActiveTab(this); + loadNewsList(); + } + }); + }); +} + +// 更新活跃标签 +function updateActiveTab(activeBtn) { + tabBtns.forEach(btn => btn.classList.remove('active')); + activeBtn.classList.add('active'); +} + +// 刷新按钮点击事件 +refreshBtn.addEventListener('click', function() { + loadNewsList(); +}); + +// 加载新闻列表 +async function loadNewsList() { + showLoading(); + hideError(); + + try { + const data = await fetchData(); + displayNewsList(data.data); + updateRefreshTime(); + } catch (error) { + console.error('加载失败:', error); + showError(); + } + + hideLoading(); +} + +// 获取数据 +async function fetchData() { + for (let i = 0; i < API_ENDPOINTS.length; i++) { + const apiUrl = API_ENDPOINTS[currentApiIndex]; + + try { + const response = await fetch(`${apiUrl}/v2/hacker-news/${currentType}`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + timeout: 10000 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + return data; + } else { + throw new Error('数据格式错误'); + } + } catch (error) { + console.error(`API ${apiUrl} 请求失败:`, error); + currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (i === API_ENDPOINTS.length - 1) { + throw new Error('所有API接口都无法访问'); + } + } + } +} + +// 显示新闻列表 +function displayNewsList(newsData) { + newsListElement.innerHTML = ''; + + newsData.forEach((item, index) => { + const newsItem = createNewsItem(item, index + 1); + newsListElement.appendChild(newsItem); + }); +} + +// 创建新闻项目 +function createNewsItem(item, rank) { + const newsItem = document.createElement('div'); + newsItem.className = 'news-item'; + + const rankClass = rank <= 5 ? 'news-rank top-5' : 'news-rank'; + const formattedScore = formatScore(item.score); + const formattedTime = formatTime(item.created); + + // 根据排名添加特殊标识 + let rankEmoji = ''; + if (rank === 1) rankEmoji = '🏆'; + else if (rank === 2) rankEmoji = '🥈'; + else if (rank === 3) rankEmoji = '🥉'; + else if (rank <= 10) rankEmoji = '💎'; + else rankEmoji = '⭐'; + + // 根据评分添加热度指示 + let heatLevel = ''; + if (item.score >= 1000) heatLevel = '🔥🔥🔥'; + else if (item.score >= 500) heatLevel = '🔥🔥'; + else if (item.score >= 100) heatLevel = '🔥'; + else heatLevel = '💫'; + + newsItem.innerHTML = ` +
+
${rank}
+
${heatLevel} ${formattedScore}
+
+
${rankEmoji} ${escapeHtml(item.title)}
+
+
👤 ${escapeHtml(item.author)}
+
🕒 ${formattedTime}
+
+ + 🚀 阅读全文 + + `; + + return newsItem; +} + +// 格式化评分 +function formatScore(score) { + if (score >= 1000) { + return (score / 1000).toFixed(1) + 'K'; + } else { + return score.toString(); + } +} + +// 格式化时间 +function formatTime(timeStr) { + try { + const date = new Date(timeStr); + const now = new Date(); + const diff = now - date; + const minutes = Math.floor(diff / (1000 * 60)); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + if (days > 0) { + return `${days}天前`; + } else if (hours > 0) { + return `${hours}小时前`; + } else if (minutes > 0) { + return `${minutes}分钟前`; + } else { + return '刚刚'; + } + } catch (error) { + return timeStr; + } +} + +// HTML转义 +function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +// 更新刷新时间 +function updateRefreshTime() { + const now = new Date(); + const timeStr = now.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + updateTimeElement.textContent = `最后更新: ${timeStr}`; + + // 添加成功提示 + showSuccessMessage('🌈 数据已更新'); +} + +// 显示成功消息 +function showSuccessMessage(message) { + // 移除之前的提示 + const existingToast = document.querySelector('.success-toast'); + if (existingToast) { + existingToast.remove(); + } + + const toast = document.createElement('div'); + toast.className = 'success-toast'; + toast.textContent = message; + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: linear-gradient(135deg, #ff6b6b, #4ecdc4, #45b7d1); + color: white; + padding: 12px 20px; + border-radius: 25px; + box-shadow: 0 4px 20px rgba(255, 107, 107, 0.3); + z-index: 1000; + font-weight: 600; + font-size: 0.9em; + animation: rainbowToastSlide 0.5s ease-out; + backdrop-filter: blur(10px); + `; + + document.body.appendChild(toast); + + // 3秒后自动移除 + setTimeout(() => { + toast.style.animation = 'rainbowToastSlideOut 0.5s ease-in forwards'; + setTimeout(() => toast.remove(), 500); + }, 3000); +} + +// 显示加载状态 +function showLoading() { + loadingElement.style.display = 'block'; + newsListElement.style.display = 'none'; +} + +// 隐藏加载状态 +function hideLoading() { + loadingElement.style.display = 'none'; + newsListElement.style.display = 'block'; +} + +// 显示错误信息 +function showError() { + errorMessageElement.style.display = 'block'; + newsListElement.style.display = 'none'; +} + +// 隐藏错误信息 +function hideError() { + errorMessageElement.style.display = 'none'; +} + +// 添加CSS动画到页面 +if (!document.querySelector('#toast-styles')) { + const style = document.createElement('style'); + style.id = 'toast-styles'; + style.textContent = ` + @keyframes rainbowToastSlide { + from { + opacity: 0; + transform: translateX(100px) scale(0.8); + } + to { + opacity: 1; + transform: translateX(0) scale(1); + } + } + + @keyframes rainbowToastSlideOut { + from { + opacity: 1; + transform: translateX(0) scale(1); + } + to { + opacity: 0; + transform: translateX(100px) scale(0.8); + } + } + + .success-toast { + background-size: 200% 200%; + animation: rainbowToastSlide 0.5s ease-out, toastRainbow 2s ease-in-out infinite !important; + } + + @keyframes toastRainbow { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + } + `; + document.head.appendChild(style); +} + +// 自动刷新 (每5分钟) +setInterval(function() { + loadNewsList(); +}, 5 * 60 * 1000); + +// 键盘快捷键支持 +document.addEventListener('keydown', function(e) { + if (e.key === 'r' && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + loadNewsList(); + } + + // 数字键切换标签 + if (e.key >= '1' && e.key <= '3') { + e.preventDefault(); + const typeMap = { '1': 'top', '2': 'new', '3': 'best' }; + const targetType = typeMap[e.key]; + const targetBtn = document.querySelector(`[data-type="${targetType}"]`); + if (targetBtn && targetType !== currentType) { + currentType = targetType; + updateActiveTab(targetBtn); + loadNewsList(); + } + } +}); diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/返回接口.json new file mode 100644 index 00000000..0008f691 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/HackerNews榜单/返回接口.json @@ -0,0 +1,87 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "id": 45087396, + "title": "We should have the ability to run any code we want on hardware we own", + "link": "https://hugotunius.se/2025/08/31/what-every-argument-about-sideloading-gets-wrong.html", + "score": 995, + "author": "K0nserv", + "created": "2025-08-31 21:46:26", + "created_at": 1756676786000 + }, + { + "id": 45053029, + "title": "Why countries trade with each other while fighting", + "link": "https://news.mit.edu/2025/why-countries-trade-each-other-while-fighting-mariya-grinberg-book-0828", + "score": 32, + "author": "LorenDB", + "created": "2025-08-28 14:58:28", + "created_at": 1756393108000 + }, + { + "id": 45086020, + "title": "Eternal Struggle", + "link": "https://yoavg.github.io/eternal/", + "score": 481, + "author": "yurivish", + "created": "2025-08-31 19:04:03", + "created_at": 1756667043000 + }, + { + "id": 45052960, + "title": "C++: Strongly Happens Before?", + "link": "https://nekrozqliphort.github.io/posts/happens-b4/", + "score": 16, + "author": "signa11", + "created": "2025-08-28 14:54:37", + "created_at": 1756392877000 + }, + { + "id": 45087971, + "title": "Nintendo Switch 2 Dock USB-C Compatibility", + "link": "https://www.lttlabs.com/blog/2025/08/30/nintendo-switch-2-dock", + "score": 192, + "author": "croes", + "created": "2025-08-31 23:21:46", + "created_at": 1756682506000 + }, + { + "id": 45082731, + "title": "“This telegram must be closely paraphrased before being communicated to anyone”", + "link": "https://history.stackexchange.com/questions/79371/this-telegram-must-be-closely-paraphrased-before-being-communicated-to-anyone", + "score": 645, + "author": "azeemba", + "created": "2025-08-31 12:39:47", + "created_at": 1756643987000 + }, + { + "id": 45089256, + "title": "What Is Complexity in Chess?", + "link": "https://lichess.org/@/Toadofsky/blog/what-is-complexity/pKo1swFh", + "score": 41, + "author": "fzliu", + "created": "2025-09-01 03:45:33", + "created_at": 1756698333000 + }, + { + "id": 45087815, + "title": "Lewis and Clark marked their trail with laxatives", + "link": "https://offbeatoregon.com/2501d1006d_biliousPills-686.077.html", + "score": 141, + "author": "toomuchtodo", + "created": "2025-08-31 22:54:26", + "created_at": 1756680866000 + }, + { + "id": 45083952, + "title": "Jujutsu for everyone", + "link": "https://jj-for-everyone.github.io/", + "score": 363, + "author": "Bogdanp", + "created": "2025-08-31 15:31:04", + "created_at": 1756654264000 + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/background.css b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/background.css new file mode 100644 index 00000000..91b3ee72 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/background.css @@ -0,0 +1,40 @@ +.background-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + overflow: hidden; +} + +.rainbow-gradient { + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 217deg, + rgba(255, 0, 0, 0.6), + rgba(255, 0, 0, 0) 70.71% + ), linear-gradient( + 127deg, + rgba(0, 255, 0, 0.6), + rgba(0, 255, 0, 0) 70.71% + ), linear-gradient( + 336deg, + rgba(0, 0, 255, 0.6), + rgba(0, 0, 255, 0) 70.71% + ); + animation: rainbow-rotate 15s linear infinite; +} + +@keyframes rainbow-rotate { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/style.css b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/style.css new file mode 100644 index 00000000..b7d33692 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/css/style.css @@ -0,0 +1,155 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; + color: #333; + background-color: #f5f5f5; + position: relative; + min-height: 100vh; +} + +.container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + position: relative; + z-index: 1; + background-color: rgba(255, 255, 255, 0.85); + border-radius: 10px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +header { + text-align: center; + margin-bottom: 20px; + padding-bottom: 15px; + border-bottom: 1px solid #eaeaea; +} + +header h1 { + color: #07a35a; + margin-bottom: 10px; + font-size: 2rem; +} + +.update-time { + color: #888; + font-size: 0.9rem; +} + +.hot-list { + list-style: none; +} + +.hot-item { + padding: 15px; + margin-bottom: 10px; + border-radius: 8px; + background-color: white; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); + transition: transform 0.2s, box-shadow 0.2s; + display: flex; + align-items: center; +} + +.hot-item:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.hot-rank { + font-size: 1.2rem; + font-weight: bold; + color: #ff8200; + margin-right: 15px; + min-width: 30px; + text-align: center; +} + +.hot-rank.top-1 { + color: #ff4500; +} + +.hot-rank.top-2, .hot-rank.top-3 { + color: #ff6600; +} + +.hot-content { + flex: 1; +} + +.hot-title { + font-size: 1.1rem; + margin-bottom: 5px; + color: #333; + text-decoration: none; + display: block; +} + +.hot-title:hover { + color: #07a35a; +} + +.hot-value { + font-size: 0.85rem; + color: #888; +} + +.loading { + text-align: center; + padding: 20px; + color: #888; +} + +footer { + text-align: center; + margin-top: 30px; + padding-top: 15px; + border-top: 1px solid #eaeaea; + color: #888; + font-size: 0.9rem; +} + +/* 响应式设计 */ +/* 手机端 */ +@media (max-width: 576px) { + .container { + padding: 15px; + margin: 10px; + } + + header h1 { + font-size: 1.5rem; + } + + .hot-item { + padding: 12px; + } + + .hot-rank { + font-size: 1rem; + min-width: 25px; + margin-right: 10px; + } + + .hot-title { + font-size: 1rem; + } +} + +/* 平板端 */ +@media (min-width: 577px) and (max-width: 992px) { + .container { + max-width: 90%; + } + + header h1 { + font-size: 1.8rem; + } +} + +/* 电脑端 - 默认样式已经设置 */ \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/index.html b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/index.html new file mode 100644 index 00000000..0cb32410 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/index.html @@ -0,0 +1,34 @@ + + + + + + 微博热搜榜 + + + + +
+
+
+ +
+
+

微博热搜榜

+
+
+ +
+
+
加载中...
+
+
+ +
+

数据来源于微博热搜榜

+
+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/js/main.js b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/js/main.js new file mode 100644 index 00000000..8a5e3bd4 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/js/main.js @@ -0,0 +1,94 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s-cf.viki.moe/v2/weibo", + "https://60s.viki.moe/v2/weibo", + "https://60s.b23.run/v2/weibo", + "https://60s.114128.xyz/v2/weibo", + "https://60s-cf.114128.xyz/v2/weibo" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const hotListElement = document.getElementById('hotList'); +const updateTimeElement = document.getElementById('updateTime'); + +// 格式化时间 +function formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + +// 渲染热搜列表 +function renderHotList(data) { + hotListElement.innerHTML = ''; + + data.forEach((item, index) => { + const hotItem = document.createElement('div'); + hotItem.className = 'hot-item'; + + const rankClass = index < 3 ? `top-${index + 1}` : ''; + + hotItem.innerHTML = ` +
${index + 1}
+
+ ${item.title} + ${item.hot_value ? `
${item.hot_value}
` : ''} +
+ `; + + hotListElement.appendChild(hotItem); + }); + + // 更新时间 + updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; +} + +// 获取微博热搜数据 +async function fetchWeiboHotList() { + try { + const response = await fetch(API_ENDPOINTS[currentApiIndex]); + + if (!response.ok) { + throw new Error('网络响应不正常'); + } + + const result = await response.json(); + + if (result.code === 200 && result.data) { + renderHotList(result.data); + } else { + throw new Error('数据格式错误'); + } + } catch (error) { + console.error('获取数据失败:', error); + + // 尝试切换到下一个API + currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + // 显示错误信息 + hotListElement.innerHTML = ` +
+ 获取数据失败,正在尝试其他接口... +
+ `; + + // 延迟后重试 + setTimeout(fetchWeiboHotList, 2000); + } +} + +// 页面加载完成后获取数据 +document.addEventListener('DOMContentLoaded', () => { + fetchWeiboHotList(); + + // 每隔5分钟刷新一次数据 + setInterval(fetchWeiboHotList, 5 * 60 * 1000); +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/返回接口.json new file mode 100644 index 00000000..0779a075 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/微博热搜榜/返回接口.json @@ -0,0 +1,261 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "title": "00后男生0.6秒飞针采血惊呆患者", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=00%E5%90%8E%E7%94%B7%E7%94%9F0.6%E7%A7%92%E9%A3%9E%E9%92%88%E9%87%87%E8%A1%80%E6%83%8A%E5%91%86%E6%82%A3%E8%80%85" + }, + { + "title": "普京带3位副总理10多位部长到中国", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%99%AE%E4%BA%AC%E5%B8%A63%E4%BD%8D%E5%89%AF%E6%80%BB%E7%90%8610%E5%A4%9A%E4%BD%8D%E9%83%A8%E9%95%BF%E5%88%B0%E4%B8%AD%E5%9B%BD" + }, + { + "title": "始终高举上海精神旗帜", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%A7%8B%E7%BB%88%E9%AB%98%E4%B8%BE%E4%B8%8A%E6%B5%B7%E7%B2%BE%E7%A5%9E%E6%97%97%E5%B8%9C" + }, + { + "title": "女生苦练化妆1年的变化", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%A5%B3%E7%94%9F%E8%8B%A6%E7%BB%83%E5%8C%96%E5%A6%861%E5%B9%B4%E7%9A%84%E5%8F%98%E5%8C%96" + }, + { + "title": "香港1200架无人机重现日本投降矣", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%A6%99%E6%B8%AF1200%E6%9E%B6%E6%97%A0%E4%BA%BA%E6%9C%BA%E9%87%8D%E7%8E%B0%E6%97%A5%E6%9C%AC%E6%8A%95%E9%99%8D%E7%9F%A3" + }, + { + "title": "尚公主全阵容官宣", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%B0%9A%E5%85%AC%E4%B8%BB%E5%85%A8%E9%98%B5%E5%AE%B9%E5%AE%98%E5%AE%A3" + }, + { + "title": "真的可以永远相信刘宇舞台", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E7%9C%9F%E7%9A%84%E5%8F%AF%E4%BB%A5%E6%B0%B8%E8%BF%9C%E7%9B%B8%E4%BF%A1%E5%88%98%E5%AE%87%E8%88%9E%E5%8F%B0" + }, + { + "title": "九三阅兵徒步方队铿锵步伐", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E4%B9%9D%E4%B8%89%E9%98%85%E5%85%B5%E5%BE%92%E6%AD%A5%E6%96%B9%E9%98%9F%E9%93%BF%E9%94%B5%E6%AD%A5%E4%BC%90" + }, + { + "title": "唐朝诡事录", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%94%90%E6%9C%9D%E8%AF%A1%E4%BA%8B%E5%BD%95" + }, + { + "title": "抗战胜利80周年第3场记者招待会", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%8A%97%E6%88%98%E8%83%9C%E5%88%A980%E5%91%A8%E5%B9%B4%E7%AC%AC3%E5%9C%BA%E8%AE%B0%E8%80%85%E6%8B%9B%E5%BE%85%E4%BC%9A" + }, + { + "title": "王曼昱钱天一3比2蒯曼孙颖莎", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E7%8E%8B%E6%9B%BC%E6%98%B1%E9%92%B1%E5%A4%A9%E4%B8%803%E6%AF%942%E8%92%AF%E6%9B%BC%E5%AD%99%E9%A2%96%E8%8E%8E" + }, + { + "title": "张维伊对96岁的姥姥说长命百岁", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%BC%A0%E7%BB%B4%E4%BC%8A%E5%AF%B996%E5%B2%81%E7%9A%84%E5%A7%A5%E5%A7%A5%E8%AF%B4%E9%95%BF%E5%91%BD%E7%99%BE%E5%B2%81" + }, + { + "title": "孟子义李昀锐定妆照", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%AD%9F%E5%AD%90%E4%B9%89%E6%9D%8E%E6%98%80%E9%94%90%E5%AE%9A%E5%A6%86%E7%85%A7" + }, + { + "title": "以为张艺兴穿的蓝色抹胸", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E4%BB%A5%E4%B8%BA%E5%BC%A0%E8%89%BA%E5%85%B4%E7%A9%BF%E7%9A%84%E8%93%9D%E8%89%B2%E6%8A%B9%E8%83%B8" + }, + { + "title": "尚公主开机", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%B0%9A%E5%85%AC%E4%B8%BB%E5%BC%80%E6%9C%BA" + }, + { + "title": "心动的信号8", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%BF%83%E5%8A%A8%E7%9A%84%E4%BF%A1%E5%8F%B78" + }, + { + "title": "霍建华病娇疯批演爽了", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%9C%8D%E5%BB%BA%E5%8D%8E%E7%97%85%E5%A8%87%E7%96%AF%E6%89%B9%E6%BC%94%E7%88%BD%E4%BA%86" + }, + { + "title": "普京抵达天津", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%99%AE%E4%BA%AC%E6%8A%B5%E8%BE%BE%E5%A4%A9%E6%B4%A5" + }, + { + "title": "龚俊的体面只给旅游前几天", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%BE%9A%E4%BF%8A%E7%9A%84%E4%BD%93%E9%9D%A2%E5%8F%AA%E7%BB%99%E6%97%85%E6%B8%B8%E5%89%8D%E5%87%A0%E5%A4%A9" + }, + { + "title": "开学焦虑更严重的另有其人", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%BC%80%E5%AD%A6%E7%84%A6%E8%99%91%E6%9B%B4%E4%B8%A5%E9%87%8D%E7%9A%84%E5%8F%A6%E6%9C%89%E5%85%B6%E4%BA%BA" + }, + { + "title": "那英小发雷霆", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%82%A3%E8%8B%B1%E5%B0%8F%E5%8F%91%E9%9B%B7%E9%9C%86" + }, + { + "title": "居然有演员一句台词背1小时", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%B1%85%E7%84%B6%E6%9C%89%E6%BC%94%E5%91%98%E4%B8%80%E5%8F%A5%E5%8F%B0%E8%AF%8D%E8%83%8C1%E5%B0%8F%E6%97%B6" + }, + { + "title": "谁教魏哲鸣冷脸跳这些的", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%B0%81%E6%95%99%E9%AD%8F%E5%93%B2%E9%B8%A3%E5%86%B7%E8%84%B8%E8%B7%B3%E8%BF%99%E4%BA%9B%E7%9A%84" + }, + { + "title": "朱孝天爆冷出局", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%9C%B1%E5%AD%9D%E5%A4%A9%E7%88%86%E5%86%B7%E5%87%BA%E5%B1%80" + }, + { + "title": "俄军称掌握战略主动权", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E4%BF%84%E5%86%9B%E7%A7%B0%E6%8E%8C%E6%8F%A1%E6%88%98%E7%95%A5%E4%B8%BB%E5%8A%A8%E6%9D%83" + }, + { + "title": "谈恋爱3个月定律", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%B0%88%E6%81%8B%E7%88%B13%E4%B8%AA%E6%9C%88%E5%AE%9A%E5%BE%8B" + }, + { + "title": "沈腾说错了最怕人笨还不勤快", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%B2%88%E8%85%BE%E8%AF%B4%E9%94%99%E4%BA%86%E6%9C%80%E6%80%95%E4%BA%BA%E7%AC%A8%E8%BF%98%E4%B8%8D%E5%8B%A4%E5%BF%AB" + }, + { + "title": "王菲最新状态", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E7%8E%8B%E8%8F%B2%E6%9C%80%E6%96%B0%E7%8A%B6%E6%80%81" + }, + { + "title": "张紫宁转行当拉拉队经理人了", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%BC%A0%E7%B4%AB%E5%AE%81%E8%BD%AC%E8%A1%8C%E5%BD%93%E6%8B%89%E6%8B%89%E9%98%9F%E7%BB%8F%E7%90%86%E4%BA%BA%E4%BA%86" + }, + { + "title": "金价大涨两大原因", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%87%91%E4%BB%B7%E5%A4%A7%E6%B6%A8%E4%B8%A4%E5%A4%A7%E5%8E%9F%E5%9B%A0" + }, + { + "title": "陕西Shaanxi官方标准拼音", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E9%99%95%E8%A5%BFShaanxi%E5%AE%98%E6%96%B9%E6%A0%87%E5%87%86%E6%8B%BC%E9%9F%B3" + }, + { + "title": "边伯贤跳刀马刀马", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%BE%B9%E4%BC%AF%E8%B4%A4%E8%B7%B3%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC" + }, + { + "title": "冷冻太久的肉就不要再吃了", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%86%B7%E5%86%BB%E5%A4%AA%E4%B9%85%E7%9A%84%E8%82%89%E5%B0%B1%E4%B8%8D%E8%A6%81%E5%86%8D%E5%90%83%E4%BA%86" + }, + { + "title": "95后00后恋爱有代沟", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=95%E5%90%8E00%E5%90%8E%E6%81%8B%E7%88%B1%E6%9C%89%E4%BB%A3%E6%B2%9F" + }, + { + "title": "易烊千玺抢票", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA%E6%8A%A2%E7%A5%A8" + }, + { + "title": "孙闻被乒协处罚", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%AD%99%E9%97%BB%E8%A2%AB%E4%B9%92%E5%8D%8F%E5%A4%84%E7%BD%9A" + }, + { + "title": "这居然是白举纲", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%BF%99%E5%B1%85%E7%84%B6%E6%98%AF%E7%99%BD%E4%B8%BE%E7%BA%B2" + }, + { + "title": "纪凌尘出演孟子义新剧", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E7%BA%AA%E5%87%8C%E5%B0%98%E5%87%BA%E6%BC%94%E5%AD%9F%E5%AD%90%E4%B9%89%E6%96%B0%E5%89%A7" + }, + { + "title": "外卖员妈妈暴雨中将孩子托付派出所", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%A4%96%E5%8D%96%E5%91%98%E5%A6%88%E5%A6%88%E6%9A%B4%E9%9B%A8%E4%B8%AD%E5%B0%86%E5%AD%A9%E5%AD%90%E6%89%98%E4%BB%98%E6%B4%BE%E5%87%BA%E6%89%80" + }, + { + "title": "我点外卖没用上券就这样", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%88%91%E7%82%B9%E5%A4%96%E5%8D%96%E6%B2%A1%E7%94%A8%E4%B8%8A%E5%88%B8%E5%B0%B1%E8%BF%99%E6%A0%B7" + }, + { + "title": "孙颖莎小时候真来过新疆", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%AD%99%E9%A2%96%E8%8E%8E%E5%B0%8F%E6%97%B6%E5%80%99%E7%9C%9F%E6%9D%A5%E8%BF%87%E6%96%B0%E7%96%86" + }, + { + "title": "印尼首都交通瘫痪", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%8D%B0%E5%B0%BC%E9%A6%96%E9%83%BD%E4%BA%A4%E9%80%9A%E7%98%AB%E7%97%AA" + }, + { + "title": "停狗位停满了小狗", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%81%9C%E7%8B%97%E4%BD%8D%E5%81%9C%E6%BB%A1%E4%BA%86%E5%B0%8F%E7%8B%97" + }, + { + "title": "怪不得校服裤子屁股锃亮", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%80%AA%E4%B8%8D%E5%BE%97%E6%A0%A1%E6%9C%8D%E8%A3%A4%E5%AD%90%E5%B1%81%E8%82%A1%E9%94%83%E4%BA%AE" + }, + { + "title": "这一幕幕中国浪漫看得心暖暖", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%BF%99%E4%B8%80%E5%B9%95%E5%B9%95%E4%B8%AD%E5%9B%BD%E6%B5%AA%E6%BC%AB%E7%9C%8B%E5%BE%97%E5%BF%83%E6%9A%96%E6%9A%96" + }, + { + "title": "林书豪退役", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E6%9E%97%E4%B9%A6%E8%B1%AA%E9%80%80%E5%BD%B9" + }, + { + "title": "小猫咪舔毛把自己累睡着", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%B0%8F%E7%8C%AB%E5%92%AA%E8%88%94%E6%AF%9B%E6%8A%8A%E8%87%AA%E5%B7%B1%E7%B4%AF%E7%9D%A1%E7%9D%80" + }, + { + "title": "iPhone17国行预计涨价500元", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=iPhone17%E5%9B%BD%E8%A1%8C%E9%A2%84%E8%AE%A1%E6%B6%A8%E4%BB%B7500%E5%85%83" + }, + { + "title": "土耳其总统埃尔多安抵达天津", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%9C%9F%E8%80%B3%E5%85%B6%E6%80%BB%E7%BB%9F%E5%9F%83%E5%B0%94%E5%A4%9A%E5%AE%89%E6%8A%B5%E8%BE%BE%E5%A4%A9%E6%B4%A5" + }, + { + "title": "脱口秀和Ta的朋友们", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E8%84%B1%E5%8F%A3%E7%A7%80%E5%92%8CTa%E7%9A%84%E6%9C%8B%E5%8F%8B%E4%BB%AC" + }, + { + "title": "孟子义暮晚摇", + "hot_value": 0, + "link": "https://s.weibo.com/weibo?q=%E5%AD%9F%E5%AD%90%E4%B9%89%E6%9A%AE%E6%99%9A%E6%91%87" + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/background.css b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/background.css new file mode 100644 index 00000000..fbf1fd3f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/background.css @@ -0,0 +1,52 @@ +/* 背景相关样式 */ +body { + background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 25%, #a5d6a7 50%, #81c784 75%, #66bb6a 100%); + background-attachment: fixed; + min-height: 100vh; + position: relative; +} + +/* 背景装饰元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 80%, rgba(120, 200, 120, 0.15) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(100, 180, 100, 0.15) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(140, 220, 140, 0.1) 0%, transparent 50%), + radial-gradient(circle at 60% 70%, rgba(160, 240, 160, 0.08) 0%, transparent 40%); + pointer-events: none; + z-index: -1; +} + +/* 浮动装饰圆点 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 10% 10%, rgba(76, 175, 80, 0.1) 2px, transparent 2px), + radial-gradient(circle at 90% 90%, rgba(76, 175, 80, 0.08) 1px, transparent 1px), + radial-gradient(circle at 30% 80%, rgba(76, 175, 80, 0.06) 1.5px, transparent 1.5px), + radial-gradient(circle at 70% 20%, rgba(76, 175, 80, 0.05) 1px, transparent 1px); + background-size: 100px 100px, 150px 150px, 80px 80px, 120px 120px; + animation: float 20s ease-in-out infinite alternate; + pointer-events: none; + z-index: -1; +} + +@keyframes float { + 0% { + transform: translateY(0px) rotate(0deg); + } + 100% { + transform: translateY(-10px) rotate(1deg); + } +} diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/style.css b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/style.css new file mode 100644 index 00000000..2d1682db --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/css/style.css @@ -0,0 +1,956 @@ +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2e7d32; + overflow-x: hidden; +} + +/* 容器 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + animation: containerFadeIn 0.8s ease-out; +} + +@keyframes containerFadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 头部 */ +.header { + text-align: center; + margin-bottom: 40px; + background: rgba(255, 255, 255, 0.95); + padding: 35px 25px; + border-radius: 20px; + box-shadow: 0 8px 32px rgba(46, 125, 50, 0.12); + backdrop-filter: blur(15px); + border: 1px solid rgba(255, 255, 255, 0.3); + position: relative; + overflow: hidden; +} + +.header::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(76, 175, 80, 0.1), transparent); + animation: shimmer 3s infinite; +} + +@keyframes shimmer { + 0% { left: -100%; } + 100% { left: 100%; } +} + +.header-icon { + font-size: 3em; + margin-bottom: 10px; + animation: bounce 2s infinite; +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } + 40% { transform: translateY(-10px); } + 60% { transform: translateY(-5px); } +} + +.title { + font-size: 2.8em; + font-weight: 700; + color: #1b5e20; + margin-bottom: 8px; + text-shadow: 0 2px 4px rgba(46, 125, 50, 0.1); + letter-spacing: 1px; +} + +.subtitle { + font-size: 1.1em; + color: #4caf50; + margin-bottom: 20px; + font-weight: 500; + opacity: 0.9; +} + +.update-time { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + color: #4caf50; + font-size: 0.95em; + margin-bottom: 20px; + padding: 8px 16px; + background: rgba(76, 175, 80, 0.1); + border-radius: 20px; + display: inline-flex; +} + +.time-icon { + font-size: 1.1em; + animation: tick 1s infinite; +} + +@keyframes tick { + 0%, 50% { transform: rotate(0deg); } + 25% { transform: rotate(15deg); } + 75% { transform: rotate(-15deg); } +} + +.refresh-btn { + background: linear-gradient(135deg, #4caf50, #66bb6a, #81c784); + color: white; + border: none; + padding: 12px 30px; + border-radius: 30px; + cursor: pointer; + font-size: 1em; + font-weight: 600; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); + display: inline-flex; + align-items: center; + gap: 8px; + position: relative; + overflow: hidden; +} + +.refresh-btn::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(255, 255, 255, 0.2); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.5s ease; +} + +.refresh-btn:hover::before { + width: 300px; + height: 300px; +} + +.refresh-btn:hover { + background: linear-gradient(135deg, #388e3c, #4caf50, #66bb6a); + box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4); + transform: translateY(-3px); +} + +.refresh-btn:active { + transform: translateY(-1px); +} + +.btn-icon { + font-size: 1.1em; + transition: transform 0.3s ease; +} + +.refresh-btn:hover .btn-icon { + transform: rotate(180deg); +} + +/* 加载动画 */ +.loading { + text-align: center; + padding: 60px 30px; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + margin-bottom: 20px; + box-shadow: 0 8px 32px rgba(46, 125, 50, 0.1); + backdrop-filter: blur(15px); +} + +.loading-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.spinner { + width: 50px; + height: 50px; + border: 5px solid #e8f5e8; + border-top: 5px solid #4caf50; + border-radius: 50%; + animation: spin 1s linear infinite; + position: relative; +} + +.spinner::after { + content: ''; + position: absolute; + top: -5px; + left: -5px; + right: -5px; + bottom: -5px; + border: 2px solid transparent; + border-top: 2px solid #81c784; + border-radius: 50%; + animation: spin 2s linear infinite reverse; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading-text { + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; +} + +.loading-emoji { + font-size: 2.5em; + animation: pulse 1.5s ease-in-out infinite alternate; +} + +@keyframes pulse { + 0% { transform: scale(1); opacity: 0.8; } + 100% { transform: scale(1.1); opacity: 1; } +} + +.loading-text p { + font-size: 1.1em; + color: #4caf50; + font-weight: 500; + margin: 0; +} + +.loading-dots { + display: flex; + gap: 5px; +} + +.loading-dots span { + width: 8px; + height: 8px; + background: #4caf50; + border-radius: 50%; + animation: dot-bounce 1.4s ease-in-out infinite both; +} + +.loading-dots span:nth-child(1) { animation-delay: -0.32s; } +.loading-dots span:nth-child(2) { animation-delay: -0.16s; } + +@keyframes dot-bounce { + 0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; } + 40% { transform: scale(1.2); opacity: 1; } +} + +/* 热搜列表 */ +.hot-list { + display: grid; + gap: 20px; + animation: fadeInUp 0.6s ease-out; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.hot-item { + background: rgba(255, 255, 255, 0.98); + border-radius: 16px; + padding: 25px; + box-shadow: 0 4px 20px rgba(46, 125, 50, 0.08); + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + border: 1px solid rgba(76, 175, 80, 0.15); + backdrop-filter: blur(10px); + position: relative; + overflow: hidden; + animation: slideInLeft 0.6s ease-out; + animation-fill-mode: both; +} + +.hot-item:nth-child(odd) { + animation-delay: 0.1s; +} + +.hot-item:nth-child(even) { + animation-delay: 0.2s; +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.hot-item::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 4px; + height: 100%; + background: linear-gradient(to bottom, #4caf50, #81c784); + transform: scaleY(0); + transition: transform 0.3s ease; +} + +.hot-item:hover::before { + transform: scaleY(1); +} + +.hot-item:hover { + box-shadow: 0 8px 40px rgba(46, 125, 50, 0.15); + transform: translateY(-5px) scale(1.02); + border-color: rgba(76, 175, 80, 0.3); +} + +.hot-item-header { + display: flex; + align-items: center; + margin-bottom: 18px; + gap: 15px; +} + +.hot-rank { + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + min-width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 1em; + flex-shrink: 0; + position: relative; + box-shadow: 0 3px 10px rgba(76, 175, 80, 0.3); +} + +.hot-rank::after { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, #4caf50, #81c784, #4caf50); + border-radius: 50%; + z-index: -1; + opacity: 0; + transition: opacity 0.3s ease; +} + +.hot-item:hover .hot-rank::after { + opacity: 0.7; +} + +.hot-rank.top-3 { + background: linear-gradient(135deg, #ff6b35, #f7931e, #ffa726); + box-shadow: 0 3px 15px rgba(255, 107, 53, 0.4); + animation: glow 2s ease-in-out infinite alternate; +} + +@keyframes glow { + 0% { box-shadow: 0 3px 15px rgba(255, 107, 53, 0.4); } + 100% { box-shadow: 0 3px 20px rgba(255, 107, 53, 0.6), 0 0 25px rgba(255, 107, 53, 0.3); } +} + +.hot-rank.top-3::before { + content: '👑'; + position: absolute; + top: -8px; + right: -5px; + font-size: 0.7em; + animation: crown-bounce 1s ease-in-out infinite alternate; +} + +@keyframes crown-bounce { + 0% { transform: translateY(0) rotate(-5deg); } + 100% { transform: translateY(-2px) rotate(5deg); } +} + +.hot-title { + font-size: 1.15em; + font-weight: 600; + color: #1b5e20; + flex: 1; + line-height: 1.4; + position: relative; +} + +.hot-content { + display: flex; + gap: 18px; + align-items: flex-start; +} + +.hot-cover { + width: 90px; + height: 90px; + border-radius: 12px; + object-fit: cover; + flex-shrink: 0; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.hot-cover::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%); + transform: translateX(-100%); + transition: transform 0.6s ease; +} + +.hot-item:hover .hot-cover::after { + transform: translateX(100%); +} + +.hot-item:hover .hot-cover { + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); + transform: scale(1.05); +} + +.hot-info { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; +} + +.hot-value { + color: #e91e63; + font-weight: 700; + font-size: 1.1em; + display: flex; + align-items: center; + gap: 6px; +} + +.hot-value::before { + content: '热度'; + font-size: 1.2em; + animation: fire 1.5s ease-in-out infinite alternate; +} + +@keyframes fire { + 0% { transform: scale(1); } + 100% { transform: scale(1.1); } +} + +.hot-time { + color: #757575; + font-size: 0.9em; + display: flex; + align-items: center; + gap: 6px; +} + +.hot-time::before { + content: '📅日期'; + font-size: 1em; +} + +.hot-link { + display: inline-flex; + align-items: center; + gap: 6px; + color: #4caf50; + text-decoration: none; + font-size: 0.95em; + font-weight: 600; + padding: 8px 18px; + border: 2px solid #4caf50; + border-radius: 25px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + max-width: fit-content; +} + +.hot-link::before { + content: '👀'; + font-size: 1em; +} + +.hot-link::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(76, 175, 80, 0.2), transparent); + transition: left 0.5s ease; +} + +.hot-link:hover::after { + left: 100%; +} + +.hot-link:hover { + background: #4caf50; + color: white; + transform: scale(1.05); + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); +} + +/* 错误信息 */ +.error-message { + text-align: center; + padding: 60px 30px; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + box-shadow: 0 8px 32px rgba(211, 47, 47, 0.1); + backdrop-filter: blur(15px); + border: 1px solid rgba(255, 255, 255, 0.3); +} + +.error-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.error-icon { + font-size: 4em; + animation: shake 1s ease-in-out infinite alternate; +} + +@keyframes shake { + 0% { transform: translateX(0); } + 25% { transform: translateX(-5px) rotate(-5deg); } + 50% { transform: translateX(5px) rotate(5deg); } + 75% { transform: translateX(-3px) rotate(-3deg); } + 100% { transform: translateX(0) rotate(0deg); } +} + +.error-content h3 { + font-size: 1.5em; + color: #d32f2f; + margin: 0; + font-weight: 600; +} + +.error-content p { + color: #757575; + font-size: 1em; + margin: 0; + line-height: 1.5; +} + +.retry-btn { + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + border: none; + padding: 12px 25px; + border-radius: 25px; + cursor: pointer; + font-size: 1em; + font-weight: 600; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); + display: inline-flex; + align-items: center; + gap: 8px; +} + +.retry-btn:hover { + background: linear-gradient(135deg, #388e3c, #4caf50); + box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4); + transform: translateY(-2px); +} + +.retry-btn span { + font-size: 1.1em; + transition: transform 0.3s ease; +} + +.retry-btn:hover span { + transform: rotate(180deg); +} + +/* 平板端适配 (768px - 1024px) */ +@media (min-width: 768px) and (max-width: 1024px) { + .container { + padding: 30px; + } + + .header { + padding: 40px 30px; + } + + .header-icon { + font-size: 3.5em; + } + + .title { + font-size: 2.5em; + } + + .subtitle { + font-size: 1.2em; + } + + .hot-list { + grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); + gap: 25px; + } + + .hot-item { + padding: 30px; + } + + .hot-cover { + width: 85px; + height: 85px; + } + + .hot-rank { + min-width: 42px; + height: 42px; + font-size: 1.05em; + } + + .hot-title { + font-size: 1.2em; + } + + .hot-value { + font-size: 1.15em; + } +} + +/* 电脑端适配 (1025px+) */ +@media (min-width: 1025px) { + .container { + padding: 40px; + } + + .header { + padding: 50px 40px; + margin-bottom: 50px; + } + + .header-icon { + font-size: 4em; + } + + .title { + font-size: 3.5em; + letter-spacing: 2px; + } + + .subtitle { + font-size: 1.3em; + } + + .hot-list { + grid-template-columns: repeat(auto-fit, minmax(550px, 1fr)); + gap: 30px; + } + + .hot-item { + padding: 35px; + } + + .hot-rank { + min-width: 45px; + height: 45px; + font-size: 1.1em; + } + + .hot-cover { + width: 110px; + height: 110px; + } + + .hot-title { + font-size: 1.3em; + } + + .hot-value { + font-size: 1.2em; + } + + .hot-time { + font-size: 1em; + } + + .hot-link { + font-size: 1em; + padding: 10px 20px; + } + + /* 电脑端特殊效果 */ + .hot-item:hover { + transform: translateY(-8px) scale(1.03); + } + + .hot-item::after { + content: ''; + position: absolute; + top: 50%; + right: 20px; + transform: translateY(-50%); + font-size: 1.5em; + opacity: 0; + transition: opacity 0.3s ease; + } + + .hot-item:hover::after { + opacity: 0.3; + } +} + +/* 手机端适配 (默认, 767px以下) */ +@media (max-width: 767px) { + .container { + padding: 15px; + } + + .header { + padding: 25px 20px; + margin-bottom: 25px; + } + + .header-icon { + font-size: 2.5em; + } + + .title { + font-size: 2.2em; + letter-spacing: 0.5px; + } + + .subtitle { + font-size: 1em; + } + + .update-time { + font-size: 0.9em; + padding: 6px 12px; + } + + .refresh-btn { + padding: 10px 20px; + font-size: 0.9em; + } + + .hot-item { + padding: 20px; + border-radius: 12px; + } + + .hot-rank { + min-width: 35px; + height: 35px; + font-size: 0.9em; + } + + .hot-title { + font-size: 1.05em; + line-height: 1.3; + } + + .hot-content { + flex-direction: column; + gap: 15px; + } + + .hot-cover { + width: 100%; + height: 180px; + align-self: center; + max-width: 280px; + border-radius: 10px; + } + + .hot-info { + gap: 10px; + } + + .hot-value { + font-size: 1.05em; + } + + .hot-time { + font-size: 0.85em; + } + + .hot-link { + font-size: 0.9em; + padding: 8px 16px; + align-self: flex-start; + } + + /* 手机端动画优化 */ + .hot-item { + animation-duration: 0.4s; + } + + .hot-item:hover { + transform: translateY(-2px) scale(1.01); + } +} + +/* 超小屏幕适配 (480px以下) */ +@media (max-width: 480px) { + .container { + padding: 12px; + } + + .header { + padding: 20px 15px; + margin-bottom: 20px; + } + + .header-icon { + font-size: 2.2em; + } + + .title { + font-size: 1.9em; + letter-spacing: 0.3px; + } + + .subtitle { + font-size: 0.95em; + } + + .update-time { + font-size: 0.85em; + padding: 5px 10px; + } + + .refresh-btn { + padding: 8px 16px; + font-size: 0.85em; + } + + .hot-list { + gap: 15px; + } + + .hot-item { + padding: 18px 15px; + border-radius: 10px; + } + + .hot-item-header { + margin-bottom: 15px; + gap: 12px; + } + + .hot-rank { + min-width: 32px; + height: 32px; + font-size: 0.85em; + } + + .hot-title { + font-size: 1em; + line-height: 1.25; + } + + .hot-content { + gap: 12px; + } + + .hot-cover { + height: 160px; + max-width: 260px; + border-radius: 8px; + } + + .hot-info { + gap: 8px; + } + + .hot-value { + font-size: 1em; + } + + .hot-time { + font-size: 0.8em; + } + + .hot-link { + font-size: 0.85em; + padding: 6px 14px; + } + + /* 超小屏幕性能优化 */ + .hot-item { + transition: transform 0.2s ease, box-shadow 0.2s ease; + } + + .hot-item::before, + .hot-item::after, + .hot-cover::after, + .hot-link::after { + display: none; + } + + .loading-content { + gap: 15px; + } + + .loading-emoji { + font-size: 2em; + } + + .loading-text p { + font-size: 1em; + } + + .error-icon { + font-size: 3em; + } + + .error-content h3 { + font-size: 1.3em; + } + + .error-content p { + font-size: 0.9em; + } +} diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/index.html b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/index.html new file mode 100644 index 00000000..9892695a --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/index.html @@ -0,0 +1,60 @@ + + + + + + 抖音热搜榜 + + + + +
+
+
🔥
+

📱 抖音热搜榜 🎵

+

实时热门话题 · 紧跟潮流趋势

+
+ + 加载中... +
+ +
+ +
+
+
+
+ 🎭 +

正在获取最新热搜...

+
+ + + +
+
+
+
+ +
+ +
+ + +
+ + + + diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/js/script.js b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/js/script.js new file mode 100644 index 00000000..5e57415c --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/js/script.js @@ -0,0 +1,300 @@ +// API接口列表 +const API_ENDPOINTS = [ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +]; + +// 当前使用的API索引 +let currentApiIndex = 0; + +// DOM元素 +const loadingElement = document.getElementById('loading'); +const hotListElement = document.getElementById('hotList'); +const errorMessageElement = document.getElementById('errorMessage'); +const updateTimeElement = document.getElementById('updateTime'); +const refreshBtn = document.getElementById('refreshBtn'); + +// 页面加载完成后自动加载数据 +document.addEventListener('DOMContentLoaded', function() { + loadHotList(); +}); + +// 刷新按钮点击事件 +refreshBtn.addEventListener('click', function() { + loadHotList(); +}); + +// 加载热搜列表 +async function loadHotList() { + showLoading(); + hideError(); + + try { + const data = await fetchData(); + displayHotList(data.data); + updateRefreshTime(); + } catch (error) { + console.error('加载失败:', error); + showError(); + } + + hideLoading(); +} + +// 获取数据 +async function fetchData() { + for (let i = 0; i < API_ENDPOINTS.length; i++) { + const apiUrl = API_ENDPOINTS[currentApiIndex]; + + try { + const response = await fetch(`${apiUrl}/v2/douyin`, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + timeout: 10000 + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const data = await response.json(); + + if (data.code === 200 && data.data) { + return data; + } else { + throw new Error('数据格式错误'); + } + } catch (error) { + console.error(`API ${apiUrl} 请求失败:`, error); + currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; + + if (i === API_ENDPOINTS.length - 1) { + throw new Error('所有API接口都无法访问'); + } + } + } +} + +// 显示热搜列表 +function displayHotList(hotData) { + hotListElement.innerHTML = ''; + + hotData.forEach((item, index) => { + const hotItem = createHotItem(item, index + 1); + hotListElement.appendChild(hotItem); + }); +} + +// 创建热搜项目 +function createHotItem(item, rank) { + const hotItem = document.createElement('div'); + hotItem.className = 'hot-item'; + + const rankClass = rank <= 3 ? 'hot-rank top-3' : 'hot-rank'; + const formattedHotValue = formatHotValue(item.hot_value); + const formattedTime = formatTime(item.event_time); + + // 根据排名添加特殊标识 + let rankEmoji = ''; + if (rank === 1) rankEmoji = '🥇'; + else if (rank === 2) rankEmoji = '🥈'; + else if (rank === 3) rankEmoji = '🥉'; + else if (rank <= 10) rankEmoji = '🔥'; + else rankEmoji = '📈'; + + // 根据热度值添加火焰等级 + let fireLevel = ''; + if (item.hot_value >= 11000000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥🔥🔥'; + else if (item.hot_value >= 1000000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥🔥'; + else if (item.hot_value >= 9500000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥'; + else if (item.hot_value >= 9000000) fireLevel = '🔥🔥🔥🔥🔥🔥'; + else if (item.hot_value >= 8000000) fireLevel = '🔥🔥🔥🔥🔥'; + else if (item.hot_value >= 7000000) fireLevel = '🔥🔥🔥🔥'; + else if (item.hot_value >= 6000000) fireLevel = '🔥🔥🔥'; + else if (item.hot_value >= 5000000) fireLevel = '🔥🔥'; + else fireLevel = '🔥'; + + hotItem.innerHTML = ` +
+
${rank}
+
${rankEmoji} ${escapeHtml(item.title)}
+
+
+ ${escapeHtml(item.title)} +
+
${fireLevel} ${formattedHotValue}
+
${formattedTime}
+ + 查看详情 + +
+
+ `; + + return hotItem; +} + +// 格式化热度值 +function formatHotValue(value) { + if (value >= 100000000) { + return (value / 100000000).toFixed(1) + '亿'; + } else if (value >= 10000) { + return (value / 10000).toFixed(1) + '万'; + } else { + return value.toLocaleString(); + } +} + +// 格式化时间 +function formatTime(timeStr) { + try { + const formattedTime = timeStr.replace(/\//g, '-'); + const date = new Date(formattedTime); + const now = new Date(); + const diff = now - date; + const minutes = Math.floor(diff / (1000 * 60)); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + if (days > 0) { + return `${days}天前`; + } else if (hours > 0) { + return `${hours}小时前`; + } else if (minutes > 0) { + return `${minutes}分钟前`; + } else { + return '刚刚'; + } + } catch (error) { + return timeStr; + } +} + +// HTML转义 +function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +// 图片加载错误处理 +function handleImageError(img) { + img.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjZjVmNWY1Ii8+CjxwYXRoIGQ9Ik00MCAyMEM0NCAyMCA0NyAyMyA0NyAyN1Y1M0M0NyA1NyA0NCA2MCA0MCA2MEgxNkMxMiA2MCA5IDU3IDkgNTNWMjdDOSAyMyAxMiAyMCAxNiAyMEg0MFoiIHN0cm9rZT0iI2NjY2NjYyIgc3Ryb2tlLXdpZHRoPSIyIi8+CjxjaXJjbGUgY3g9IjMzIiBjeT0iMzIiIHI9IjMiIGZpbGw9IiNjY2NjY2MiLz4KPHBhdGggZD0iTTEzIDQ4TDIzIDM4TDMzIDQ4TDQzIDM4TDUzIDQ4IiBzdHJva2U9IiNjY2NjY2MiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo='; + img.alt = '图片加载失败'; +} + +// 更新刷新时间 +function updateRefreshTime() { + const now = new Date(); + const timeStr = now.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + updateTimeElement.textContent = `最后更新: ${timeStr}`; + + // 添加成功提示 + showSuccessMessage('🎉 数据已更新'); +} + +// 显示成功消息 +function showSuccessMessage(message) { + // 移除之前的提示 + const existingToast = document.querySelector('.success-toast'); + if (existingToast) { + existingToast.remove(); + } + + const toast = document.createElement('div'); + toast.className = 'success-toast'; + toast.textContent = message; + toast.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + padding: 12px 20px; + border-radius: 25px; + box-shadow: 0 4px 20px rgba(76, 175, 80, 0.3); + z-index: 1000; + font-weight: 600; + font-size: 0.9em; + animation: slideIn 0.3s ease-out; + backdrop-filter: blur(10px); + `; + + document.body.appendChild(toast); + + // 3秒后自动移除 + setTimeout(() => { + toast.style.animation = 'slideOut 0.3s ease-in forwards'; + setTimeout(() => toast.remove(), 300); + }, 3000); +} + +// 添加CSS动画到页面 +if (!document.querySelector('#toast-styles')) { + const style = document.createElement('style'); + style.id = 'toast-styles'; + style.textContent = ` + @keyframes slideIn { + from { + opacity: 0; + transform: translateX(100px); + } + to { + opacity: 1; + transform: translateX(0); + } + } + + @keyframes slideOut { + from { + opacity: 1; + transform: translateX(0); + } + to { + opacity: 0; + transform: translateX(100px); + } + } + `; + document.head.appendChild(style); +} + +// 显示加载状态 +function showLoading() { + loadingElement.style.display = 'block'; + hotListElement.style.display = 'none'; +} + +// 隐藏加载状态 +function hideLoading() { + loadingElement.style.display = 'none'; + hotListElement.style.display = 'block'; +} + +// 显示错误信息 +function showError() { + errorMessageElement.style.display = 'block'; + hotListElement.style.display = 'none'; +} + +// 隐藏错误信息 +function hideError() { + errorMessageElement.style.display = 'none'; +} + +// 自动刷新 (每5分钟) +setInterval(function() { + loadHotList(); +}, 5 * 60 * 1000); diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/返回接口.json new file mode 100644 index 00000000..5094d4ec --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/抖音热搜榜/返回接口.json @@ -0,0 +1,496 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "title": "九三阅兵具体安排公布", + "hot_value": 11821633, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oY1c972B7QzApGweaeQD3fGRo5aLIBrpCAuUSa~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=q01Se46GlLKYNv2klGKP1aM1cT0%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%B9%9D%E4%B8%89%E9%98%85%E5%85%B5%E5%85%B7%E4%BD%93%E5%AE%89%E6%8E%92%E5%85%AC%E5%B8%83", + "event_time": "2025/09/01 15:20:34", + "event_time_at": 1756711234, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "九月第一天", + "hot_value": 11327170, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oofTvDaDRCSs4hBFEFVJlAI9BBs0faZAc7IpGf~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=otkowVCSglk%2BS3tPrmBQFq6rIDw%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%B9%9D%E6%9C%88%E7%AC%AC%E4%B8%80%E5%A4%A9", + "event_time": "2025/09/01 07:28:57", + "event_time_at": 1756682937, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "遇见上合共享津彩", + "hot_value": 11222444, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oIJeINhBDBAiHADD4gi9Ae0CGALg1BqWI7vg0i~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=K%2BaEx5p%2BDv%2B1h3RgNnH0Yb9WT%2B8%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E9%81%87%E8%A7%81%E4%B8%8A%E5%90%88%E5%85%B1%E4%BA%AB%E6%B4%A5%E5%BD%A9", + "event_time": "2025/09/01 11:46:59", + "event_time_at": 1756698419, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "2025年开学第一课铭记与奋斗", + "hot_value": 11078403, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oA9NgVCRBABg7r70pQue8IzAUlfMaXf3hawOIB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=3xYeXsD6JpXLDOVp6gYRxrvKFaM%3D&from=3218412987", + "link": "https://www.douyin.com/search/2025%E5%B9%B4%E5%BC%80%E5%AD%A6%E7%AC%AC%E4%B8%80%E8%AF%BE%E9%93%AD%E8%AE%B0%E4%B8%8E%E5%A5%8B%E6%96%97", + "event_time": "2025/09/01 11:21:13", + "event_time_at": 1756696873, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "石宇奇首夺世锦赛男单冠军", + "hot_value": 10395092, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oAf9IAlEuyE3lFiogfBuQFl8gDFqAoAHtFDNkE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=tamoorhMGYhajvpmVNdX0TuUuZM%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%9F%B3%E5%AE%87%E5%A5%87%E9%A6%96%E5%A4%BA%E4%B8%96%E9%94%A6%E8%B5%9B%E7%94%B7%E5%8D%95%E5%86%A0%E5%86%9B", + "event_time": "2025/09/01 07:47:03", + "event_time_at": 1756684023, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "告别信息裸奔 国家网络身份认证来了", + "hot_value": 10255200, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oskNjrEUQIN9BBRCfeiDTGPE0geX0q6eAAyLr2~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=FrZQSxERPOBd6ktV8K%2Bt%2F3LgJ4A%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%91%8A%E5%88%AB%E4%BF%A1%E6%81%AF%E8%A3%B8%E5%A5%94%20%E5%9B%BD%E5%AE%B6%E7%BD%91%E7%BB%9C%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E6%9D%A5%E4%BA%86", + "event_time": "2025/09/01 10:28:41", + "event_time_at": 1756693721, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "记录我的开学第一天", + "hot_value": 9133236, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/owTXhhk40MlJDQHi8P2B07AviaBqAL0VI9EQi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=pTEfiV%2FfsmGuQxNllsV8PqT0RYc%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%AE%B0%E5%BD%95%E6%88%91%E7%9A%84%E5%BC%80%E5%AD%A6%E7%AC%AC%E4%B8%80%E5%A4%A9", + "event_time": "2025/09/01 12:43:33", + "event_time_at": 1756701813, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "9月起这些新规开始施行", + "hot_value": 9105252, + "cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oEE9BseGagtA7JRBmzYA1aRMoCMAeIxfLFY5gA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=YgH%2BJdVPmi76okIWTRoyEEZ3iDg%3D&from=3218412987", + "link": "https://www.douyin.com/search/9%E6%9C%88%E8%B5%B7%E8%BF%99%E4%BA%9B%E6%96%B0%E8%A7%84%E5%BC%80%E5%A7%8B%E6%96%BD%E8%A1%8C", + "event_time": "2025/09/01 11:48:01", + "event_time_at": 1756698481, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "李幼斌与李云龙跨时空对话", + "hot_value": 8998174, + "cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oAarINBoAgRIPi9VTEMIfHeA11nDtF7hRDuGcA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=3x7yTXHYKiIcnNJjznvZjCw%2FW94%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E6%9D%8E%E5%B9%BC%E6%96%8C%E4%B8%8E%E6%9D%8E%E4%BA%91%E9%BE%99%E8%B7%A8%E6%97%B6%E7%A9%BA%E5%AF%B9%E8%AF%9D", + "event_time": "2025/09/01 12:01:05", + "event_time_at": 1756699265, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "幼儿园第一天开学哀嚎一片", + "hot_value": 8962824, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osbXMAQYgIwwpkDCfeiDpGaE0gb9MXfeAAuLV2~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=w1l8V4VvjuO%2BvOvuQkXiEuXYko0%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%B9%BC%E5%84%BF%E5%9B%AD%E7%AC%AC%E4%B8%80%E5%A4%A9%E5%BC%80%E5%AD%A6%E5%93%80%E5%9A%8E%E4%B8%80%E7%89%87", + "event_time": "2025/09/01 11:05:01", + "event_time_at": 1756695901, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "田汉把国歌歌词写烟盒上系谣传", + "hot_value": 8930615, + "cover": "https://p3-sign.douyinpic.com/tos-cn-i-0813c001/ogA2AoCCXZMEAGF9f9QAlSACKRgfsC2oAFtIgD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=7%2F8qsoQJd6TgpAEylOW1VyQrqeY%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%94%B0%E6%B1%89%E6%8A%8A%E5%9B%BD%E6%AD%8C%E6%AD%8C%E8%AF%8D%E5%86%99%E7%83%9F%E7%9B%92%E4%B8%8A%E7%B3%BB%E8%B0%A3%E4%BC%A0", + "event_time": "2025/09/01 13:51:28", + "event_time_at": 1756705888, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "苏超联赛积分榜", + "hot_value": 8838219, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o4vPLtWIQAaiggBRkQq5kw9ZlIVA0v1iDAILU~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=JJlPUPmWRzT3UPMenizW639pqVg%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%8B%8F%E8%B6%85%E8%81%94%E8%B5%9B%E7%A7%AF%E5%88%86%E6%A6%9C", + "event_time": "2025/08/31 22:01:53", + "event_time_at": 1756648913, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "一切正开始", + "hot_value": 8609507, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/o8wN0EuXoETsyMz0ADCFFaAsFFTQeQf9fAublW~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=5I8uLkfpNYrGArQm%2BXLBa81NhYY%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%B8%80%E5%88%87%E6%AD%A3%E5%BC%80%E5%A7%8B", + "event_time": "2025/09/01 11:56:50", + "event_time_at": 1756699010, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "张玉宁为与球迷起冲突致歉", + "hot_value": 8511631, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oMfoIAFMN5GEWOzpBCDAQfaj7yRArCdByaEUfE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=59ipMtNxZ8W3R5NNAJamlSOEbPo%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%BC%A0%E7%8E%89%E5%AE%81%E4%B8%BA%E4%B8%8E%E7%90%83%E8%BF%B7%E8%B5%B7%E5%86%B2%E7%AA%81%E8%87%B4%E6%AD%89", + "event_time": "2025/09/01 07:53:39", + "event_time_at": 1756684419, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "这一口会很疯狂", + "hot_value": 8454971, + "cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oUIozRIBqC0ahA7FimIAmFEBeqDFfZK3Qfo8PE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=ZBSuTMuu4678gSfReaVIfdK22J8%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%BF%99%E4%B8%80%E5%8F%A3%E4%BC%9A%E5%BE%88%E7%96%AF%E7%8B%82", + "event_time": "2025/09/01 10:36:16", + "event_time_at": 1756694176, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "邓超鹿晗合唱超级英雄", + "hot_value": 8357197, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oUBPIdtyQx0j8THRZAmZbyATihavQHI0niLIP~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=%2F66dsj8evHN94wNNFCn%2Bfhagee0%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E9%82%93%E8%B6%85%E9%B9%BF%E6%99%97%E5%90%88%E5%94%B1%E8%B6%85%E7%BA%A7%E8%8B%B1%E9%9B%84", + "event_time": "2025/09/01 07:45:11", + "event_time_at": 1756683911, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "伊萨克加盟利物浦", + "hot_value": 7963081, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ocAw2yaT4I99iDIPh9I3LaIiLBTnBASvH0Q1a~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=v4Gq0Iz87wyZ6lEYYOnKmaeur%2FM%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%BC%8A%E8%90%A8%E5%85%8B%E5%8A%A0%E7%9B%9F%E5%88%A9%E7%89%A9%E6%B5%A6", + "event_time": "2025/09/01 09:12:12", + "event_time_at": 1756689132, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "山东泰山6:0北京国安", + "hot_value": 7830358, + "cover": "https://p9-sign.douyinpic.com/tos-cn-p-0015/ogtA9BEEJZDJ9SgzBBLfFN0AflNDGoIAQ2I8A8~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=gu6O%2BhGDarr%2BHQe1P%2BHo9pUmBGU%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%B1%B1%E4%B8%9C%E6%B3%B0%E5%B1%B16%3A0%E5%8C%97%E4%BA%AC%E5%9B%BD%E5%AE%89", + "event_time": "2025/08/31 20:32:53", + "event_time_at": 1756643573, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "又到开学你包书皮了吗", + "hot_value": 7828995, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oUAwaPjCIiLAQI6ADQMAm06TBJxPJFAkCpIIi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=aUkYTtkfaUKbK2DhznXU69sg8SU%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%8F%88%E5%88%B0%E5%BC%80%E5%AD%A6%E4%BD%A0%E5%8C%85%E4%B9%A6%E7%9A%AE%E4%BA%86%E5%90%97", + "event_time": "2025/08/31 17:04:09", + "event_time_at": 1756631049, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "樊振东德甲首秀两连败", + "hot_value": 7754365, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osOdEdibznClYwP0AABAIZW1eg0gbBmAzjiJfl~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=AyWBGXt%2FFFSp0QBM%2Bd5%2F9B4GPvo%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E6%A8%8A%E6%8C%AF%E4%B8%9C%E5%BE%B7%E7%94%B2%E9%A6%96%E7%A7%80%E4%B8%A4%E8%BF%9E%E8%B4%A5", + "event_time": "2025/09/01 07:16:58", + "event_time_at": 1756682218, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "为什么说00后的童年含金量高", + "hot_value": 7735122, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ogOQEQsnAACDBICh7LeFWRGCjeZneIB9I3oVFy~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Htnqu7SupC%2FmvQpF2DDsLDh5FYA%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B400%E5%90%8E%E7%9A%84%E7%AB%A5%E5%B9%B4%E5%90%AB%E9%87%91%E9%87%8F%E9%AB%98", + "event_time": "2025/08/31 16:38:30", + "event_time_at": 1756629510, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "刘宇千年直拍", + "hot_value": 7734149, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/ostjBSmQ78E8estIXgFlHQxZQALRFfMepbTJWC~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=CPNw9h%2BpBB82qBykpuT11uMVFjo%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%88%98%E5%AE%87%E5%8D%83%E5%B9%B4%E7%9B%B4%E6%8B%8D", + "event_time": "2025/08/31 21:39:38", + "event_time_at": 1756647578, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "胡塞武装称将对以军袭击发起报复", + "hot_value": 7728698, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oseWgjCRBAfgft7c3QUm8JGApnYMaWdJdGj0SB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=fX6AvTWQvNrihcvEraPHjJIS9iY%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%83%A1%E5%A1%9E%E6%AD%A6%E8%A3%85%E7%A7%B0%E5%B0%86%E5%AF%B9%E4%BB%A5%E5%86%9B%E8%A2%AD%E5%87%BB%E5%8F%91%E8%B5%B7%E6%8A%A5%E5%A4%8D", + "event_time": "2025/09/01 09:40:13", + "event_time_at": 1756690813, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "手把手教你手机变车机", + "hot_value": 7725104, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o47qAXUjDQN6KLr9AjFSCq92ZBf4okAQEfgSAp~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=OoNNciUVTOwZbl17IUYBOjFyBJ4%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E6%89%8B%E6%9C%BA%E5%8F%98%E8%BD%A6%E6%9C%BA", + "event_time": "2025/09/01 11:15:15", + "event_time_at": 1756696515, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "莫迪与普京拥抱手拉手热聊", + "hot_value": 7723445, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oIaWAojVPLRUILGIyvvg1Sd1ZiLAKiCB6zQIX~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=u1IGnKz%2FAckLe%2BYFCQulFw0ioB8%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%8E%AB%E8%BF%AA%E4%B8%8E%E6%99%AE%E4%BA%AC%E6%8B%A5%E6%8A%B1%E6%89%8B%E6%8B%89%E6%89%8B%E7%83%AD%E8%81%8A", + "event_time": "2025/09/01 15:38:27", + "event_time_at": 1756712307, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "原来猪猪侠搞抽象领先我20年", + "hot_value": 7706786, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oINGyAfS2oFpfAgF2kYxEJAqTbSeEcgotfxeHv~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=S1Ve0ORP5%2BrHumx%2FK7uJbfm8PbM%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%8E%9F%E6%9D%A5%E7%8C%AA%E7%8C%AA%E4%BE%A0%E6%90%9E%E6%8A%BD%E8%B1%A1%E9%A2%86%E5%85%88%E6%88%9120%E5%B9%B4", + "event_time": "2025/09/01 10:52:59", + "event_time_at": 1756695179, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "北京国安就惨败道歉", + "hot_value": 7702358, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oYiXICjfn7uEi3AeK6W04BiXu3iBjigAAs9W0B~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=hgh%2Bfy4Ul82LWgXAL2hkIBMEpJM%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%8C%97%E4%BA%AC%E5%9B%BD%E5%AE%89%E5%B0%B1%E6%83%A8%E8%B4%A5%E9%81%93%E6%AD%89", + "event_time": "2025/09/01 09:21:10", + "event_time_at": 1756689670, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "港姐冠军陈咏诗是博士生", + "hot_value": 7702059, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/okoRaMGvQBCI6KmVeBAAQ1eLEg1HK2foQuM7aB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=5Lattu1v38oeQ8xGdXiDLcK4fwM%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E6%B8%AF%E5%A7%90%E5%86%A0%E5%86%9B%E9%99%88%E5%92%8F%E8%AF%97%E6%98%AF%E5%8D%9A%E5%A3%AB%E7%94%9F", + "event_time": "2025/09/01 10:47:23", + "event_time_at": 1756694843, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "王楚钦2:3徐瑛彬", + "hot_value": 7699514, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o00BTIi1ogMR8LBAiQdLmSaIPAuEyIQv1IP48~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=2%2BI5KkQpEugBkQcVCrSLgOtC088%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%8E%8B%E6%A5%9A%E9%92%A62%3A3%E5%BE%90%E7%91%9B%E5%BD%AC", + "event_time": "2025/08/31 21:21:08", + "event_time_at": 1756646468, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "王源 高音", + "hot_value": 7693290, + "cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oYzDIaQiavwPRBUpanIkjAIWzwLCIgPkAyiOj~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=uXVN6xfkB3tz3iVo0DQuxqeaGk0%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%8E%8B%E6%BA%90%20%E9%AB%98%E9%9F%B3", + "event_time": "2025/08/31 20:30:04", + "event_time_at": 1756643404, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "俄乌在苏贾前线展开阵地争夺", + "hot_value": 7691808, + "cover": "https://p9-sign.douyinpic.com/tos-cn-p-0015/oo7iATIG8vA5hIIQBILB4oCgvygsUNzBS1aPi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=SNzQbbxAJqqtdIkck9kvtRUJnZg%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%BF%84%E4%B9%8C%E5%9C%A8%E8%8B%8F%E8%B4%BE%E5%89%8D%E7%BA%BF%E5%B1%95%E5%BC%80%E9%98%B5%E5%9C%B0%E4%BA%89%E5%A4%BA", + "event_time": "2025/09/01 12:56:05", + "event_time_at": 1756702565, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "范丞丞温柔版一个人的夜变装", + "hot_value": 7689433, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oAPLWIAoR3CsXgVBuIQIRiTDyS14gaLPwELAi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=yp9l95J9xlKf55IEP14P7sD7J%2F4%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%8C%83%E4%B8%9E%E4%B8%9E%E6%B8%A9%E6%9F%94%E7%89%88%E4%B8%80%E4%B8%AA%E4%BA%BA%E7%9A%84%E5%A4%9C%E5%8F%98%E8%A3%85", + "event_time": "2025/09/01 15:32:00", + "event_time_at": 1756711920, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "用美食致敬这场胜利", + "hot_value": 7681826, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oIFcUfHotAXxALhJEj2EK9SBNp0fQwKhAbCgQD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Dkuyg5REqCAMEIsp0Dr%2B%2BkAO%2BmQ%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%94%A8%E7%BE%8E%E9%A3%9F%E8%87%B4%E6%95%AC%E8%BF%99%E5%9C%BA%E8%83%9C%E5%88%A9", + "event_time": "2025/09/01 12:08:24", + "event_time_at": 1756699704, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "田曦薇猫猫本体藏不住了", + "hot_value": 7674729, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015c000-ce/oceyeLnbxAXFERxnPfLR2egAkYaXeRpHfhAQME~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=omEVZta%2FQeV%2FSBRNZ3%2BJF0iMXPQ%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%94%B0%E6%9B%A6%E8%96%87%E7%8C%AB%E7%8C%AB%E6%9C%AC%E4%BD%93%E8%97%8F%E4%B8%8D%E4%BD%8F%E4%BA%86", + "event_time": "2025/09/01 14:33:25", + "event_time_at": 1756708405, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "少年心气是不可再生之物", + "hot_value": 7673518, + "cover": "https://p3-sign.douyinpic.com/tos-cn-i-0813c001/oAUJIWFyAFCmtGpmAADAQis69JogkCFAA0Eqff~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=YHeldSJZXPEBMLF2i%2Bj%2Fc60oKsQ%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%B0%91%E5%B9%B4%E5%BF%83%E6%B0%94%E6%98%AF%E4%B8%8D%E5%8F%AF%E5%86%8D%E7%94%9F%E4%B9%8B%E7%89%A9", + "event_time": "2025/09/01 07:54:31", + "event_time_at": 1756684471, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "南通2:1战胜苏州", + "hot_value": 7670255, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/o4WAaBigTGBaeBgrqm5Kir0Af6DGO0IAF6IQPA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=uV2f%2FvbzU4Y9DfhXxnPBc3hOAxY%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%8D%97%E9%80%9A2%3A1%E6%88%98%E8%83%9C%E8%8B%8F%E5%B7%9E", + "event_time": "2025/08/31 18:02:42", + "event_time_at": 1756634562, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "起猛了差点以为入冬了", + "hot_value": 7669368, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/ogA5HPw1xiIwS2szhaBPMZvC1P0LAPPQAigEZ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=UQNTgz2vyL2UMvzVj2gzBmPbM2A%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%B5%B7%E7%8C%9B%E4%BA%86%E5%B7%AE%E7%82%B9%E4%BB%A5%E4%B8%BA%E5%85%A5%E5%86%AC%E4%BA%86", + "event_time": "2025/09/01 14:23:50", + "event_time_at": 1756707830, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "终于轮到我围观军训了", + "hot_value": 7655201, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/oobwIeLUf4O7iiazJOGAQLZO7DRgCDCBLhI2ez~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=WQn5PvdzvIerbF%2B1iNjF3b6itqQ%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%BB%88%E4%BA%8E%E8%BD%AE%E5%88%B0%E6%88%91%E5%9B%B4%E8%A7%82%E5%86%9B%E8%AE%AD%E4%BA%86", + "event_time": "2025/08/31 13:09:34", + "event_time_at": 1756616974, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "金铲铲陪伴是李现最长情的告白", + "hot_value": 7653496, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/oYPAKIM2vpBnPULXOmBbAEac6KzbOhSiILiLP~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=rsA7DcONzMySFGRNa4PMk6ftyBk%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E9%87%91%E9%93%B2%E9%93%B2%E9%99%AA%E4%BC%B4%E6%98%AF%E6%9D%8E%E7%8E%B0%E6%9C%80%E9%95%BF%E6%83%85%E7%9A%84%E5%91%8A%E7%99%BD", + "event_time": "2025/08/31 22:58:48", + "event_time_at": 1756652328, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "张予曦妈妈不介意女儿谈姐弟恋", + "hot_value": 7650811, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oEB5A1NsLFeadA9HQoED9TfmQ8jHgUPxACzjw9~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=KF3nedfpt5iPcUZ%2Fv9SyYI0ZSWg%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%BC%A0%E4%BA%88%E6%9B%A6%E5%A6%88%E5%A6%88%E4%B8%8D%E4%BB%8B%E6%84%8F%E5%A5%B3%E5%84%BF%E8%B0%88%E5%A7%90%E5%BC%9F%E6%81%8B", + "event_time": "2025/08/31 17:44:23", + "event_time_at": 1756633463, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "边伯贤也来刀马刀马了", + "hot_value": 7650164, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ogfBltLZDIGmRGCAseKAeaIBRnQH79gBGOb4kC~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=nLrGTCoyqEGU882IYRhJOStMdpg%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%BE%B9%E4%BC%AF%E8%B4%A4%E4%B9%9F%E6%9D%A5%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC%E4%BA%86", + "event_time": "2025/08/31 13:44:44", + "event_time_at": 1756619084, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "金靖演绎甜美女孩", + "hot_value": 7649913, + "cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/o0cBcsRQjiGGFCOOArGzzeIfLBA7FEYojeKwGQ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=9BY7gGsW39uBcs06t%2BrXTCQ5J5k%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E9%87%91%E9%9D%96%E6%BC%94%E7%BB%8E%E7%94%9C%E7%BE%8E%E5%A5%B3%E5%AD%A9", + "event_time": "2025/08/31 19:00:32", + "event_time_at": 1756638032, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "一口气看日本如何造出反华体制", + "hot_value": 7648850, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oUoyIxcAADE55goYWdhBfFF4HACpRIpy9Xse6K~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=xjjRJGl0AzxkaEnOiVrzRx1hoZ8%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E4%B8%80%E5%8F%A3%E6%B0%94%E7%9C%8B%E6%97%A5%E6%9C%AC%E5%A6%82%E4%BD%95%E9%80%A0%E5%87%BA%E5%8F%8D%E5%8D%8E%E4%BD%93%E5%88%B6", + "event_time": "2025/08/30 21:50:31", + "event_time_at": 1756561831, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "张艺兴真空西装跳狼与美女", + "hot_value": 7646868, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/o4YKfLEIEEwo5stfDSFe0s2TFRjxXAAZDCE9Bl~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=gqBuLvszd8eew81uXP8rf7idtog%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%BC%A0%E8%89%BA%E5%85%B4%E7%9C%9F%E7%A9%BA%E8%A5%BF%E8%A3%85%E8%B7%B3%E7%8B%BC%E4%B8%8E%E7%BE%8E%E5%A5%B3", + "event_time": "2025/08/31 22:12:44", + "event_time_at": 1756649564, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "罗永浩对谈脱口秀新王何广智", + "hot_value": 7644688, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/okQ0qo1AKBQP3g981qQA1FEAzGDYjtFFdfYVeD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Mg24ss6tlv%2FY%2B%2B9PS5UdijEG1Dw%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E7%BD%97%E6%B0%B8%E6%B5%A9%E5%AF%B9%E8%B0%88%E8%84%B1%E5%8F%A3%E7%A7%80%E6%96%B0%E7%8E%8B%E4%BD%95%E5%B9%BF%E6%99%BA", + "event_time": "2025/09/01 13:56:14", + "event_time_at": 1756706174, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "周深的刀马刀马好可爱", + "hot_value": 7644052, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osAPL0laAbWHtEmVBUIKMQDypItTiF3HI0PQi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=qcK3K8uko38iBuRXDg4uCTaqEPc%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%91%A8%E6%B7%B1%E7%9A%84%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC%E5%A5%BD%E5%8F%AF%E7%88%B1", + "event_time": "2025/08/31 18:31:56", + "event_time_at": 1756636316, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "杜克一哥的对话太好哭了", + "hot_value": 7639907, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oofoeQ9VAPDsphKEAiFQbQwCAEwoQgBpLtBC0A~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=wulyNlwPrSoIJu1JKBdKpE142mA%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E6%9D%9C%E5%85%8B%E4%B8%80%E5%93%A5%E7%9A%84%E5%AF%B9%E8%AF%9D%E5%A4%AA%E5%A5%BD%E5%93%AD%E4%BA%86", + "event_time": "2025/08/30 21:17:58", + "event_time_at": 1756559878, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "外媒全景记录普京抵华现场", + "hot_value": 7637541, + "cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oIGC9LxDIQ6QAI1fG1eEipfA2eZjiGInCHFFEJ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=HiKj%2FiLGiaN2D5GdS5OlAISbGHo%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E5%A4%96%E5%AA%92%E5%85%A8%E6%99%AF%E8%AE%B0%E5%BD%95%E6%99%AE%E4%BA%AC%E6%8A%B5%E5%8D%8E%E7%8E%B0%E5%9C%BA", + "event_time": "2025/09/01 11:59:34", + "event_time_at": 1756699174, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + }, + { + "title": "赵丽颖工作室明兰代班营业", + "hot_value": 7635755, + "cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015c000-ce/oIhHELPBeI6Ieb0A9OpCuWXh0CAAgiuniEweIw~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=xmQOeLdWN4FaeZjFBqtMQuctYv8%3D&from=3218412987", + "link": "https://www.douyin.com/search/%E8%B5%B5%E4%B8%BD%E9%A2%96%E5%B7%A5%E4%BD%9C%E5%AE%A4%E6%98%8E%E5%85%B0%E4%BB%A3%E7%8F%AD%E8%90%A5%E4%B8%9A", + "event_time": "2025/08/31 20:52:34", + "event_time_at": 1756644754, + "active_time": "2025-09-01 16:46:46", + "active_time_at": 1756745206000 + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/css/style.css b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/css/style.css new file mode 100644 index 00000000..e76f60c9 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/css/style.css @@ -0,0 +1,495 @@ +/* 猫眼票房排行榜 - 淡绿色清新风格样式 */ + +/* 重置样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); + min-height: 100vh; + color: #2d5016; + line-height: 1.6; + overflow-x: hidden; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 30px; + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.header h1 { + font-size: 2.5rem; + color: #2d5016; + margin-bottom: 10px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + gap: 15px; +} + +.header p { + color: #5a7c65; + font-size: 1.1rem; +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #e8f5e8; + border-top: 4px solid #81c784; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 票房排行榜容器 */ +.ranking-container { + background: rgba(255, 255, 255, 0.85); + border-radius: 20px; + padding: 30px; + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); + margin-bottom: 20px; +} + +/* 排行榜标题 */ +.ranking-title { + text-align: center; + font-size: 1.8rem; + font-weight: 700; + color: #2d5016; + margin-bottom: 25px; +} + +/* 票房排行榜列表 */ +.movie-list { + display: grid; + gap: 15px; +} + +/* 电影项目 */ +.movie-item { + background: rgba(255, 255, 255, 0.9); + border-radius: 15px; + padding: 20px; + box-shadow: 0 4px 15px rgba(45, 80, 22, 0.05); + transition: all 0.3s ease; + border-left: 5px solid transparent; + position: relative; + overflow: hidden; +} + +.movie-item:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(45, 80, 22, 0.12); +} + +/* 前三名特殊样式 */ +.movie-item.top-1 { + border-left-color: #ffd700; + background: linear-gradient(135deg, rgba(255, 215, 0, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%); +} + +.movie-item.top-2 { + border-left-color: #c0c0c0; + background: linear-gradient(135deg, rgba(192, 192, 192, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%); +} + +.movie-item.top-3 { + border-left-color: #cd7f32; + background: linear-gradient(135deg, rgba(205, 127, 50, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%); +} + +/* 排名徽章 */ +.rank-badge { + position: absolute; + top: -10px; + right: -10px; + width: 50px; + height: 50px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-weight: bold; + font-size: 1.2rem; + color: white; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); +} + +.rank-badge.gold { + background: linear-gradient(135deg, #ffd700, #ffed4a); +} + +.rank-badge.silver { + background: linear-gradient(135deg, #c0c0c0, #e2e8f0); +} + +.rank-badge.bronze { + background: linear-gradient(135deg, #cd7f32, #d69e2e); +} + +.rank-badge.regular { + background: linear-gradient(135deg, #81c784, #66bb6a); +} + +/* 电影信息布局 */ +.movie-info { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 20px; +} + +.rank-number { + font-size: 2rem; + font-weight: bold; + color: #2d5016; + min-width: 60px; +} + +.movie-details { + flex: 1; +} + +.movie-name { + font-size: 1.3rem; + font-weight: 700; + color: #2d5016; + margin-bottom: 5px; +} + +.movie-year { + color: #5a7c65; + font-size: 0.95rem; + margin-bottom: 8px; +} + +.box-office { + text-align: right; +} + +.box-office-amount { + font-size: 1.4rem; + font-weight: bold; + color: #1b5e20; + margin-bottom: 3px; +} + +.box-office-desc { + color: #5a7c65; + font-size: 0.9rem; +} + +/* 统计信息 */ +.stats-container { + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + padding: 20px; + margin-bottom: 20px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); + backdrop-filter: blur(10px); +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 20px; + text-align: center; +} + +.stat-item { + background: rgba(129, 199, 132, 0.1); + border-radius: 10px; + padding: 15px; +} + +.stat-value { + font-size: 1.5rem; + font-weight: bold; + color: #2d5016; +} + +.stat-label { + color: #5a7c65; + font-size: 0.9rem; + margin-top: 5px; +} + +/* 更新时间 */ +.update-time { + text-align: center; + color: #5a7c65; + font-size: 0.9rem; + margin-top: 20px; + padding: 15px; + background: rgba(255, 255, 255, 0.7); + border-radius: 10px; +} + +/* 错误提示 */ +.error { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.85); + border-radius: 15px; + box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08); +} + +.error h3 { + color: #d32f2f; + margin-bottom: 15px; + font-size: 1.5rem; +} + +.error p { + color: #5a7c65; + margin-bottom: 10px; +} + +/* 动画效果 */ +.fade-in { + animation: fadeIn 0.6s ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* 平板端适配 (768px - 1024px) */ +@media screen and (max-width: 1024px) and (min-width: 768px) { + .container { + padding: 15px; + } + + .header h1 { + font-size: 2.2rem; + } + + .ranking-container { + padding: 25px; + } + + .movie-info { + gap: 15px; + } + + .rank-number { + font-size: 1.8rem; + min-width: 50px; + } + + .movie-name { + font-size: 1.2rem; + } + + .box-office-amount { + font-size: 1.3rem; + } +} + +/* 手机端适配 (最大767px) - 优先优化 */ +@media screen and (max-width: 767px) { + .container { + padding: 10px; + } + + .header { + padding: 20px; + margin-bottom: 20px; + } + + .header h1 { + font-size: 1.8rem; + flex-direction: column; + gap: 10px; + } + + .header p { + font-size: 1rem; + } + + .ranking-container { + padding: 20px 15px; + margin-bottom: 15px; + } + + .ranking-title { + font-size: 1.5rem; + margin-bottom: 20px; + } + + .movie-item { + padding: 15px; + margin-bottom: 10px; + } + + .movie-info { + grid-template-columns: 50px 1fr; + grid-template-rows: auto auto; + gap: 10px; + } + + .rank-number { + font-size: 1.5rem; + min-width: 40px; + grid-row: 1 / 3; + } + + .movie-details { + grid-column: 2; + grid-row: 1; + } + + .box-office { + grid-column: 2; + grid-row: 2; + text-align: left; + margin-top: 8px; + } + + .movie-name { + font-size: 1.1rem; + margin-bottom: 3px; + } + + .movie-year { + font-size: 0.85rem; + margin-bottom: 5px; + } + + .box-office-amount { + font-size: 1.2rem; + } + + .box-office-desc { + font-size: 0.85rem; + } + + .rank-badge { + width: 40px; + height: 40px; + font-size: 1rem; + top: -8px; + right: -8px; + } + + .stats-grid { + grid-template-columns: 1fr; + gap: 15px; + } + + .stat-item { + padding: 12px; + } + + .stat-value { + font-size: 1.3rem; + } + + .update-time { + padding: 12px; + font-size: 0.85rem; + } +} + +/* 小屏手机适配 (最大480px) */ +@media screen and (max-width: 480px) { + .container { + padding: 8px; + } + + .header { + padding: 15px; + } + + .header h1 { + font-size: 1.6rem; + } + + .ranking-container { + padding: 15px 10px; + } + + .movie-item { + padding: 12px; + } + + .movie-name { + font-size: 1rem; + } + + .box-office-amount { + font-size: 1.1rem; + } + + .rank-number { + font-size: 1.3rem; + min-width: 35px; + } +} + +/* 高分辨率显示器优化 */ +@media screen and (min-width: 1440px) { + .container { + max-width: 1400px; + } + + .header h1 { + font-size: 3rem; + } + + .movie-list { + gap: 20px; + } + + .movie-item { + padding: 25px; + } + + .movie-name { + font-size: 1.4rem; + } + + .box-office-amount { + font-size: 1.5rem; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/index.html b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/index.html new file mode 100644 index 00000000..21b84c4b --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/index.html @@ -0,0 +1,40 @@ + + + + + + + + 猫眼票房排行榜 | 全球电影总票房 + + + + + + + + +
+ +
+

+ 🎬 + 猫眼票房排行榜(时更) +

+

展示全球电影总票房排行榜,数据来自权威源头,稳定实时

+
+ + +
+
+

正在加载票房数据...

+
+ + +
+
+ + + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/js/script.js b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/js/script.js new file mode 100644 index 00000000..39119c89 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/js/script.js @@ -0,0 +1,249 @@ +// 猫眼票房排行榜 - JavaScript 实现 + +const API = { + endpoints: [], + currentIndex: 0, + params: { + encoding: 'json' + }, + localFallback: '返回接口.json', + // 初始化API接口列表 + async init() { + try { + const res = await fetch('./接口集合.json'); + const endpoints = await res.json(); + this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/maoyan`); + } catch (e) { + // 如果无法加载接口集合,使用默认接口 + this.endpoints = ['https://60s.viki.moe/v2/maoyan']; + } + }, + // 获取当前接口URL + getCurrentUrl() { + if (this.endpoints.length === 0) return null; + const url = new URL(this.endpoints[this.currentIndex]); + Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v)); + return url.toString(); + }, + // 切换到下一个接口 + switchToNext() { + this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; + return this.currentIndex < this.endpoints.length; + }, + // 重置到第一个接口 + reset() { + this.currentIndex = 0; + } +}; + +let elements = {}; + +// 初始化 +window.addEventListener('DOMContentLoaded', () => { + initElements(); + loadMaoyanList(); +}); + +function initElements() { + elements = { + container: document.getElementById('ranking-content'), + loading: document.getElementById('loading'), + updateTime: document.getElementById('api-update-time'), + statsTotal: document.getElementById('stats-total'), + statsTop10: document.getElementById('stats-top10') + }; +} + +async function loadMaoyanList() { + try { + showLoading(true); + + // 优先从线上API请求 + let data = await fetchFromAPI(); + + // 如果线上失败,尝试从本地返回接口.json加载 + if (!data) { + data = await fetchFromLocal(); + } + + if (!data || data.code !== 200 || !data.data) { + throw new Error(data && data.message ? data.message : '未能获取到有效数据'); + } + + renderRanking(data.data); + } catch (error) { + console.error('加载排行榜失败:', error); + showError(error.message || '加载失败,请稍后重试'); + } finally { + showLoading(false); + } +} + +async function fetchFromAPI() { + // 初始化API接口列表 + await API.init(); + + // 重置API索引到第一个接口 + API.reset(); + + // 尝试所有API接口 + for (let i = 0; i < API.endpoints.length; i++) { + try { + const url = API.getCurrentUrl(); + console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); + + const resp = await fetch(url, { + cache: 'no-store', + timeout: 10000 // 10秒超时 + }); + + if (!resp.ok) { + throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); + } + + const data = await resp.json(); + + if (data && data.code === 200) { + console.log(`接口 ${i + 1} 请求成功`); + return data; + } + + throw new Error(data && data.message ? data.message : '接口返回异常'); + + } catch (e) { + console.warn(`接口 ${i + 1} 失败:`, e.message); + + // 如果不是最后一个接口,切换到下一个 + if (i < API.endpoints.length - 1) { + API.switchToNext(); + continue; + } + + // 所有接口都失败了 + console.warn('所有远程接口都失败,尝试本地数据'); + return null; + } + } +} + +async function fetchFromLocal() { + try { + const resp = await fetch(API.localFallback + `?t=${Date.now()}`); + if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`); + const data = await resp.json(); + return data; + } catch (e) { + console.error('读取本地返回接口.json失败:', e); + return null; + } +} + +function renderRanking(payload) { + const { list = [], tip = '', update_time = '', update_time_at } = payload || {}; + + // 更新时间 + if (elements.updateTime) { + elements.updateTime.textContent = update_time ? `更新时间:${update_time}` : ''; + } + + // 统计信息 + if (elements.statsTotal) { + elements.statsTotal.textContent = list.length; + } + if (elements.statsTop10) { + elements.statsTop10.textContent = Math.min(10, list.length); + } + + // 渲染列表 + const html = ` +
+
+
+
${list.length}
+
入榜影片数量
+
+
+
${Math.min(10, list.length)}
+
TOP10 数量
+
+
+
+
+

全球电影总票房排行榜

+
+ ${list.map(item => renderMovieItem(item)).join('')} +
+
+ ${tip ? `
${escapeHtml(tip)}
` : ''} + ${update_time ? `
更新时间:${escapeHtml(update_time)}
` : ''} + `; + + elements.container.innerHTML = html; + elements.container.classList.add('fade-in'); +} + +function renderMovieItem(item) { + const rank = item.rank; + const cls = rank === 1 ? 'top-1' : rank === 2 ? 'top-2' : rank === 3 ? 'top-3' : ''; + const badgeCls = rank === 1 ? 'gold' : rank === 2 ? 'silver' : rank === 3 ? 'bronze' : 'regular'; + + return ` +
+
${rank}
+
+
#${rank}
+
+
${escapeHtml(item.movie_name)}
+
上映年份:${escapeHtml(item.release_year || '')}
+
+
+
${formatCurrencyDesc(item.box_office_desc, item.box_office)}
+
总票房
+
+
+
+ `; +} + +function formatCurrencyDesc(desc, num) { + if (desc && typeof desc === 'string' && desc.trim()) return desc; + if (typeof num === 'number') { + // 人民币按亿元显示 + if (num >= 1e8) return (num / 1e8).toFixed(2) + '亿元'; + if (num >= 1e4) return (num / 1e4).toFixed(2) + '万元'; + return num.toLocaleString('zh-CN') + '元'; + } + return '—'; +} + +function showLoading(show) { + if (elements.loading) elements.loading.style.display = show ? 'block' : 'none'; + if (elements.container) elements.container.style.display = show ? 'none' : 'block'; +} + +function showError(message) { + if (!elements.container) return; + elements.container.innerHTML = ` +
+

⚠️ 加载失败

+

${escapeHtml(message)}

+

请稍后重试

+
+ `; + elements.container.style.display = 'block'; +} + +function escapeHtml(text) { + if (text == null) return ''; + const div = document.createElement('div'); + div.textContent = String(text); + return div.innerHTML; +} + +// 键盘刷新快捷键 Ctrl/Cmd + R 刷新数据区域(不刷新整页) +window.addEventListener('keydown', (e) => { + if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'r') { + e.preventDefault(); + loadMaoyanList(); + } +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json new file mode 100644 index 00000000..945e5cfe --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json @@ -0,0 +1,171 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": { + "list": [ + { + "rank": 1, + "maoyan_id": 243, + "movie_name": "阿凡达", + "release_year": "2009", + "box_office": 21200972239, + "box_office_desc": "212.01亿元" + }, + { + "rank": 2, + "maoyan_id": 248172, + "movie_name": "复仇者联盟 4:终局之战", + "release_year": "2019", + "box_office": 20299852689, + "box_office_desc": "203亿元" + }, + { + "rank": 3, + "maoyan_id": 78461, + "movie_name": "阿凡达:水之道", + "release_year": "2022", + "box_office": 16825062887, + "box_office_desc": "168.25亿元" + }, + { + "rank": 4, + "maoyan_id": 267, + "movie_name": "泰坦尼克号", + "release_year": "1997", + "box_office": 16423064756, + "box_office_desc": "164.23亿元" + }, + { + "rank": 5, + "maoyan_id": 1294273, + "movie_name": "哪吒之魔童闹海", + "release_year": "2025", + "box_office": 15908714214, + "box_office_desc": "159.09亿元" + }, + { + "rank": 6, + "maoyan_id": 78536, + "movie_name": "星球大战:原力觉醒", + "release_year": "2015", + "box_office": 15019898914, + "box_office_desc": "150.2亿元" + }, + { + "rank": 7, + "maoyan_id": 248170, + "movie_name": "复仇者联盟 3:无限战争", + "release_year": "2018", + "box_office": 14882882413, + "box_office_desc": "148.83亿元" + }, + { + "rank": 8, + "maoyan_id": 1254435, + "movie_name": "蜘蛛侠:英雄无归", + "release_year": "2021", + "box_office": 14160042137, + "box_office_desc": "141.6亿元" + }, + { + "rank": 9, + "maoyan_id": 1479534, + "movie_name": "头脑特工队 2", + "release_year": "2024", + "box_office": 12319141075, + "box_office_desc": "123.19亿元" + }, + { + "rank": 10, + "maoyan_id": 78602, + "movie_name": "侏罗纪世界", + "release_year": "2015", + "box_office": 12120986621, + "box_office_desc": "121.21亿元" + }, + { + "rank": 11, + "maoyan_id": 1189879, + "movie_name": "狮子王", + "release_year": "2019", + "box_office": 12051977766, + "box_office_desc": "120.52亿元" + }, + { + "rank": 12, + "maoyan_id": 262, + "movie_name": "复仇者联盟", + "release_year": "2012", + "box_office": 11026033139, + "box_office_desc": "110.26亿元" + }, + { + "rank": 13, + "maoyan_id": 78405, + "movie_name": "速度与激情 7", + "release_year": "2015", + "box_office": 10988354292, + "box_office_desc": "109.88亿元" + }, + { + "rank": 14, + "maoyan_id": 341152, + "movie_name": "壮志凌云 2:独行侠", + "release_year": "2022", + "box_office": 10845892091, + "box_office_desc": "108.46亿元" + }, + { + "rank": 15, + "maoyan_id": 247949, + "movie_name": "冰雪奇缘 2", + "release_year": "2019", + "box_office": 10541240357, + "box_office_desc": "105.41亿元" + }, + { + "rank": 16, + "maoyan_id": 344942, + "movie_name": "芭比", + "release_year": "2023", + "box_office": 10493054406, + "box_office_desc": "104.93亿元" + }, + { + "rank": 17, + "maoyan_id": 78429, + "movie_name": "复仇者联盟 2:奥创纪元", + "release_year": "2015", + "box_office": 10188347873, + "box_office_desc": "101.88亿元" + }, + { + "rank": 18, + "maoyan_id": 1250896, + "movie_name": "超级马里奥兄弟大电影", + "release_year": "2023", + "box_office": 9868050757, + "box_office_desc": "98.68亿元" + }, + { + "rank": 19, + "maoyan_id": 341138, + "movie_name": "黑豹", + "release_year": "2018", + "box_office": 9788853998, + "box_office_desc": "97.89亿元" + }, + { + "rank": 20, + "maoyan_id": 916, + "movie_name": "哈利・波特与死亡圣器(下)", + "release_year": "2011", + "box_office": 9735002643, + "box_office_desc": "97.35亿元" + } + ], + "tip": "注:内地票房数据实时更新,包括点映及预售票房。港澳台及海外票房为统计数据,每小时更新。汇率采用 2025年1月31日市场汇率,1美元≈7.2514人民币", + "update_time": "2025/08/19 14:41:34", + "update_time_at": 1755585694385 + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/返回接口.json new file mode 100644 index 00000000..f0b8c79f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单列表/返回接口.json @@ -0,0 +1,750 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "id": 19723756, + "name": "飙升榜", + "description": "云音乐中每天热度上升最快的100首单曲,每日更新。", + "cover": "https://p1.music.126.net/rIi7Qzy2i2Y_1QD7cd0MYA==/109951170048506929.jpg", + "update_frequency": "每天更新", + "updated": "2025-08-27 01:24:43", + "updated_at": 1756257883349, + "created": "2014-06-30 07:58:56", + "created_at": 1404115136883, + "link": "https://music.163.com/#/discover/toplist?id=19723756" + }, + { + "id": 3779629, + "name": "新歌榜", + "description": "云音乐新歌榜:云音乐用户一周内收听所有新歌(一月内最新发行) 官方TOP排行榜,每天更新。", + "cover": "https://p1.music.126.net/5guhqPBTcIrrhLBotgaT6w==/109951170048511751.jpg", + "update_frequency": "每天更新", + "updated": "2025-08-27 00:56:52", + "updated_at": 1756256212440, + "created": "2013-09-09 10:09:58", + "created_at": 1378721398225, + "link": "https://music.163.com/#/discover/toplist?id=3779629" + }, + { + "id": 2884035, + "name": "原创榜", + "description": "云音乐独立原创音乐人作品官方榜单,以推荐优秀原创作品为目的。每周四网易云音乐首发。申请网易音乐人:http://music.163.com/nmusician/", + "cover": "https://p1.music.126.net/BaP9nrocNTL3gGThysv4eQ==/109951170091896587.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 02:53:19", + "updated_at": 1755744799157, + "created": "2013-07-25 06:05:25", + "created_at": 1374732325894, + "link": "https://music.163.com/#/discover/toplist?id=2884035" + }, + { + "id": 3778678, + "name": "热歌榜", + "description": "云音乐热歌榜:云音乐用户一周内收听所有线上歌曲官方TOP排行榜,每日更新。", + "cover": "https://p1.music.126.net/0SUEG8yDACfx0Bw2MYFv4Q==/109951170048519512.jpg", + "update_frequency": "每天更新", + "updated": "2025-08-27 00:57:07", + "updated_at": 1756256227510, + "created": "2013-09-09 10:10:06", + "created_at": 1378721406014, + "link": "https://music.163.com/#/discover/toplist?id=3778678" + }, + { + "id": 991319590, + "name": "网易云中文说唱榜", + "description": "网易云原创说唱音乐人作品官方榜单,每周五更新。以网易云用户一周播放热度为主,收录2个月内发行的原创说唱作品,按照综合数据排名取前50名。申请网易音乐人:http://music.163.com/nmusician", + "cover": "https://p1.music.126.net/GgHbgDfGXHpE2YTchU7IvA==/109951171510498108.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 02:45:48", + "updated_at": 1755830748504, + "created": "2017-11-10 05:06:29", + "created_at": 1510290389440, + "link": "https://music.163.com/#/discover/toplist?id=991319590" + }, + { + "id": 71384707, + "name": "网易云古典榜", + "description": "网易云用户一周内收听所有古典音乐官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/urByD_AmfBDBrs7fA9-O8A==/109951167976973225.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 02:59:09", + "updated_at": 1755745149157, + "created": "2015-05-07 03:22:00", + "created_at": 1430968920537, + "link": "https://music.163.com/#/discover/toplist?id=71384707" + }, + { + "id": 1978921795, + "name": "网易云电音榜", + "description": "网易云用户一周内收听电子音乐官方TOP排行榜,每周五更新。喜力星电音,用先锋电音带你解锁全新维度和体验!", + "cover": "https://p1.music.126.net/hXGObvXfsGtFjFvRhOYAkA==/109951170091888741.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 09:07:49", + "updated_at": 1755853669156, + "created": "2017-11-16 09:47:12", + "created_at": 1510825632233, + "link": "https://music.163.com/#/discover/toplist?id=1978921795" + }, + { + "id": 14028249541, + "name": "网易云全球说唱榜", + "description": "想聆听世界的说唱节奏?全球说唱榜每周五更新,聚焦华语地区以外的优秀说唱作品。根据云音乐用户每周播放热度数据,按照综合数据排名取前 50 名。", + "cover": "https://p1.music.126.net/0hhFjP6WyIjHYDXKW5E7BA==/109951171535150782.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 01:58:14", + "updated_at": 1755827894399, + "created": "2025-07-24 06:09:26", + "created_at": 1753337366883, + "link": "https://music.163.com/#/discover/toplist?id=14028249541" + }, + { + "id": 13372522766, + "name": "潮流风向榜", + "description": "精心挑选云音乐极具声量的音乐作品,呈现歌曲真实热度趋势,榜单每日更新。", + "cover": "https://p1.music.126.net/dIKA5e7jCncz2Br1Toxgaw==/109951170621574552.jpg", + "update_frequency": "更新74首", + "updated": "2025-08-27 04:05:55", + "updated_at": 1756267555368, + "created": "2025-02-26 06:01:33", + "created_at": 1740549693794, + "link": "https://music.163.com/#/discover/toplist?id=13372522766" + }, + { + "id": 12911403728, + "name": "音乐合伙人推荐榜", + "description": "音乐合伙人近一个月内推荐过的歌曲官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", + "cover": "https://p1.music.126.net/s6ITpmGjKbyDpi7DPkqd2w==/109951170187827373.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 04:06:02", + "updated_at": 1756094762192, + "created": "2024-11-25 07:14:30", + "created_at": 1732518870190, + "link": "https://music.163.com/#/discover/toplist?id=12911403728" + }, + { + "id": 12911589513, + "name": "音乐合伙人热歌榜", + "description": "音乐合伙人近一周评定过的高分热歌官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", + "cover": "https://p1.music.126.net/RgYxQmB-ZUjkMRo2N1jWnQ==/109951170187823494.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 04:05:58", + "updated_at": 1756094758751, + "created": "2024-11-25 07:13:46", + "created_at": 1732518826543, + "link": "https://music.163.com/#/discover/toplist?id=12911589513" + }, + { + "id": 12911619970, + "name": "音乐合伙人留名榜", + "description": "音乐合伙人近一个月内留名过的所有歌曲官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", + "cover": "https://p1.music.126.net/aJJzGIxhkVaD7dX0XBNUnw==/109951170187831145.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 04:05:45", + "updated_at": 1756094745722, + "created": "2024-11-25 07:12:50", + "created_at": 1732518770868, + "link": "https://music.163.com/#/discover/toplist?id=12911619970" + }, + { + "id": 12911379734, + "name": "音乐合伙人高分新歌榜", + "description": "音乐合伙人近期评定过的所有新歌(一个月内最新发行)官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", + "cover": "https://p1.music.126.net/bfk15bvanhdPFU7yjPFgWA==/109951170187832038.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 04:05:50", + "updated_at": 1756094750117, + "created": "2024-11-25 07:11:53", + "created_at": 1732518713161, + "link": "https://music.163.com/#/discover/toplist?id=12911379734" + }, + { + "id": 12768855486, + "name": "音乐合伙人高分榜", + "description": "音乐合伙人的高分歌曲官方榜单,收录近半年来获得音乐合伙人高分推荐的TOP100首歌曲,每日更新。跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", + "cover": "https://p1.music.126.net/fPP5T0Z8Ac15qNvRTcHa6g==/109951170074028970.jpg", + "update_frequency": "更新27首", + "updated": "2025-08-27 04:05:47", + "updated_at": 1756267547739, + "created": "2024-10-25 03:51:10", + "created_at": 1729828270342, + "link": "https://music.163.com/#/discover/toplist?id=12768855486" + }, + { + "id": 5453912201, + "name": "黑胶VIP爱听榜", + "description": "云音乐站内会员播放热度TOP100的歌曲,每周四更新。\n黑胶们都爱听什么歌曲?\n热门好歌一站式收听,让你念念不忘~\n做尊贵黑胶,畅听品味好歌~", + "cover": "https://p1.music.126.net/qo6-o9n5AhMjNyejev38-A==/109951169743111905.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 10:05:01", + "updated_at": 1755770701110, + "created": "2021-01-08 06:30:24", + "created_at": 1610087424470, + "link": "https://music.163.com/#/discover/toplist?id=5453912201" + }, + { + "id": 71385702, + "name": "网易云ACG榜", + "description": "网易云用户一周内收听所有ACG音乐官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/na1kEeCS1iZEkzOrs9r_9g==/109951167976973667.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 04:05:02", + "updated_at": 1755749102516, + "created": "2015-05-07 03:22:15", + "created_at": 1430968935040, + "link": "https://music.163.com/#/discover/toplist?id=71385702" + }, + { + "id": 745956260, + "name": "网易云韩语榜", + "description": "网易云用户一周内收听所有韩语歌曲官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/5oN9YaFznwNGXkmi8i2Ytw==/109951167430864741.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 04:05:01", + "updated_at": 1755749101352, + "created": "2017-05-31 03:34:51", + "created_at": 1496201691281, + "link": "https://music.163.com/#/discover/toplist?id=745956260" + }, + { + "id": 180106, + "name": "UK排行榜周榜", + "description": "UK排行榜", + "cover": "https://p1.music.126.net/fhAqiflLy3eU-ldmBQByrg==/109951165613082765.jpg", + "update_frequency": "每天更新", + "updated": "2025-08-25 03:59:06", + "updated_at": 1756094346206, + "created": "2013-02-19 02:09:26", + "created_at": 1361239766844, + "link": "https://music.163.com/#/discover/toplist?id=180106" + }, + { + "id": 60198, + "name": "美国Billboard榜", + "description": "美国Billboard排行榜", + "cover": "https://p1.music.126.net/rwRsVIJHQ68gglhA6TNEYA==/109951165611413732.jpg", + "update_frequency": "刚刚更新", + "updated": "2025-08-27 03:38:38", + "updated_at": 1756265918370, + "created": "2013-01-22 02:51:16", + "created_at": 1358823076818, + "link": "https://music.163.com/#/discover/toplist?id=60198" + }, + { + "id": 3812895, + "name": "Beatport全球电子舞曲榜", + "description": "Beatport全球电子舞曲排行榜TOP100(本榜每周三更新)", + "cover": "https://p1.music.126.net/oT-RHuPBJiD7WMoU7WG5Rw==/109951166093489621.jpg", + "update_frequency": "更新20首", + "updated": "2025-08-27 02:29:37", + "updated_at": 1756261777726, + "created": "2013-09-11 08:03:09", + "created_at": 1378886589466, + "link": "https://music.163.com/#/discover/toplist?id=3812895" + }, + { + "id": 21845217, + "name": "KTV唛榜", + "description": "KTV唛榜是目前国内首个以全国超过200家KTV点歌平台真实数据的当红歌曲榜单。所涉及的KTV店铺覆盖全国近100多个城市,囊括一、二、三线各级城市及地区。在综合全国各地KTV点唱数据的前提下进行汇总与统计。为了保证信息的及时性,唛榜每周五更新。提供给K迷们最新和最准确的数据。", + "cover": "https://p1.music.126.net/5wDP78s43ydVTKt62C8OjQ==/109951165613100063.jpg", + "update_frequency": "每周五更新", + "updated": "2021-11-26 09:56:43", + "updated_at": 1637920603975, + "created": "2014-07-18 03:11:33", + "created_at": 1405653093230, + "link": "https://music.163.com/#/discover/toplist?id=21845217" + }, + { + "id": 60131, + "name": "日本Oricon榜", + "description": "日本Oricon数字单曲周榜,每周三更新,欢迎关注。", + "cover": "https://p1.music.126.net/aXUPgImt8hhf4cMUZEjP4g==/109951165611417794.jpg", + "update_frequency": "每天更新", + "updated": "2025-08-22 02:15:24", + "updated_at": 1755828924438, + "created": "2013-01-08 08:51:24", + "created_at": 1357635084874, + "link": "https://music.163.com/#/discover/toplist?id=60131" + }, + { + "id": 2809513713, + "name": "网易云欧美热歌榜", + "description": "网易云用户一周内收听所有欧美歌曲官方TOP排行榜,每周四更新。\nWestern Hit Chart (updated every Thursday)", + "cover": "https://p1.music.126.net/70_EO_Dc7NT_hhfvsapzcQ==/109951167430862162.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 15:44:14", + "updated_at": 1755791054932, + "created": "2019-05-22 02:49:33", + "created_at": 1558493373769, + "link": "https://music.163.com/#/discover/toplist?id=2809513713" + }, + { + "id": 2809577409, + "name": "网易云欧美新歌榜", + "description": "网易云用户一周内收听所有欧美新歌(一月内最新发行)官方TOP排行榜,每天更新。\nWestern New Release Chart (new songs released in last 30 days, updated daily)\n", + "cover": "https://p1.music.126.net/0lPWpI9Ejn1OiW2LSbg-qw==/109951167430863224.jpg", + "update_frequency": "更新17首", + "updated": "2025-08-27 07:16:02", + "updated_at": 1756278962152, + "created": "2019-05-22 02:46:54", + "created_at": 1558493214795, + "link": "https://music.163.com/#/discover/toplist?id=2809577409" + }, + { + "id": 27135204, + "name": "法国 NRJ Vos Hits 周榜", + "description": "法国NRJ电台(national Radio de Jeunes)成立于1981年,总部位于法国巴黎。是法国最受欢迎的音乐电台和听众最多的广播电台之一。NRJ音乐奖素有法国的“格莱美”之称。此榜单针对NRJ电台法国本土热门歌曲排行。【每周五更新】", + "cover": "https://p1.music.126.net/-fyzrPWd06FfWl_0JDAxMQ==/109951165613108584.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 02:15:42", + "updated_at": 1755828942531, + "created": "2014-09-04 10:03:33", + "created_at": 1409825013948, + "link": "https://music.163.com/#/discover/toplist?id=27135204" + }, + { + "id": 3001835560, + "name": "网易云ACG动画榜", + "description": "网易云中每天热度上升最快的100首ACG动画单曲,每日更新。", + "cover": "https://p1.music.126.net/SkGlKQ6acixthb77VlD9eQ==/109951164432300406.jpg", + "update_frequency": "更新84首", + "updated": "2025-08-27 04:05:09", + "updated_at": 1756267509031, + "created": "2019-09-27 02:03:58", + "created_at": 1569549838610, + "link": "https://music.163.com/#/discover/toplist?id=3001835560" + }, + { + "id": 3001795926, + "name": "网易云ACG游戏榜", + "description": "网易云中每天热度上升最快的100首ACG游戏单曲,每日更新。", + "cover": "https://p1.music.126.net/hivOOHMwEmnn9s_6rgZwEQ==/109951164432303700.jpg", + "update_frequency": "更新87首", + "updated": "2025-08-27 04:05:18", + "updated_at": 1756267518248, + "created": "2019-09-27 02:04:56", + "created_at": 1569549896656, + "link": "https://music.163.com/#/discover/toplist?id=3001795926" + }, + { + "id": 3001890046, + "name": "网易云ACG VOCALOID榜", + "description": "", + "cover": "https://p1.music.126.net/Ag7RyRCYiINcd9EtRXf6xA==/109951164432303690.jpg", + "update_frequency": "更新87首", + "updated": "2025-08-27 04:05:27", + "updated_at": 1756267527413, + "created": "2019-09-27 02:05:25", + "created_at": 1569549925472, + "link": "https://music.163.com/#/discover/toplist?id=3001890046" + }, + { + "id": 5059644681, + "name": "网易云日语榜", + "description": "网易云用户一周内收听所有日语歌曲官方TOP排行榜,每周二更新。", + "cover": "https://p1.music.126.net/YFBFNI2F-4BveUpv6FKFuw==/109951167430864069.jpg", + "update_frequency": "每周二更新", + "updated": "2025-08-26 06:05:02", + "updated_at": 1756188302867, + "created": "2020-06-11 08:10:00", + "created_at": 1591863000459, + "link": "https://music.163.com/#/discover/toplist?id=5059644681" + }, + { + "id": 5059633707, + "name": "网易云摇滚榜", + "description": "网易云用户一周内收听所有摇滚歌曲官方TOP排行榜,每周五更新。", + "cover": "https://p1.music.126.net/LjkX2hktgFD1NXc3W6w0sA==/109951170048522513.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 09:12:43", + "updated_at": 1755853963904, + "created": "2020-06-11 08:13:33", + "created_at": 1591863213389, + "link": "https://music.163.com/#/discover/toplist?id=5059633707" + }, + { + "id": 5059642708, + "name": "网易云国风榜", + "description": "网易云用户一周内收听所有国风歌曲官方TOP排行榜,每周五更新。", + "cover": "https://p1.music.126.net/kTJC5OBhg8I477X_ZmXyDQ==/109951168539740982.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 03:10:57", + "updated_at": 1755832257607, + "created": "2020-06-11 08:14:18", + "created_at": 1591863258438, + "link": "https://music.163.com/#/discover/toplist?id=5059642708" + }, + { + "id": 5338990334, + "name": "潜力爆款榜", + "description": "全民一起PICK潜力好歌,每周二更新", + "cover": "https://p1.music.126.net/Mi4QPklg1mtbWAfq74tEqQ==/109951165498334721.jpg", + "update_frequency": "每周二更新", + "updated": "2025-08-26 04:05:32", + "updated_at": 1756181132964, + "created": "2020-11-17 06:24:34", + "created_at": 1605594274077, + "link": "https://music.163.com/#/discover/toplist?id=5338990334" + }, + { + "id": 5059661515, + "name": "网易云民谣榜", + "description": "网易云用户一周内收听所有民谣歌曲官方TOP排行榜,每周五更新。", + "cover": "https://p1.music.126.net/Xe9qLTAqtBAWX_hPgFHMyw==/109951170048510929.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 08:39:36", + "updated_at": 1755851976839, + "created": "2020-06-11 08:10:52", + "created_at": 1591863052757, + "link": "https://music.163.com/#/discover/toplist?id=5059661515" + }, + { + "id": 6688069460, + "name": "听歌识曲榜", + "description": "网易云音乐站内歌曲按用户“听歌识曲”次数排列,每周四更新", + "cover": "https://p1.music.126.net/wJVUAiUuykKk7yGbQxDBug==/109951167430857712.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 15:35:02", + "updated_at": 1755790502462, + "created": "2021-03-31 08:45:54", + "created_at": 1617180354803, + "link": "https://music.163.com/#/discover/toplist?id=6688069460" + }, + { + "id": 6723173524, + "name": "网络热歌榜", + "description": "网罗一周热门网络歌曲,反映云音乐用户近一周网络热歌收听趋势。每周五更新。", + "cover": "https://p1.music.126.net/_kSxOPqQ5J5etC5DKTFwNA==/109951170048519530.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 01:59:18", + "updated_at": 1755827958008, + "created": "2021-04-22 02:41:46", + "created_at": 1619059306654, + "link": "https://music.163.com/#/discover/toplist?id=6723173524" + }, + { + "id": 6732051320, + "name": "俄语榜", + "description": "网易云音乐用户一周内收听所有俄罗斯语歌曲官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/HbJ0BK5doY4I4pEMY6-FQw==/109951167430852698.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 04:05:27", + "updated_at": 1755749127585, + "created": "2021-04-28 04:05:12", + "created_at": 1619582712108, + "link": "https://music.163.com/#/discover/toplist?id=6732051320" + }, + { + "id": 6732014811, + "name": "越南语榜", + "description": "网易云音乐用户一周内收听所有越南语歌曲官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/N-Y5maLGWgrowt3TE6RtSg==/109951167430857045.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 04:05:28", + "updated_at": 1755749128002, + "created": "2021-04-28 04:05:49", + "created_at": 1619582749349, + "link": "https://music.163.com/#/discover/toplist?id=6732014811" + }, + { + "id": 6886768100, + "name": "中文慢摇DJ榜", + "description": "搜索“DJ”,进入慢摇DJ专区,探索更多网络热歌!", + "cover": "https://p1.music.126.net/w_01BfDU012ojxnzLO6tYw==/109951167977358686.jpg", + "update_frequency": "刚刚更新", + "updated": "2025-08-27 04:00:00", + "updated_at": 1756267200565, + "created": "2021-07-28 10:09:59", + "created_at": 1627466999260, + "link": "https://music.163.com/#/discover/toplist?id=6886768100" + }, + { + "id": 6939992364, + "name": "俄罗斯top hit流行音乐榜", + "description": "top hit榜根据俄罗斯及全球400多个无线广播的音乐播放量和YouTube播放量计算得来,每周一更新。", + "cover": "https://p1.music.126.net/KLVO8PxVZzOoLdWQQNyprA==/109951166327316568.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 06:10:23", + "updated_at": 1755843023964, + "created": "2021-08-27 03:30:02", + "created_at": 1630035002268, + "link": "https://music.163.com/#/discover/toplist?id=6939992364" + }, + { + "id": 7095271308, + "name": "泰语榜", + "description": "网易云音乐用户一周内收听所有泰语歌曲官方TOP排行榜,每周四更新。", + "cover": "https://p1.music.126.net/4W0WBHBgwYlYfRniuyL47A==/109951167430843284.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 02:26:07", + "updated_at": 1755743167588, + "created": "2021-11-29 06:22:17", + "created_at": 1638166937809, + "link": "https://music.163.com/#/discover/toplist?id=7095271308" + }, + { + "id": 7356827205, + "name": "BEAT排行榜", + "description": "嘿~朋友,欢迎来到本周的Beat排行榜\n我们挑选了近一周内热门的Beat作品,一起来感受下大家近期的“口味”吧!\n每周都会更新哦,记得按下收藏,我每天都会在这里等你来与我交流!~\n\n关于Beat的必备小知识\nQ1.什么是Beat?\nBeat即节拍,特指嘻哈音乐中的伴奏,现在也可指所有流行音乐的伴奏\nQ2.Beat有什么用?\n在Beat的帮助下,你只需要填词演唱即可完成一首歌曲的创作,而且Beat也可以作为各种流媒体的背景音乐或是多场景现场演出的得力助手,不同风格的Beat还能为你的音乐创作提供灵感哦~\n搜索关注“BEATSOUL激灵”网易云官号,探索更多炸裂音乐内容~", + "cover": "https://p1.music.126.net/yhzlQJCJ9NcT4MvJBG_HgQ==/109951167977014958.jpg", + "update_frequency": "每周四更新", + "updated": "2025-08-21 12:05:01", + "updated_at": 1755777901037, + "created": "2022-03-29 11:39:58", + "created_at": 1648553998273, + "link": "https://music.163.com/#/discover/toplist?id=7356827205" + }, + { + "id": 7325478166, + "name": "星云榜VOL.29 Addison Rae新专来袭,寻找最真实的自己", + "description": "精心评审,专业推荐。每周五更新,为你呈现宝藏新歌。\n1、《Aquamarinee》歌手:Addison Rae\n2、《羽毛剑》歌手:秦凡淇\n3、《Take me back》歌手:HAIM\n4、《妈妈的眼睛》歌手:张震岳\n5、《25岁永不停下》歌手:张醒婵\n6、《雨季症候》歌手:SHARK卫彬月\n7、《山东王FREESTYLE》歌手:华云龙KLE\n8、《LOVE I NEED》歌手:陈瑜Estelle\n9、《FFFFF》歌手:刘柏辛Lexie\n10、《Vipaśyanā》歌手:Namunong\n本期封面:Addison Rae,Aquamarine", + "cover": "https://p2.music.126.net/u440jFG0N5i06C9ejOeMCQ==/109951171381091309.jpg", + "update_frequency": "每周五更新", + "updated": "2025-06-30 08:17:26", + "updated_at": 1751271446032, + "created": "2022-03-09 03:24:46", + "created_at": 1646796286440, + "link": "https://music.163.com/#/discover/toplist?id=7325478166" + }, + { + "id": 7603212484, + "name": "LOOK直播歌曲榜", + "description": "LOOK直播好歌共赏,专属你的声音聊愈场。榜单选取符合条件且近7日热度最高的前50首歌曲,每周二更新。", + "cover": "https://p2.music.126.net/u-RQC-LyY0aoeseRumJ14A==/109951167977730469.jpg", + "update_frequency": "每周二更新", + "updated": "2024-05-07 13:23:03", + "updated_at": 1715088183913, + "created": "2022-08-23 01:54:56", + "created_at": 1661219696017, + "link": "https://music.163.com/#/discover/toplist?id=7603212484" + }, + { + "id": 7775163417, + "name": "赏音榜", + "description": "云音乐歌曲赏音榜,以让用户鉴赏到更多潜力好歌为目的,以用户对歌曲互动热度为核心,按照综合数据排名取前100名,每日更新", + "cover": "https://p2.music.126.net/m9hQzC-d5wefBipedNPaHg==/109951168178601971.jpg", + "update_frequency": "更新92首", + "updated": "2025-08-27 04:05:36", + "updated_at": 1756267536926, + "created": "2022-11-28 06:46:19", + "created_at": 1669617979380, + "link": "https://music.163.com/#/discover/toplist?id=7775163417" + }, + { + "id": 7785123708, + "name": "黑胶VIP新歌榜", + "description": "云音乐站内播放热度TOP50的7日内新晋会员歌曲,每日更新。\n更适合黑胶体质的新歌榜单来啦!\n耳机分你一只,新曲一起来听~\n成为尊贵黑胶,不错过每一首VIP新歌!", + "cover": "https://p2.music.126.net/vjitpkT9nXBCth6tvdDMWg==/109951169743115266.jpg", + "update_frequency": "更新33首", + "updated": "2025-08-27 04:05:38", + "updated_at": 1756267538662, + "created": "2022-12-02 10:51:16", + "created_at": 1669978276103, + "link": "https://music.163.com/#/discover/toplist?id=7785123708" + }, + { + "id": 7785066739, + "name": "黑胶VIP热歌榜", + "description": "云音乐站内播放和付费热度TOP50的会员歌曲,每日更新。\n更适合黑胶体质的热歌榜单来啦!\n哪首是你的单曲循环?\n成为尊贵黑胶,随心畅听热门好歌!", + "cover": "https://p2.music.126.net/Ay3mLgQ9weG_c8JjYrD-Bw==/109951169743106495.jpg", + "update_frequency": "刚刚更新", + "updated": "2025-08-27 04:05:37", + "updated_at": 1756267537688, + "created": "2022-12-02 10:51:31", + "created_at": 1669978291024, + "link": "https://music.163.com/#/discover/toplist?id=7785066739" + }, + { + "id": 7785091694, + "name": "黑胶VIP爱搜榜", + "description": "云音乐站内会员搜索播放热度TOP50的歌曲,每日更新。\n更适合黑胶体质的搜歌榜单来啦!\n热搜好歌一网打尽,只为有品位的你~\n成为尊贵黑胶,你搜我听畅听不停!", + "cover": "https://p2.music.126.net/R7DtZqNraesnsiaIKvzTHA==/109951169743112799.jpg", + "update_frequency": "更新36首", + "updated": "2025-08-27 04:05:42", + "updated_at": 1756267542318, + "created": "2022-12-02 10:51:43", + "created_at": 1669978303210, + "link": "https://music.163.com/#/discover/toplist?id=7785091694" + }, + { + "id": 8246775932, + "name": "实时热度榜", + "description": "每天9-23点为你精选当下歌曲热度最高的歌曲", + "cover": "https://p2.music.126.net/U7ZbdpWzRdmZVr6Khn_4ag==/109951168673982478.jpg", + "update_frequency": "刚刚更新", + "updated": "2025-08-27 13:15:01", + "updated_at": 1756300501119, + "created": "2023-03-20 02:39:59", + "created_at": 1679279999154, + "link": "https://music.163.com/#/discover/toplist?id=8246775932" + }, + { + "id": 8537588450, + "name": "喜力®星电音派对潮音榜", + "description": "乐无界,越未来!《星电音联盟》歌曲官方榜单,每周一更新,让云村村民们随时随地躁起高燃派对氛围!喜力®星电音构建狂欢永不停歇的新奇电音宇宙,激活潮流基因,释放先锋灵感,跨维开启奇妙电音之旅!", + "cover": "https://p2.music.126.net/HVu2hGYvzN5XBuvFc_4Bgg==/109951168730309120.jpg", + "update_frequency": "每周五更新", + "updated": "2024-09-16 04:05:30", + "updated_at": 1726459530378, + "created": "2023-07-07 02:48:39", + "created_at": 1688698119437, + "link": "https://music.163.com/#/discover/toplist?id=8537588450" + }, + { + "id": 8661209031, + "name": "乐夏榜", + "description": "听乐夏,上网易云,一头扎进爱音乐的人群! 综艺《乐队的夏天3》官方榜单,每周一更新。和三星折叠屏手机一起畅听《乐队的夏天3》官方榜单,折叠看三星,五代更来劲。", + "cover": "https://p2.music.126.net/RlStCmE97y0xYFk7rS3Zww==/109951168864907822.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 04:05:40", + "updated_at": 1756094740529, + "created": "2023-08-16 09:47:27", + "created_at": 1692179247425, + "link": "https://music.163.com/#/discover/toplist?id=8661209031" + }, + { + "id": 8703179781, + "name": "特斯拉车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/UL8dhobSa3TR6Wd1JmWe_g==/109951168924385363.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:04", + "updated_at": 1756109104224, + "created": "2023-08-31 04:29:59", + "created_at": 1693456199735, + "link": "https://music.163.com/#/discover/toplist?id=8703179781" + }, + { + "id": 8703052295, + "name": "理想车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/U--PWdWupY1ER5cVSjr1jQ==/109951168928365496.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:04", + "updated_at": 1756109104985, + "created": "2023-08-31 04:38:29", + "created_at": 1693456709598, + "link": "https://music.163.com/#/discover/toplist?id=8703052295" + }, + { + "id": 8702582160, + "name": "比亚迪车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/S1OG-OLTaofa3HfrHW48kA==/109951168924393585.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:03", + "updated_at": 1756109103855, + "created": "2023-08-31 04:38:42", + "created_at": 1693456722262, + "link": "https://music.163.com/#/discover/toplist?id=8702582160" + }, + { + "id": 8703220480, + "name": "蔚来车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/r9kBQNsOro1EAB82Ol51WQ==/109951168924380971.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:02", + "updated_at": 1756109102267, + "created": "2023-08-31 04:38:56", + "created_at": 1693456736086, + "link": "https://music.163.com/#/discover/toplist?id=8703220480" + }, + { + "id": 8702982391, + "name": "极氪车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/Cu0RXoKewSPM9Gyc7Cp8jw==/109951168924391596.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:03", + "updated_at": 1756109103634, + "created": "2023-08-31 04:39:19", + "created_at": 1693456759762, + "link": "https://music.163.com/#/discover/toplist?id=8702982391" + }, + { + "id": 8532443277, + "name": "蛋仔派对听歌榜", + "description": "来自蛋仔岛的热播歌曲速递,网易《蛋仔派对》官方榜单,每周五更新。云村村民们,和蛋仔们一起随歌摇摆吧!", + "cover": "https://p2.music.126.net/TMb0be5QLMZKOFeuOKT4tg==/109951168717283910.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 04:05:44", + "updated_at": 1755835544365, + "created": "2023-07-05 02:32:04", + "created_at": 1688524324879, + "link": "https://music.163.com/#/discover/toplist?id=8532443277" + }, + { + "id": 9651277674, + "name": "AI歌曲榜", + "description": "精心挑选每日最新最热AI生成歌曲,榜单每日更新,一起感受AI的独特魅力吧!", + "cover": "https://p2.music.126.net/M0m6GeZ1Y8Osz9jqxaW8Wg==/109951169462048035.jpg", + "update_frequency": "更新12首", + "updated": "2025-08-27 04:05:43", + "updated_at": 1756267543655, + "created": "2024-04-02 10:25:12", + "created_at": 1712053512213, + "link": "https://music.163.com/#/discover/toplist?id=9651277674" + }, + { + "id": 10131772880, + "name": "昊铂车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/EL7H4rkKejZY7Uv54EFNXg==/109951169655010112.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:01", + "updated_at": 1756109101438, + "created": "2024-06-04 08:50:00", + "created_at": 1717491000945, + "link": "https://music.163.com/#/discover/toplist?id=10131772880" + }, + { + "id": 10162841534, + "name": "埃安车友爱听榜", + "description": "埃安车友平时都在听什么??", + "cover": "https://p2.music.126.net/FcP1U6Bck0wPKqd0XgBwSQ==/109951169679731241.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:03", + "updated_at": 1756109103115, + "created": "2024-06-12 05:31:44", + "created_at": 1718170304691, + "link": "https://music.163.com/#/discover/toplist?id=10162841534" + }, + { + "id": 12225155968, + "name": "欧美R&B榜", + "description": "云音乐用户一周内收听节奏布鲁斯(R&B)官方TOP排行榜,每周五更新。", + "cover": "https://p2.music.126.net/0E6MzYzyA5uvQ4CSoIG2mw==/109951169739660034.jpg", + "update_frequency": "每周五更新", + "updated": "2025-08-22 04:05:46", + "updated_at": 1755835546525, + "created": "2024-06-25 10:14:05", + "created_at": 1719310445382, + "link": "https://music.163.com/#/discover/toplist?id=12225155968" + }, + { + "id": 12344472377, + "name": "黑胶VIP限免榜", + "description": "云音乐站内热度最高的限免播放歌曲TOP50,每日更新。\n人气旋律一听就会爱上!现在马上进入免费模式(点击云音乐首页左上角侧边栏,选择“免费听歌”)畅听全榜吧!", + "cover": "https://p2.music.126.net/WXCSf4ZNcDCdOTY5ixm3Bg==/109951169809318325.jpg", + "update_frequency": "更新11首", + "updated": "2025-08-27 04:05:44", + "updated_at": 1756267544856, + "created": "2024-07-23 08:08:37", + "created_at": 1721722117311, + "link": "https://music.163.com/#/discover/toplist?id=12344472377" + }, + { + "id": 12717025277, + "name": "吉利车友爱听榜", + "description": null, + "cover": "https://p2.music.126.net/XVmZb3JSyrwMgqu9WVz61A==/109951170037568570.jpg", + "update_frequency": "每周一更新", + "updated": "2025-08-25 08:05:00", + "updated_at": 1756109100809, + "created": "2024-10-12 05:44:04", + "created_at": 1728711844151, + "link": "https://music.163.com/#/discover/toplist?id=12717025277" + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/background.css b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/background.css new file mode 100644 index 00000000..a4c76f7a --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/background.css @@ -0,0 +1,123 @@ +/* 背景样式文件 */ +body { + background: linear-gradient(135deg, #E8F5E8 0%, #F1F8E9 25%, #E0F2F1 50%, #E8F5E8 75%, #F3E5F5 100%); + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; + position: relative; +} + +/* 背景渐变动画 */ +@keyframes gradientShift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* 背景装饰元素 */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(129, 199, 132, 0.1) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(165, 214, 167, 0.08) 0%, transparent 50%); + pointer-events: none; + z-index: -2; +} + +/* 背景粒子效果 */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: + radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent), + radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent), + radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent); + background-repeat: repeat; + background-size: 200px 100px; + animation: particleFloat 20s linear infinite; + pointer-events: none; + z-index: -1; + opacity: 0.6; +} + +@keyframes particleFloat { + 0% { + transform: translateY(0px); + } + 100% { + transform: translateY(-100px); + } +} + +/* 响应式背景调整 */ +@media (max-width: 768px) { + body::after { + background-size: 150px 75px; + animation-duration: 25s; + } +} + +@media (max-width: 480px) { + body::after { + background-size: 100px 50px; + animation-duration: 30s; + opacity: 0.4; + } +} + +/* 高性能模式 - 减少动画 */ +@media (prefers-reduced-motion: reduce) { + body { + animation: none; + background: linear-gradient(135deg, #E8F5E8 0%, #F1F8E9 50%, #E0F2F1 100%); + } + + body::after { + animation: none; + } + + .title { + animation: none; + } +} + +/* 深色模式支持 */ +@media (prefers-color-scheme: dark) { + body { + background: linear-gradient(135deg, #1B5E20 0%, #2E7D32 25%, #388E3C 50%, #43A047 75%, #4CAF50 100%); + } + + body::before { + background-image: + radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.03) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(255, 255, 255, 0.02) 0%, transparent 50%); + } + + body::after { + background-image: + radial-gradient(1px 1px at 20px 30px, rgba(255, 255, 255, 0.1), transparent), + radial-gradient(1px 1px at 40px 70px, rgba(255, 255, 255, 0.08), transparent), + radial-gradient(1px 1px at 90px 40px, rgba(255, 255, 255, 0.06), transparent), + radial-gradient(1px 1px at 130px 80px, rgba(255, 255, 255, 0.04), transparent), + radial-gradient(1px 1px at 160px 30px, rgba(255, 255, 255, 0.05), transparent); + opacity: 0.3; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/style.css b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/style.css new file mode 100644 index 00000000..5f93a361 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/css/style.css @@ -0,0 +1,483 @@ +/* 基础样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; + line-height: 1.6; + color: #2c3e50; + min-height: 100vh; + overflow-x: hidden; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + position: relative; + z-index: 1; +} + +/* 头部样式 */ +.header { + text-align: center; + margin-bottom: 40px; + padding: 40px 20px; + background: rgba(255, 255, 255, 0.9); + border-radius: 20px; + backdrop-filter: blur(10px); + box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1); +} + +.title { + font-size: 2.5rem; + font-weight: 700; + background: linear-gradient(135deg, #4CAF50, #81C784); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 10px; + animation: titleGlow 3s ease-in-out infinite alternate; +} + +@keyframes titleGlow { + from { filter: drop-shadow(0 0 5px rgba(76, 175, 80, 0.3)); } + to { filter: drop-shadow(0 0 15px rgba(76, 175, 80, 0.6)); } +} + +.subtitle { + font-size: 1.1rem; + color: #666; + opacity: 0.8; +} + +/* 榜单信息样式 */ +.rank-info { + background: rgba(255, 255, 255, 0.95); + border-radius: 15px; + padding: 25px; + margin-bottom: 30px; + box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1); + border: 1px solid rgba(76, 175, 80, 0.2); +} + +.rank-header { + display: flex; + gap: 20px; + align-items: flex-start; +} + +.rank-cover { + width: 120px; + height: 120px; + border-radius: 12px; + object-fit: cover; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + flex-shrink: 0; +} + +.rank-details { + flex: 1; +} + +.rank-name { + font-size: 1.8rem; + color: #2c3e50; + margin-bottom: 10px; + font-weight: 600; +} + +.rank-description { + color: #666; + margin-bottom: 15px; + line-height: 1.6; +} + +.rank-meta { + display: flex; + gap: 20px; + flex-wrap: wrap; +} + +.update-time, .update-frequency { + background: linear-gradient(135deg, #E8F5E8, #C8E6C9); + padding: 6px 12px; + border-radius: 20px; + font-size: 0.9rem; + color: #2E7D32; + border: 1px solid rgba(76, 175, 80, 0.3); +} + +/* 控制区域样式 */ +.controls { + background: rgba(255, 255, 255, 0.9); + border-radius: 15px; + padding: 25px; + margin-bottom: 30px; + box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1); +} + +.input-group { + display: flex; + gap: 15px; + align-items: center; + flex-wrap: wrap; +} + +.input-group label { + font-weight: 600; + color: #2c3e50; + min-width: 80px; +} + +#rankId { + flex: 1; + min-width: 200px; + padding: 12px 16px; + border: 2px solid #E0E0E0; + border-radius: 10px; + font-size: 1rem; + transition: all 0.3s ease; + background: rgba(255, 255, 255, 0.9); +} + +#rankId:focus { + outline: none; + border-color: #4CAF50; + box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); +} + +.load-btn { + padding: 12px 24px; + background: linear-gradient(135deg, #4CAF50, #66BB6A); + color: white; + border: none; + border-radius: 10px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); +} + +.load-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4); +} + +.load-btn:active { + transform: translateY(0); +} + +.load-btn:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none; +} + +/* 加载动画 */ +.loading { + text-align: center; + padding: 40px; + background: rgba(255, 255, 255, 0.9); + border-radius: 15px; + margin-bottom: 30px; +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #E0E0E0; + border-top: 4px solid #4CAF50; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 15px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +/* 错误提示 */ +.error { + text-align: center; + padding: 30px; + background: rgba(255, 245, 245, 0.95); + border: 2px solid #ffcdd2; + border-radius: 15px; + margin-bottom: 30px; +} + +.error-icon { + font-size: 3rem; + margin-bottom: 15px; +} + +.error-message { + color: #c62828; + margin-bottom: 20px; + font-size: 1.1rem; +} + +.retry-btn { + padding: 10px 20px; + background: #f44336; + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.retry-btn:hover { + background: #d32f2f; + transform: translateY(-1px); +} + +/* 歌曲列表样式 */ +.song-list { + background: rgba(255, 255, 255, 0.95); + border-radius: 15px; + padding: 25px; + margin-bottom: 30px; + box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1); +} + +.list-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 25px; + padding-bottom: 15px; + border-bottom: 2px solid #E8F5E8; +} + +.list-header h3 { + font-size: 1.5rem; + color: #2c3e50; + font-weight: 600; +} + +.song-count { + background: linear-gradient(135deg, #4CAF50, #66BB6A); + color: white; + padding: 6px 12px; + border-radius: 20px; + font-size: 0.9rem; + font-weight: 600; +} + +/* 歌曲项样式 */ +.song-item { + display: flex; + align-items: center; + padding: 15px; + margin-bottom: 12px; + background: rgba(248, 255, 248, 0.8); + border-radius: 12px; + transition: all 0.3s ease; + border: 1px solid rgba(76, 175, 80, 0.1); + cursor: pointer; +} + +.song-item:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(76, 175, 80, 0.15); + background: rgba(232, 245, 232, 0.9); +} + +.song-rank { + font-size: 1.2rem; + font-weight: 700; + color: #4CAF50; + min-width: 40px; + text-align: center; +} + +.song-rank.top3 { + background: linear-gradient(135deg, #FFD700, #FFA000); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.song-info { + flex: 1; + margin-left: 15px; +} + +.song-title { + font-size: 1.1rem; + font-weight: 600; + color: #2c3e50; + margin-bottom: 5px; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.song-artist { + color: #666; + font-size: 0.9rem; + margin-bottom: 3px; +} + +.song-album { + color: #888; + font-size: 0.85rem; +} + +.song-meta { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 5px; +} + +.song-duration { + color: #666; + font-size: 0.9rem; +} + +.song-popularity { + background: linear-gradient(135deg, #4CAF50, #66BB6A); + color: white; + padding: 3px 8px; + border-radius: 12px; + font-size: 0.8rem; + font-weight: 600; +} + +/* 返回按钮 */ +.back-to-list { + text-align: center; + margin: 30px 0; +} + +.back-btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 12px 24px; + background: linear-gradient(135deg, #81C784, #A5D6A7); + color: white; + text-decoration: none; + border-radius: 10px; + font-weight: 600; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3); +} + +.back-btn:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4); +} + +/* 页脚 */ +.footer { + text-align: center; + padding: 30px 20px; + background: rgba(255, 255, 255, 0.9); + border-radius: 15px; + margin-top: 40px; + color: #666; + backdrop-filter: blur(10px); +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .container { + padding: 15px; + } + + .title { + font-size: 2rem; + } + + .rank-header { + flex-direction: column; + text-align: center; + } + + .rank-cover { + width: 100px; + height: 100px; + margin: 0 auto 15px; + } + + .input-group { + flex-direction: column; + align-items: stretch; + } + + .input-group label { + min-width: auto; + margin-bottom: 5px; + } + + #rankId { + min-width: auto; + margin-bottom: 10px; + } + + .song-item { + flex-direction: column; + text-align: center; + gap: 10px; + } + + .song-info { + margin-left: 0; + } + + .song-meta { + align-items: center; + flex-direction: row; + justify-content: center; + } + + .list-header { + flex-direction: column; + gap: 10px; + text-align: center; + } +} + +@media (max-width: 480px) { + .title { + font-size: 1.8rem; + } + + .header { + padding: 30px 15px; + } + + .rank-info, .controls, .song-list { + padding: 20px; + } + + .song-item { + padding: 12px; + } +} + +/* 平板端适配 */ +@media (min-width: 769px) and (max-width: 1024px) { + .container { + padding: 25px; + } + + .song-item { + padding: 18px; + } + + .rank-cover { + width: 110px; + height: 110px; + } +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/index.html b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/index.html new file mode 100644 index 00000000..9215b81c --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/index.html @@ -0,0 +1,69 @@ + + + + + + 网易云榜单详情 + + + + +
+
+

🎵 网易云榜单详情

+

发现音乐的魅力

+
+ + + +
+
+ + + +
+
+ + + + + + + + +
+ +
+

© 2025 网易云榜单详情 - 数据来源于官方API

+
+ + + + \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/js/script.js b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/js/script.js new file mode 100644 index 00000000..0ff2eb10 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/js/script.js @@ -0,0 +1,349 @@ +// 网易云榜单详情 JavaScript +class NeteaseMusicRankDetail { + constructor() { + this.apiUrls = []; + this.currentApiIndex = 0; + this.rankData = null; + this.init(); + } + + async init() { + try { + await this.loadApiUrls(); + this.bindEvents(); + this.checkUrlParams(); + } catch (error) { + console.error('初始化失败:', error); + this.showError('初始化失败,请刷新页面重试'); + } + } + + // 加载API接口列表 + async loadApiUrls() { + try { + const response = await fetch('./接口集合.json'); + if (!response.ok) { + throw new Error('无法加载API接口配置'); + } + this.apiUrls = await response.json(); + console.log('API接口加载成功:', this.apiUrls); + } catch (error) { + console.error('加载API接口失败:', error); + // 使用默认接口 + this.apiUrls = [ + 'https://60s-cf.viki.moe', + 'https://60s.viki.moe', + 'https://60s.b23.run', + 'https://60s.114128.xyz', + 'https://60s-cf.114128.xyz' + ]; + } + } + + // 绑定事件 + bindEvents() { + const loadBtn = document.getElementById('loadBtn'); + const rankIdInput = document.getElementById('rankId'); + const retryBtn = document.getElementById('retryBtn'); + + loadBtn.addEventListener('click', () => this.loadRankDetail()); + retryBtn.addEventListener('click', () => this.loadRankDetail()); + + // 回车键加载 + rankIdInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + this.loadRankDetail(); + } + }); + + // 输入验证 + rankIdInput.addEventListener('input', (e) => { + const value = e.target.value.trim(); + loadBtn.disabled = !value || !/^\d+$/.test(value); + }); + } + + // 检查URL参数 + checkUrlParams() { + const urlParams = new URLSearchParams(window.location.search); + const rankId = urlParams.get('id'); + const rankName = urlParams.get('name'); + + if (rankId && /^\d+$/.test(rankId)) { + document.getElementById('rankId').value = rankId; + + // 如果有榜单名称,更新页面标题 + if (rankName) { + document.title = `${decodeURIComponent(rankName)} - 网易云榜单详情`; + document.querySelector('.title').textContent = `🎵 ${decodeURIComponent(rankName)}`; + document.querySelector('.subtitle').textContent = '正在加载榜单详情...'; + } + + this.loadRankDetail(); + } + } + + // 加载榜单详情 + async loadRankDetail() { + const rankId = document.getElementById('rankId').value.trim(); + + if (!rankId) { + this.showError('请输入榜单ID'); + return; + } + + if (!/^\d+$/.test(rankId)) { + this.showError('榜单ID必须是数字'); + return; + } + + this.showLoading(); + this.currentApiIndex = 0; + + try { + const data = await this.fetchRankDetail(rankId); + this.displayRankDetail(data); + this.hideLoading(); + + // 更新URL + const newUrl = new URL(window.location); + newUrl.searchParams.set('id', rankId); + window.history.replaceState({}, '', newUrl); + + } catch (error) { + console.error('加载榜单详情失败:', error); + this.hideLoading(); + this.showError(error.message || '加载失败,请检查榜单ID是否正确'); + } + } + + // 获取榜单详情数据 + async fetchRankDetail(rankId) { + let lastError = null; + + for (let i = 0; i < this.apiUrls.length; i++) { + try { + const apiUrl = this.apiUrls[this.currentApiIndex]; + const url = `${apiUrl}/v2/ncm-rank/${rankId}`; + + console.log(`尝试API ${this.currentApiIndex + 1}:`, url); + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); + + const response = await fetch(url, { + signal: controller.signal, + headers: { + 'Accept': 'application/json', + } + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + if (data.code !== 200) { + throw new Error(data.message || '获取数据失败'); + } + + console.log('API调用成功:', data); + return data; + + } catch (error) { + console.warn(`API ${this.currentApiIndex + 1} 失败:`, error.message); + lastError = error; + this.currentApiIndex = (this.currentApiIndex + 1) % this.apiUrls.length; + + if (error.name === 'AbortError') { + lastError = new Error('请求超时,请重试'); + } + } + } + + throw lastError || new Error('所有API接口都无法访问'); + } + + // 显示榜单详情 + displayRankDetail(data) { + this.rankData = data; + const songs = data.data || []; + + // 显示榜单信息(如果有的话) + this.displayRankInfo(songs[0]); + + // 显示歌曲列表 + this.displaySongList(songs); + + // 显示相关区域 + document.getElementById('songList').style.display = 'block'; + document.getElementById('error').style.display = 'none'; + } + + // 显示榜单信息 + displayRankInfo(firstSong) { + const rankInfo = document.getElementById('rankInfo'); + + if (firstSong && firstSong.rank_name) { + document.getElementById('rankName').textContent = firstSong.rank_name; + document.getElementById('rankDescription').textContent = `${firstSong.rank_name} - 网易云音乐官方榜单`; + + // 如果有专辑封面,使用第一首歌的专辑封面作为榜单封面 + if (firstSong.album && firstSong.album.cover) { + document.getElementById('rankCover').src = firstSong.album.cover; + document.getElementById('rankCover').alt = firstSong.rank_name; + } + + document.getElementById('updateTime').textContent = `更新时间: ${this.formatDate(new Date())}`; + document.getElementById('updateFrequency').textContent = '实时更新'; + + rankInfo.style.display = 'block'; + } else { + rankInfo.style.display = 'none'; + } + } + + // 显示歌曲列表 + displaySongList(songs) { + const songsContainer = document.getElementById('songs'); + const songCount = document.getElementById('songCount'); + + songCount.textContent = `共 ${songs.length} 首歌曲`; + + songsContainer.innerHTML = ''; + + songs.forEach((song, index) => { + const songElement = this.createSongElement(song, index); + songsContainer.appendChild(songElement); + }); + } + + // 创建歌曲元素 + createSongElement(song) { + const songDiv = document.createElement('div'); + songDiv.className = 'song-item'; + + // 处理艺术家信息 + const artists = Array.isArray(song.artist) ? song.artist : [song.artist].filter(Boolean); + const artistNames = artists.map(artist => + typeof artist === 'object' ? artist.name : artist + ).join(', ') || '未知艺术家'; + + // 处理专辑信息 + const albumName = song.album && song.album.name ? song.album.name : '未知专辑'; + + // 处理时长 + const duration = song.duration_desc || this.formatDuration(song.duration); + + // 处理热度 + const popularity = song.popularity || song.score || 0; + + songDiv.innerHTML = ` +
${song.rank}
+
+
${this.escapeHtml(song.title)}
+
${this.escapeHtml(artistNames)}
+
${this.escapeHtml(albumName)}
+
+
+
${duration}
+
${popularity}%
+
+ `; + + // 添加点击事件 + if (song.link) { + songDiv.style.cursor = 'pointer'; + songDiv.addEventListener('click', () => { + window.open(song.link, '_blank'); + }); + } + + return songDiv; + } + + // 格式化时长 + formatDuration(duration) { + if (!duration) return '--:--'; + + const seconds = Math.floor(duration / 1000); + const minutes = Math.floor(seconds / 60); + const remainingSeconds = seconds % 60; + + return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; + } + + // 格式化日期 + formatDate(date) { + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + } + + // HTML转义 + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + // 显示加载状态 + showLoading() { + document.getElementById('loading').style.display = 'block'; + document.getElementById('error').style.display = 'none'; + document.getElementById('songList').style.display = 'none'; + document.getElementById('loadBtn').disabled = true; + } + + // 隐藏加载状态 + hideLoading() { + document.getElementById('loading').style.display = 'none'; + document.getElementById('loadBtn').disabled = false; + } + + // 显示错误信息 + showError(message) { + document.getElementById('error').style.display = 'block'; + document.getElementById('errorMessage').textContent = message; + document.getElementById('loading').style.display = 'none'; + document.getElementById('songList').style.display = 'none'; + document.getElementById('loadBtn').disabled = false; + } +} + +// 全局错误处理 +window.addEventListener('error', (event) => { + console.error('全局错误:', event.error); +}); + +window.addEventListener('unhandledrejection', (event) => { + console.error('未处理的Promise拒绝:', event.reason); +}); + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', () => { + new NeteaseMusicRankDetail(); +}); + +// 添加CSS动画类 +document.addEventListener('DOMContentLoaded', () => { + // 为页面元素添加淡入动画 + const elements = document.querySelectorAll('.container > *'); + elements.forEach((el, index) => { + el.style.opacity = '0'; + el.style.transform = 'translateY(20px)'; + el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; + + setTimeout(() => { + el.style.opacity = '1'; + el.style.transform = 'translateY(0)'; + }, index * 100); + }); +}); \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/接口集合.json b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/接口集合.json new file mode 100644 index 00000000..04e92b7f --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/接口集合.json @@ -0,0 +1,7 @@ +[ + "https://60s-cf.viki.moe", + "https://60s.viki.moe", + "https://60s.b23.run", + "https://60s.114128.xyz", + "https://60s-cf.114128.xyz" +] diff --git a/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/返回接口.json b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/返回接口.json new file mode 100644 index 00000000..c5ed47a3 --- /dev/null +++ b/frontend/react-app/public/60sapi/热搜榜单/网易云榜单详情/返回接口.json @@ -0,0 +1,5612 @@ +{ + "code": 200, + "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", + "data": [ + { + "id": 2040015902, + "rank": 1, + "rank_name": "飙升榜", + "title": "熄灭", + "artist": [ + { + "id": 12324449, + "name": "TC", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12324449" + } + ], + "album": { + "id": 163848123, + "name": "熄灭", + "cover": "http://p1.music.126.net/sNOy5UAdfk_OYumV4qF-0g==/109951168551205771.jpg", + "published": "2023-07-15", + "published_at": 1689436800000, + "company": "" + }, + "duration": 148611, + "duration_desc": "2:28", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 29724874, + "size_desc": "29.72 MB", + "bitrate": 1600134, + "extension": "flac" + }, + "hq": { + "size": 5947603, + "size_desc": "5.95 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3568579, + "size_desc": "3.57 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2379067, + "size_desc": "2.38 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2040015902" + }, + { + "id": 2733008419, + "rank": 2, + "rank_name": "飙升榜", + "title": "LOVE", + "artist": [ + { + "id": 12356808, + "name": "范世錡", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12356808" + } + ], + "album": { + "id": 280422980, + "name": "LOVE,So...", + "cover": "http://p1.music.126.net/BHdtr1R0-yuXLdoY3kJGUg==/109951171697418256.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "天娱传媒" + }, + "duration": 238523, + "duration_desc": "3:58", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 30885411, + "size_desc": "30.89 MB", + "bitrate": 1035740, + "extension": "flac" + }, + "hq": { + "size": 9543405, + "size_desc": "9.54 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5726061, + "size_desc": "5.73 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3817389, + "size_desc": "3.82 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2733008419" + }, + { + "id": 2735554018, + "rank": 3, + "rank_name": "飙升榜", + "title": "拍拍灰", + "artist": [ + { + "id": 30000014, + "name": "脏饼干", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=30000014" + } + ], + "album": { + "id": 281295264, + "name": "拍拍灰", + "cover": "http://p1.music.126.net/4riboo3M7VuJj6We6Sc1xw==/109951171845374025.jpg", + "published": "2025-08-14", + "published_at": 1755187200000, + "company": "" + }, + "duration": 184106, + "duration_desc": "3:04", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 21134984, + "size_desc": "21.13 MB", + "bitrate": 918233, + "extension": "flac" + }, + "hq": { + "size": 7367085, + "size_desc": "7.37 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4420269, + "size_desc": "4.42 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2946861, + "size_desc": "2.95 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2735554018" + }, + { + "id": 2684422547, + "rank": 4, + "rank_name": "飙升榜", + "title": "Money Loves Me", + "artist": [ + { + "id": 97594003, + "name": "Alchemist Harmony", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=97594003" + } + ], + "album": { + "id": 265812259, + "name": "Money Loves Me", + "cover": "http://p1.music.126.net/nKyjr2f050Dl7CD4NUyKCQ==/109951170609858632.jpg", + "published": "2025-03-09", + "published_at": 1741536000000, + "company": "Alchemist Harmony" + }, + "duration": 174000, + "duration_desc": "2:54", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 34717430, + "size_desc": "34.72 MB", + "bitrate": 1596056, + "extension": "flac" + }, + "hq": { + "size": 6962199, + "size_desc": "6.96 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4177337, + "size_desc": "4.18 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2784906, + "size_desc": "2.78 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2684422547" + }, + { + "id": 2677396501, + "rank": 5, + "rank_name": "飙升榜", + "title": "NOT GOOD", + "artist": [ + { + "id": 12563131, + "name": "Rapeter", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12563131" + } + ], + "album": { + "id": 263242113, + "name": "IMGOOD别担心我", + "cover": "http://p1.music.126.net/QpNRZsfMP5J4tOlziA8Pnw==/109951170504642760.jpg", + "published": "2025-02-21", + "published_at": 1740153600000, + "company": "" + }, + "duration": 190558, + "duration_desc": "3:10", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 24001098, + "size_desc": "24 MB", + "bitrate": 1007462, + "extension": "flac" + }, + "hq": { + "size": 7624365, + "size_desc": "7.62 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4574637, + "size_desc": "4.57 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3049773, + "size_desc": "3.05 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2677396501" + }, + { + "id": 405253632, + "rank": 6, + "rank_name": "飙升榜", + "title": "梦回还 (TV size)", + "artist": [ + { + "id": 1215003, + "name": "呦猫UNEKO", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1215003" + } + ], + "album": { + "id": 34513527, + "name": "梦回还", + "cover": "http://p1.music.126.net/hAfIXJP_ZBRQKd1VE_Hqbg==/16625715324173485.jpg", + "published": "2016-03-05", + "published_at": 1457142849504, + "company": "" + }, + "duration": 72456, + "duration_desc": "1:12", + "popularity": 100, + "score": 100, + "fee": 0, + "status": 0, + "mb": { + "sq": null, + "hq": { + "size": 2902769, + "size_desc": "2.9 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 1741679, + "size_desc": "1.74 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1161133, + "size_desc": "1.16 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=405253632" + }, + { + "id": 1975295694, + "rank": 7, + "rank_name": "飙升榜", + "title": "小哑巴", + "artist": [ + { + "id": 48277407, + "name": "BOBBYNOPEACE", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48277407" + } + ], + "album": { + "id": 150299202, + "name": "小哑巴", + "cover": "http://p1.music.126.net/IhsEqn9OXuBYt2_Y8pAgCQ==/109951167815351812.jpg", + "published": "2022-08-27", + "published_at": 1661616000000, + "company": "" + }, + "duration": 171176, + "duration_desc": "2:51", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 17473483, + "size_desc": "17.47 MB", + "bitrate": 816630, + "extension": "flac" + }, + "hq": { + "size": 6849645, + "size_desc": "6.85 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4109805, + "size_desc": "4.11 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2739885, + "size_desc": "2.74 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1975295694" + }, + { + "id": 88926, + "rank": 8, + "rank_name": "飙升榜", + "title": "想你的夜", + "artist": [ + { + "id": 2868, + "name": "关喆", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=2868" + } + ], + "album": { + "id": 8668, + "name": "永远的永远", + "cover": "http://p1.music.126.net/zu9MjBERozqTv_0NpM91Rg==/109951164094037727.jpg", + "published": "2009-07-05", + "published_at": 1246809600000, + "company": "爱贝克思" + }, + "duration": 265960, + "duration_desc": "4:25", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 26941966, + "size_desc": "26.94 MB", + "bitrate": 1411000, + "extension": "flac" + }, + "hq": { + "size": 10641285, + "size_desc": "10.64 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6384788, + "size_desc": "6.38 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4256540, + "size_desc": "4.26 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=88926" + }, + { + "id": 2118740086, + "rank": 9, + "rank_name": "飙升榜", + "title": "黒のバースデイ", + "artist": [ + { + "id": 56525844, + "name": "Ave Mujica", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=56525844" + } + ], + "album": { + "id": 183578899, + "name": "黒のバースデイ", + "cover": "http://p1.music.126.net/0QwEBXfAZ8RzE41vZPlu7A==/109951170223390839.jpg", + "published": "2023-04-10", + "published_at": 1681142400000, + "company": "ブシロードミュージック" + }, + "duration": 225706, + "duration_desc": "3:45", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 31389013, + "size_desc": "31.39 MB", + "bitrate": 1112559, + "extension": "flac" + }, + "hq": { + "size": 9030765, + "size_desc": "9.03 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5418477, + "size_desc": "5.42 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3612333, + "size_desc": "3.61 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2118740086" + }, + { + "id": 2729810172, + "rank": 10, + "rank_name": "飙升榜", + "title": "Montagem Nada Tropic", + "artist": [ + { + "id": 99376836, + "name": "MHM", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=99376836" + } + ], + "album": { + "id": 279515736, + "name": "Montagem Nada Tropic", + "cover": "http://p1.music.126.net/YTA1HZJcLit_QoFfG81puQ==/109951171520378357.jpg", + "published": "2025-07-26", + "published_at": 1753545600000, + "company": "" + }, + "duration": 121997, + "duration_desc": "2:01", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 12718907, + "size_desc": "12.72 MB", + "bitrate": 833893, + "extension": "flac" + }, + "hq": { + "size": 4882852, + "size_desc": "4.88 MB", + "bitrate": 320003, + "extension": "mp3" + }, + "mq": { + "size": 2929729, + "size_desc": "2.93 MB", + "bitrate": 192003, + "extension": "mp3" + }, + "lq": { + "size": 1953167, + "size_desc": "1.95 MB", + "bitrate": 128003, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2729810172" + }, + { + "id": 2734387620, + "rank": 11, + "rank_name": "飙升榜", + "title": "No title -10 Years Later Edition-", + "artist": [ + { + "id": 13059968, + "name": "Reol", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=13059968" + } + ], + "album": { + "id": 280924754, + "name": "“No title” in NIPPON BUDOKAN", + "cover": "http://p1.music.126.net/1OmrYxGKdMGXH_lql-N3iA==/109951171817417918.jpg", + "published": "2025-08-16", + "published_at": 1755360000000, + "company": "索尼音乐" + }, + "duration": 265264, + "duration_desc": "4:25", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 58682245, + "size_desc": "58.68 MB", + "bitrate": 1769624, + "extension": "flac" + }, + "hq": { + "size": 10613072, + "size_desc": "10.61 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6367861, + "size_desc": "6.37 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4245255, + "size_desc": "4.25 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2734387620" + }, + { + "id": 2738501239, + "rank": 12, + "rank_name": "飙升榜", + "title": "七小夕", + "artist": [ + { + "id": 53868079, + "name": "Vvy王泽宇", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=53868079" + } + ], + "album": { + "id": 282255005, + "name": "七小夕", + "cover": "http://p1.music.126.net/EcEdbDFwZS41UcleVx5rAA==/109951171907096312.jpg", + "published": "2025-08-20", + "published_at": 1755705600000, + "company": "" + }, + "duration": 234461, + "duration_desc": "3:54", + "popularity": 100, + "score": 100, + "fee": 0, + "status": 0, + "mb": { + "sq": { + "size": 25150986, + "size_desc": "25.15 MB", + "bitrate": 858023, + "extension": "flac" + }, + "hq": { + "size": 9381138, + "size_desc": "9.38 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5628700, + "size_desc": "5.63 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3752481, + "size_desc": "3.75 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738501239" + }, + { + "id": 2622939350, + "rank": 13, + "rank_name": "飙升榜", + "title": "莆田才子", + "artist": [ + { + "id": 35884195, + "name": "翁杰Winjay", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=35884195" + } + ], + "album": { + "id": 247120411, + "name": "莆田才子", + "cover": "http://p1.music.126.net/quYbskDqRirX3-wqgRLk7A==/109951169934912352.jpg", + "published": "2024-09-06", + "published_at": 1725638400000, + "company": "" + }, + "duration": 150205, + "duration_desc": "2:30", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 17815377, + "size_desc": "17.82 MB", + "bitrate": 948852, + "extension": "flac" + }, + "hq": { + "size": 6010605, + "size_desc": "6.01 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3606381, + "size_desc": "3.61 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2404269, + "size_desc": "2.4 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2622939350" + }, + { + "id": 2737575141, + "rank": 14, + "rank_name": "飙升榜", + "title": "陪你度过漫长岁月", + "artist": [ + { + "id": 58810912, + "name": "赵小童", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=58810912" + } + ], + "album": { + "id": 282015216, + "name": "漫漫协奏曲", + "cover": "http://p1.music.126.net/a0yqXomXz_85AzybTmxBCA==/109951171910165132.jpg", + "published": "2025-08-21", + "published_at": 1755792000000, + "company": "网易·云上" + }, + "duration": 307472, + "duration_desc": "5:07", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 32893926, + "size_desc": "32.89 MB", + "bitrate": 855708, + "extension": "flac" + }, + "hq": { + "size": 12301485, + "size_desc": "12.3 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 7380909, + "size_desc": "7.38 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4920621, + "size_desc": "4.92 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2737575141" + }, + { + "id": 2739871903, + "rank": 15, + "rank_name": "飙升榜", + "title": "路", + "artist": [ + { + "id": 62183661, + "name": "DOMMIU李由音", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=62183661" + } + ], + "album": { + "id": 282846013, + "name": "路", + "cover": "http://p2.music.126.net/RWMmqPsIpY96teLLGPVKqg==/109951171928997751.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "索尼音乐X 深声不息" + }, + "duration": 222890, + "duration_desc": "3:42", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 27957021, + "size_desc": "27.96 MB", + "bitrate": 1003287, + "extension": "flac" + }, + "hq": { + "size": 8918445, + "size_desc": "8.92 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5351085, + "size_desc": "5.35 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3567405, + "size_desc": "3.57 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2739871903" + }, + { + "id": 2161222939, + "rank": 16, + "rank_name": "飙升榜", + "title": "沦陷", + "artist": [ + { + "id": 13005262, + "name": "JuggShots", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=13005262" + } + ], + "album": { + "id": 197781559, + "name": "沦陷", + "cover": "http://p2.music.126.net/ctib5R--oR68W2IrOk765w==/109951169635716223.jpg", + "published": "2024-05-28", + "published_at": 1716912000000, + "company": "" + }, + "duration": 183770, + "duration_desc": "3:03", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 22189011, + "size_desc": "22.19 MB", + "bitrate": 965943, + "extension": "flac" + }, + "hq": { + "size": 7353645, + "size_desc": "7.35 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4412205, + "size_desc": "4.41 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2941485, + "size_desc": "2.94 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2161222939" + }, + { + "id": 26093064, + "rank": 17, + "rank_name": "飙升榜", + "title": "Sacred Play Secret Place", + "artist": [ + { + "id": 12283, + "name": "Matryoshka", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12283" + } + ], + "album": { + "id": 2386118, + "name": "Laideronnette", + "cover": "http://p2.music.126.net/1opYZaMgfAQrKMKfLy1xZA==/109951169789816801.jpg", + "published": "2012-12-11", + "published_at": 1355241600000, + "company": "Virgin Babylon Records" + }, + "duration": 317547, + "duration_desc": "5:17", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 30171985, + "size_desc": "30.17 MB", + "bitrate": 760124, + "extension": "flac" + }, + "hq": { + "size": 12704958, + "size_desc": "12.7 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 7622992, + "size_desc": "7.62 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 5082009, + "size_desc": "5.08 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=26093064" + }, + { + "id": 2081549596, + "rank": 18, + "rank_name": "飙升榜", + "title": "下次见", + "artist": [ + { + "id": 55305505, + "name": "林心念", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=55305505" + } + ], + "album": { + "id": 174605542, + "name": "下次见", + "cover": "http://p2.music.126.net/g6STNqcm32HjAm4CpoJcBg==/109951168910388635.jpg", + "published": "2023-09-15", + "published_at": 1694793600000, + "company": "讯飞音乐" + }, + "duration": 159375, + "duration_desc": "2:39", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 17672725, + "size_desc": "17.67 MB", + "bitrate": 887101, + "extension": "flac" + }, + "hq": { + "size": 6377325, + "size_desc": "6.38 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3826413, + "size_desc": "3.83 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2550957, + "size_desc": "2.55 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2081549596" + }, + { + "id": 1894316939, + "rank": 19, + "rank_name": "飙升榜", + "title": "最渣男主角", + "artist": [ + { + "id": 12292664, + "name": "Shooter", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12292664" + }, + { + "id": 30003804, + "name": "404 RAPPER", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=30003804" + } + ], + "album": { + "id": 136039945, + "name": "最渣男主角", + "cover": "http://p2.music.126.net/9UTbTz8efieRMQvnaoJRwQ==/109951166612306430.jpg", + "published": "2021-11-11", + "published_at": 1636646400000, + "company": "" + }, + "duration": 203664, + "duration_desc": "3:23", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 20614401, + "size_desc": "20.61 MB", + "bitrate": 809738, + "extension": "flac" + }, + "hq": { + "size": 8149485, + "size_desc": "8.15 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4889709, + "size_desc": "4.89 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3259821, + "size_desc": "3.26 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1894316939" + }, + { + "id": 2740938171, + "rank": 20, + "rank_name": "飙升榜", + "title": "须臾Karios(栩渝同人曲)", + "artist": [ + { + "id": 33696439, + "name": "周冠宏", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=33696439" + }, + { + "id": 34270051, + "name": "赵春寒Z&Hanl", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=34270051" + } + ], + "album": { + "id": 283152840, + "name": "须臾Karios(栩渝同人曲)", + "cover": "http://p2.music.126.net/s28QYI-yCjr2kHRGVsrr2g==/109951171943770807.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "" + }, + "duration": 246342, + "duration_desc": "4:06", + "popularity": 100, + "score": 100, + "fee": 0, + "status": 0, + "mb": { + "sq": { + "size": 32856508, + "size_desc": "32.86 MB", + "bitrate": 1066872, + "extension": "flac" + }, + "hq": { + "size": 9856365, + "size_desc": "9.86 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5913837, + "size_desc": "5.91 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3942573, + "size_desc": "3.94 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740938171" + }, + { + "id": 2738228860, + "rank": 21, + "rank_name": "飙升榜", + "title": "Dehors (普通话版)", + "artist": [ + { + "id": 338718, + "name": "JORDANN", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=338718" + } + ], + "album": { + "id": 282257834, + "name": "Dehors (普通话版)", + "cover": "http://p2.music.126.net/8mNbLer5tKnkgj3Q4JPpWw==/109951171903070287.jpg", + "published": "2025-08-21", + "published_at": 1755792000000, + "company": "JORDANN" + }, + "duration": 198026, + "duration_desc": "3:18", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 20334981, + "size_desc": "20.33 MB", + "bitrate": 821356, + "extension": "flac" + }, + "hq": { + "size": 7923885, + "size_desc": "7.92 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4754349, + "size_desc": "4.75 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3169581, + "size_desc": "3.17 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738228860" + }, + { + "id": 2710416778, + "rank": 22, + "rank_name": "飙升榜", + "title": "Long term", + "artist": [ + { + "id": 94359653, + "name": "AI MUSIC MATRIX", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=94359653" + } + ], + "album": { + "id": 273690835, + "name": "Relax R&B 76", + "cover": "http://p2.music.126.net/p8hySF3PjpGyEdExUAocCw==/109951171182041062.jpg", + "published": "2025-05-30", + "published_at": 1748620800000, + "company": "Sound Matrix" + }, + "duration": 189960, + "duration_desc": "3:09", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 14200860, + "size_desc": "14.2 MB", + "bitrate": 597909, + "extension": "flac" + }, + "hq": { + "size": 7600631, + "size_desc": "7.6 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4560396, + "size_desc": "4.56 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3040279, + "size_desc": "3.04 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2710416778" + }, + { + "id": 2038203229, + "rank": 23, + "rank_name": "飙升榜", + "title": "FRIDAY9 II", + "artist": [ + { + "id": 28642672, + "name": "kkluv", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=28642672" + } + ], + "album": { + "id": 163444153, + "name": "FRIDAY9 II", + "cover": "http://p2.music.126.net/TAz4QuITFBhN4D1xsiq0kg==/109951168538063565.jpg", + "published": "2023-01-17", + "published_at": 1673971200000, + "company": "索尼音乐" + }, + "duration": 166285, + "duration_desc": "2:46", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 32263929, + "size_desc": "32.26 MB", + "bitrate": 1552216, + "extension": "flac" + }, + "hq": { + "size": 6653954, + "size_desc": "6.65 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3992390, + "size_desc": "3.99 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2661608, + "size_desc": "2.66 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2038203229" + }, + { + "id": 2740641241, + "rank": 24, + "rank_name": "飙升榜", + "title": "归舟", + "artist": [ + { + "id": 9491, + "name": "谭晶", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=9491" + }, + { + "id": 53926051, + "name": "燕云十六声", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=53926051" + } + ], + "album": { + "id": 283122508, + "name": "归舟", + "cover": "http://p2.music.126.net/gWQj5VbaDK8kUvJS3uOl2g==/109951171939389473.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "" + }, + "duration": 301006, + "duration_desc": "5:01", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 35503109, + "size_desc": "35.5 MB", + "bitrate": 943436, + "extension": "flac" + }, + "hq": { + "size": 12042285, + "size_desc": "12.04 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 7225389, + "size_desc": "7.23 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 4816941, + "size_desc": "4.82 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740641241" + }, + { + "id": 2604224368, + "rank": 25, + "rank_name": "飙升榜", + "title": "São Paulo", + "artist": [ + { + "id": 30384202, + "name": "Fyex", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=30384202" + } + ], + "album": { + "id": 240979251, + "name": "São Paulo", + "cover": "http://p2.music.126.net/aGGl_ANW0kVZzfJMtmLR9Q==/109951169743205693.jpg", + "published": "2024-06-06", + "published_at": 1717689600000, + "company": "Fyex" + }, + "duration": 97850, + "duration_desc": "1:37", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 9831272, + "size_desc": "9.83 MB", + "bitrate": 803775, + "extension": "flac" + }, + "hq": { + "size": 3916321, + "size_desc": "3.92 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 2349810, + "size_desc": "2.35 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1566555, + "size_desc": "1.57 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2604224368" + }, + { + "id": 2738715964, + "rank": 26, + "rank_name": "飙升榜", + "title": "染春", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p2.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 206094, + "duration_desc": "3:26", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 23766803, + "size_desc": "23.77 MB", + "bitrate": 922409, + "extension": "flac" + }, + "hq": { + "size": 8246445, + "size_desc": "8.25 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4947885, + "size_desc": "4.95 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3298605, + "size_desc": "3.3 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738715964" + }, + { + "id": 2716412355, + "rank": 27, + "rank_name": "飙升榜", + "title": "Supra", + "artist": [ + { + "id": 52410166, + "name": "泰格西", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=52410166" + }, + { + "id": 32438941, + "name": "cLoner23", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=32438941" + } + ], + "album": { + "id": 275450408, + "name": "Block Core", + "cover": "http://p2.music.126.net/w6MAd3zX38cPTkB9v9aMZg==/109951171319396818.jpg", + "published": "2025-06-17", + "published_at": 1750176000000, + "company": "" + }, + "duration": 126666, + "duration_desc": "2:06", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 15475009, + "size_desc": "15.48 MB", + "bitrate": 977219, + "extension": "flac" + }, + "hq": { + "size": 5068845, + "size_desc": "5.07 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3041325, + "size_desc": "3.04 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2027565, + "size_desc": "2.03 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2716412355" + }, + { + "id": 109196, + "rank": 28, + "rank_name": "飙升榜", + "title": "想太多", + "artist": [ + { + "id": 3689, + "name": "李玖哲", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=3689" + } + ], + "album": { + "id": 10826, + "name": "想太多", + "cover": "http://p2.music.126.net/rseQHt6MVwmyLMpY_f5bOQ==/131941395346293.jpg", + "published": "2007-10-11", + "published_at": 1192118400000, + "company": "华纳音乐" + }, + "duration": 216613, + "duration_desc": "3:36", + "popularity": 100, + "score": 100, + "fee": 0, + "status": 0, + "mb": { + "sq": { + "size": 23196782, + "size_desc": "23.2 MB", + "bitrate": 856705, + "extension": "flac" + }, + "hq": { + "size": 8667472, + "size_desc": "8.67 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5200501, + "size_desc": "5.2 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3467015, + "size_desc": "3.47 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=109196" + }, + { + "id": 167942, + "rank": 29, + "rank_name": "飙升榜", + "title": "王妃", + "artist": [ + { + "id": 5768, + "name": "萧敬腾", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=5768" + } + ], + "album": { + "id": 16961, + "name": "王妃", + "cover": "http://p2.music.126.net/Ewy0QAwwv6gXxszRn1KNpQ==/109951168271412207.jpg", + "published": "2009-07-16", + "published_at": 1247760000000, + "company": "华纳音乐" + }, + "duration": 221760, + "duration_desc": "3:41", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 29095408, + "size_desc": "29.1 MB", + "bitrate": 1049617, + "extension": "flac" + }, + "hq": { + "size": 8873317, + "size_desc": "8.87 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5324008, + "size_desc": "5.32 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3549353, + "size_desc": "3.55 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=167942" + }, + { + "id": 2738583947, + "rank": 30, + "rank_name": "飙升榜", + "title": "Happy Hare", + "artist": [ + { + "id": 97654074, + "name": "X Chamber", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=97654074" + } + ], + "album": { + "id": 282405671, + "name": "Happy Hare", + "cover": "http://p2.music.126.net/ctQm9kmi8CjooxADvLyMQA==/109951171908403517.jpg", + "published": "2025-08-20", + "published_at": 1755705600000, + "company": "" + }, + "duration": 96190, + "duration_desc": "1:36", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 20048170, + "size_desc": "20.05 MB", + "bitrate": 1667227, + "extension": "flac" + }, + "hq": { + "size": 3850493, + "size_desc": "3.85 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 2310313, + "size_desc": "2.31 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1540223, + "size_desc": "1.54 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738583947" + }, + { + "id": 2735962127, + "rank": 31, + "rank_name": "飙升榜", + "title": "放大", + "artist": [ + { + "id": 49844742, + "name": "徐子未", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=49844742" + } + ], + "album": { + "id": 281446148, + "name": "放大", + "cover": "http://p2.music.126.net/WBbtAlKQBRgItkpbzUXa1w==/109951171856097610.jpg", + "published": "2025-08-15", + "published_at": 1755273600000, + "company": "索尼音乐" + }, + "duration": 205200, + "duration_desc": "3:25", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 23835315, + "size_desc": "23.84 MB", + "bitrate": 929104, + "extension": "flac" + }, + "hq": { + "size": 8209965, + "size_desc": "8.21 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4925997, + "size_desc": "4.93 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3284013, + "size_desc": "3.28 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2735962127" + }, + { + "id": 2738719308, + "rank": 32, + "rank_name": "飙升榜", + "title": "骑士", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p2.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 205376, + "duration_desc": "3:25", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 24969418, + "size_desc": "24.97 MB", + "bitrate": 972482, + "extension": "flac" + }, + "hq": { + "size": 8217645, + "size_desc": "8.22 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4930605, + "size_desc": "4.93 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3287085, + "size_desc": "3.29 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738719308" + }, + { + "id": 2162160807, + "rank": 33, + "rank_name": "飙升榜", + "title": "NEXT!", + "artist": [ + { + "id": 54842340, + "name": "NCTS", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=54842340" + } + ], + "album": { + "id": 198075556, + "name": "NEXT!", + "cover": "http://p2.music.126.net/W4C4eI4EAE4dXwtZAeZv8Q==/109951169644186817.jpg", + "published": "2024-06-06", + "published_at": 1717689600000, + "company": "broke" + }, + "duration": 99692, + "duration_desc": "1:39", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 12133996, + "size_desc": "12.13 MB", + "bitrate": 973715, + "extension": "flac" + }, + "hq": { + "size": 3990509, + "size_desc": "3.99 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 2394323, + "size_desc": "2.39 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1596230, + "size_desc": "1.6 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2162160807" + }, + { + "id": 2099778087, + "rank": 34, + "rank_name": "飙升榜", + "title": "发迹", + "artist": [ + { + "id": 49141872, + "name": "Top Barry", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=49141872" + } + ], + "album": { + "id": 179034955, + "name": "发迹", + "cover": "http://p2.music.126.net/WKf8wp_58LjK2I2EA1gKjQ==/109951169055625483.jpg", + "published": "2023-11-14", + "published_at": 1699977600000, + "company": "" + }, + "duration": 162304, + "duration_desc": "2:42", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 16266288, + "size_desc": "16.27 MB", + "bitrate": 801764, + "extension": "flac" + }, + "hq": { + "size": 6494445, + "size_desc": "6.49 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3896685, + "size_desc": "3.9 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2597805, + "size_desc": "2.6 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2099778087" + }, + { + "id": 2738719309, + "rank": 35, + "rank_name": "飙升榜", + "title": "梦蝶", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p2.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 239939, + "duration_desc": "3:59", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 32723142, + "size_desc": "32.72 MB", + "bitrate": 1090898, + "extension": "flac" + }, + "hq": { + "size": 9600045, + "size_desc": "9.6 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5760045, + "size_desc": "5.76 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3840045, + "size_desc": "3.84 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738719309" + }, + { + "id": 2740511420, + "rank": 36, + "rank_name": "飙升榜", + "title": "WANTCHU (94bpm)", + "artist": [ + { + "id": 12544511, + "name": "keshi", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12544511" + } + ], + "album": { + "id": 283084927, + "name": "WANTCHU (94bpm)", + "cover": "http://p2.music.126.net/6EQM-q53CjlapnKMTOSyKQ==/109951171937786942.jpg", + "published": "2025-08-26", + "published_at": 1756224000000, + "company": "Island Records" + }, + "duration": 254873, + "duration_desc": "4:14", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 29015872, + "size_desc": "29.02 MB", + "bitrate": 910607, + "extension": "flac" + }, + "hq": { + "size": 10197203, + "size_desc": "10.2 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6118339, + "size_desc": "6.12 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4078907, + "size_desc": "4.08 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740511420" + }, + { + "id": 2729743751, + "rank": 37, + "rank_name": "飙升榜", + "title": "Dreamin", + "artist": [ + { + "id": 51253492, + "name": "穆祉丞", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=51253492" + } + ], + "album": { + "id": 279543769, + "name": "Dreamin", + "cover": "http://p2.music.126.net/X0NUwa8wMffZGXoPZtNpsA==/109951171517669783.jpg", + "published": "2025-07-27", + "published_at": 1753632000000, + "company": "北京时代峰峻文化艺术发展有限公司" + }, + "duration": 136944, + "duration_desc": "2:16", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 19166561, + "size_desc": "19.17 MB", + "bitrate": 1119520, + "extension": "flac" + }, + "hq": { + "size": 5480685, + "size_desc": "5.48 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3288429, + "size_desc": "3.29 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2192301, + "size_desc": "2.19 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2729743751" + }, + { + "id": 2729689943, + "rank": 38, + "rank_name": "飙升榜", + "title": "为时已晚(越大越觉孤单)", + "artist": [ + { + "id": 58568204, + "name": "管小天", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=58568204" + } + ], + "album": { + "id": 279534034, + "name": "为时已晚", + "cover": "http://p2.music.126.net/xSs5l9BWlKJGqXdH3SW_oA==/109951171516866306.jpg", + "published": "2025-07-24", + "published_at": 1753372800000, + "company": "看见音乐" + }, + "duration": 204218, + "duration_desc": "3:24", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 18189938, + "size_desc": "18.19 MB", + "bitrate": 712421, + "extension": "flac" + }, + "hq": { + "size": 8171146, + "size_desc": "8.17 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4902705, + "size_desc": "4.9 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3268484, + "size_desc": "3.27 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2729689943" + }, + { + "id": 2736196294, + "rank": 39, + "rank_name": "飙升榜", + "title": "你啊你,我的心", + "artist": [ + { + "id": 37092139, + "name": "babychair", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=37092139" + }, + { + "id": 12789956, + "name": "陈婧霏", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12789956" + } + ], + "album": { + "id": 281535136, + "name": "你啊你,我的心", + "cover": "http://p2.music.126.net/zWRB5KYDrulefgh_FVzIfw==/109951171865682128.jpg", + "published": "2025-08-18", + "published_at": 1755532800000, + "company": "网易云音乐|网易音乐人 x 中国数字音乐基地" + }, + "duration": 199621, + "duration_desc": "3:19", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 17022552, + "size_desc": "17.02 MB", + "bitrate": 682047, + "extension": "flac" + }, + "hq": { + "size": 7987245, + "size_desc": "7.99 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4792365, + "size_desc": "4.79 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3194925, + "size_desc": "3.19 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2736196294" + }, + { + "id": 27955654, + "rank": 40, + "rank_name": "飙升榜", + "title": "其实", + "artist": [ + { + "id": 5781, + "name": "薛之谦", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=5781" + } + ], + "album": { + "id": 2681139, + "name": "意外", + "cover": "http://p2.music.126.net/ywVjRpbu9KpcBQh9KJz2HA==/109951164499974026.jpg", + "published": "2013-11-10", + "published_at": 1384099200000, + "company": "潮石音乐" + }, + "duration": 242146, + "duration_desc": "4:02", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 23339701, + "size_desc": "23.34 MB", + "bitrate": 771093, + "extension": "flac" + }, + "hq": { + "size": 9688338, + "size_desc": "9.69 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 5813020, + "size_desc": "5.81 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3875361, + "size_desc": "3.88 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=27955654" + }, + { + "id": 2738459901, + "rank": 41, + "rank_name": "飙升榜", + "title": "空心人札记", + "artist": [ + { + "id": 98856697, + "name": "Calia-林焰", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=98856697" + }, + { + "id": 12046092, + "name": "星尘", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12046092" + } + ], + "album": { + "id": 282297325, + "name": "空心人札记", + "cover": "http://p2.music.126.net/7pZP5egJfBxAnJ1xZNdhXg==/109951171906929489.jpg", + "published": "2025-08-19", + "published_at": 1755619200000, + "company": "" + }, + "duration": 178909, + "duration_desc": "2:58", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 22224636, + "size_desc": "22.22 MB", + "bitrate": 993636, + "extension": "flac" + }, + "hq": { + "size": 7158765, + "size_desc": "7.16 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4295277, + "size_desc": "4.3 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2863533, + "size_desc": "2.86 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738459901" + }, + { + "id": 2721839629, + "rank": 42, + "rank_name": "飙升榜", + "title": "Velvet Horizon/天鹅绒地平线", + "artist": [ + { + "id": 97183508, + "name": "朱砂未央", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=97183508" + } + ], + "album": { + "id": 275635771, + "name": "Eternal Echoes", + "cover": "http://p2.music.126.net/RxQ2ueBidRYZBCtQTXJdLw==/109951171331877000.jpg", + "published": "2025-06-18", + "published_at": 1750262400000, + "company": "" + }, + "duration": 203149, + "duration_desc": "3:23", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 20906818, + "size_desc": "20.91 MB", + "bitrate": 823160, + "extension": "flac" + }, + "hq": { + "size": 8128365, + "size_desc": "8.13 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4877037, + "size_desc": "4.88 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3251373, + "size_desc": "3.25 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2721839629" + }, + { + "id": 63574, + "rank": 43, + "rank_name": "飙升榜", + "title": "背叛", + "artist": [ + { + "id": 2110, + "name": "曹格", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=2110" + } + ], + "album": { + "id": 6295, + "name": "Superman", + "cover": "http://p2.music.126.net/eDinSMXNYMZHP9nAZ_sQkw==/48378511634444.jpg", + "published": "2006-12-26", + "published_at": 1167148800000, + "company": "滚石唱片" + }, + "duration": 321629, + "duration_desc": "5:21", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 34294620, + "size_desc": "34.29 MB", + "bitrate": 853022, + "extension": "flac" + }, + "hq": { + "size": 12867962, + "size_desc": "12.87 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 7720795, + "size_desc": "7.72 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 5147211, + "size_desc": "5.15 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=63574" + }, + { + "id": 2738719310, + "rank": 44, + "rank_name": "飙升榜", + "title": "福寿螺", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p2.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 171106, + "duration_desc": "2:51", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 22295052, + "size_desc": "22.3 MB", + "bitrate": 1042244, + "extension": "flac" + }, + "hq": { + "size": 6846765, + "size_desc": "6.85 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4108077, + "size_desc": "4.11 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2738733, + "size_desc": "2.74 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738719310" + }, + { + "id": 2730270719, + "rank": 45, + "rank_name": "飙升榜", + "title": "Hollow", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p2.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 360000, + "duration_desc": "6:00", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 44161333, + "size_desc": "44.16 MB", + "bitrate": 981217, + "extension": "flac" + }, + "hq": { + "size": 14401965, + "size_desc": "14.4 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 8641197, + "size_desc": "8.64 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 5760813, + "size_desc": "5.76 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730270719" + }, + { + "id": 2738719307, + "rank": 46, + "rank_name": "飙升榜", + "title": "降临", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p2.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 330139, + "duration_desc": "5:30", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 41595472, + "size_desc": "41.6 MB", + "bitrate": 1007803, + "extension": "flac" + }, + "hq": { + "size": 13207725, + "size_desc": "13.21 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 7924653, + "size_desc": "7.92 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 5283117, + "size_desc": "5.28 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738719307" + }, + { + "id": 2730270717, + "rank": 47, + "rank_name": "飙升榜", + "title": "隐藏(Hide)", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p1.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 306000, + "duration_desc": "5:06", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 31438598, + "size_desc": "31.44 MB", + "bitrate": 821778, + "extension": "flac" + }, + "hq": { + "size": 12241965, + "size_desc": "12.24 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 7345197, + "size_desc": "7.35 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 4896813, + "size_desc": "4.9 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730270717" + }, + { + "id": 413812470, + "rank": 48, + "rank_name": "飙升榜", + "title": "One More Time", + "artist": [ + { + "id": 29959, + "name": "Craig David", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=29959" + } + ], + "album": { + "id": 34701579, + "name": "One More Time", + "cover": "http://p1.music.126.net/yGOnOKbJYXd7O_h0Ns_W_w==/1390882218000288.jpg", + "published": "2016-05-19", + "published_at": 1463673600007, + "company": "索尼音乐" + }, + "duration": 194520, + "duration_desc": "3:14", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 40301209, + "size_desc": "40.3 MB", + "bitrate": 1657462, + "extension": "flac" + }, + "hq": { + "size": 7783489, + "size_desc": "7.78 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4670111, + "size_desc": "4.67 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3113422, + "size_desc": "3.11 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=413812470" + }, + { + "id": 2740182817, + "rank": 49, + "rank_name": "飙升榜", + "title": "暗码", + "artist": [ + { + "id": 12236269, + "name": "高天佐", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12236269" + }, + { + "id": 12085066, + "name": "ZIV", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12085066" + } + ], + "album": { + "id": 282953625, + "name": "暗码", + "cover": "http://p1.music.126.net/zUqNfcfmNePSEazkOt9KXg==/109951171933460415.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "" + }, + "duration": 186838, + "duration_desc": "3:06", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 22486402, + "size_desc": "22.49 MB", + "bitrate": 962670, + "extension": "flac" + }, + "hq": { + "size": 7475565, + "size_desc": "7.48 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4485357, + "size_desc": "4.49 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2990253, + "size_desc": "2.99 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740182817" + }, + { + "id": 2735983727, + "rank": 50, + "rank_name": "飙升榜", + "title": "光影戒断反应.wav", + "artist": [ + { + "id": 99613013, + "name": "云落", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=99613013" + } + ], + "album": { + "id": 281406500, + "name": "光影戒断反应", + "cover": "http://p1.music.126.net/BZYzH0ODE-ypCtJvC6_x7w==/109951171857042141.jpg", + "published": "2025-08-12", + "published_at": 1755014400000, + "company": "" + }, + "duration": 275439, + "duration_desc": "4:35", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 31477192, + "size_desc": "31.48 MB", + "bitrate": 914091, + "extension": "flac" + }, + "hq": { + "size": 11019885, + "size_desc": "11.02 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6611949, + "size_desc": "6.61 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4407981, + "size_desc": "4.41 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2735983727" + }, + { + "id": 2738715963, + "rank": 51, + "rank_name": "飙升榜", + "title": "宝藏", + "artist": [ + { + "id": 27730224, + "name": "回春丹", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27730224" + } + ], + "album": { + "id": 282452357, + "name": "大把时间璀璨", + "cover": "http://p1.music.126.net/_gJgbfqTgWH2T1vk1Br1ig==/109951171911478103.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "池沼版全" + }, + "duration": 174001, + "duration_desc": "2:54", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 23432952, + "size_desc": "23.43 MB", + "bitrate": 1077220, + "extension": "flac" + }, + "hq": { + "size": 6962925, + "size_desc": "6.96 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4177773, + "size_desc": "4.18 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2785197, + "size_desc": "2.79 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738715963" + }, + { + "id": 2730600192, + "rank": 52, + "rank_name": "飙升榜", + "title": "Out of my system", + "artist": [ + { + "id": 95288932, + "name": "Nia Nkuna", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=95288932" + } + ], + "album": { + "id": 279776498, + "name": "Mixed signals", + "cover": "http://p1.music.126.net/ulsDcoiZogmbQ96YccOp3g==/109951171529990940.jpg", + "published": "2025-08-06", + "published_at": 1754496000000, + "company": "7296470 Records DK2" + }, + "duration": 211039, + "duration_desc": "3:31", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 26480510, + "size_desc": "26.48 MB", + "bitrate": 1003662, + "extension": "flac" + }, + "hq": { + "size": 8444205, + "size_desc": "8.44 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 5066541, + "size_desc": "5.07 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3377709, + "size_desc": "3.38 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730600192" + }, + { + "id": 2739853860, + "rank": 53, + "rank_name": "飙升榜", + "title": "幻想彼岸", + "artist": [ + { + "id": 95441940, + "name": "Tekoo", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=95441940" + }, + { + "id": 29303235, + "name": "PSY.P", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=29303235" + } + ], + "album": { + "id": 282839523, + "name": "幻想彼岸", + "cover": "http://p1.music.126.net/Gi4zmlg7bemQ7_TG5QLI0w==/109951171928760549.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "" + }, + "duration": 154532, + "duration_desc": "2:34", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 15954957, + "size_desc": "15.95 MB", + "bitrate": 825824, + "extension": "flac" + }, + "hq": { + "size": 6183405, + "size_desc": "6.18 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3710061, + "size_desc": "3.71 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2473389, + "size_desc": "2.47 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2739853860" + }, + { + "id": 2715139032, + "rank": 54, + "rank_name": "飙升榜", + "title": "Got It Now (Phonk)", + "artist": [ + { + "id": 52436538, + "name": "YaKio", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=52436538" + }, + { + "id": 96953508, + "name": "Wehti", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=96953508" + }, + { + "id": 48853047, + "name": "VZEUS", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48853047" + }, + { + "id": 48855131, + "name": "离离离", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48855131" + } + ], + "album": { + "id": 275048395, + "name": "Got It Now (Phonk)", + "cover": "http://p1.music.126.net/zmottkLtPAA6_xz4ywWXhA==/109951171301374976.jpg", + "published": "2025-06-12", + "published_at": 1749744000000, + "company": "" + }, + "duration": 113170, + "duration_desc": "1:53", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 13958890, + "size_desc": "13.96 MB", + "bitrate": 986598, + "extension": "flac" + }, + "hq": { + "size": 4529676, + "size_desc": "4.53 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 2717823, + "size_desc": "2.72 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1811897, + "size_desc": "1.81 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2715139032" + }, + { + "id": 2730268845, + "rank": 55, + "rank_name": "飙升榜", + "title": "Intro", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p1.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 122000, + "duration_desc": "2:02", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 11610545, + "size_desc": "11.61 MB", + "bitrate": 761197, + "extension": "flac" + }, + "hq": { + "size": 4882605, + "size_desc": "4.88 MB", + "bitrate": 320003, + "extension": "mp3" + }, + "mq": { + "size": 2929581, + "size_desc": "2.93 MB", + "bitrate": 192003, + "extension": "mp3" + }, + "lq": { + "size": 1953069, + "size_desc": "1.95 MB", + "bitrate": 128003, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730268845" + }, + { + "id": 2730268846, + "rank": 56, + "rank_name": "飙升榜", + "title": "Forlorn Hope", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p1.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 371000, + "duration_desc": "6:11", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 47693449, + "size_desc": "47.69 MB", + "bitrate": 1028284, + "extension": "flac" + }, + "hq": { + "size": 14842605, + "size_desc": "14.84 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 8905581, + "size_desc": "8.91 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 5937069, + "size_desc": "5.94 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730268846" + }, + { + "id": 2739834858, + "rank": 57, + "rank_name": "飙升榜", + "title": "调色板", + "artist": [ + { + "id": 37334229, + "name": "Sasuke", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=37334229" + } + ], + "album": { + "id": 282832994, + "name": "调色板", + "cover": "http://p1.music.126.net/F2fIIywgZ-U8-jGQnlWj-A==/109951171928465892.jpg", + "published": "2025-08-25", + "published_at": 1756137600000, + "company": "" + }, + "duration": 176206, + "duration_desc": "2:56", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 21253895, + "size_desc": "21.25 MB", + "bitrate": 964805, + "extension": "flac" + }, + "hq": { + "size": 7050285, + "size_desc": "7.05 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4230189, + "size_desc": "4.23 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2820141, + "size_desc": "2.82 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2739834858" + }, + { + "id": 2605650585, + "rank": 58, + "rank_name": "飙升榜", + "title": "Baigasai 想要有你在", + "artist": [ + { + "id": 31001926, + "name": "Bohbat", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=31001926" + }, + { + "id": 94228106, + "name": "Suie", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=94228106" + }, + { + "id": 34279887, + "name": "布和都古仁", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=34279887" + } + ], + "album": { + "id": 241400517, + "name": "Baigasai(想要有你在)", + "cover": "http://p1.music.126.net/zA3k1aD3PRCDnmSI9zDqsw==/109951169757659301.jpg", + "published": "2024-07-06", + "published_at": 1720281600000, + "company": "" + }, + "duration": 170623, + "duration_desc": "2:50", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 17200040, + "size_desc": "17.2 MB", + "bitrate": 806455, + "extension": "flac" + }, + "hq": { + "size": 6827565, + "size_desc": "6.83 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4096557, + "size_desc": "4.1 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2731053, + "size_desc": "2.73 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2605650585" + }, + { + "id": 2730270720, + "rank": 59, + "rank_name": "飙升榜", + "title": "季风(Monsoon)", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p1.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 279500, + "duration_desc": "4:39", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 34576225, + "size_desc": "34.58 MB", + "bitrate": 989513, + "extension": "flac" + }, + "hq": { + "size": 11182125, + "size_desc": "11.18 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6709293, + "size_desc": "6.71 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4472877, + "size_desc": "4.47 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730270720" + }, + { + "id": 167655, + "rank": 60, + "rank_name": "飙升榜", + "title": "幻听", + "artist": [ + { + "id": 5771, + "name": "许嵩", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=5771" + } + ], + "album": { + "id": 16932, + "name": "梦游计", + "cover": "http://p1.music.126.net/IYgyEjL7w4xwPfyNDw8OzA==/109951169525619688.jpg", + "published": "2012-07-10", + "published_at": 1341936000000, + "company": "海蝶" + }, + "duration": 273266, + "duration_desc": "4:33", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 26751365, + "size_desc": "26.75 MB", + "bitrate": 783157, + "extension": "flac" + }, + "hq": { + "size": 10932811, + "size_desc": "10.93 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6559704, + "size_desc": "6.56 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4373151, + "size_desc": "4.37 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=167655" + }, + { + "id": 642723, + "rank": 61, + "rank_name": "飙升榜", + "title": "17", + "artist": [ + { + "id": 17635, + "name": "椎名林檎", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=17635" + } + ], + "album": { + "id": 61637, + "name": "罪と罰", + "cover": "http://p1.music.126.net/W3zh73z9SEOVx4IugvgQ-g==/109951163318826464.jpg", + "published": "2000-01-25", + "published_at": 948816000000, + "company": "Universal Music LLC" + }, + "duration": 272625, + "duration_desc": "4:32", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 59365794, + "size_desc": "59.37 MB", + "bitrate": 1742046, + "extension": "flac" + }, + "hq": { + "size": 10907733, + "size_desc": "10.91 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6544657, + "size_desc": "6.54 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4363119, + "size_desc": "4.36 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=642723" + }, + { + "id": 429348598, + "rank": 62, + "rank_name": "飙升榜", + "title": "沦陷", + "artist": [ + { + "id": 1081293, + "name": "李嘉格", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1081293" + } + ], + "album": { + "id": 34841497, + "name": "四格", + "cover": "http://p1.music.126.net/svLJT1S1O0DXHRIghiuJyg==/18599338695655987.jpg", + "published": "2016-03-01", + "published_at": 1456848000000, + "company": "梦响当然" + }, + "duration": 258933, + "duration_desc": "4:18", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 30269959, + "size_desc": "30.27 MB", + "bitrate": 935220, + "extension": "flac" + }, + "hq": { + "size": 10360207, + "size_desc": "10.36 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6216142, + "size_desc": "6.22 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4144109, + "size_desc": "4.14 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=429348598" + }, + { + "id": 2678794854, + "rank": 63, + "rank_name": "飙升榜", + "title": "MISERICÓRDIA GALLARDO", + "artist": [ + { + "id": 34342469, + "name": "Prompto", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=34342469" + } + ], + "album": { + "id": 264022495, + "name": "MISERICÓRDIA GALLARDO", + "cover": "http://p1.music.126.net/JJYwOODi3m-YkPwAXeeiFA==/109951170518532282.jpg", + "published": "2025-03-06", + "published_at": 1741276800000, + "company": "Prompto Productions" + }, + "duration": 96000, + "duration_desc": "1:36", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 11096948, + "size_desc": "11.1 MB", + "bitrate": 924594, + "extension": "flac" + }, + "hq": { + "size": 3841965, + "size_desc": "3.84 MB", + "bitrate": 320004, + "extension": "mp3" + }, + "mq": { + "size": 2305197, + "size_desc": "2.31 MB", + "bitrate": 192004, + "extension": "mp3" + }, + "lq": { + "size": 1536813, + "size_desc": "1.54 MB", + "bitrate": 128004, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2678794854" + }, + { + "id": 1859339684, + "rank": 64, + "rank_name": "飙升榜", + "title": "般配", + "artist": [ + { + "id": 12471927, + "name": "江皓南", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12471927" + } + ], + "album": { + "id": 130039504, + "name": "般配", + "cover": "http://p1.music.126.net/_8D98wTjXWMhYl5Bofui0w==/109951166155884642.jpg", + "published": "2021-07-09", + "published_at": 1625846400000, + "company": "" + }, + "duration": 181500, + "duration_desc": "3:01", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 37682299, + "size_desc": "37.68 MB", + "bitrate": 1660927, + "extension": "flac" + }, + "hq": { + "size": 7263129, + "size_desc": "7.26 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4357895, + "size_desc": "4.36 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2905278, + "size_desc": "2.91 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1859339684" + }, + { + "id": 2730270721, + "rank": 65, + "rank_name": "飙升榜", + "title": "Distance", + "artist": [ + { + "id": 1132066, + "name": "Fayzz", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1132066" + } + ], + "album": { + "id": 279675457, + "name": "Patch", + "cover": "http://p1.music.126.net/AmLRTNKjHJwOo11jlQX0lw==/109951171525802692.jpg", + "published": "2025-08-04", + "published_at": 1754323200000, + "company": "HIFIVE" + }, + "duration": 301250, + "duration_desc": "5:01", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 31481807, + "size_desc": "31.48 MB", + "bitrate": 835885, + "extension": "flac" + }, + "hq": { + "size": 12052845, + "size_desc": "12.05 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 7231725, + "size_desc": "7.23 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4821165, + "size_desc": "4.82 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2730270721" + }, + { + "id": 1919524295, + "rank": 66, + "rank_name": "飙升榜", + "title": "问情", + "artist": [ + { + "id": 29234568, + "name": "陈亦洺", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=29234568" + }, + { + "id": 13699766, + "name": "尚辰", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=13699766" + } + ], + "album": { + "id": 140260623, + "name": "问情", + "cover": "http://p1.music.126.net/6_Skolb_X075lr2gSwQNew==/109951167039546994.jpg", + "published": "2022-02-15", + "published_at": 1644940800000, + "company": "雪球音乐" + }, + "duration": 247134, + "duration_desc": "4:07", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 31029712, + "size_desc": "31.03 MB", + "bitrate": 1004465, + "extension": "flac" + }, + "hq": { + "size": 9887913, + "size_desc": "9.89 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 5932765, + "size_desc": "5.93 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 3955191, + "size_desc": "3.96 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1919524295" + }, + { + "id": 2600493765, + "rank": 67, + "rank_name": "飙升榜", + "title": "恋人", + "artist": [ + { + "id": 4292, + "name": "李荣浩", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=4292" + } + ], + "album": { + "id": 250748750, + "name": "黑马", + "cover": "http://p1.music.126.net/0bk3Iqe2OZGBH2Iuyx7RzA==/109951170045577565.jpg", + "published": "2024-10-17", + "published_at": 1729180800000, + "company": "一样音乐" + }, + "duration": 275912, + "duration_desc": "4:35", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 30058936, + "size_desc": "30.06 MB", + "bitrate": 871549, + "extension": "flac" + }, + "hq": { + "size": 11039085, + "size_desc": "11.04 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6623469, + "size_desc": "6.62 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4415661, + "size_desc": "4.42 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2600493765" + }, + { + "id": 1893505014, + "rank": 68, + "rank_name": "飙升榜", + "title": "年轮说", + "artist": [ + { + "id": 10199, + "name": "杨丞琳", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=10199" + } + ], + "album": { + "id": 135874294, + "name": "20首華語重溫經典", + "cover": "http://p1.music.126.net/3Ao29M_Bk9wuMe6Zq6mU2w==/109951168278832954.jpg", + "published": "2021-11-07", + "published_at": 1636300800000, + "company": "UME - Global Clearing House" + }, + "duration": 266452, + "duration_desc": "4:26", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 26845620, + "size_desc": "26.85 MB", + "bitrate": 806014, + "extension": "flac" + }, + "hq": { + "size": 10661138, + "size_desc": "10.66 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6396700, + "size_desc": "6.4 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4264481, + "size_desc": "4.26 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1893505014" + }, + { + "id": 209923, + "rank": 69, + "rank_name": "飙升榜", + "title": "Love Love Love", + "artist": [ + { + "id": 7219, + "name": "蔡依林", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=7219" + } + ], + "album": { + "id": 21343, + "name": "城堡", + "cover": "http://p1.music.126.net/lKIkniPBdOWqZzl1yvgz9g==/109951170708258712.jpg", + "published": "2004-02-26", + "published_at": 1077811200000, + "company": "索尼音乐" + }, + "duration": 229520, + "duration_desc": "3:49", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 29983141, + "size_desc": "29.98 MB", + "bitrate": 1045072, + "extension": "flac" + }, + "hq": { + "size": 9183652, + "size_desc": "9.18 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5510209, + "size_desc": "5.51 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3673487, + "size_desc": "3.67 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=209923" + }, + { + "id": 2724694389, + "rank": 70, + "rank_name": "飙升榜", + "title": "背篓少年", + "artist": [ + { + "id": 54093175, + "name": "TCG尹妹", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=54093175" + } + ], + "album": { + "id": 277990540, + "name": "背篓少年", + "cover": "http://p1.music.126.net/ceoHVs2dvrfX50Ka6z2E9A==/109951171443733631.jpg", + "published": "2025-07-11", + "published_at": 1752249600000, + "company": "太合麦田" + }, + "duration": 153845, + "duration_desc": "2:33", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 21621158, + "size_desc": "21.62 MB", + "bitrate": 1124160, + "extension": "flac" + }, + "hq": { + "size": 6156525, + "size_desc": "6.16 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3693933, + "size_desc": "3.69 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2462637, + "size_desc": "2.46 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2724694389" + }, + { + "id": 1407658105, + "rank": 71, + "rank_name": "飙升榜", + "title": "我要找到你", + "artist": [ + { + "id": 5998, + "name": "易泽禹", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=5998" + } + ], + "album": { + "id": 83891446, + "name": "我要找到你", + "cover": "http://p1.music.126.net/mKjg3atpmn9M4J951CiVTA==/109951164528618554.jpg", + "published": "2019-12-03", + "published_at": 1575388800000, + "company": "" + }, + "duration": 202353, + "duration_desc": "3:22", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 21975656, + "size_desc": "21.98 MB", + "bitrate": 1411000, + "extension": "flac" + }, + "hq": { + "size": 8096958, + "size_desc": "8.1 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4858192, + "size_desc": "4.86 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3238809, + "size_desc": "3.24 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1407658105" + }, + { + "id": 2100282715, + "rank": 72, + "rank_name": "飙升榜", + "title": "歪歪", + "artist": [ + { + "id": 37343207, + "name": "拂言", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=37343207" + } + ], + "album": { + "id": 179091457, + "name": "歪歪", + "cover": "http://p1.music.126.net/G0pr2aux9dzK9hT4-n2n5A==/109951169058424179.jpg", + "published": "2023-11-15", + "published_at": 1700064000000, + "company": "" + }, + "duration": 167927, + "duration_desc": "2:47", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 18617591, + "size_desc": "18.62 MB", + "bitrate": 886934, + "extension": "flac" + }, + "hq": { + "size": 6719085, + "size_desc": "6.72 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4031469, + "size_desc": "4.03 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2687661, + "size_desc": "2.69 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2100282715" + }, + { + "id": 2656356278, + "rank": 73, + "rank_name": "飙升榜", + "title": "HARPY HARE", + "artist": [ + { + "id": 59651243, + "name": "NoAki", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=59651243" + }, + { + "id": 12886162, + "name": "Skyver", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12886162" + } + ], + "album": { + "id": 256868094, + "name": "HARPY HARE", + "cover": "http://p1.music.126.net/y2GIIiHLPFn44tBUGqSBlg==/109951170259120670.jpg", + "published": "2025-01-09", + "published_at": 1736438400000, + "company": "HOUSE OF PHONK" + }, + "duration": 77619, + "duration_desc": "1:17", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 10860026, + "size_desc": "10.86 MB", + "bitrate": 1119303, + "extension": "flac" + }, + "hq": { + "size": 3107570, + "size_desc": "3.11 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 1864560, + "size_desc": "1.86 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1243054, + "size_desc": "1.24 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2656356278" + }, + { + "id": 2738936457, + "rank": 74, + "rank_name": "飙升榜", + "title": "Can't go back (Live)", + "artist": [ + { + "id": 49141872, + "name": "Top Barry", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=49141872" + } + ], + "album": { + "id": 281143386, + "name": "新说唱2025 第十二期", + "cover": "http://p1.music.126.net/QQsOcKcT6kleCUhIFMn-mg==/109951171834703159.jpg", + "published": "2025-08-22", + "published_at": 1755878400000, + "company": "韶愔音乐娱乐(北京)有限公司" + }, + "duration": 203999, + "duration_desc": "3:23", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 22384573, + "size_desc": "22.38 MB", + "bitrate": 877679, + "extension": "flac" + }, + "hq": { + "size": 8161965, + "size_desc": "8.16 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4897197, + "size_desc": "4.9 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3264813, + "size_desc": "3.26 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738936457" + }, + { + "id": 2739501337, + "rank": 75, + "rank_name": "飙升榜", + "title": "余烬", + "artist": [ + { + "id": 48497149, + "name": "柠安", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48497149" + } + ], + "album": { + "id": 282723264, + "name": "余烬", + "cover": "http://p1.music.126.net/XXwdSc8kr1b9WNCKI7FKHw==/109951171923938239.jpg", + "published": "2025-08-24", + "published_at": 1756051200000, + "company": "" + }, + "duration": 161123, + "duration_desc": "2:41", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": null, + "hq": { + "size": 6447064, + "size_desc": "6.45 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 3868256, + "size_desc": "3.87 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2578852, + "size_desc": "2.58 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2739501337" + }, + { + "id": 2715166863, + "rank": 76, + "rank_name": "飙升榜", + "title": "雨会告诉你", + "artist": [ + { + "id": 12600046, + "name": "陈文非", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12600046" + } + ], + "album": { + "id": 275076578, + "name": "我在等世界回电", + "cover": "http://p1.music.126.net/5UG9XVaPOdk7xVMjK6SS5w==/109951171301651895.jpg", + "published": "2025-06-15", + "published_at": 1750003200000, + "company": "海神音乐" + }, + "duration": 240208, + "duration_desc": "4:00", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 25879917, + "size_desc": "25.88 MB", + "bitrate": 861768, + "extension": "flac" + }, + "hq": { + "size": 9610605, + "size_desc": "9.61 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5766381, + "size_desc": "5.77 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3844269, + "size_desc": "3.84 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2715166863" + }, + { + "id": 2114019727, + "rank": 77, + "rank_name": "飙升榜", + "title": "Don't Say Goodbye (Interlude) (feat. Lodoni)", + "artist": [ + { + "id": 50848454, + "name": "thirtykay", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=50848454" + }, + { + "id": 49090888, + "name": "LODONI", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=49090888" + } + ], + "album": { + "id": 182366445, + "name": "The Gift of Music", + "cover": "http://p1.music.126.net/on9kaYplg1ozEBx7Ep3G6g==/109951169232504429.jpg", + "published": "2023-12-27", + "published_at": 1703692800000, + "company": "3377803 Records DK" + }, + "duration": 149347, + "duration_desc": "2:29", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 15661502, + "size_desc": "15.66 MB", + "bitrate": 838931, + "extension": "flac" + }, + "hq": { + "size": 5976860, + "size_desc": "5.98 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3586133, + "size_desc": "3.59 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2390770, + "size_desc": "2.39 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2114019727" + }, + { + "id": 29567193, + "rank": 78, + "rank_name": "飙升榜", + "title": "我们的时光", + "artist": [ + { + "id": 6731, + "name": "赵雷", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=6731" + } + ], + "album": { + "id": 3048030, + "name": "吉姆餐厅", + "cover": "http://p1.music.126.net/pwcUlwh9MFZ_V3hGBOPaCQ==/109951169213425474.jpg", + "published": "2014-10-18", + "published_at": 1413648000000, + "company": "华宇世博" + }, + "duration": 270746, + "duration_desc": "4:30", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 28479102, + "size_desc": "28.48 MB", + "bitrate": 841498, + "extension": "flac" + }, + "hq": { + "size": 10832501, + "size_desc": "10.83 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6499518, + "size_desc": "6.5 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4333026, + "size_desc": "4.33 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=29567193" + }, + { + "id": 2075593054, + "rank": 79, + "rank_name": "飙升榜", + "title": "林宛瑜", + "artist": [ + { + "id": 12563131, + "name": "Rapeter", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12563131" + } + ], + "album": { + "id": 174245605, + "name": "DirtyGOOD 装乖", + "cover": "http://p1.music.126.net/-RYv_KQ7OjQYENoqhoXDmg==/109951168899147692.jpg", + "published": "2023-09-09", + "published_at": 1694275200000, + "company": "" + }, + "duration": 186109, + "duration_desc": "3:06", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 19086070, + "size_desc": "19.09 MB", + "bitrate": 820423, + "extension": "flac" + }, + "hq": { + "size": 7446765, + "size_desc": "7.45 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4468077, + "size_desc": "4.47 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 2978733, + "size_desc": "2.98 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2075593054" + }, + { + "id": 2677400220, + "rank": 80, + "rank_name": "飙升榜", + "title": "NO HOOK FREESTYLE Pt.4", + "artist": [ + { + "id": 12563131, + "name": "Rapeter", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12563131" + } + ], + "album": { + "id": 263242113, + "name": "IMGOOD别担心我", + "cover": "http://p1.music.126.net/QpNRZsfMP5J4tOlziA8Pnw==/109951170504642760.jpg", + "published": "2025-02-21", + "published_at": 1740153600000, + "company": "" + }, + "duration": 225000, + "duration_desc": "3:45", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 28370966, + "size_desc": "28.37 MB", + "bitrate": 1008598, + "extension": "flac" + }, + "hq": { + "size": 9001965, + "size_desc": "9 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 5401197, + "size_desc": "5.4 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3600813, + "size_desc": "3.6 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2677400220" + }, + { + "id": 2736690863, + "rank": 81, + "rank_name": "飙升榜", + "title": "MENTE MA", + "artist": [ + { + "id": 48853047, + "name": "VZEUS", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48853047" + } + ], + "album": { + "id": 281730160, + "name": "MENTA MA", + "cover": "http://p1.music.126.net/Jv1aVe2po_f2bE50czHSEQ==/109951171874809370.jpg", + "published": "2025-08-15", + "published_at": 1755246600000, + "company": "" + }, + "duration": 127399, + "duration_desc": "2:07", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 15420410, + "size_desc": "15.42 MB", + "bitrate": 968172, + "extension": "flac" + }, + "hq": { + "size": 5098101, + "size_desc": "5.1 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3058878, + "size_desc": "3.06 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2039266, + "size_desc": "2.04 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2736690863" + }, + { + "id": 2735855320, + "rank": 82, + "rank_name": "飙升榜", + "title": "下课钟声", + "artist": [ + { + "id": 34094059, + "name": "关浩德Walter", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=34094059" + } + ], + "album": { + "id": 281405272, + "name": "下课钟声", + "cover": "http://p1.music.126.net/_7Wa7O6fCdlRrNt17RzdAw==/109951171853737963.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "StreetVoice/触底而上DTT" + }, + "duration": 273237, + "duration_desc": "4:33", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 26949536, + "size_desc": "26.95 MB", + "bitrate": 788897, + "extension": "flac" + }, + "hq": { + "size": 10931565, + "size_desc": "10.93 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6558957, + "size_desc": "6.56 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4372653, + "size_desc": "4.37 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2735855320" + }, + { + "id": 2717035826, + "rank": 83, + "rank_name": "飙升榜", + "title": "半情歌", + "artist": [ + { + "id": 12275767, + "name": "step.jad依加", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12275767" + } + ], + "album": { + "id": 275651228, + "name": "半情歌", + "cover": "http://p1.music.126.net/ROw9CASwYMvQvuDOH6eVbw==/109951171330027735.jpg", + "published": "2025-07-14", + "published_at": 1752508800000, + "company": "华纳音乐" + }, + "duration": 214905, + "duration_desc": "3:34", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 25754214, + "size_desc": "25.75 MB", + "bitrate": 958570, + "extension": "flac" + }, + "hq": { + "size": 8598765, + "size_desc": "8.6 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5159277, + "size_desc": "5.16 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3439533, + "size_desc": "3.44 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2717035826" + }, + { + "id": 2735409135, + "rank": 84, + "rank_name": "飙升榜", + "title": "ハンドサイン", + "artist": [ + { + "id": 27889701, + "name": "Kizuna AI", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=27889701" + } + ], + "album": { + "id": 281242596, + "name": "ハンドサイン", + "cover": "http://p1.music.126.net/1gnbsJg2rYHalSxBRSReYA==/109951171840112594.jpg", + "published": "2025-08-19", + "published_at": 1755619200000, + "company": "KizunaAI" + }, + "duration": 238693, + "duration_desc": "3:58", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 29926707, + "size_desc": "29.93 MB", + "bitrate": 1002871, + "extension": "flac" + }, + "hq": { + "size": 9550125, + "size_desc": "9.55 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5730093, + "size_desc": "5.73 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3820077, + "size_desc": "3.82 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2735409135" + }, + { + "id": 2082176014, + "rank": 85, + "rank_name": "飙升榜", + "title": "最后的道别", + "artist": [ + { + "id": 4464, + "name": "梁雨", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=4464" + } + ], + "album": { + "id": 174775874, + "name": "最后的道别", + "cover": "http://p1.music.126.net/EeoTFA6yT1e9k89QblcvHQ==/109951168914975164.jpg", + "published": "2023-09-14", + "published_at": 1694707200000, + "company": "淳music" + }, + "duration": 264444, + "duration_desc": "4:24", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 34255476, + "size_desc": "34.26 MB", + "bitrate": 1036300, + "extension": "flac" + }, + "hq": { + "size": 10580205, + "size_desc": "10.58 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 6348141, + "size_desc": "6.35 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 4232109, + "size_desc": "4.23 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2082176014" + }, + { + "id": 2739596293, + "rank": 86, + "rank_name": "飙升榜", + "title": "五千两百遍", + "artist": [ + { + "id": 34634779, + "name": "999PUNKSTA", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=34634779" + } + ], + "album": { + "id": 282723760, + "name": "五千两百遍", + "cover": "http://p1.music.126.net/d2BE2e7gxx0cKvZh3TiOew==/109951171925663378.jpg", + "published": "2025-08-23", + "published_at": 1755964800000, + "company": "" + }, + "duration": 158261, + "duration_desc": "2:38", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 30834253, + "size_desc": "30.83 MB", + "bitrate": 1558497, + "extension": "flac" + }, + "hq": { + "size": 6333170, + "size_desc": "6.33 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3799920, + "size_desc": "3.8 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2533294, + "size_desc": "2.53 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2739596293" + }, + { + "id": 150422, + "rank": 87, + "rank_name": "飙升榜", + "title": "今天你要嫁给我", + "artist": [ + { + "id": 7219, + "name": "蔡依林", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=7219" + }, + { + "id": 5196, + "name": "陶喆", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=5196" + } + ], + "album": { + "id": 15184, + "name": "太美丽", + "cover": "http://p1.music.126.net/Fq9QNt2SYKvPEL3ipfVc9g==/109951166916020363.jpg", + "published": "2006-08-03", + "published_at": 1154620800000, + "company": "华纳音乐" + }, + "duration": 272066, + "duration_desc": "4:32", + "popularity": 100, + "score": 100, + "fee": 1, + "status": 0, + "mb": { + "sq": { + "size": 31284971, + "size_desc": "31.28 MB", + "bitrate": 919920, + "extension": "flac" + }, + "hq": { + "size": 10885791, + "size_desc": "10.89 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 6531492, + "size_desc": "6.53 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 4354342, + "size_desc": "4.35 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=150422" + }, + { + "id": 1958677933, + "rank": 88, + "rank_name": "飙升榜", + "title": "不温暖的歌", + "artist": [ + { + "id": 1204076, + "name": "欧瑞SoulCore", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1204076" + } + ], + "album": { + "id": 147035916, + "name": "不温暖的歌", + "cover": "http://p1.music.126.net/HnGeUR5qsVmbvtk5LEMvng==/109951167584589643.jpg", + "published": "2022-06-23", + "published_at": 1656000000000, + "company": "" + }, + "duration": 190000, + "duration_desc": "3:10", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 38897482, + "size_desc": "38.9 MB", + "bitrate": 1637788, + "extension": "flac" + }, + "hq": { + "size": 7602721, + "size_desc": "7.6 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 4561650, + "size_desc": "4.56 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3041115, + "size_desc": "3.04 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=1958677933" + }, + { + "id": 2738570393, + "rank": 89, + "rank_name": "飙升榜", + "title": "爱情火车", + "artist": [ + { + "id": 48577041, + "name": "Mikey-18", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=48577041" + }, + { + "id": 37343744, + "name": "Katastic卡老师", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=37343744" + } + ], + "album": { + "id": 282399455, + "name": "爱情火车", + "cover": "http://p1.music.126.net/X7FCkAy-zM3KK3ulekJl-w==/109951171934200418.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "网易电波" + }, + "duration": 168874, + "duration_desc": "2:48", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 19597500, + "size_desc": "19.6 MB", + "bitrate": 928231, + "extension": "flac" + }, + "hq": { + "size": 6757399, + "size_desc": "6.76 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4054457, + "size_desc": "4.05 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2702986, + "size_desc": "2.7 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738570393" + }, + { + "id": 2733116489, + "rank": 90, + "rank_name": "飙升榜", + "title": "云朵的歌", + "artist": [ + { + "id": 29865317, + "name": "斯丹曼簇", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=29865317" + } + ], + "album": { + "id": 280458270, + "name": "云朵的歌", + "cover": "http://p1.music.126.net/EDicVyZ4SZJAnI-RqYLPSw==/109951171914367691.jpg", + "published": "2025-08-22", + "published_at": 1755878400000, + "company": "" + }, + "duration": 254153, + "duration_desc": "4:14", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 27926440, + "size_desc": "27.93 MB", + "bitrate": 878894, + "extension": "flac" + }, + "hq": { + "size": 10168365, + "size_desc": "10.17 MB", + "bitrate": 320001, + "extension": "mp3" + }, + "mq": { + "size": 6101037, + "size_desc": "6.1 MB", + "bitrate": 192001, + "extension": "mp3" + }, + "lq": { + "size": 4067373, + "size_desc": "4.07 MB", + "bitrate": 128001, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2733116489" + }, + { + "id": 2666658963, + "rank": 91, + "rank_name": "飙升榜", + "title": "Show Me Love", + "artist": [ + { + "id": 31988286, + "name": "WizTheMC", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=31988286" + }, + { + "id": 94332017, + "name": "bees & honey", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=94332017" + } + ], + "album": { + "id": 259913344, + "name": "Show Me Love", + "cover": "http://p1.music.126.net/sPZ1mJ3Rh10cjRenbQ3bAg==/109951170383524946.jpg", + "published": "2025-02-06", + "published_at": 1738857600000, + "company": "Bamboo Artists" + }, + "duration": 176965, + "duration_desc": "2:56", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 34535501, + "size_desc": "34.54 MB", + "bitrate": 1561083, + "extension": "flac" + }, + "hq": { + "size": 7081317, + "size_desc": "7.08 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4248808, + "size_desc": "4.25 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2832553, + "size_desc": "2.83 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2666658963" + }, + { + "id": 2740196131, + "rank": 92, + "rank_name": "飙升榜", + "title": "一步几回头", + "artist": [ + { + "id": 31364543, + "name": "蒋孜怡", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=31364543" + } + ], + "album": { + "id": 282958925, + "name": "一步几回头", + "cover": "http://p1.music.126.net/rzb1yI0jHl7jgoUnzZa_qg==/109951171933563007.jpg", + "published": "2025-08-27", + "published_at": 1756310400000, + "company": "Universal Music China" + }, + "duration": 222659, + "duration_desc": "3:42", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 26687271, + "size_desc": "26.69 MB", + "bitrate": 958706, + "extension": "flac" + }, + "hq": { + "size": 8908844, + "size_desc": "8.91 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5345324, + "size_desc": "5.35 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3563564, + "size_desc": "3.56 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740196131" + }, + { + "id": 2736339025, + "rank": 93, + "rank_name": "飙升榜", + "title": "桃花签", + "artist": [ + { + "id": 1215003, + "name": "呦猫UNEKO", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1215003" + }, + { + "id": 816079, + "name": "薄彩生", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=816079" + } + ], + "album": { + "id": 281577462, + "name": "《百妖谱·洛阳篇》动画原声带", + "cover": "http://p1.music.126.net/MSfQ702QFv0w2OmifzyJEA==/109951171867725169.jpg", + "published": "2025-08-14", + "published_at": 1755187200000, + "company": "bilibili" + }, + "duration": 239808, + "duration_desc": "3:59", + "popularity": 95, + "score": 95, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 27381733, + "size_desc": "27.38 MB", + "bitrate": 913308, + "extension": "flac" + }, + "hq": { + "size": 9594285, + "size_desc": "9.59 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 5756589, + "size_desc": "5.76 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3837741, + "size_desc": "3.84 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2736339025" + }, + { + "id": 2652410538, + "rank": 94, + "rank_name": "飙升榜", + "title": "红太狼狂想曲(《喜羊羊与灰太狼之兔年顶呱呱》动画电影插曲)", + "artist": [ + { + "id": 7481, + "name": "崔子格", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=7481" + } + ], + "album": { + "id": 255582143, + "name": "《喜羊羊与灰太狼》音乐原声带合辑", + "cover": "http://p1.music.126.net/KeZoz-csqAe30ovzgDFehQ==/109951170213887287.jpg", + "published": "2024-12-01", + "published_at": 1733068800000, + "company": "宇歌风行" + }, + "duration": 160920, + "duration_desc": "2:40", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 18494176, + "size_desc": "18.49 MB", + "bitrate": 919422, + "extension": "flac" + }, + "hq": { + "size": 6438765, + "size_desc": "6.44 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3863277, + "size_desc": "3.86 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2575533, + "size_desc": "2.58 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2652410538" + }, + { + "id": 2733113572, + "rank": 95, + "rank_name": "飙升榜", + "title": "espero(等着你)", + "artist": [ + { + "id": 46957283, + "name": "曼尼洛夫", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=46957283" + }, + { + "id": 12568026, + "name": "小白羊HUSH", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12568026" + } + ], + "album": { + "id": 280457742, + "name": "espero(等着你)", + "cover": "http://p1.music.126.net/2CY0ZyIyAbCWErHS6VnX5g==/109951171715764900.jpg", + "published": "2025-08-03", + "published_at": 1754236800000, + "company": "独立发行" + }, + "duration": 230999, + "duration_desc": "3:50", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 26319483, + "size_desc": "26.32 MB", + "bitrate": 911350, + "extension": "flac" + }, + "hq": { + "size": 9242166, + "size_desc": "9.24 MB", + "bitrate": 320002, + "extension": "mp3" + }, + "mq": { + "size": 5545317, + "size_desc": "5.55 MB", + "bitrate": 192002, + "extension": "mp3" + }, + "lq": { + "size": 3696893, + "size_desc": "3.7 MB", + "bitrate": 128002, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2733113572" + }, + { + "id": 2738549556, + "rank": 96, + "rank_name": "飙升榜", + "title": "Vai Toma(PHONK)", + "artist": [ + { + "id": 56856041, + "name": "GTR7", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=56856041" + } + ], + "album": { + "id": 282297619, + "name": "Vai Toma", + "cover": "http://p1.music.126.net/crZu8zAKrCR3pN8lzdUUVA==/109951171907812124.jpg", + "published": "2025-08-20", + "published_at": 1755705600000, + "company": "" + }, + "duration": 131000, + "duration_desc": "2:11", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 28401103, + "size_desc": "28.4 MB", + "bitrate": 1734269, + "extension": "flac" + }, + "hq": { + "size": 5242297, + "size_desc": "5.24 MB", + "bitrate": 320003, + "extension": "mp3" + }, + "mq": { + "size": 3145395, + "size_desc": "3.15 MB", + "bitrate": 192003, + "extension": "mp3" + }, + "lq": { + "size": 2096945, + "size_desc": "2.1 MB", + "bitrate": 128003, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2738549556" + }, + { + "id": 2739231169, + "rank": 97, + "rank_name": "飙升榜", + "title": "她走的那夜下起了大雨 (纯音乐)", + "artist": [ + { + "id": 59019507, + "name": "韦大鱼", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=59019507" + } + ], + "album": { + "id": 282657964, + "name": "纯音乐合集", + "cover": "http://p1.music.126.net/cfBzsQXbFCV1E_m5y1ZA3w==/109951171919074070.jpg", + "published": "2025-08-22", + "published_at": 1755878400000, + "company": "广西青衫网络传媒有限公司" + }, + "duration": 188424, + "duration_desc": "3:08", + "popularity": 95, + "score": 95, + "fee": 0, + "status": 0, + "mb": { + "sq": null, + "hq": { + "size": 7538925, + "size_desc": "7.54 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4523373, + "size_desc": "4.52 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": null + }, + "link": "https://music.163.com/#/song?id=2739231169" + }, + { + "id": 2740703897, + "rank": 98, + "rank_name": "飙升榜", + "title": "Start Today", + "artist": [ + { + "id": 56782, + "name": "Fall Out Boy", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=56782" + } + ], + "album": { + "id": 283140201, + "name": "Start Today", + "cover": "http://p1.music.126.net/gnMq2u8Nhsdewz3nnsEIVA==/109951171940498828.jpg", + "published": "2025-08-26", + "published_at": 1756224000000, + "company": "Island Records" + }, + "duration": 122706, + "duration_desc": "2:02", + "popularity": 90, + "score": 90, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 14898805, + "size_desc": "14.9 MB", + "bitrate": 971194, + "extension": "flac" + }, + "hq": { + "size": 4911064, + "size_desc": "4.91 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 2946656, + "size_desc": "2.95 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 1964452, + "size_desc": "1.96 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2740703897" + }, + { + "id": 2100963421, + "rank": 99, + "rank_name": "飙升榜", + "title": "山海花开不是你", + "artist": [ + { + "id": 12444269, + "name": "高源", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=12444269" + } + ], + "album": { + "id": 179350982, + "name": "山海花开不是你", + "cover": "http://p1.music.126.net/AksAWvy9M90X-quVpRm9aA==/109951169063447299.jpg", + "published": "2023-11-19", + "published_at": 1700409600000, + "company": "音符跳动" + }, + "duration": 194516, + "duration_desc": "3:14", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 21032122, + "size_desc": "21.03 MB", + "bitrate": 864999, + "extension": "flac" + }, + "hq": { + "size": 7782765, + "size_desc": "7.78 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 4669677, + "size_desc": "4.67 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 3113133, + "size_desc": "3.11 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2100963421" + }, + { + "id": 2731613461, + "rank": 100, + "rank_name": "飙升榜", + "title": "不会在乎时间走多快", + "artist": [ + { + "id": 1142011, + "name": "王极", + "cover": "http://p1.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", + "link": "https://music.163.com/#/artist?id=1142011" + } + ], + "album": { + "id": 280119457, + "name": "不会在乎时间走多快", + "cover": "http://p1.music.126.net/QwXt6wm-zpToUdKVa-sXHA==/109951171580254229.jpg", + "published": "2025-08-01", + "published_at": 1754064000000, + "company": "" + }, + "duration": 138929, + "duration_desc": "2:18", + "popularity": 100, + "score": 100, + "fee": 8, + "status": 0, + "mb": { + "sq": { + "size": 16673736, + "size_desc": "16.67 MB", + "bitrate": 959978, + "extension": "flac" + }, + "hq": { + "size": 5559405, + "size_desc": "5.56 MB", + "bitrate": 320000, + "extension": "mp3" + }, + "mq": { + "size": 3335661, + "size_desc": "3.34 MB", + "bitrate": 192000, + "extension": "mp3" + }, + "lq": { + "size": 2223789, + "size_desc": "2.22 MB", + "bitrate": 128000, + "extension": "mp3" + } + }, + "link": "https://music.163.com/#/song?id=2731613461" + } + ] +} \ No newline at end of file diff --git a/frontend/react-app/public/60sapi/生成要求模板.txt b/frontend/react-app/public/60sapi/生成要求模板.txt new file mode 100644 index 00000000..0a3addc7 --- /dev/null +++ b/frontend/react-app/public/60sapi/生成要求模板.txt @@ -0,0 +1,8 @@ +1.生成为静态网页,js,css,html分离出来,不要混合在一起放入html里,难以阅读 +2.网页要适配手机端,电脑端和平板端三个设备分别做不同的css格式,优先优化手机端用户体验 +3.网页默认风格以淡绿色清新风格为主,除非用户要求 +4.尽量不要引用外部css,js,实在要引用就使用中国国内的cdn,否则用户可能加载不出来 +5.返回接口.json储存了网页api返回的数据格式 +6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...” +7.接口集合.json保存了所有已知的后端API接口,一个访问不了尝试自动切换另一个 +8.在css中有关背景的css单独一个css文件,方便我直接迁移 \ No newline at end of file diff --git a/frontend/react-app/public/index.html b/frontend/react-app/public/index.html new file mode 100644 index 00000000..a9715b67 --- /dev/null +++ b/frontend/react-app/public/index.html @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ✨ 神奇万事通 ✨ + + + + + + + +
+ +
神奇万事通
+
🎨 多功能聚合应用 💬
+
+
+ +
+ + + + diff --git a/frontend/react-app/public/manifest.json b/frontend/react-app/public/manifest.json new file mode 100644 index 00000000..5cbf4f73 --- /dev/null +++ b/frontend/react-app/public/manifest.json @@ -0,0 +1,38 @@ +{ + "short_name": "神奇万事通", + "name": "✨ 神奇万事通 - 多功能聚合应用", + "description": "🎨 一个多功能的聚合软件应用,提供60s API、小游戏、AI模型等丰富功能", + "icons": [ + { + "src": "data:image/svg+xml,", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/svg+xml" + }, + { + "src": "data:image/svg+xml,", + "type": "image/svg+xml", + "sizes": "192x192" + }, + { + "src": "data:image/svg+xml,", + "type": "image/svg+xml", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#667eea", + "background_color": "#ffffff", + "orientation": "portrait-primary", + "scope": "/", + "lang": "zh-CN", + "categories": ["utilities", "productivity", "entertainment"], + "screenshots": [ + { + "src": "data:image/svg+xml,神奇万事通", + "type": "image/svg+xml", + "sizes": "400x800", + "form_factor": "narrow" + } + ] +} diff --git a/frontend/react-app/src/App.js b/frontend/react-app/src/App.js new file mode 100644 index 00000000..5f47a585 --- /dev/null +++ b/frontend/react-app/src/App.js @@ -0,0 +1,88 @@ +import React from 'react'; +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import { Toaster } from 'react-hot-toast'; +import styled from 'styled-components'; + +// 页面组件 +import HomePage from './pages/HomePage'; +import LoginPage from './pages/LoginPage'; +import Api60sPage from './pages/Api60sPage'; +import SmallGamePage from './pages/SmallGamePage'; +import AiModelPage from './pages/AiModelPage'; + +// 公共组件 +import Header from './components/Header'; +import Navigation from './components/Navigation'; +import Footer from './components/Footer'; + +// 上下文 +import { UserProvider } from './contexts/UserContext'; + +// 样式 +import './styles/global.css'; + +const AppContainer = styled.div` + min-height: 100vh; + display: flex; + flex-direction: column; + background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%); +`; + +const MainContent = styled.main` + flex: 1; + padding: 0; + margin: 0; +`; + +function App() { + return ( + + + +
+ + + {/* 主要页面 */} + } /> + } /> + } /> + } /> + } /> + + + +
+ + {/* 全局提示组件 */} + + + + + ); +} + +export default App; diff --git a/frontend/react-app/src/components/Footer.js b/frontend/react-app/src/components/Footer.js new file mode 100644 index 00000000..b3db4ebb --- /dev/null +++ b/frontend/react-app/src/components/Footer.js @@ -0,0 +1,115 @@ +import React from 'react'; +import styled from 'styled-components'; + +const FooterContainer = styled.footer` + background: #1f2937; + color: #d1d5db; + padding: 40px 0 80px; /* 底部留出导航栏空间 */ + margin-top: 60px; + + @media (min-width: 769px) { + padding: 40px 0 20px; + } +`; + +const FooterContent = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +`; + +const FooterInfo = styled.div` + text-align: center; + margin-bottom: 24px; +`; + +const FooterTitle = styled.h3` + color: white; + margin-bottom: 12px; + font-size: 20px; + font-weight: bold; +`; + +const FooterDescription = styled.p` + font-size: 14px; + line-height: 1.6; + margin-bottom: 16px; + color: #9ca3af; +`; + +const FooterLinks = styled.div` + display: flex; + justify-content: center; + gap: 24px; + margin-bottom: 24px; + flex-wrap: wrap; + + @media (max-width: 768px) { + gap: 16px; + } +`; + +const FooterLink = styled.a` + color: #d1d5db; + text-decoration: none; + font-size: 14px; + transition: color 0.2s ease; + + &:hover { + color: #667eea; + } +`; + +const FooterDivider = styled.div` + height: 1px; + background: #374151; + margin: 24px 0; +`; + +const FooterBottom = styled.div` + text-align: center; + font-size: 12px; + color: #6b7280; + line-height: 1.5; +`; + +const Copyright = styled.p` + margin-bottom: 8px; +`; + +const ICP = styled.p` + margin: 0; +`; + +const Footer = () => { + const currentYear = new Date().getFullYear(); + + return ( + + + + ✨ 神奇万事通 ✨ + + 🎨 一个多功能的聚合软件应用 💬 + + + + + 📡聚合应用 + 🎮小游戏 + 🤖AI工具 + + + + + + + 📄 蜀ICP备2025151694号 | Copyright © 2025-{currentYear} ✨ + + + + + ); +}; + +export default Footer; diff --git a/frontend/react-app/src/components/Header.js b/frontend/react-app/src/components/Header.js new file mode 100644 index 00000000..a368be52 --- /dev/null +++ b/frontend/react-app/src/components/Header.js @@ -0,0 +1,349 @@ +import React, { useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import styled from 'styled-components'; +import { FiUser, FiMenu, FiX, FiLogOut } from 'react-icons/fi'; +import { useUser } from '../contexts/UserContext'; + +const HeaderContainer = styled.header` + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + padding: 12px 0; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + position: sticky; + top: 0; + z-index: 1000; +`; + +const HeaderContent = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; + display: flex; + align-items: center; + justify-content: space-between; +`; + +const Logo = styled(Link)` + display: flex; + align-items: center; + font-size: 20px; + font-weight: bold; + text-decoration: none; + color: white; + + .logo-icon { + margin-right: 8px; + font-size: 24px; + } + + @media (max-width: 768px) { + font-size: 18px; + + .logo-icon { + font-size: 20px; + } + } +`; + +const Nav = styled.nav` + display: flex; + align-items: center; + gap: 24px; + + @media (max-width: 768px) { + display: none; + } +`; + +const NavLink = styled(Link)` + color: rgba(255, 255, 255, 0.9); + text-decoration: none; + padding: 8px 16px; + border-radius: 6px; + transition: all 0.2s ease; + + &:hover { + background: rgba(255, 255, 255, 0.1); + color: white; + } +`; + +const UserSection = styled.div` + display: flex; + align-items: center; + gap: 12px; +`; + +const UserButton = styled.button` + display: flex; + align-items: center; + gap: 8px; + background: rgba(255, 255, 255, 0.1); + color: white; + border: none; + padding: 8px 16px; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: rgba(255, 255, 255, 0.2); + } + + @media (max-width: 768px) { + padding: 8px 12px; + + .user-text { + display: none; + } + } +`; + +const UserAvatar = styled.img` + width: 24px; + height: 24px; + border-radius: 50%; + border: 2px solid rgba(255, 255, 255, 0.3); + object-fit: cover; +`; + +const UserInfo = styled.div` + display: flex; + align-items: center; + gap: 8px; + background: rgba(255, 255, 255, 0.1); + color: white; + padding: 6px 12px; + border-radius: 6px; + + @media (max-width: 768px) { + .user-name { + display: none; + } + } +`; + +const MobileMenuButton = styled.button` + display: none; + background: none; + border: none; + color: white; + font-size: 24px; + cursor: pointer; + + @media (max-width: 768px) { + display: block; + } +`; + +const MobileMenu = styled.div.withConfig({ + shouldForwardProp: (prop) => prop !== 'isOpen' +})` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 2000; + display: ${props => props.isOpen ? 'block' : 'none'}; + + @media (min-width: 769px) { + display: none; + } +`; + +const MobileMenuContent = styled.div.withConfig({ + shouldForwardProp: (prop) => prop !== 'isOpen' +})` + position: absolute; + top: 0; + right: 0; + width: 280px; + height: 100vh; + background: white; + transform: translateX(${props => props.isOpen ? '0' : '100%'}); + transition: transform 0.3s ease; + padding: 20px; + overflow-y: auto; +`; + +const MobileMenuHeader = styled.div` + display: flex; + justify-content: between; + align-items: center; + margin-bottom: 24px; + padding-bottom: 16px; + border-bottom: 1px solid #e5e7eb; +`; + +const MobileMenuTitle = styled.h3` + color: #1f2937; + margin: 0; +`; + +const CloseButton = styled.button` + background: none; + border: none; + font-size: 24px; + color: #6b7280; + cursor: pointer; +`; + +const MobileNavLink = styled(Link)` + display: block; + color: #374151; + text-decoration: none; + padding: 12px 0; + border-bottom: 1px solid #f3f4f6; + transition: color 0.2s ease; + + &:hover { + color: #667eea; + } + + &:last-child { + border-bottom: none; + } +`; + +const Header = () => { + const { user, isLoggedIn, logout, getQQAvatar } = useUser(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + const navigate = useNavigate(); + + const handleLogout = async () => { + await logout(); + setIsMenuOpen(false); + navigate('/'); + }; + + const handleMenuToggle = () => { + setIsMenuOpen(!isMenuOpen); + }; + + const handleMenuClose = () => { + setIsMenuOpen(false); + }; + + return ( + <> + + + + + 神奇万事通 + + + + + + {isLoggedIn && user ? ( + <> + + {getQQAvatar(user.account) ? ( + { + e.target.style.display = 'none'; + e.target.nextSibling.style.display = 'inline'; + }} + /> + ) : null} + + {user.account} + + + + 退出 + + + ) : ( + + + 登录 + + )} + + + + + + + + + + e.stopPropagation()}> + + 菜单 + + + + + + + 🏠 首页 + + + 📡 60s API + + + 🎮 小游戏 + + + 🤖 AI模型 + + + {isLoggedIn && user ? ( + <> +
+ {getQQAvatar(user.account) ? ( + + ) : ( + + )} + {user.account} +
+ { + handleLogout(); + handleMenuClose(); + }} + > + 🚪 退出登录 + + + ) : ( + + 👤 登录注册 + + )} +
+
+ + ); +}; + +export default Header; diff --git a/frontend/react-app/src/components/Navigation.js b/frontend/react-app/src/components/Navigation.js new file mode 100644 index 00000000..a8ca3655 --- /dev/null +++ b/frontend/react-app/src/components/Navigation.js @@ -0,0 +1,126 @@ +import React from 'react'; +import { Link, useLocation } from 'react-router-dom'; +import styled from 'styled-components'; +import { FiHome, FiActivity, FiGrid, FiCpu } from 'react-icons/fi'; + +const NavigationContainer = styled.nav` + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.95); + border-top: 1px solid rgba(168, 230, 207, 0.3); + padding: 8px 0 calc(8px + env(safe-area-inset-bottom)); + z-index: 1000; + box-shadow: 0 -4px 20px rgba(168, 230, 207, 0.2); + backdrop-filter: blur(15px); + + @media (min-width: 769px) { + display: none; + } +`; + +const NavList = styled.div` + display: flex; + justify-content: space-around; + align-items: center; + max-width: 500px; + margin: 0 auto; + padding: 0 16px; +`; + +const NavItem = styled(Link).withConfig({ + shouldForwardProp: (prop) => prop !== 'isActive' +})` + display: flex; + flex-direction: column; + align-items: center; + text-decoration: none; + color: ${props => props.isActive ? '#66bb6a' : '#6b7280'}; + transition: all 0.2s ease; + padding: 8px 12px; + border-radius: 12px; + min-width: 60px; + + &:hover { + color: #66bb6a; + background: rgba(129, 199, 132, 0.1); + } + + .nav-icon { + font-size: 20px; + margin-bottom: 4px; + transition: transform 0.2s ease; + } + + .nav-text { + font-size: 11px; + font-weight: 500; + line-height: 1; + } + + ${props => props.isActive && ` + .nav-icon { + transform: scale(1.1); + } + `} +`; + +const Navigation = () => { + const location = useLocation(); + + const navItems = [ + { + path: '/', + icon: FiHome, + text: '首页', + exact: true + }, + { + path: '/60sapi', + icon: FiActivity, + text: '60s API' + }, + { + path: '/smallgame', + icon: FiGrid, + text: '小游戏' + }, + { + path: '/aimodel', + icon: FiCpu, + text: 'AI模型' + } + ]; + + const isActive = (path, exact = false) => { + if (exact) { + return location.pathname === path; + } + return location.pathname.startsWith(path); + }; + + return ( + + + {navItems.map((item) => { + const IconComponent = item.icon; + const active = isActive(item.path, item.exact); + + return ( + + + {item.text} + + ); + })} + + + ); +}; + +export default Navigation; diff --git a/frontend/react-app/src/contexts/UserContext.js b/frontend/react-app/src/contexts/UserContext.js new file mode 100644 index 00000000..b2ac651b --- /dev/null +++ b/frontend/react-app/src/contexts/UserContext.js @@ -0,0 +1,118 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; +import { authAPI } from '../utils/api'; +import toast from 'react-hot-toast'; + +const UserContext = createContext(); + +export const useUser = () => { + const context = useContext(UserContext); + if (!context) { + throw new Error('useUser must be used within a UserProvider'); + } + return context; +}; + +export const UserProvider = ({ children }) => { + const [user, setUser] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [isLoggedIn, setIsLoggedIn] = useState(false); + + // 检查登录状态 + const checkLoginStatus = async () => { + try { + const response = await authAPI.checkLogin(); + if (response.data.success && response.data.logged_in) { + const userData = response.data.user; + setUser(userData); + setIsLoggedIn(true); + } else { + setUser(null); + setIsLoggedIn(false); + } + } catch (error) { + console.error('检查登录状态失败:', error); + setUser(null); + setIsLoggedIn(false); + } finally { + setIsLoading(false); + } + }; + + // 登录 + const login = async (loginData) => { + try { + const response = await authAPI.login(loginData); + if (response.data.success) { + const userData = response.data.user; + setUser(userData); + setIsLoggedIn(true); + toast.success('登录成功!'); + return { success: true }; + } else { + toast.error(response.data.message || '登录失败'); + return { success: false, message: response.data.message }; + } + } catch (error) { + console.error('登录失败:', error); + const message = error.response?.data?.message || '登录失败,请重试'; + toast.error(message); + return { success: false, message }; + } + }; + + // 登出 + const logout = async () => { + try { + await authAPI.logout(); + setUser(null); + setIsLoggedIn(false); + toast.success('已成功登出'); + } catch (error) { + console.error('登出失败:', error); + // 即使登出请求失败,也清除本地状态 + setUser(null); + setIsLoggedIn(false); + toast.error('登出失败'); + } + }; + + // 获取QQ头像URL + const getQQAvatar = (email) => { + if (!email) return null; + + const qqDomains = ['qq.com', 'vip.qq.com', 'foxmail.com']; + const domain = email.split('@')[1]?.toLowerCase(); + + if (qqDomains.includes(domain)) { + const qqNumber = email.split('@')[0]; + if (/^\d+$/.test(qqNumber)) { + return `http://q1.qlogo.cn/g?b=qq&nk=${qqNumber}&s=100`; + } + } + + return null; + }; + + // 组件挂载时检查登录状态 + useEffect(() => { + checkLoginStatus(); + }, []); + + const value = { + user, + isLoading, + isLoggedIn, + login, + logout, + checkLoginStatus, + getQQAvatar + }; + + return ( + + {children} + + ); +}; + +export default UserContext; \ No newline at end of file diff --git a/frontend/react-app/src/index.js b/frontend/react-app/src/index.js new file mode 100644 index 00000000..882116ee --- /dev/null +++ b/frontend/react-app/src/index.js @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './styles/index.css'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + +); diff --git a/frontend/react-app/src/md/前端邮件功能测试指南.md b/frontend/react-app/src/md/前端邮件功能测试指南.md new file mode 100644 index 00000000..61e8d9c1 --- /dev/null +++ b/frontend/react-app/src/md/前端邮件功能测试指南.md @@ -0,0 +1,118 @@ +# 前端邮件功能测试指南 + +## 问题修复说明 + +### 修复的问题 +- **响应拦截器问题**:修复了 `api.js` 中响应拦截器直接返回 `response.data` 导致前端无法正确访问 `response.data.success` 的问题 +- **API响应格式不匹配**:现在前端代码可以正确处理后端返回的响应格式 + +### 修复内容 +在 `src/utils/api.js` 文件中: +```javascript +// 修复前 +api.interceptors.response.use( + (response) => { + return response.data; // 这里直接返回了data,导致前端无法访问response.data.success + }, + // ... +); + +// 修复后 +api.interceptors.response.use( + (response) => { + return response; // 现在返回完整的response对象 + }, + // ... +); +``` + +## 测试步骤 + +### 1. 启动服务 +确保以下服务正在运行: +- **后端服务**:`http://localhost:5000` +- **前端服务**:`http://localhost:3001` + +### 2. 测试注册功能 +1. 打开浏览器访问 `http://localhost:3001` +2. 点击登录按钮或直接访问 `/login` 页面 +3. 切换到「注册」标签 +4. 填写以下信息: + - **邮箱**:输入有效的QQ邮箱(如:your_qq@qq.com) + - **用户名**:输入用户名 + - **密码**:输入密码(至少6位) + - **确认密码**:再次输入相同密码 +5. 点击「发送验证码」按钮 +6. 检查是否显示成功提示:"验证码已发送到您的邮箱" +7. 检查邮箱是否收到验证码邮件 +8. 输入收到的验证码 +9. 点击「注册」按钮完成注册 + +### 3. 测试登录功能(验证码登录) +1. 在登录页面选择「验证码登录」 +2. 输入已注册的QQ邮箱 +3. 点击「发送验证码」按钮 +4. 检查是否显示成功提示 +5. 检查邮箱是否收到登录验证码 +6. 输入验证码并点击「登录」 + +### 4. 测试登录功能(密码登录) +1. 在登录页面选择「密码登录」 +2. 输入邮箱和密码 +3. 点击「登录」按钮 + +## 预期结果 + +### 成功的表现 +- ✅ 点击「发送验证码」后显示绿色成功提示 +- ✅ 倒计时正常显示(60秒) +- ✅ 邮箱收到格式正确的验证码邮件 +- ✅ 后端日志显示:"验证码邮件发送成功: your_email@qq.com" +- ✅ 验证码验证成功,注册/登录流程完整 + +### 失败的表现 +- ❌ 显示红色错误提示 +- ❌ 邮箱未收到验证码 +- ❌ 后端日志显示SMTP错误 + +## 技术细节 + +### API调用流程 +1. 前端调用 `authAPI.sendVerification(data)` +2. 请求发送到 `/api/auth/send-verification` +3. 后端处理邮件发送 +4. 返回响应格式:`{ success: true/false, message: "...", data: {...} }` +5. 前端通过 `response.data.success` 判断是否成功 + +### 环境变量要求 +确保后端设置了正确的环境变量: +```bash +MAIL_USERNAME=your_qq_email@qq.com +MAIL_PASSWORD=your_qq_auth_code +``` + +## 故障排除 + +### 如果仍然无法发送邮件 +1. 检查后端环境变量是否正确设置 +2. 确认QQ邮箱已开启SMTP服务并获取授权码 +3. 检查网络连接是否正常 +4. 查看浏览器开发者工具的Network标签,确认API请求状态 +5. 查看后端控制台日志,确认具体错误信息 + +### 常见错误 +- **535 Authentication failed**:QQ邮箱授权码错误 +- **Network Error**:前后端连接问题 +- **Timeout**:网络超时或SMTP服务器响应慢 + +## 注意事项 +- 仅支持QQ邮箱系列(qq.com、vip.qq.com、foxmail.com) +- 验证码有效期为10分钟 +- 同一邮箱60秒内只能发送一次验证码 +- 验证码最多尝试5次 + +--- + +**修复完成时间**:2025年9月2日 +**修复内容**:API响应拦截器格式问题 +**测试状态**:✅ 后端功能正常,前端API调用已修复 \ No newline at end of file diff --git a/frontend/react-app/src/pages/AiModelPage.js b/frontend/react-app/src/pages/AiModelPage.js new file mode 100644 index 00000000..881329d5 --- /dev/null +++ b/frontend/react-app/src/pages/AiModelPage.js @@ -0,0 +1,287 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import styled from 'styled-components'; +import { FiCpu, FiLock, FiMessageCircle, FiImage, FiFileText, FiUser } from 'react-icons/fi'; +import { useUser } from '../contexts/UserContext'; + +const AiContainer = styled.div` + min-height: calc(100vh - 140px); + padding: 20px 0; +`; + +const Container = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +`; + +const PageHeader = styled.div` + text-align: center; + margin-bottom: 40px; + padding: 40px 20px; + background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); + border-radius: 16px; +`; + +const PageTitle = styled.h1` + font-size: 32px; + font-weight: bold; + color: #1f2937; + margin-bottom: 16px; + + .title-emoji { + margin: 0 8px; + } + + @media (max-width: 768px) { + font-size: 24px; + } +`; + +const PageDescription = styled.p` + font-size: 16px; + color: #6b7280; + line-height: 1.6; +`; + +const LoginPrompt = styled.div` + background: white; + border-radius: 16px; + padding: 60px 40px; + text-align: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + margin-bottom: 40px; +`; + +const LoginIcon = styled.div` + font-size: 64px; + margin-bottom: 24px; +`; + +const LoginTitle = styled.h2` + font-size: 24px; + font-weight: bold; + color: #1f2937; + margin-bottom: 16px; +`; + +const LoginText = styled.p` + color: #6b7280; + font-size: 16px; + line-height: 1.6; + margin-bottom: 24px; +`; + +const LoginButton = styled.button` + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + padding: 14px 32px; + border-radius: 8px; + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: all 0.2s ease; + display: inline-flex; + align-items: center; + gap: 8px; + + &:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3); + } +`; + +const FeatureGrid = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 20px; + margin-bottom: 40px; +`; + +const FeatureCard = styled.div` + background: white; + border-radius: 12px; + padding: 24px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + position: relative; + + &:hover { + transform: translateY(-4px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); + } +`; + +const FeatureIcon = styled.div` + width: 48px; + height: 48px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 20px; + margin-bottom: 16px; +`; + +const FeatureTitle = styled.h3` + font-size: 18px; + font-weight: bold; + color: #1f2937; + margin-bottom: 8px; +`; + +const FeatureDescription = styled.p` + color: #6b7280; + font-size: 14px; + line-height: 1.5; + margin-bottom: 12px; +`; + +const FeatureStatus = styled.div` + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + color: #f59e0b; + font-weight: 500; +`; + +const LockOverlay = styled.div` + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.9); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(2px); +`; + +const LockIcon = styled.div` + font-size: 32px; + color: #9ca3af; +`; + +const AiModelPage = () => { + const { isLoggedIn, isLoading } = useUser(); + const navigate = useNavigate(); + + const handleLogin = () => { + navigate('/login'); + }; + + const aiFeatures = [ + { + icon: , + title: 'AI对话助手', + description: '智能对话机器人,回答问题、提供建议、进行闲聊', + status: '开发中' + }, + { + icon: , + title: '智能文本生成', + description: '根据提示生成文章、总结、翻译等文本内容', + status: '开发中' + }, + { + icon: , + title: '图像识别分析', + description: '上传图片进行内容识别、文字提取、场景分析', + status: '规划中' + }, + { + icon: , + title: '数据智能处理', + description: '自动化数据分析、图表生成、趋势预测', + status: '规划中' + } + ]; + + if (isLoading) { + return ( + + +
+
+

加载中...

+
+
+
+ ); + } + + return ( + + + + + 🤖 + AI模型 + 🤖 + + + 智能AI工具和模型应用,提供对话、文本生成、图像识别等功能 + + + + {!isLoggedIn ? ( + + 🔒 + 需要登录访问 + + AI模型功能需要登录后才能使用,请先登录您的账户。 +
+ 登录后即可体验强大的AI工具和服务。 +
+ + + 立即登录 + +
+ ) : ( + + 🚧 + 功能开发中 + + AI模型功能正在紧张开发中,即将为您带来强大的人工智能体验。 +
+ 感谢您的耐心等待! +
+
+ )} + + + {aiFeatures.map((feature, index) => ( + + + {feature.icon} + + {feature.title} + {feature.description} + + + {feature.status} + + + {!isLoggedIn && ( + + + + + + )} + + ))} + +
+
+ ); +}; + +export default AiModelPage; diff --git a/frontend/react-app/src/pages/Api60sPage.js b/frontend/react-app/src/pages/Api60sPage.js new file mode 100644 index 00000000..e10a7453 --- /dev/null +++ b/frontend/react-app/src/pages/Api60sPage.js @@ -0,0 +1,427 @@ +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { FiActivity, FiStar, FiExternalLink, FiArrowLeft } from 'react-icons/fi'; + +const Api60sContainer = styled.div` + min-height: calc(100vh - 140px); + padding: 20px 0; +`; + +const Container = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +`; + +const Header = styled.div` + text-align: center; + margin-bottom: 40px; +`; + +const Title = styled.h1` + color: white; + font-size: 32px; + font-weight: 700; + margin-bottom: 10px; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); +`; + +const Subtitle = styled.p` + color: rgba(255, 255, 255, 0.8); + font-size: 18px; + max-width: 600px; + margin: 0 auto; +`; + +const CategorySection = styled.div` + margin-bottom: 50px; +`; + +const CategoryTitle = styled.h2` + color: rgba(255, 255, 255, 0.95); + font-size: 24px; + font-weight: 600; + margin-bottom: 20px; + display: flex; + align-items: center; + gap: 10px; + text-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); +`; + +const CategoryGrid = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); + gap: 12px; + + @media (max-width: 768px) { + grid-template-columns: repeat(2, 1fr); + gap: 10px; + } +`; + +const ApiCard = styled.div` + background: rgba(255, 255, 255, 0.98); + border-radius: 16px; + padding: 16px; + text-decoration: none; + color: inherit; + transition: all 0.2s ease; + border: none; + position: relative; + overflow: hidden; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + cursor: pointer; + min-height: 80px; + display: flex; + align-items: center; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: ${props => props.color || 'linear-gradient(135deg, #81c784 0%, #a5d6a7 100%)'}; + } + + &:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + + &:active { + transform: translateY(0); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + } +`; + +const CardHeader = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; +`; + +const CardIcon = styled.div` + font-size: 20px; + color: ${props => props.color || '#66bb6a'}; + margin-right: 10px; + flex-shrink: 0; +`; + +const CardTitle = styled.h3` + font-size: 15px; + font-weight: 600; + color: #2e7d32; + margin: 0; + flex: 1; + line-height: 1.3; + + @media (max-width: 768px) { + font-size: 14px; + } +`; + +const ExternalIcon = styled.div` + font-size: 14px; + color: #81c784; + opacity: 0.7; + flex-shrink: 0; +`; + + + + + +const EmbeddedContainer = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #000; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 0; +`; + +const EmbeddedContent = styled.div` + background: white; + border-radius: 0; + width: 100%; + height: 100%; + position: relative; + overflow: hidden; + box-shadow: none; +`; + +const EmbeddedHeader = styled.div` + background: linear-gradient(135deg, #4caf50, #66bb6a); + color: white; + padding: 15px 20px; + padding-top: max(15px, env(safe-area-inset-top)); + display: flex; + align-items: center; + justify-content: space-between; + position: relative; + z-index: 1001; +`; + +const BackButton = styled.button` + background: rgba(255, 255, 255, 0.2); + border: none; + color: white; + padding: 8px 16px; + border-radius: 20px; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + transition: all 0.3s ease; + + &:hover { + background: rgba(255, 255, 255, 0.3); + } +`; + +const EmbeddedFrame = styled.iframe` + width: 100%; + height: calc(100% - 60px); + border: none; + background: white; + position: relative; + z-index: 1000; +`; + +const Api60sPage = () => { + const [mounted, setMounted] = useState(false); + const [apiCategories, setApiCategories] = useState([]); + const [loading, setLoading] = useState(true); + const [embeddedApi, setEmbeddedApi] = useState(null); + + // 动态扫描60sapi文件夹 + const scanApiModules = async () => { + try { + // 定义分类配置 + const categoryConfig = { + '热搜榜单': { + icon: , + color: '#66bb6a' + }, + '日更资讯': { + icon: , + color: '#4caf50' + }, + '实用功能': { + icon: , + color: '#388e3c' + }, + '娱乐消遣': { + icon: , + color: '#66bb6a' + } + }; + + // 颜色渐变配置 + const gradientColors = [ + 'linear-gradient(135deg, #81c784 0%, #66bb6a 100%)', + 'linear-gradient(135deg, #a5d6a7 0%, #81c784 100%)', + 'linear-gradient(135deg, #c8e6c9 0%, #a5d6a7 100%)', + 'linear-gradient(135deg, #66bb6a 0%, #4caf50 100%)', + 'linear-gradient(135deg, #4caf50 0%, #388e3c 100%)' + ]; + + // 从后端API获取目录结构 + const scanDirectories = async () => { + try { + const response = await fetch('http://localhost:5000/api/60s/scan-directories'); + if (response.ok) { + const data = await response.json(); + return data; + } + } catch (error) { + console.warn('无法从后端获取目录结构,使用前端扫描方式'); + } + return null; + }; + + // 前端扫描方式(备用) + const frontendScan = async () => { + const categories = []; + + for (const [categoryName, config] of Object.entries(categoryConfig)) { + const apis = []; + + // 尝试访问已知的模块列表(只包含实际存在的模块) + const knownModules = { + '热搜榜单': ['抖音热搜榜'], + '日更资讯': [], + '实用功能': [], + '娱乐消遣': [] + }; + + const moduleNames = knownModules[categoryName] || []; + + for (let i = 0; i < moduleNames.length; i++) { + const moduleName = moduleNames[i]; + try { + const indexPath = `/60sapi/${categoryName}/${moduleName}/index.html`; + const response = await fetch(indexPath, { method: 'HEAD' }); + + if (response.ok) { + // 获取页面标题 + const htmlResponse = await fetch(indexPath); + const html = await htmlResponse.text(); + const titleMatch = html.match(/(.*?)<\/title>/i); + const title = titleMatch ? titleMatch[1].trim() : moduleName; + + apis.push({ + title, + description: `${moduleName}相关功能`, + link: `http://localhost:5000${indexPath}`, + status: 'active', + color: gradientColors[i % gradientColors.length] + }); + } + } catch (error) { + // 忽略访问失败的模块 + } + } + + if (apis.length > 0) { + categories.push({ + title: categoryName, + icon: config.icon, + color: config.color, + apis + }); + } + } + + return categories; + }; + + // 首先尝试后端扫描,失败则使用前端扫描 + const backendResult = await scanDirectories(); + if (backendResult && backendResult.success) { + return backendResult.categories || []; + } else { + return await frontendScan(); + } + + } catch (error) { + console.error('扫描API模块时出错:', error); + return []; + } + }; + + useEffect(() => { + const loadApiModules = async () => { + setLoading(true); + const categories = await scanApiModules(); + setApiCategories(categories); + setLoading(false); + setMounted(true); + }; + + loadApiModules(); + }, []); + + // 处理API卡片点击 + const handleApiClick = (api) => { + setEmbeddedApi(api); + }; + + // 关闭内嵌显示 + const closeEmbedded = () => { + setEmbeddedApi(null); + }; + + if (!mounted || loading) { + return ( + <Api60sContainer> + <Container> + <Header> + <Title>60s API 数据聚合 + 正在加载API模块... +
+ + + ); + } + + return ( + + +
+ 60s API 数据聚合 + + 提供丰富的实时数据接口,涵盖热搜榜单、日更资讯、实用工具和娱乐功能 + +
+ + {apiCategories.length === 0 ? ( + +
+

暂无可用的API模块

+

请检查60sapi目录结构或联系管理员

+
+
+ ) : ( + apiCategories.map((category, index) => ( + + + {category.icon} + {category.title} + + + {category.apis.map((api, apiIndex) => ( + handleApiClick(api)} + color={api.color} + > + + + {category.icon} + + {api.title} + + + + + + ))} + + + )) + )} +
+ + {/* 内嵌显示组件 */} + {embeddedApi && ( + + e.stopPropagation()}> + +

{embeddedApi.title}

+ + + 返回 + +
+ +
+
+ )} +
+ ); +}; + +export default Api60sPage; diff --git a/frontend/react-app/src/pages/HomePage.js b/frontend/react-app/src/pages/HomePage.js new file mode 100644 index 00000000..1588b82c --- /dev/null +++ b/frontend/react-app/src/pages/HomePage.js @@ -0,0 +1,278 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import styled from 'styled-components'; +import { FiActivity, FiGrid, FiCpu, FiTrendingUp } from 'react-icons/fi'; + +const HomeContainer = styled.div` + min-height: calc(100vh - 140px); + padding: 20px 0; +`; + +const HeroSection = styled.section` + background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); + padding: 60px 0; + text-align: center; + margin-bottom: 40px; +`; + +const HeroContent = styled.div` + max-width: 800px; + margin: 0 auto; + padding: 0 16px; +`; + +const HeroTitle = styled.h1` + font-size: 36px; + font-weight: bold; + color: #1f2937; + margin-bottom: 16px; + + .title-emoji { + margin: 0 8px; + } + + @media (max-width: 768px) { + font-size: 28px; + } +`; + +const HeroSubtitle = styled.p` + font-size: 18px; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 32px; + line-height: 1.6; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + + @media (max-width: 768px) { + font-size: 16px; + } +`; + +const HeroButton = styled(Link)` + display: inline-flex; + align-items: center; + gap: 8px; + background: linear-gradient(135deg, #81c784 0%, #a5d6a7 100%); + color: white; + padding: 16px 32px; + border-radius: 16px; + text-decoration: none; + font-weight: 600; + font-size: 16px; + transition: all 0.3s ease; + box-shadow: 0 8px 32px rgba(129, 199, 132, 0.4); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + + &:hover { + transform: translateY(-3px); + box-shadow: 0 12px 40px rgba(129, 199, 132, 0.5); + background: linear-gradient(135deg, #66bb6a 0%, #81c784 100%); + } +`; + +const Container = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +`; + +const SectionTitle = styled.h2` + font-size: 24px; + font-weight: bold; + color: #1f2937; + margin-bottom: 24px; + text-align: center; + + .section-emoji { + margin-right: 12px; + } +`; + +const ModuleGrid = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 24px; + margin-bottom: 60px; + + @media (max-width: 768px) { + grid-template-columns: 1fr; + gap: 16px; + } +`; + +const ModuleCard = styled(Link)` + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 32px 24px; + text-decoration: none; + color: inherit; + box-shadow: 0 8px 32px rgba(168, 230, 207, 0.3); + transition: all 0.3s ease; + border: 1px solid rgba(168, 230, 207, 0.2); + backdrop-filter: blur(10px); + + &:hover { + transform: translateY(-6px); + box-shadow: 0 12px 40px rgba(168, 230, 207, 0.4); + border-color: #81c784; + background: rgba(255, 255, 255, 0.98); + } +`; + +const ModuleIcon = styled.div` + width: 60px; + height: 60px; + background: linear-gradient(135deg, #81c784 0%, #a5d6a7 100%); + border-radius: 20px; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 24px; + margin-bottom: 20px; + box-shadow: 0 4px 16px rgba(129, 199, 132, 0.3); +`; + +const ModuleTitle = styled.h3` + font-size: 20px; + font-weight: bold; + color: #2e7d32; + margin-bottom: 12px; +`; + +const ModuleDescription = styled.p` + color: #4a4a4a; + line-height: 1.6; + margin-bottom: 16px; +`; + +const ModuleFeatures = styled.ul` + list-style: none; + padding: 0; + margin: 0; +`; + +const ModuleFeature = styled.li` + color: #374151; + font-size: 14px; + margin-bottom: 8px; + padding-left: 20px; + position: relative; + + &:before { + content: '✓'; + position: absolute; + left: 0; + color: #10b981; + font-weight: bold; + } + + &:last-child { + margin-bottom: 0; + } +`; + + + +const HomePage = () => { + + const modules = [ + { + path: '/60sapi', + icon: FiActivity, + title: '60s API', + description: '实时获取各种热门数据和资讯信息', + features: [ + '抖音热搜榜单', + '微博热搜话题', + '猫眼票房排行', + '每日60秒读懂世界', + '必应每日壁纸', + '实时天气信息' + ] + }, + { + path: '/smallgame', + icon: FiGrid, + title: '小游戏', + description: '轻松有趣的休闲小游戏合集', + features: [ + '经典益智游戏', + '休闲娱乐游戏', + '技能挑战游戏', + '即点即玩', + '无需下载', + '移动端优化' + ] + }, + { + path: '/aimodel', + icon: FiCpu, + title: 'AI模型', + description: '智能AI工具和模型应用', + features: [ + 'AI对话助手', + '智能文本生成', + '图像识别分析', + '数据智能处理', + '个性化推荐', + '需要登录使用' + ] + } + ]; + + return ( + + + + + + 神奇万事通 + + + + 🎨 一个多功能的聚合软件应用 💬 +
+ 提供实时数据、娱乐游戏、AI工具等丰富功能 +
+ + + 开始探索 + +
+
+ + + + 🚀 + 功能模块 + + + + {modules.map((module) => { + const IconComponent = module.icon; + return ( + + + + + {module.title} + {module.description} + + {module.features.map((feature, index) => ( + {feature} + ))} + + + ); + })} + + + + +
+ ); +}; + +export default HomePage; diff --git a/frontend/react-app/src/pages/LoginPage.js b/frontend/react-app/src/pages/LoginPage.js new file mode 100644 index 00000000..d90bd232 --- /dev/null +++ b/frontend/react-app/src/pages/LoginPage.js @@ -0,0 +1,593 @@ +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { FiMail, FiUser, FiLock, FiEye, FiEyeOff, FiCheck } from 'react-icons/fi'; +import { authAPI } from '../utils/api'; +import toast from 'react-hot-toast'; +import { useNavigate } from 'react-router-dom'; +import { useUser } from '../contexts/UserContext'; + +const LoginContainer = styled.div` + min-height: calc(100vh - 140px); + display: flex; + align-items: center; + justify-content: center; + padding: 20px; +`; + +const LoginCard = styled.div` + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 40px; + box-shadow: 0 15px 35px rgba(168, 230, 207, 0.3); + width: 100%; + max-width: 420px; + backdrop-filter: blur(15px); + border: 1px solid rgba(168, 230, 207, 0.3); +`; + +const Title = styled.h1` + text-align: center; + margin-bottom: 30px; + color: #2e7d32; + font-size: 28px; + font-weight: 700; +`; + +const TabContainer = styled.div` + display: flex; + margin-bottom: 30px; + background: #f1f8e9; + border-radius: 12px; + padding: 4px; +`; + +const Tab = styled.button` + flex: 1; + padding: 12px 20px; + border: none; + background: ${props => props.active ? '#81c784' : 'transparent'}; + color: ${props => props.active ? 'white' : '#666'}; + border-radius: 10px; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: ${props => props.active ? '#81c784' : '#e8f5e8'}; + } +`; + +const Form = styled.form` + display: flex; + flex-direction: column; + gap: 20px; +`; + +const InputGroup = styled.div` + position: relative; +`; + +const Input = styled.input` + width: 100%; + padding: 15px 20px 15px 50px; + border: 2px solid #e8f5e8; + border-radius: 14px; + font-size: 16px; + transition: all 0.3s ease; + background: #fafffe; + box-sizing: border-box; + + &:focus { + outline: none; + border-color: #81c784; + background: white; + box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.1); + } + + &::placeholder { + color: #adb5bd; + } +`; + +const InputIcon = styled.div` + position: absolute; + left: 15px; + top: 50%; + transform: translateY(-50%); + color: #81c784; + font-size: 18px; +`; + +const PasswordToggle = styled.button` + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: #adb5bd; + cursor: pointer; + font-size: 18px; + + &:hover { + color: #66bb6a; + } +`; + +const VerificationGroup = styled.div` + display: flex; + gap: 10px; + align-items: start; +`; + +const VerificationInput = styled(Input)` + flex: 1; + padding-right: 15px; +`; + +const SendCodeButton = styled.button` + padding: 15px 20px; + background: ${props => props.disabled ? '#e8f5e8' : 'linear-gradient(135deg, #81c784 0%, #66bb6a 100%)'}; + color: ${props => props.disabled ? '#adb5bd' : 'white'}; + border: none; + border-radius: 14px; + font-size: 14px; + font-weight: 600; + cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'}; + transition: all 0.3s ease; + white-space: nowrap; + min-width: 100px; + + &:hover { + transform: ${props => props.disabled ? 'none' : 'translateY(-2px)'}; + box-shadow: ${props => props.disabled ? 'none' : '0 8px 25px rgba(129, 199, 132, 0.3)'}; + } +`; + +const SubmitButton = styled.button` + width: 100%; + padding: 16px; + background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); + color: white; + border: none; + border-radius: 14px; + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + margin-top: 12px; + box-shadow: 0 4px 20px rgba(129, 199, 132, 0.3); + + &:hover { + transform: translateY(-2px); + box-shadow: 0 8px 30px rgba(129, 199, 132, 0.4); + } + + &:disabled { + opacity: 0.7; + cursor: not-allowed; + transform: none; + } +`; + +const ErrorMessage = styled.div` + color: #e57373; + font-size: 14px; + margin-top: 5px; +`; + +const QQHint = styled.div` + background: #e8f5e8; + padding: 12px 16px; + border-radius: 10px; + margin-bottom: 20px; + font-size: 14px; + color: #4a4a4a; + display: flex; + align-items: center; + gap: 8px; +`; + +const AvatarPreview = styled.div` + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; + + img { + width: 64px; + height: 64px; + border-radius: 50%; + border: 3px solid #81c784; + object-fit: cover; + } +`; + +const LoginMethod = styled.div` + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 15px; + padding: 12px; + background: #f8f9fa; + border-radius: 10px; + font-size: 14px; + color: #666; + + input[type="radio"] { + margin: 0; + margin-right: 8px; + } + + label { + cursor: pointer; + } +`; + +const LoginPage = () => { + const { login, getQQAvatar } = useUser(); + const [activeTab, setActiveTab] = useState('login'); + const [showPassword, setShowPassword] = useState(false); + const [loading, setLoading] = useState(false); + const [sendingCode, setSendingCode] = useState(false); + const [countdown, setCountdown] = useState(0); + const [loginMethod, setLoginMethod] = useState('password'); // 'password' or 'code' + const [formData, setFormData] = useState({ + email: '', + username: '', + password: '', + confirmPassword: '', + code: '' + }); + const [errors, setErrors] = useState({}); + const [avatarUrl, setAvatarUrl] = useState(''); + const navigate = useNavigate(); + + // 倒计时效果 + useEffect(() => { + let timer; + if (countdown > 0) { + timer = setTimeout(() => setCountdown(countdown - 1), 1000); + } + return () => clearTimeout(timer); + }, [countdown]); + + const handleInputChange = (e) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + + // 清除对应字段的错误 + if (errors[name]) { + setErrors(prev => ({ + ...prev, + [name]: '' + })); + } + + // 预览QQ头像 + if (name === 'email' && isQQEmail(value)) { + const avatar = getQQAvatar(value); + setAvatarUrl(avatar || ''); + } + }; + + const isQQEmail = (email) => { + const qqDomains = ['qq.com', 'vip.qq.com', 'foxmail.com']; + if (!email || !email.includes('@')) return false; + const domain = email.split('@')[1]?.toLowerCase(); + return qqDomains.includes(domain); + }; + + const validateForm = () => { + const newErrors = {}; + + if (!formData.email.trim()) { + newErrors.email = '邮箱地址不能为空'; + } else if (!isQQEmail(formData.email)) { + newErrors.email = '仅支持QQ邮箱(qq.com、vip.qq.com、foxmail.com)'; + } + + if (activeTab === 'register') { + if (!formData.username.trim()) { + newErrors.username = '用户名不能为空'; + } + + if (!formData.password.trim()) { + newErrors.password = '密码不能为空'; + } else if (formData.password.length < 6) { + newErrors.password = '密码长度至少6位'; + } + + if (formData.password !== formData.confirmPassword) { + newErrors.confirmPassword = '两次输入的密码不一致'; + } + + if (!formData.code.trim()) { + newErrors.code = '验证码不能为空'; + } + } else { + // 登录验证 + if (loginMethod === 'password') { + if (!formData.password.trim()) { + newErrors.password = '密码不能为空'; + } + } else { + if (!formData.code.trim()) { + newErrors.code = '验证码不能为空'; + } + } + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const sendVerificationCode = async () => { + if (!formData.email.trim()) { + toast.error('请先输入邮箱地址'); + return; + } + + if (!isQQEmail(formData.email)) { + toast.error('仅支持QQ邮箱'); + return; + } + + setSendingCode(true); + + try { + const response = await authAPI.sendVerification({ + email: formData.email, + type: activeTab + }); + + if (response.data.success) { + toast.success('验证码已发送到您的邮箱'); + setCountdown(60); + } else { + toast.error(response.data.message || '发送失败'); + } + } catch (error) { + console.error('发送验证码失败:', error); + toast.error(error.response?.data?.message || '发送失败,请重试'); + } finally { + setSendingCode(false); + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + + if (!validateForm()) { + return; + } + + setLoading(true); + + try { + if (activeTab === 'login') { + const loginData = { email: formData.email }; + + if (loginMethod === 'password') { + loginData.password = formData.password; + } else { + loginData.code = formData.code; + } + + const result = await login(loginData); + + if (result.success) { + navigate('/'); + } + } else { + const response = await authAPI.register({ + email: formData.email, + username: formData.username, + password: formData.password, + code: formData.code + }); + + if (response.data.success) { + toast.success('注册成功!请登录'); + setActiveTab('login'); + setFormData({ + email: '', + username: '', + password: '', + confirmPassword: '', + code: '' + }); + } else { + toast.error(response.data.message || '注册失败'); + } + } + } catch (error) { + console.error('操作失败:', error); + toast.error(error.response?.data?.message || '操作失败,请重试'); + } finally { + setLoading(false); + } + }; + + const switchTab = (tab) => { + setActiveTab(tab); + setLoginMethod('password'); + setErrors({}); + setFormData({ + email: '', + username: '', + password: '', + confirmPassword: '', + code: '' + }); + setAvatarUrl(''); + }; + + return ( + + + {activeTab === 'login' ? '欢迎回来' : '创建账户'} + + {avatarUrl && ( + + QQ头像 setAvatarUrl('')} /> + + )} + + + switchTab('login')} + type="button" + > + 登录 + + switchTab('register')} + type="button" + > + 注册 + + + + + + 仅支持QQ邮箱登录注册,会自动获取您的QQ头像 + + + {activeTab === 'login' && ( +
+ + setLoginMethod(e.target.value)} + /> + + + + setLoginMethod(e.target.value)} + /> + + +
+ )} + +
+ + + + + + {errors.email && {errors.email}} + + + {activeTab === 'register' && ( + + + + + + {errors.username && {errors.username}} + + )} + + {(activeTab === 'register' || (activeTab === 'login' && loginMethod === 'password')) && ( + + + + + + setShowPassword(!showPassword)} + > + {showPassword ? : } + + {errors.password && {errors.password}} + + )} + + {activeTab === 'register' && ( + + + + + + {errors.confirmPassword && {errors.confirmPassword}} + + )} + + {(activeTab === 'register' || (activeTab === 'login' && loginMethod === 'code')) && ( + + + + + + + {errors.code && {errors.code}} + + 0} + > + {sendingCode ? '发送中...' : countdown > 0 ? `${countdown}s` : '发送验证码'} + + + )} + + + {loading ? '处理中...' : (activeTab === 'login' ? '登录' : '注册')} + +
+
+
+ ); +}; + +export default LoginPage; diff --git a/frontend/react-app/src/pages/SmallGamePage.js b/frontend/react-app/src/pages/SmallGamePage.js new file mode 100644 index 00000000..cda9c625 --- /dev/null +++ b/frontend/react-app/src/pages/SmallGamePage.js @@ -0,0 +1,183 @@ +import React from 'react'; +import styled from 'styled-components'; +import { FiGrid, FiPlay, FiZap, FiHeart } from 'react-icons/fi'; + +const GameContainer = styled.div` + min-height: calc(100vh - 140px); + padding: 20px 0; +`; + +const Container = styled.div` + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +`; + +const PageHeader = styled.div` + text-align: center; + margin-bottom: 40px; + padding: 40px 20px; + background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); + border-radius: 16px; +`; + +const PageTitle = styled.h1` + font-size: 32px; + font-weight: bold; + color: #1f2937; + margin-bottom: 16px; + + .title-emoji { + margin: 0 8px; + } + + @media (max-width: 768px) { + font-size: 24px; + } +`; + +const PageDescription = styled.p` + font-size: 16px; + color: #6b7280; + line-height: 1.6; +`; + +const ComingSoonCard = styled.div` + background: white; + border-radius: 16px; + padding: 60px 40px; + text-align: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + margin-bottom: 40px; +`; + +const ComingSoonIcon = styled.div` + font-size: 64px; + margin-bottom: 24px; +`; + +const ComingSoonTitle = styled.h2` + font-size: 24px; + font-weight: bold; + color: #1f2937; + margin-bottom: 16px; +`; + +const ComingSoonText = styled.p` + color: #6b7280; + font-size: 16px; + line-height: 1.6; + margin-bottom: 24px; +`; + +const FeatureGrid = styled.div` + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 20px; + margin-bottom: 40px; +`; + +const FeatureCard = styled.div` + background: white; + border-radius: 12px; + padding: 24px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + + &:hover { + transform: translateY(-4px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); + } +`; + +const FeatureIcon = styled.div` + width: 48px; + height: 48px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 20px; + margin-bottom: 16px; +`; + +const FeatureTitle = styled.h3` + font-size: 18px; + font-weight: bold; + color: #1f2937; + margin-bottom: 8px; +`; + +const FeatureDescription = styled.p` + color: #6b7280; + font-size: 14px; + line-height: 1.5; +`; + +const SmallGamePage = () => { + const plannedFeatures = [ + { + icon: , + title: '经典游戏', + description: '俄罗斯方块、贪吃蛇、2048等经典小游戏' + }, + { + icon: , + title: '反应游戏', + description: '测试反应速度和手眼协调能力的趣味游戏' + }, + { + icon: , + title: '休闲游戏', + description: '轻松愉快的休闲娱乐游戏,适合放松心情' + }, + { + icon: , + title: '益智游戏', + description: '锻炼思维能力的益智类游戏和谜题' + } + ]; + + return ( + + + + + 🎮 + 小游戏 + 🎮 + + + 轻松有趣的休闲小游戏合集,即点即玩,无需下载 + + + + + 🚧 + 敬请期待 + + 小游戏模块正在开发中,即将为您带来丰富多彩的游戏体验。 +
+ 所有游戏都经过移动端优化,支持触屏操作。 +
+
+ + + {plannedFeatures.map((feature, index) => ( + + + {feature.icon} + + {feature.title} + {feature.description} + + ))} + +
+
+ ); +}; + +export default SmallGamePage; diff --git a/frontend/react-app/src/styles/global.css b/frontend/react-app/src/styles/global.css new file mode 100644 index 00000000..c421d617 --- /dev/null +++ b/frontend/react-app/src/styles/global.css @@ -0,0 +1,332 @@ +/* 全局组件样式 */ + +/* 容器样式 */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 16px; +} + +.mobile-container { + padding: 0 12px; +} + +/* 卡片样式 */ +.card { + background: rgba(255, 255, 255, 0.95); + border-radius: 16px; + box-shadow: 0 8px 32px rgba(168, 230, 207, 0.3); + overflow: hidden; + transition: all 0.3s ease; + backdrop-filter: blur(10px); + border: 1px solid rgba(168, 230, 207, 0.2); +} + +.card:hover { + transform: translateY(-6px); + box-shadow: 0 12px 40px rgba(168, 230, 207, 0.4); +} + +.card-header { + padding: 20px; + border-bottom: 1px solid #e5e7eb; +} + +.card-body { + padding: 20px; +} + +.card-footer { + padding: 16px 20px; + background: #f9fafb; + border-top: 1px solid #e5e7eb; +} + +/* 按钮样式 */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 12px 24px; + border-radius: 8px; + font-weight: 500; + font-size: 14px; + transition: all 0.2s ease; + cursor: pointer; + border: none; + text-decoration: none; + min-height: 44px; +} + +.btn-primary { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +.btn-primary:hover { + background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%); + transform: translateY(-1px); +} + +.btn-secondary { + background: #f3f4f6; + color: #374151; +} + +.btn-secondary:hover { + background: #e5e7eb; +} + +.btn-success { + background: #10b981; + color: white; +} + +.btn-success:hover { + background: #059669; +} + +.btn-danger { + background: #ef4444; + color: white; +} + +.btn-danger:hover { + background: #dc2626; +} + +.btn-sm { + padding: 8px 16px; + font-size: 12px; + min-height: 36px; +} + +.btn-lg { + padding: 16px 32px; + font-size: 16px; + min-height: 52px; +} + +.btn-full { + width: 100%; +} + +.btn-disabled { + opacity: 0.6; + cursor: not-allowed; + pointer-events: none; +} + +/* 输入框样式 */ +.input { + width: 100%; + padding: 12px 16px; + border: 2px solid #e5e7eb; + border-radius: 8px; + font-size: 14px; + transition: all 0.2s ease; + min-height: 44px; +} + +.input:focus { + border-color: #667eea; + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); +} + +.input-error { + border-color: #ef4444; +} + +.input-error:focus { + border-color: #ef4444; + box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1); +} + +/* 加载动画 */ +.loading { + display: flex; + align-items: center; + justify-content: center; + padding: 40px; +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #f3f4f6; + border-top: 4px solid #667eea; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +.spinner-sm { + width: 20px; + height: 20px; + border-width: 2px; +} + +/* 标签样式 */ +.tag { + display: inline-block; + padding: 4px 12px; + background: #f3f4f6; + color: #374151; + border-radius: 16px; + font-size: 12px; + font-weight: 500; +} + +.tag-primary { + background: rgba(102, 126, 234, 0.1); + color: #667eea; +} + +.tag-success { + background: rgba(16, 185, 129, 0.1); + color: #10b981; +} + +.tag-warning { + background: rgba(245, 158, 11, 0.1); + color: #f59e0b; +} + +.tag-danger { + background: rgba(239, 68, 68, 0.1); + color: #ef4444; +} + +/* 徽章样式 */ +.badge { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 20px; + height: 20px; + padding: 0 6px; + background: #ef4444; + color: white; + border-radius: 10px; + font-size: 11px; + font-weight: 600; + line-height: 1; +} + +/* 分割线 */ +.divider { + height: 1px; + background: #e5e7eb; + margin: 16px 0; +} + +/* 空状态 */ +.empty-state { + text-align: center; + padding: 60px 20px; + color: #6b7280; +} + +.empty-state-icon { + font-size: 48px; + margin-bottom: 16px; + opacity: 0.5; +} + +.empty-state-title { + font-size: 18px; + font-weight: 600; + margin-bottom: 8px; + color: #374151; +} + +.empty-state-description { + font-size: 14px; + line-height: 1.5; +} + +/* 错误状态 */ +.error-state { + text-align: center; + padding: 40px 20px; + color: #ef4444; +} + +.error-state-icon { + font-size: 36px; + margin-bottom: 12px; +} + +.error-state-title { + font-size: 16px; + font-weight: 600; + margin-bottom: 8px; +} + +.error-state-description { + font-size: 14px; + color: #6b7280; + margin-bottom: 16px; +} + +/* 网格布局 */ +.grid { + display: grid; + gap: 16px; +} + +.grid-1 { + grid-template-columns: 1fr; +} + +.grid-2 { + grid-template-columns: repeat(2, 1fr); +} + +.grid-3 { + grid-template-columns: repeat(3, 1fr); +} + +.grid-4 { + grid-template-columns: repeat(4, 1fr); +} + +@media (max-width: 768px) { + .grid-2, + .grid-3, + .grid-4 { + grid-template-columns: 1fr; + } + + .mobile-grid-2 { + grid-template-columns: repeat(2, 1fr); + } +} + +/* 间距工具 */ +.mt-1 { margin-top: 4px; } +.mt-2 { margin-top: 8px; } +.mt-3 { margin-top: 12px; } +.mt-4 { margin-top: 16px; } +.mt-5 { margin-top: 20px; } +.mt-6 { margin-top: 24px; } + +.mb-1 { margin-bottom: 4px; } +.mb-2 { margin-bottom: 8px; } +.mb-3 { margin-bottom: 12px; } +.mb-4 { margin-bottom: 16px; } +.mb-5 { margin-bottom: 20px; } +.mb-6 { margin-bottom: 24px; } + +.pt-1 { padding-top: 4px; } +.pt-2 { padding-top: 8px; } +.pt-3 { padding-top: 12px; } +.pt-4 { padding-top: 16px; } +.pt-5 { padding-top: 20px; } +.pt-6 { padding-top: 24px; } + +.pb-1 { padding-bottom: 4px; } +.pb-2 { padding-bottom: 8px; } +.pb-3 { padding-bottom: 12px; } +.pb-4 { padding-bottom: 16px; } +.pb-5 { padding-bottom: 20px; } +.pb-6 { padding-bottom: 24px; } diff --git a/frontend/react-app/src/styles/index.css b/frontend/react-app/src/styles/index.css new file mode 100644 index 00000000..27290cf4 --- /dev/null +++ b/frontend/react-app/src/styles/index.css @@ -0,0 +1,219 @@ +/* 全局样式重置 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + font-size: 16px; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + line-height: 1.6; + color: #333; + background: #f5f7fa; + overflow-x: hidden; +} + +/* 移动端适配 */ +@media (max-width: 768px) { + html { + font-size: 14px; + } +} + +/* 链接样式 */ +a { + color: inherit; + text-decoration: none; +} + +/* 按钮重置 */ +button { + border: none; + background: none; + cursor: pointer; + font-family: inherit; +} + +/* 输入框重置 */ +input, textarea { + border: none; + outline: none; + font-family: inherit; +} + +/* 列表重置 */ +ul, ol { + list-style: none; +} + +/* 图片响应式 */ +img { + max-width: 100%; + height: auto; +} + +/* 滚动条样式 */ +::-webkit-scrollbar { + width: 6px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; +} + +/* 公共动画 */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* 公共工具类 */ +.fade-in { + animation: fadeIn 0.6s ease-out; +} + +.pulse { + animation: pulse 2s infinite; +} + +.spin { + animation: spin 1s linear infinite; +} + +.text-center { + text-align: center; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.flex { + display: flex; +} + +.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; +} + +.hidden { + display: none; +} + +.visible { + display: block; +} + +/* 响应式工具类 */ +.mobile-only { + display: block; +} + +.desktop-only { + display: none; +} + +@media (min-width: 769px) { + .mobile-only { + display: none; + } + + .desktop-only { + display: block; + } +} + +/* 阴影效果 */ +.shadow-sm { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.shadow-md { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.shadow-lg { + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2); +} + +/* 圆角 */ +.rounded-sm { + border-radius: 4px; +} + +.rounded-md { + border-radius: 8px; +} + +.rounded-lg { + border-radius: 12px; +} + +.rounded-xl { + border-radius: 16px; +} + +.rounded-full { + border-radius: 50%; +} diff --git a/frontend/react-app/src/utils/api.js b/frontend/react-app/src/utils/api.js new file mode 100644 index 00000000..9a033504 --- /dev/null +++ b/frontend/react-app/src/utils/api.js @@ -0,0 +1,106 @@ +import axios from 'axios'; +import toast from 'react-hot-toast'; + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.REACT_APP_API_URL || '/api', + timeout: 10000, + withCredentials: true, // 支持携带cookie + headers: { + 'Content-Type': 'application/json', + } +}); + +// 请求拦截器 +api.interceptors.request.use( + (config) => { + // 可以在这里添加token等认证信息 + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// 响应拦截器 +api.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + // 统一错误处理 + const message = error.response?.data?.message || '网络错误,请稍后重试'; + + if (error.response?.status === 401) { + // 未授权,跳转到登录页 + window.location.href = '/login'; + } + + toast.error(message); + return Promise.reject(error); + } +); + +// 认证相关API +export const authAPI = { + // 发送验证码 + sendVerification: (data) => api.post('/auth/send-verification', data), + + // 验证验证码 + verifyCode: (data) => api.post('/auth/verify-code', data), + + // 登录 + login: (credentials) => api.post('/auth/login', credentials), + + // 注册 + register: (userData) => api.post('/auth/register', userData), + + // 登出 + logout: () => api.post('/auth/logout'), + + // 检查登录状态 + checkLogin: () => api.get('/auth/check'), +}; + +// 用户相关API +export const userAPI = { + // 获取用户资料 + getProfile: () => api.get('/user/profile'), + + // 修改密码 + changePassword: (passwordData) => api.post('/user/change-password', passwordData), + + // 获取用户统计 + getStats: () => api.get('/user/stats'), + + // 删除账户 + deleteAccount: (password) => api.post('/user/delete', { password }), +}; + +// 60s API相关接口 +export const api60s = { + // 抖音热搜 + getDouyinHot: () => api.get('/60s/douyin'), + + // 微博热搜 + getWeiboHot: () => api.get('/60s/weibo'), + + // 猫眼票房 + getMaoyanBoxOffice: () => api.get('/60s/maoyan'), + + // 60秒读懂世界 + get60sNews: () => api.get('/60s/60s'), + + // 必应壁纸 + getBingWallpaper: () => api.get('/60s/bing-wallpaper'), + + // 天气信息 + getWeather: (city = '北京') => api.get(`/60s/weather?city=${encodeURIComponent(city)}`), +}; + +// 健康检查 +export const healthAPI = { + check: () => api.get('/health'), +}; + +export default api; diff --git a/frontend/react-app/src/utils/helpers.js b/frontend/react-app/src/utils/helpers.js new file mode 100644 index 00000000..3cf1dd76 --- /dev/null +++ b/frontend/react-app/src/utils/helpers.js @@ -0,0 +1,310 @@ +// 工具函数集合 + +/** + * 格式化时间 + * @param {string|Date} date - 日期 + * @param {string} format - 格式 ('datetime', 'date', 'time') + * @returns {string} 格式化后的时间字符串 + */ +export const formatTime = (date, format = 'datetime') => { + if (!date) return ''; + + const d = new Date(date); + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + switch (format) { + case 'date': + return `${year}-${month}-${day}`; + case 'time': + return `${hours}:${minutes}:${seconds}`; + case 'datetime': + default: + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } +}; + +/** + * 获取相对时间 + * @param {string|Date} date - 日期 + * @returns {string} 相对时间字符串 + */ +export const getRelativeTime = (date) => { + if (!date) return ''; + + const now = new Date(); + const target = new Date(date); + const diff = now - target; + + const minute = 60 * 1000; + const hour = 60 * minute; + const day = 24 * hour; + + if (diff < minute) { + return '刚刚'; + } else if (diff < hour) { + return `${Math.floor(diff / minute)}分钟前`; + } else if (diff < day) { + return `${Math.floor(diff / hour)}小时前`; + } else if (diff < 7 * day) { + return `${Math.floor(diff / day)}天前`; + } else { + return formatTime(date, 'date'); + } +}; + +/** + * 防抖函数 + * @param {Function} func - 要防抖的函数 + * @param {number} wait - 等待时间(毫秒) + * @returns {Function} 防抖后的函数 + */ +export const debounce = (func, wait) => { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +}; + +/** + * 节流函数 + * @param {Function} func - 要节流的函数 + * @param {number} limit - 限制时间(毫秒) + * @returns {Function} 节流后的函数 + */ +export const throttle = (func, limit) => { + let inThrottle; + return function executedFunction(...args) { + if (!inThrottle) { + func.apply(this, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + }; +}; + +/** + * 深拷贝对象 + * @param {any} obj - 要拷贝的对象 + * @returns {any} 深拷贝后的对象 + */ +export const deepClone = (obj) => { + if (obj === null || typeof obj !== 'object') return obj; + if (obj instanceof Date) return new Date(obj.getTime()); + if (obj instanceof Array) return obj.map(item => deepClone(item)); + if (typeof obj === 'object') { + const clonedObj = {}; + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + clonedObj[key] = deepClone(obj[key]); + } + } + return clonedObj; + } +}; + +/** + * 生成唯一ID + * @returns {string} 唯一ID + */ +export const generateId = () => { + return Date.now().toString(36) + Math.random().toString(36).substr(2); +}; + +/** + * 检查是否为移动设备 + * @returns {boolean} 是否为移动设备 + */ +export const isMobile = () => { + return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); +}; + +/** + * 获取屏幕尺寸类型 + * @returns {string} 屏幕尺寸类型 ('mobile', 'tablet', 'desktop') + */ +export const getScreenSize = () => { + const width = window.innerWidth; + if (width < 768) return 'mobile'; + if (width < 1024) return 'tablet'; + return 'desktop'; +}; + +/** + * 滚动到顶部 + * @param {number} duration - 动画持续时间(毫秒) + */ +export const scrollToTop = (duration = 300) => { + const start = window.pageYOffset; + const startTime = 'now' in window.performance ? performance.now() : new Date().getTime(); + + const animateScroll = (currentTime) => { + const timeElapsed = currentTime - startTime; + const progress = Math.min(timeElapsed / duration, 1); + + window.scroll(0, start * (1 - progress)); + + if (progress < 1) { + requestAnimationFrame(animateScroll); + } + }; + + requestAnimationFrame(animateScroll); +}; + +/** + * 格式化数字 + * @param {number} num - 数字 + * @returns {string} 格式化后的数字字符串 + */ +export const formatNumber = (num) => { + if (num >= 100000000) { + return (num / 100000000).toFixed(1) + '亿'; + } else if (num >= 10000) { + return (num / 10000).toFixed(1) + '万'; + } else if (num >= 1000) { + return (num / 1000).toFixed(1) + 'K'; + } + return num.toString(); +}; + +/** + * 验证手机号 + * @param {string} phone - 手机号 + * @returns {boolean} 是否有效 + */ +export const validatePhone = (phone) => { + const phoneRegex = /^1[3-9]\d{9}$/; + return phoneRegex.test(phone); +}; + +/** + * 验证用户名 + * @param {string} username - 用户名 + * @returns {boolean} 是否有效 + */ +export const validateUsername = (username) => { + const usernameRegex = /^[a-zA-Z0-9_]{6,20}$/; + return usernameRegex.test(username); +}; + +/** + * 验证密码强度 + * @param {string} password - 密码 + * @returns {object} 验证结果 + */ +export const validatePassword = (password) => { + const result = { + valid: false, + strength: 'weak', + message: '' + }; + + if (password.length < 6) { + result.message = '密码长度至少6位'; + return result; + } + + if (password.length > 20) { + result.message = '密码长度不能超过20位'; + return result; + } + + let strength = 0; + + // 检查是否包含小写字母 + if (/[a-z]/.test(password)) strength++; + + // 检查是否包含大写字母 + if (/[A-Z]/.test(password)) strength++; + + // 检查是否包含数字 + if (/\d/.test(password)) strength++; + + // 检查是否包含特殊字符 + if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) strength++; + + if (strength >= 3) { + result.strength = 'strong'; + result.message = '密码强度:强'; + } else if (strength >= 2) { + result.strength = 'medium'; + result.message = '密码强度:中等'; + } else { + result.strength = 'weak'; + result.message = '密码强度:弱'; + } + + result.valid = true; + return result; +}; + +/** + * 本地存储工具 + */ +export const storage = { + set: (key, value) => { + try { + localStorage.setItem(key, JSON.stringify(value)); + } catch (error) { + console.error('存储数据失败:', error); + } + }, + + get: (key, defaultValue = null) => { + try { + const item = localStorage.getItem(key); + return item ? JSON.parse(item) : defaultValue; + } catch (error) { + console.error('读取数据失败:', error); + return defaultValue; + } + }, + + remove: (key) => { + try { + localStorage.removeItem(key); + } catch (error) { + console.error('删除数据失败:', error); + } + }, + + clear: () => { + try { + localStorage.clear(); + } catch (error) { + console.error('清空数据失败:', error); + } + } +}; + +/** + * URL参数工具 + */ +export const urlParams = { + get: (param) => { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get(param); + }, + + set: (param, value) => { + const url = new URL(window.location); + url.searchParams.set(param, value); + window.history.pushState({}, '', url); + }, + + remove: (param) => { + const url = new URL(window.location); + url.searchParams.delete(param); + window.history.pushState({}, '', url); + } +}; diff --git a/frontend/setting.json b/frontend/setting.json new file mode 100644 index 00000000..5578dba9 --- /dev/null +++ b/frontend/setting.json @@ -0,0 +1,8 @@ +{ + "网站名字": "✨ 神奇万事通 ✨", + "网站描述": "🎨 一个多功能的聚合软件应用 💬", + "站长": "👨‍💻 by-神奇万事通", + "备案号": "📄 蜀ICP备2025151694号", + "网站页尾": "✨ 神奇万事通 ✨ | Copyright © 2025-2025 ✨", + "网站logo": "assets/logo.png" +} \ No newline at end of file diff --git a/start_backend.bat b/start_backend.bat new file mode 100644 index 00000000..f98ddefd --- /dev/null +++ b/start_backend.bat @@ -0,0 +1,3 @@ +@echo off +cd /d "E:\Python\InfoGenie\backend" +python app.py \ No newline at end of file diff --git a/start_frontend.bat b/start_frontend.bat new file mode 100644 index 00000000..22df3166 --- /dev/null +++ b/start_frontend.bat @@ -0,0 +1,3 @@ +@echo off +cd /d "e:\Python\InfoGenie\frontend\react-app" +npm start diff --git a/用户数据模板.json b/用户数据模板.json index be5aac90..764b3c75 100644 --- a/用户数据模板.json +++ b/用户数据模板.json @@ -1,4 +1,5 @@ { "账号":"3205788256", - "密码":"tyh@19900420" + "邮箱":"3205788256@qq.com", + "密码":"0123456789" } \ No newline at end of file diff --git a/项目架构说明.txt b/项目架构说明.txt index f74f571c..7a23c62f 100644 --- a/项目架构说明.txt +++ b/项目架构说明.txt @@ -1,10 +1,10 @@ 1.一个前后端分离的网站项目,前端使用React框架,后端使用Python3.13.2的Flask框架,采用模块化架构避免单个文件过大 前端代码放在frontend文件夹,后端代码放在backend文件夹,确保代码结构清晰有少量中文注释,便于后期扩展维护 -2.前端网页要适配手机竖屏端和电脑端 +2.前端网页要适配手机竖屏端和电脑端,主要先适配手机端用户体验 3.后端目前需要一个连接MongoDB数据库来储存用户登录数据, -用户数据储存在MongoDB的InfoGenie数据库的userdata集合中 +用户数据储存在MongoDB的InfoGenie数据库的userdata集合中 玩家数据库储存模板在玩家数据模板.json文件里 软件app前端分三个主要模块 60sapi模块:为静态页面,又分四个子模块:热搜榜单,日更资讯,实用功能,娱乐消遣 -smallgame模块:为静态页面 -aimodelapp模块: 为静态页面 (需要登录验证)(暂时不弄) \ No newline at end of file +smallgame模块:为静态页面 +aimodelapp模块: 为静态页面 (需要登录验证才能进入使用)(暂时不弄) \ No newline at end of file