未命名 JCwUo2edit icon

作者:
藤原
Fork(复制)
下载
嵌入
设置
BUG反馈
index.html
style.css
index.js
现在支持上传本地图片了!
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TENGYUAN</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap">
    <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <style>
    /* 基础样式重置 */
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        outline: none;
    }
    
    body {
        font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
        background-color: #0f172a;
        color: #e2e8f0;
        line-height: 1.6;
        overflow-x: hidden;
    }
    
    .container {
        display: flex;
        max-width: 1600px;
        height: 100vh;
        margin: 0 auto;
        position: relative;
        background-color: #1e293b;
    }
    
    /* 左侧边栏样式 */
    .left-side {
        width: 280px;
        border-right: 1px solid rgba(255, 255, 255, 0.05);
        display: flex;
        flex-direction: column;
        transition: all 0.3s ease;
        background-color: #1e293b;
        overflow: auto;
        flex-shrink: 0;
        z-index: 5;
    }
    
    /* 右侧边栏样式 */
    .right-side {
        width: 300px;
        flex-shrink: 0;
        margin-left: auto;
        overflow-y: auto;
        overflow-x: hidden;
        background-color: #1e293b;
        display: flex;
        flex-direction: column;
        border-left: 1px solid rgba(255, 255, 255, 0.05);
        max-height: 100vh;
    }
    
    /* 主要内容区域样式 */
    .main {
        flex-grow: 1;
        display: flex;
        flex-direction: column;
        background-color: #0f172a;
        min-width: 0;
        position: relative;
    }
    
    /* Logo样式 */
    .logo {
        font-family: "PingFang SC", sans-serif;
        font-size: 18px;
        color: #f8fafc;
        font-weight: 600;
        text-align: center;
        height: 68px;
        line-height: 68px;
        letter-spacing: 4px;
        position: sticky;
        top: 0;
        background-color: #1e293b;
        z-index: 2;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    }
    
    /* 侧边栏内容区域样式 */
    .side-wrapper {
        padding: 15px;
    }
    
    /* 底部关注区域样式 */
    .follow-me {
        text-decoration: none;
        font-size: 14px;
        display: flex;
        align-items: center;
        margin-top: auto;
        overflow: hidden;
        color: #94a3b8;
        padding: 0 15px;
        height: 60px;
        flex-shrink: 0;
        border-top: 1px solid rgba(255, 255, 255, 0.05);
        position: relative;
        transition: all 0.3s ease;
    }
    .follow-me svg {
        width: 16px;
        height: 16px;
        margin-right: 12px;
    }
    
    .follow-text {
        display: flex;
        align-items: center;
        transition: 0.3s;
    }
    
    .follow-me:hover .follow-text {
        transform: translateY(100%);
    }
    .follow-me:hover .developer {
        top: 0;
    }
    
    .developer {
        position: absolute;
        color: #ffffff;
        left: 0;
        top: -100%;
        display: flex;
        transition: 0.3s;
        padding: 0 15px;
        align-items: center;
        background-color: rgba(30, 41, 59, 0.9);
        width: 100%;
        height: 100%;
    }
    
    .developer img {
        border-radius: 50%;
        width: 30px;
        height: 30px;
        object-fit: cover;
        margin-right: 12px;
    }
    
    /* 浏览器风格搜索栏样式 */
    .search-bar {
        height: 60px;
        background-color: #1e293b;
        z-index: 3;
        position: relative;
        display: flex;
        align-items: center;
        padding: 0 30px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
        flex-shrink: 0;
    }
    
    .search-container {
        display: flex;
        align-items: center;
        width: 100%;
        position: relative;
        max-width: 600px;
        margin: 0 auto;
    }
    
    .search-bar input {
        height: 44px;
        width: 100%;
        display: block;
        background-color: rgba(255, 255, 255, 0.08);
        border: 2px solid rgba(255, 255, 255, 0.1);
        padding: 0 50px 0 45px;
        color: #ffffff;
        font-family: "PingFang SC", sans-serif;
        font-weight: 400;
        border-radius: 22px;
        transition: all 0.3s ease;
        font-size: 15px;
        position: relative;
    }
    
    .search-bar input:focus {
        background-color: rgba(255, 255, 255, 0.12);
        box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3);
        border-color: rgba(99, 102, 241, 0.5);
    }
    
    .search-bar input::placeholder {
        color: #64748b;
        font-size: 14px;
    }
    
    /* 搜索图标 */
    .search-icon {
        position: absolute;
        left: 16px;
        top: 50%;
        transform: translateY(-50%);
        width: 18px;
        height: 18px;
        color: #94a3b8;
        pointer-events: none;
        z-index: 1;
    }
    
    /* 搜索按钮 */
    .search-btn {
        position: absolute;
        right: 6px;
        top: 50%;
        transform: translateY(-50%);
        background: linear-gradient(135deg, #6366f1, #8b5cf6);
        border: none;
        border-radius: 18px;
        width: 32px;
        height: 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.2s ease;
        color: white;
    }
    
    .search-btn:hover {
        background: linear-gradient(135deg, #5b5bd6, #7c3aed);
        transform: translateY(-50%) scale(1.05);
    }
    
    .search-btn svg {
        width: 14px;
        height: 14px;
    }
    
    /* 主内容容器样式 */
    .main-container {
        padding: 20px;
        flex-grow: 1;
        overflow: auto;
        background-color: #0f172a;
        position: relative;
    }
    
    /* 个人资料区域样式 - 修复滚动显示问题 */
    .profile {
        position: relative;
        height: 40vh;
        min-height: 280px;
        max-height: 400px;
        z-index: 1;
        border-radius: 16px;
        overflow: hidden;
        margin-bottom: 20px;
        transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
        border: 1px solid rgba(129, 140, 248, 0.3);
        transform: translateY(0);
        opacity: 1;
    }
    
    .profile.hidden {
        transform: translateY(-20px);
        opacity: 0.7;
        height: 200px;
        min-height: 200px;
    }
    
    .profile-cover {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: center;
        filter: brightness(0.8);
        transition: transform 0.5s ease;
    }
    
    .profile:hover .profile-cover {
        transform: scale(1.05);
    }
    
    .profile-overlay {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: linear-gradient(to bottom, rgba(15, 23, 42, 0.1), rgba(15, 23, 42, 0.8));
        z-index: 1;
    }
    
    /* 头像区域样式 */
    .profile-avatar {
        position: absolute;
        display: flex;
        align-items: center;
        z-index: 2;
        bottom: 20px;
        left: 30px;
        transition: all 0.3s ease;
    }
    
    .profile-img {
        width: 120px;
        height: 120px;
        border-radius: 50%;
        object-fit: cover;
        border: 4px solid rgba(255, 255, 255, 0.2);
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
        transition: all 0.3s ease;
    }
    
    .profile-avatar:hover .profile-img {
        transform: scale(1.05);
        border-color: rgba(129, 140, 248, 0.6);
    }
    
    .profile-info {
        margin-left: 24px;
    }
    
    .profile-name {
        font-size: 24px;
        color: #ffffff;
        font-weight: 600;
        font-family: "PingFang SC", sans-serif;
        margin-bottom: 8px;
        text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    }
    
    .profile-title {
        font-size: 16px;
        color: #cbd5e1;
        margin-bottom: 15px;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    }
    
    /* 社交图标样式 */
    .social-icons {
        display: flex;
        margin-top: 10px;
        gap: 10px;
    }
    
    .social-icon {
        color: #cbd5e1;
        font-size: 18px;
        transition: all 0.3s ease;
        width: 36px;
        height: 36px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(5px);
        text-decoration: none;
        position: relative;
    }
    
    .social-icon:hover {
        color: #ffffff;
        transform: translateY(-3px);
        background-color: rgba(129, 140, 248, 0.6);
        box-shadow: 0 5px 15px rgba(129, 140, 248, 0.3);
    }
    
    .social-icon i {
        font-size: 16px;
        line-height: 1;
    }
    
    /* 时间线布局 */
    .timeline {
        display: flex;
        padding-top: 20px;
        position: relative;
        z-index: 2;
    }
    
    .timeline-left {
        width: 100%;
        flex-shrink: 0;
    }
    
    /* 通用卡片样式 */
    .box {
        background-color: rgba(30, 41, 59, 0.8);
        border-radius: 8px;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
        margin-bottom: 20px;
        transition: transform 0.3s ease, box-shadow 0.3s ease;
        border: 1px solid rgba(255, 255, 255, 0.1);
    }
    
    .box:hover {
        transform: translateY(-5px);
        box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
        border-color: rgba(255, 255, 255, 0.2);
    }
    
    /* 账户按钮样式 */
    .account-button {
        border: 0;
        background: transparent;
        color: #94a3b8;
        padding: 8px;
        cursor: pointer;
        position: relative;
        border-radius: 50%;
        transition: all 0.3s ease;
    }
    
    .account-button:hover {
        background-color: rgba(255, 255, 255, 0.1);
        color: #ffffff;
    }
    
    .account-button svg {
        width: 20px;
        height: 20px;
    }
    
    .account-button:not(.right-side-button) + .account-button:before {
        position: absolute;
        right: 5px;
        top: 5px;
        background-color: #6366f1;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        content: "";
        border: 2px solid #1e293b;
    }
    
    .account-profile {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        margin: 0 10px;
        object-fit: cover;
        border: 2px solid rgba(255, 255, 255, 0.1);
    }
    
    .account-user {
        display: inline-flex;
        align-items: center;
        color: #94a3b8;
        font-weight: 500;
        font-size: 14px;
        transition: all 0.3s ease;
    }
    
    .account-user:hover {
        color: #ffffff;
    }
    
    .account-user span {
        font-size: 12px;
        font-weight: normal;
        margin-left: 5px;
    }
    
    /* 账户区域样式 */
    .account {
        height: 60px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        position: sticky;
        top: 0;
        background-color: rgba(30, 41, 59, 0.95);
        backdrop-filter: blur(10px);
        z-index: 10;
        flex-shrink: 0;
        padding: 0 20px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }
    
    /* 遮罩层样式 */
    .overlay {
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        background-color: rgba(15, 23, 42, 0.8);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: 0.3s;
        z-index: 9;
    }
    
    /* 右侧边栏按钮样式 */
    .right-side-button {
        position: absolute;
        right: 0;
        top: 0;
        height: 100%;
        border: 0;
        width: 52px;
        background-color: rgba(30, 41, 59, 0.8);
        border-left: 1px solid rgba(255, 255, 255, 0.1);
        color: #ffffff;
        display: none;
        cursor: pointer;
        transition: all 0.3s ease;
    }
    
    .right-side-button:hover {
        background-color: rgba(30, 41, 59, 0.9);
    }
    
    .right-side-button:before {
        content: "";
        width: 10px;
        height: 10px;
        border-radius: 50%;
        position: absolute;
        background-color: #6366f1;
        border: 2px solid #1e293b;
        top: 13px;
        right: 12px;
    }
    
    .right-side-button svg {
        width: 22px;
    }
    
    /* 左侧边栏按钮样式 */
    .left-side-button {
        display: none;
    }

    /* ================ 终端相关样式 ================ */
    :root {
        --editor-bg: #1e293b;
        --editor-secondary-bg: #334155;
        --line-color: #64748b;
        --text-color: #e2e8f0;
        --keyword-color: #7dd3fc;
        --string-color: #fca5a5;
        --comment-color: #86efac;
        --number-color: #b5cea8;
        --function-color: #dcdcaa;
        --font-family: 'JetBrains Mono', 'Consolas', 'Monaco', monospace;
        --header-bg: #1e293b;
        --window-btn-close: #ff5f56;
        --window-btn-min: #ffbd2e;
        --window-btn-max: #27c93f;
        --ai-output-color: #67e8f9;
        --user-input-color: #fde047;
        --video-bg: #000000;
        --accent-color: #818cf8;
        --accent-hover: #a5b4fc;
        --box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
        --border-radius: 8px;
        --calendar-today-bg: rgba(129, 140, 248, 0.3);
        --calendar-selected-bg: var(--accent-color);
        --weather-temp-high: #ff7e67;
        --weather-temp-low: #70c1ff;
        --birthday-color: #f472b6;
        --birthday-bg: rgba(244, 114, 182, 0.15);
        --success-color: #4caf50;
        --warning-color: #ff9800;
        --error-color: #f44336;
        --tool-header-height: 40px;
        --tool-padding: 16px;
    }

    /* 终端编辑器样式 */
    .editor {
        width: 100%;
        background: var(--editor-bg);
        border-radius: var(--border-radius);
        box-shadow: var(--box-shadow);
        transition: all 0.3s;
        overflow: hidden;
        border: 1px solid rgba(255, 255, 255, 0.1);
        display: flex;
        flex-direction: column;
        height: 600px;
        margin-bottom: 20px;
    }

    .editor-header {
        background: var(--header-bg);
        padding: 12px;
        border-radius: var(--border-radius) var(--border-radius) 0 0;
        display: flex;
        align-items: center;
        gap: 8px;
        transition: background-color 0.3s;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    }

    .window-btn {
        width: 12px;
        height: 12px;
        border-radius: 50%;
        transition: all 0.2s;
        position: relative;
        cursor: pointer;
    }

    .close { background: var(--window-btn-close); }
    .minimize { background: var(--window-btn-min); }
    .maximize { background: var(--window-btn-max); }

    .title-bar {
        color: var(--line-color);
        margin-left: 20px;
        font-size: 0.9em;
        transition: color 0.3s;
    }

    .editor-content {
        padding: 20px;
        counter-reset: line;
        font-size: 14px;
        overflow-x: auto;
        overflow-y: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
        flex: 1;
        font-family: var(--font-family);
    }

    .editor-content::-webkit-scrollbar {
        display: none;
    }

    .line {
        display: flex;
        padding: 2px 0;
        position: relative;
        min-height: 1.6em;
    }

    .line::before {
        counter-increment: line;
        content: counter(line);
        color: var(--line-color);
        width: 2em;
        text-align: right;
        padding-right: 1em;
        position: absolute;
        transition: color 0.3s;
        opacity: 0.7;
    }

    .line-content {
        padding-left: 3em;
        width: 100%;
    }

    .indent { margin-left: 2em; }
    .indent-2 { margin-left: 4em; }

    .keyword { color: var(--keyword-color); }
    .string { color: var(--string-color); }
    .comment { color: var(--comment-color); }
    .number { color: var(--number-color); }
    .function { color: var(--function-color); }

    .ai-output { color: var(--ai-output-color); }
    .user-input { color: var(--user-input-color); }

    .input-line {
        display: flex;
        align-items: center;
        background: var(--editor-secondary-bg);
        padding: 8px 10px;
        border-radius: 4px;
        transition: all 0.3s;
        margin: 0 20px 20px;
        position: sticky;
        bottom: 0;
        z-index: 10;
    }

    .input-line::before {
        content: ">";
        color: var(--accent-color);
        width: 2em;
        text-align: right;
        padding-right: 1em;
        font-weight: bold;
    }

    .input-line input {
        flex: 1;
        background: transparent;
        border: none;
        color: var(--text-color);
        font-family: var(--font-family);
        font-size: 14px;
        outline: none;
        padding: 2px 0;
    }

    /* 右侧边栏卡片样式 */
    .sidebar-card {
        background-color: rgba(30, 41, 59, 0.8);
        border-radius: 8px;
        margin-bottom: 12px;
        border: 1px solid rgba(255, 255, 255, 0.1);
        overflow: hidden;
        flex-shrink: 0;
    }

    .sidebar-card-header {
        background: var(--header-bg);
        padding: 8px 12px;
        border-radius: var(--border-radius) var(--border-radius) 0 0;
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .sidebar-card-title {
        color: var(--text-color);
        font-size: 0.8em;
        flex: 1;
        font-weight: 600;
    }

    .sidebar-card-content {
        padding: 8px;
        max-height: 300px;
        overflow-y: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .sidebar-card-content::-webkit-scrollbar {
        display: none;
    }

    /* 命令项样式 */
    .command-item {
        padding: 6px 8px;
        margin-bottom: 4px;
        border-radius: 6px;
        background-color: rgba(255, 255, 255, 0.05);
        transition: all 0.2s;
        cursor: pointer;
    }

    .command-item:hover {
        background-color: rgba(255, 255, 255, 0.1);
        transform: translateX(2px);
    }

    .command-title {
        font-weight: 500;
        color: var(--text-color);
        margin-bottom: 2px;
        font-size: 0.8em;
    }

    .command-description {
        font-size: 0.7em;
        color: var(--line-color);
        line-height: 1.3;
    }

    /* 个人信息卡片样式 */
    .profile-card {
        background-color: rgba(30, 41, 59, 0.8);
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 15px;
        border: 1px solid rgba(255, 255, 255, 0.1);
        text-align: center;
        backdrop-filter: blur(10px);
        transition: all 0.3s ease;
    }

    .profile-card:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
    }

    .profile-card-avatar {
        width: 80px;
        height: 80px;
        border-radius: 50%;
        margin: 0 auto 15px;
        object-fit: cover;
        border: 3px solid rgba(129, 140, 248, 0.3);
        transition: all 0.3s ease;
    }

    .profile-card-avatar:hover {
        border-color: rgba(129, 140, 248, 0.6);
        transform: scale(1.05);
    }

    .profile-card-name {
        font-size: 18px;
        font-weight: 600;
        margin-bottom: 5px;
        color: #ffffff;
    }

    .profile-card-title {
        font-size: 14px;
        color: #94a3b8;
        margin-bottom: 15px;
    }

    .profile-stats {
        display: flex;
        justify-content: space-around;
        margin-top: 15px;
        padding-top: 15px;
        border-top: 1px solid rgba(255, 255, 255, 0.1);
    }

    .stat-item {
        text-align: center;
        transition: all 0.3s ease;
    }

    .stat-item:hover {
        transform: translateY(-2px);
    }

    .stat-number {
        font-size: 16px;
        font-weight: 600;
        color: #ffffff;
        display: block;
    }

    .stat-label {
        font-size: 12px;
        color: #94a3b8;
        margin-top: 2px;
    }

    /* 天气组件样式 - 日历风格简约设计 */
    .weather-widget {
        background-color: rgba(30, 41, 59, 0.8);
        border-radius: 12px;
        padding: 16px;
        margin-bottom: 15px;
        border: 1px solid rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
        transition: all 0.3s ease;
        position: relative;
        overflow: hidden;
    }

    .weather-widget:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
    }

    .weather-header {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        margin-bottom: 12px;
    }

    .weather-location {
        font-size: 14px;
        font-weight: 600;
        color: #ffffff;
        display: flex;
        align-items: center;
        gap: 6px;
    }

    .weather-location svg {
        width: 14px;
        height: 14px;
        color: #94a3b8;
    }

    /* 隐藏IP地址显示 */
    .weather-ip {
        display: none;
    }

    .weather-main {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 12px;
        padding: 8px 0;
    }

    .weather-temp-section {
        display: flex;
        align-items: center;
        gap: 10px;
    }

    .weather-icon {
        width: 32px;
        height: 32px;
        color: #94a3b8;
        opacity: 0.8;
    }

    .weather-temp-info {
        display: flex;
        flex-direction: column;
    }

    .weather-temp {
        font-size: 20px;
        font-weight: 600;
        color: #ffffff;
        line-height: 1;
    }

    .weather-desc {
        font-size: 11px;
        color: #94a3b8;
        margin-top: 2px;
    }

    .weather-details {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px;
        font-size: 11px;
    }

    .weather-detail {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 4px 6px;
        background: rgba(255, 255, 255, 0.03);
        border-radius: 4px;
        border: 1px solid rgba(255, 255, 255, 0.03);
        transition: all 0.2s ease;
    }

    .weather-detail:hover {
        background: rgba(255, 255, 255, 0.05);
        border-color: rgba(255, 255, 255, 0.05);
    }

    .weather-detail-label {
        color: #94a3b8;
        font-weight: 500;
    }

    .weather-detail-value {
        color: #ffffff;
        font-weight: 500;
    }

    .weather-loading {
        text-align: center;
        color: #94a3b8;
        font-size: 12px;
        padding: 20px 16px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 8px;
    }

    .weather-loading-spinner {
        width: 20px;
        height: 20px;
        border: 2px solid rgba(148, 163, 184, 0.2);
        border-top: 2px solid #94a3b8;
        border-radius: 50%;
        animation: spin 1s linear infinite;
    }

    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }

    .weather-error {
        text-align: center;
        color: #f87171;
        font-size: 12px;
        padding: 16px;
        background: rgba(248, 113, 113, 0.05);
        border-radius: 6px;
        border: 1px solid rgba(248, 113, 113, 0.1);
    }

    .weather-tip {
        margin-top: 8px;
        padding: 6px 8px;
        background: rgba(148, 163, 184, 0.05);
        border-radius: 6px;
        font-size: 10px;
        color: #94a3b8;
        line-height: 1.3;
        border: 1px solid rgba(148, 163, 184, 0.1);
    }

    /* 日历组件样式 */
    .calendar-widget {
        background-color: rgba(30, 41, 59, 0.8);
        border-radius: 12px;
        padding: 16px;
        margin-bottom: 15px;
        border: 1px solid rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
        transition: all 0.3s ease;
    }

    .calendar-widget:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
    }

    .calendar-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 15px;
        padding-bottom: 10px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .calendar-title {
        font-size: 16px;
        font-weight: 600;
        color: #ffffff;
    }

    .calendar-nav {
        display: flex;
        gap: 5px;
    }

    .calendar-btn {
        background: rgba(255, 255, 255, 0.1);
        border: none;
        color: #94a3b8;
        width: 28px;
        height: 28px;
        border-radius: 6px;
        cursor: pointer;
        transition: all 0.2s;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .calendar-btn:hover {
        background: var(--accent-color);
        color: white;
        transform: scale(1.05);
    }

    .calendar-grid {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        gap: 2px;
        margin-bottom: 10px;
    }

    .calendar-weekday {
        text-align: center;
        font-size: 12px;
        color: #94a3b8;
        padding: 8px 0;
        font-weight: 600;
    }

    .calendar-day {
        text-align: center;
        padding: 8px 0;
        border-radius: 6px;
        cursor: pointer;
        transition: all 0.2s;
        font-size: 12px;
        aspect-ratio: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 32px;
        font-weight: 500;
    }

    .calendar-day:hover {
        background: rgba(255, 255, 255, 0.1);
        transform: scale(1.05);
    }

    .calendar-day.today {
        background: var(--calendar-today-bg);
        font-weight: bold;
        color: #ffffff;
        box-shadow: 0 2px 8px rgba(129, 140, 248, 0.3);
    }

    .calendar-day.selected {
        background: var(--calendar-selected-bg);
        color: white;
        font-weight: bold;
    }

    .calendar-day.other-month {
        color: #64748b;
        opacity: 0.5;
    }

    /* 快捷操作按钮 */
    .quick-actions {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px;
        margin-top: 10px;
    }

    .quick-action-btn {
        background: var(--accent-color);
        color: white;
        border: none;
        padding: 6px 8px;
        border-radius: 6px;
        cursor: pointer;
        font-size: 10px;
        transition: all 0.2s;
        text-align: center;
        font-weight: 500;
    }

    .quick-action-btn:hover {
        background: var(--accent-hover);
        transform: translateY(-1px);
        box-shadow: 0 2px 8px rgba(129, 140, 248, 0.3);
    }

    /* ================ 统一的工具样式 ================ */
    /* 通用工具容器样式 */
    .tool-container {
        background: var(--editor-bg);
        border-radius: var(--border-radius);
        margin: 15px 0;
        border: 1px solid rgba(255, 255, 255, 0.1);
        overflow: hidden;
    }

    /* 通用工具头部样式 */
    .tool-header {
        background: var(--header-bg);
        padding: 12px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    }

    .tool-title {
        color: var(--text-color);
        font-size: 14px;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .tool-title svg {
        width: 16px;
        height: 16px;
    }

    .tool-close {
        background: none;
        border: none;
        color: var(--line-color);
        cursor: pointer;
        transition: color 0.2s;
        padding: 4px;
        border-radius: 4px;
    }

    .tool-close:hover {
        color: var(--text-color);
        background: rgba(255, 255, 255, 0.1);
    }

    .tool-close svg {
        width: 16px;
        height: 16px;
    }

    /* 通用工具内容样式 */
    .tool-content {
        padding: 20px;
    }

    /* 通用输入区域样式 */
    .tool-input-container {
        position: relative;
        margin-bottom: 20px;
    }

    .tool-input {
        width: 100%;
        padding: 12px 50px 12px 16px;
        border: 2px solid rgba(255, 255, 255, 0.1);
        border-radius: 8px;
        background: var(--editor-secondary-bg);
        color: var(--text-color);
        font-size: 14px;
        outline: none;
        transition: all 0.3s;
    }

    .tool-input:focus {
        border-color: var(--accent-color);
        box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.2);
    }

    .tool-input::placeholder {
        color: var(--line-color);
    }

    /* 通用按钮样式 */
    .tool-btn {
        background: var(--accent-color);
        color: white;
        border: none;
        padding: 8px 16px;
        border-radius: 6px;
        cursor: pointer;
        font-size: 12px;
        display: flex;
        align-items: center;
        gap: 6px;
        transition: all 0.2s;
        font-weight: 500;
    }

    .tool-btn:hover {
        background: var(--accent-hover);
        transform: translateY(-1px);
    }

    .tool-btn:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        transform: none;
    }

    .tool-btn svg {
        width: 14px;
        height: 14px;
    }

    .tool-btn-primary {
        position: absolute;
        right: 8px;
        top: 50%;
        transform: translateY(-50%);
        padding: 6px 12px;
        font-size: 11px;
    }

    /* 通用预览区域样式 */
    .tool-preview-container {
        position: relative;
        width: 100%;
        height: 200px;
        border: 2px dashed rgba(255, 255, 255, 0.2);
        border-radius: 8px;
        overflow: hidden;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 20px;
    }

    .tool-preview {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
        display: none;
    }

    .tool-preview.active {
        display: block;
    }

    .tool-placeholder {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        color: var(--line-color);
        text-align: center;
        padding: 20px;
        transition: all 0.3s;
    }

    .tool-placeholder svg {
        width: 48px;
        height: 48px;
        margin-bottom: 12px;
        opacity: 0.5;
    }

    /* 通用操作按钮区域 */
    .tool-actions {
        display: flex;
        gap: 12px;
        justify-content: center;
        flex-wrap: wrap;
    }

    /* 通用结果区域样式 */
    .tool-result {
        margin-top: 20px;
        padding: 15px;
        background: rgba(255, 255, 255, 0.05);
        border-radius: 8px;
        border: 1px solid rgba(255, 255, 255, 0.1);
    }

    /* 通用加载动画 */
    .tool-loading {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 20px;
        flex-direction: column;
        gap: 10px;
    }

    .tool-loading-spinner {
        display: flex;
        justify-content: center;
        margin: 15px 0;
    }

    .tool-loading-spinner div {
        width: 8px;
        height: 8px;
        margin: 2px;
        background: var(--accent-color);
        border-radius: 50%;
        animation: bouncing 0.6s infinite alternate;
    }

    @keyframes bouncing {
        to {
            transform: translateY(-8px);
        }
    }

    /* 通用信息展示样式 */
    .tool-info {
        background: rgba(129, 140, 248, 0.1);
        border: 1px solid rgba(129, 140, 248, 0.3);
        border-radius: 6px;
        padding: 12px;
        margin: 10px 0;
        color: var(--text-color);
        font-size: 13px;
    }

    .tool-success {
        background: rgba(74, 222, 128, 0.1);
        border-color: rgba(74, 222, 128, 0.3);
        color: #4ade80;
    }

    .tool-error {
        background: rgba(248, 113, 113, 0.1);
        border-color: rgba(248, 113, 113, 0.3);
        color: #f87171;
    }

    /* 视频播放器样式 */
    .video-container {
        background: var(--video-bg);
        border-radius: var(--border-radius);
        margin: 15px 0;
        overflow: hidden;
        border: 1px solid rgba(255, 255, 255, 0.1);
    }

    .video-player {
        position: relative;
        width: 100%;
        height: 300px;
        background: #000;
    }

    .video-player video, .video-player iframe {
        width: 100%;
        height: 100%;
        object-fit: contain;
        border: none;
    }

    .video-controls {
        background: var(--editor-secondary-bg);
        padding: 10px;
        display: flex;
        gap: 10px;
        align-items: center;
        flex-wrap: wrap;
    }

    .video-button {
        background: var(--accent-color);
        color: white;
        border: none;
        padding: 6px 12px;
        border-radius: 4px;
        cursor: pointer;
        font-size: 12px;
        display: flex;
        align-items: center;
        gap: 6px;
        transition: all 0.2s;
    }

    .video-button:hover {
        background: var(--accent-hover);
    }

    .video-button svg {
        width: 14px;
        height: 14px;
    }

    /* 搜索结果样式 */
    .search-results {
        background: var(--editor-bg);
        border-radius: var(--border-radius);
        margin: 15px 0;
        border: 1px solid rgba(255, 255, 255, 0.1);
        overflow: hidden;
    }

    .search-results-header {
        background: var(--header-bg);
        padding: 12px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    }

    .search-results-title {
        color: var(--text-color);
        font-size: 14px;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .search-results-content {
        padding: 20px;
        max-height: 400px;
        overflow-y: auto;
    }

    .search-result-item {
        padding: 12px;
        margin-bottom: 10px;
        background: rgba(255, 255, 255, 0.05);
        border-radius: 8px;
        border: 1px solid rgba(255, 255, 255, 0.1);
        transition: all 0.2s ease;
        cursor: pointer;
    }

    .search-result-item:hover {
        background: rgba(255, 255, 255, 0.08);
        transform: translateY(-1px);
    }

    .search-result-title {
        color: var(--accent-color);
        font-weight: 600;
        margin-bottom: 5px;
        text-decoration: none;
    }

    .search-result-title:hover {
        text-decoration: underline;
    }

    .search-result-url {
        color: #4ade80;
        font-size: 12px;
        margin-bottom: 5px;
    }

    .search-result-description {
        color: var(--line-color);
        font-size: 13px;
        line-height: 1.4;
    }

    /* 响应式设计 - 左侧边栏 */
    @media screen and (max-width: 930px) {
        .left-side.active {
            z-index: 10;
        }
        .left-side.active > *:not(.logo) {
            opacity: 1;
            transition: 0.3s 0.2s;
        }
        .left-side.active .left-side-button svg:first-child {
            opacity: 0;
        }
        .left-side.active .left-side-button svg:last-child {
            transform: translate(-50%, -50%);
            opacity: 1;
        }
        .left-side:not(.active) {
            width: 56px;
            overflow: hidden;
        }
        .left-side:not(.active) > *:not(.logo):not(.left-side-button) {
            opacity: 0;
        }
        .left-side:not(.active) .logo {
            writing-mode: vertical-lr;
            transform: rotate(180deg);
            transform-origin: bottom;
            display: flex;
            align-items: center;
            margin-top: -10px;
        }
        
        .left-side-button {
            display: flex;
            flex-shrink: 0;
            align-items: center;
            justify-content: center;
            position: relative;
            cursor: pointer;
            height: 60px;
            background-color: rgba(30, 41, 59, 0.5);
            border: 0;
            padding: 0;
            line-height: 0;
            color: #ffffff;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            transition: all 0.3s ease;
        }
        
        .left-side-button:hover {
            background-color: rgba(30, 41, 59, 0.7);
        }
        
        .left-side-button svg {
            transition: 0.2s;
            width: 24px;
        }
        
        .left-side-button svg:last-child {
            position: absolute;
            left: 50%;
            transform: translate(100%, -50%);
            top: 50%;
            opacity: 0;
        }
    }
    
    /* 响应式设计 - 右侧边栏 */
    @media screen and (max-width: 1210px) {
        .right-side {
            position: fixed;
            right: 0;
            top: 0;
            transition: 0.3s;
            height: 100%;
            transform: translateX(300px);
            z-index: 10;
        }
        .right-side.active {
            transform: translatex(0);
        }
        
        .overlay.active {
            z-index: 8;
            opacity: 1;
            visibility: visible;
            pointer-events: all;
        }
        
        .right-side-button {
            display: block;
        }
    }
    
    /* 响应式设计 - 个人资料区域 */
    @media screen and (max-width: 768px) {
        .profile {
            height: 280px;
            min-height: 280px;
        }
        
        .profile.hidden {
            height: 180px;
            min-height: 180px;
        }
        
        .profile-avatar {
            flex-direction: column;
            align-items: center;
            left: 50%;
            transform: translateX(-50%);
            text-align: center;
        }
        
        .profile-img {
            width: 100px;
            height: 100px;
        }
        
        .profile-info {
            margin-left: 0;
            margin-top: 15px;
        }
        
        .social-icons {
            justify-content: center;
        }

        .weather-main {
            flex-direction: column;
            align-items: center;
            gap: 12px;
        }

        .weather-details {
            grid-template-columns: 1fr;
        }

        .search-container {
            max-width: none;
        }
    }
    
    /* 响应式设计 - 时间线布局 */
    @media screen and (max-width: 768px) {
        .timeline {
            flex-wrap: wrap;
            flex-direction: column-reverse;
        }
        .timeline-left {
            width: 100%;
        }

        .main-container {
            padding: 15px;
        }

        .editor {
            height: 500px;
        }
    }

    /* 响应式设计 - 小屏幕优化 */
    @media screen and (max-width: 480px) {
        .left-side {
            width: 260px;
        }

        .right-side {
            width: 280px;
        }

        .profile {
            height: 250px;
            min-height: 250px;
        }

        .profile.hidden {
            height: 160px;
            min-height: 160px;
        }

        .weather-widget {
            padding: 16px;
        }

        .weather-temp {
            font-size: 24px;
        }

        .calendar-widget {
            padding: 12px;
        }

        .profile-card {
            padding: 16px;
        }
    }
    
    /* 隐藏所有滚动条 */
    ::-webkit-scrollbar {
        display: none;
    }
    
    * {
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    /* 平滑滚动 */
    html {
        scroll-behavior: smooth;
    }

    /* 性能优化 */
    .profile, .weather-widget, .calendar-widget, .profile-card {
        will-change: transform;
    }

    /* 无障碍优化 */
    @media (prefers-reduced-motion: reduce) {
        * {
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.01ms !important;
        }
    }

    /* 高对比度模式支持 */
    @media (prefers-contrast: high) {
        .profile, .weather-widget, .calendar-widget, .profile-card {
            border-width: 2px;
        }
    }
      
    </style>
</head>
<body>
    <!-- 主容器 - 使用Alpine.js管理状态 -->
    <div class="container" x-data="{ rightSide: false, leftSide: false }">
        <!-- 左侧边栏 - 导航菜单 + 个人信息 + 天气 + 日历 -->
        <div class="left-side" :class="{'active' : leftSide}">
            <!-- 左侧边栏切换按钮 - 移动端显示 -->
            <div class="left-side-button" @click="leftSide = !leftSide">
                <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                    <line x1="3" y1="12" x2="21" y2="12"></line>
                    <line x1="3" y1="6" x2="21" y2="6"></line>
                    <line x1="3" y1="18" x2="21" y2="18"></line>
                </svg>
                <svg stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
                    <path d="M19 12H5M12 19l-7-7 7-7" />
                </svg>
            </div>
            
            <!-- Logo区域 -->
            <div class="logo">TENGYUAN</div>
            
            <!-- 个人信息卡片 -->
            <div class="side-wrapper">
                <div class="profile-card">
                    <img src="https://a.520gexing.com/uploads/allimg/2019032616/3mltnpfys55.jpg" alt="头像" class="profile-card-avatar">
                    <div class="profile-card-name">藤原</div>
                    <div class="profile-card-title">职场牛马!!!</div>
                    <div class="profile-stats">
                        <div class="stat-item">
                            <div class="stat-number">128</div>
                            <div class="stat-label">文章</div>
                        </div>
                        <div class="stat-item">
                            <div class="stat-number">1.2K</div>
                            <div class="stat-label">访问</div>
                        </div>
                        <div class="stat-item">
                            <div class="stat-number">256</div>
                            <div class="stat-label">点赞</div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 天气组件 - 日历风格简约设计 -->
            <div class="side-wrapper">
                <div class="weather-widget" id="weatherWidget">
                    <div class="weather-loading">
                        <div class="weather-loading-spinner"></div>
                        正在加载天气信息...
                    </div>
                </div>
            </div>

            <!-- 日历组件 -->
            <div class="side-wrapper">
                <div class="calendar-widget" id="calendarWidget">
                    <div class="calendar-header">
                        <div class="calendar-title" id="calendarTitle">2024年12月</div>
                        <div class="calendar-nav">
                            <button class="calendar-btn" id="prevMonth" aria-label="上个月">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                    <polyline points="15 18 9 12 15 6"></polyline>
                                </svg>
                            </button>
                            <button class="calendar-btn" id="nextMonth" aria-label="下个月">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                    <polyline points="9 18 15 12 9 6"></polyline>
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div class="calendar-grid" id="calendarGrid">
                        <!-- 星期标题 -->
                        <div class="calendar-weekday">日</div>
                        <div class="calendar-weekday">一</div>
                        <div class="calendar-weekday">二</div>
                        <div class="calendar-weekday">三</div>
                        <div class="calendar-weekday">四</div>
                        <div class="calendar-weekday">五</div>
                        <div class="calendar-weekday">六</div>
                        <!-- 日期将通过JavaScript动态生成 -->
                    </div>
                </div>
            </div>
            
            <!-- 关注我区域 -->
            <a href="#" class="follow-me" target="_blank">
                <span class="follow-text">
                    <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path>
                    </svg>
                    关注我
                </span>
                <span class="developer">
                    <img src="https://pbs.twimg.com/profile_images/1253782473953157124/x56UURmt_400x400.jpg" alt="" class="account-profile">
                    开发者信息
                </span>
            </a>
        </div>
        
        <!-- 主内容区域 -->
        <div class="main">
            <!-- 浏览器风格搜索栏 -->
            <div class="search-bar">
                <div class="search-container">
                    <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <circle cx="11" cy="11" r="8"></circle>
                        <path d="m21 21-4.35-4.35"></path>
                    </svg>
                    <input type="text" placeholder="搜索文章、标签或作者..." id="mainSearchInput" />
                    <button class="search-btn" id="searchButton" aria-label="搜索">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <circle cx="11" cy="11" r="8"></circle>
                            <path d="m21 21-4.35-4.35"></path>
                        </svg>
                    </button>
                </div>
                <button class="right-side-button" @click="rightSide = !rightSide" aria-label="打开右侧面板">
                    <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
                        <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
                    </svg>
                </button>
            </div>
            
            <!-- 主内容容器 -->
            <div class="main-container" id="mainContainer">
                <!-- 个人资料区域 -->
                <div class="profile" id="profileSection">
                    <img src="https://api.yilx.net/img/pc" alt="" class="profile-cover">
                    <div class="profile-overlay"></div>
                    <div class="profile-avatar" id="profileAvatar">
                        <img src="https://a.520gexing.com/uploads/allimg/2019032616/3mltnpfys55.jpg" alt="" class="profile-img">
                        <div class="profile-info">
                            <div class="profile-name" id="profileName">TENG YUAN</div>
                            <div class="profile-title">前端开发者 & 数字创意者</div>
                            <div class="social-icons" id="socialIcons">
                                <a href="tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=2083737075" class="social-icon" title="QQ" aria-label="QQ">
                                    <i class="fab fa-qq"></i>
                                </a>
                                <a href="https://www.zhihu.com/" class="social-icon" title="知乎" aria-label="知乎" target="_blank">
                                    <i class="fab fa-zhihu"></i>
                                </a>
                                <a href="https://github.com/" class="social-icon" title="GitHub" aria-label="GitHub" target="_blank">
                                    <i class="fab fa-github"></i>
                                </a>
                                <a href="mailto:2083737075@qq.com" class="social-icon" title="邮箱" aria-label="邮箱">
                                    <i class="fas fa-envelope"></i>
                                </a>
                                <a href="weixin://" class="social-icon" title="微信" aria-label="微信">
                                    <i class="fab fa-weixin"></i>
                                </a>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 时间线布局 -->
                <div class="timeline">
                    <!-- 左侧时间线 - 终端 -->
                    <div class="timeline-left">
                        <!-- 终端编辑器 -->
                        <div class="editor" id="mainEditor">
                            <div class="editor-header">
                                <span class="window-btn close"></span>
                                <span class="window-btn minimize"></span>
                                <span class="window-btn maximize"></span>
                                <span class="title-bar">terminal.js - 藤原的个人终端</span>
                            </div>
                            <div class="editor-content" id="editorContent">
                                <div class="line"><div class="line-content"><span class="comment">// 个人信息配置</span></div></div>
                                <div class="line"><div class="line-content"><span class="keyword">const</span> <span class="function">profile</span> = {</div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">name</span>: <span class="string">"藤原"</span>,</div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">title</span>: <span class="string">"职场牛马!!!"</span>,</div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">contact</span>: {</div></div>
                                <div class="line"><div class="line-content indent-2"><span class="keyword">email</span>: <span class="string"><a href="mailto:2083737075@qq.com">"2083737075@qq.com"</a></span>,</div></div>
                                <div class="line"><div class="line-content indent-2"><span class="keyword">website</span>: <span class="string"><a href="http://tengyuan.icu" target="_blank">"TengYuan.icu"</a></span>,</div></div>
                                <div class="line"><div class="line-content indent-2"><span class="keyword">FileCodeBox</span>: <span class="string"><a href="http://wp.tengyuan.icu/" target="_blank">"wp.tengyuan.icu"</a></span>,</div></div>
                                <div class="line"><div class="line-content indent">},</div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">links</span>: {</div></div>
                                <div class="line"><div class="line-content indent-2"><span class="keyword">travel blog</span>: <span class="string"><a href="http://blog.tengyuan.icu/" target="_blank">"blog.tengyuan.icu"</a></span>,</div></div>
                                <div class="line"><div class="line-content indent-2"><span class="keyword">birthday</span>: <span class="string"><a href="http://sr.0814.cn" target="_blank">"2001/11/01"</a></span>,</div></div>
                                <div class="line"><div class="line-content indent">},</div></div>
                                <div class="line"><div class="line-content indent"><span class="comment">// 座右铭</span></div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">motto</span>: <span class="string">"以清简代码,筑玖维数字宇宙。"</span>,</div></div>
                                <div class="line"><div class="line-content indent"><span class="keyword">copyright</span>: <span class="string">"2017-<span id="year"></span> 藤原"</span>,</div></div>
                                <div class="line"><div class="line-content">};</div></div>
                                
                                <div class="line"><div class="line-content"><span class="comment">// 终端交互</span></div></div>
                                <div class="line"><div class="line-content"><span class="function">console</span>.<span class="function">log</span>(<span class="string">"欢迎访问藤原的个人终端"</span>);</div></div>
                                <div class="line"><div class="line-content"><span class="function">console</span>.<span class="function">log</span>(<span class="string">"输入 'help' 获取可用命令"</span>);</div></div>
                            </div>
                            
                            <!-- 输入行 -->
                            <div class="input-line">
                                <input type="text" id="userInput" placeholder="输入命令..." autocomplete="off">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 右侧边栏 -->
        <div class="right-side" :class="{ 'active': rightSide }">
            <!-- 账户控制区域 -->
            <div class="account">
                <button class="account-button" aria-label="邮件">
                    <svg stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
                        <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
                        <path d="M22 6l-10 7L2 6" />
                    </svg>
                </button>
                <button class="account-button" aria-label="通知">
                    <svg stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
                        <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0" />
                    </svg>
                </button>
                <span class="account-user">TENG YUAN
                    <img src="https://images.genius.com/2326b69829d58232a2521f09333da1b3.1000x1000x1.jpg" alt="" class="account-profile">
                    <span>▼</span>
                </span>
            </div>
            
            <!-- 命令面板 -->
            <div class="sidebar-card">
                <div class="sidebar-card-header">
                    <span class="sidebar-card-title">命令面板</span>
                </div>
                <div class="sidebar-card-content">
                    <div class="command-item" onclick="setCommandInput('help')">
                        <div class="command-title">帮助</div>
                        <div class="command-description">显示所有可用命令</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('clear')">
                        <div class="command-title">清空终端</div>
                        <div class="command-description">清除终端中的所有内容</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('history')">
                        <div class="command-title">历史记录</div>
                        <div class="command-description">显示之前执行的命令</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('video')">
                        <div class="command-title">影视解析</div>
                        <div class="command-description">解析并播放长视频</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('shortvideo')">
                        <div class="command-title">短视频解析</div>
                        <div class="command-description">解析抖音/快手短视频</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('ai')">
                        <div class="command-title">AI助手</div>
                        <div class="command-description">与AI助手对话</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('image')">
                        <div class="command-title">图片转换</div>
                        <div class="command-description">转换图片格式</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('weather')">
                        <div class="command-title">天气查询</div>
                        <div class="command-description">查询当前位置天气信息</div>
                    </div>
                    <div class="command-item" onclick="setCommandInput('search')">
                        <div class="command-title">夸克搜索</div>
                        <div class="command-description">使用夸克搜索引擎搜索</div>
                    </div>
                </div>
            </div>

            <!-- 快捷操作 -->
            <div class="sidebar-card">
                <div class="sidebar-card-header">
                    <span class="sidebar-card-title">快捷操作</span>
                </div>
                <div class="sidebar-card-content">
                    <div class="quick-actions">
                        <button class="quick-action-btn" onclick="setCommandInput('help')">帮助</button>
                        <button class="quick-action-btn" onclick="setCommandInput('clear')">清屏</button>
                        <button class="quick-action-btn" onclick="setCommandInput('video')">影视</button>
                        <button class="quick-action-btn" onclick="setCommandInput('shortvideo')">短视频</button>
                        <button class="quick-action-btn" onclick="setCommandInput('image')">图片</button>
                        <button class="quick-action-btn" onclick="setCommandInput('ai')">AI</button>
                        <button class="quick-action-btn" onclick="setCommandInput('weather')">天气</button>
                        <button class="quick-action-btn" onclick="setCommandInput('search')">搜索</button>
                    </div>
                </div>
            </div>

            <!-- 解析统计 -->
            <div class="sidebar-card">
                <div class="sidebar-card-header">
                    <span class="sidebar-card-title">解析统计</span>
                </div>
                <div class="sidebar-card-content">
                    <div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
                        <span style="color: #94a3b8; font-size: 0.75em;">总解析次数</span>
                        <span style="color: #ffffff; font-size: 0.75em;" id="totalParseCount">0</span>
                    </div>
                    <div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
                        <span style="color: #94a3b8; font-size: 0.75em;">成功次数</span>
                        <span style="color: #4ade80; font-size: 0.75em;" id="successParseCount">0</span>
                    </div>
                    <div style="display: flex; justify-content: space-between;">
                        <span style="color: #94a3b8; font-size: 0.75em;">成功率</span>
                        <span style="color: #fbbf24; font-size: 0.75em;" id="successRate">0%</span>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 遮罩层 -->
        <div class="overlay" @click="rightSide = false; leftSide = false" :class="{ 'active': rightSide || leftSide }"></div>
    </div>

    <!-- 隐藏的文件输入元素 -->
    <input type="file" id="fileInput" accept="image/*" style="display: none;">
    
    <!-- Alpine.js 用于交互功能 -->
    <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>

    <script>
        // ================ 全局变量 ================
        let currentMonth = new Date().getMonth();
        let currentYear = new Date().getFullYear();
        let selectedDate = new Date();
        let commandHistoryArray = JSON.parse(localStorage.getItem('commandHistory') || '[]');
        let historyIndex = -1;
        let totalParseCount = parseInt(localStorage.getItem('totalParseCount') || '0');
        let successParseCount = parseInt(localStorage.getItem('successParseCount') || '0');
        let lastScrollTop = 0;
        let isScrollingDown = false;

        // 设置当前年份
        document.getElementById('year').textContent = new Date().getFullYear();

        // 更新解析统计
        function updateParseStats() {
            document.getElementById('totalParseCount').textContent = totalParseCount;
            document.getElementById('successParseCount').textContent = successParseCount;
            const rate = totalParseCount > 0 ? Math.round((successParseCount / totalParseCount) * 100) : 0;
            document.getElementById('successRate').textContent = rate + '%';
            
            localStorage.setItem('totalParseCount', totalParseCount.toString());
            localStorage.setItem('successParseCount', successParseCount.toString());
        }

        // 初始化统计
        updateParseStats();

        // ================ 滚动处理 - 修复个人资料显示问题 ================
        function handleScroll() {
            const mainContainer = document.getElementById('mainContainer');
            const profileSection = document.getElementById('profileSection');
            
            if (!mainContainer || !profileSection) return;
            
            const currentScrollTop = mainContainer.scrollTop;
            const scrollDelta = currentScrollTop - lastScrollTop;
            
            // 判断滚动方向
            if (scrollDelta > 5) {
                // 向下滚动 - 隐藏个人资料
                if (!isScrollingDown) {
                    isScrollingDown = true;
                    profileSection.classList.add('hidden');
                }
            } else if (scrollDelta < -5) {
                // 向上滚动 - 显示个人资料
                if (isScrollingDown) {
                    isScrollingDown = false;
                    profileSection.classList.remove('hidden');
                }
            }
            
            lastScrollTop = currentScrollTop;
        }

        // 节流函数
        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);
                }
            }
        }

        // ================ 终端功能 ================
        const editorContent = document.getElementById('editorContent');
        const userInput = document.getElementById('userInput');
        const mainSearchInput = document.getElementById('mainSearchInput');
        const searchButton = document.getElementById('searchButton');
        const fileInput = document.getElementById('fileInput');

        // API配置
        const apiConfig = {
            id: '10003788',
            key: 'ffa8afb46dce4916c5a74fd73c8de9f6',
            endpoint: 'https://cn.apihz.cn/api/ai/wxtiny.php'
        };

        // 新的天气API配置 - 基于IP地址的天气查询
        const weatherApiConfig = {
            id: '10003788',
            key: 'ffa8afb46dce4916c5a74fd73c8de9f6',
            endpoint: 'https://cn.apihz.cn/api/tianqi/tqybip.php'
        };

        // 夸克搜索引擎配置
        const quarkSearchConfig = {
            baseUrl: 'https://quark.sm.cn/s',
            defaultParams: {
                safe: 1,
                snum: 0
            }
        };

        // 影视解析接口
        const videoApis = [
            { name: "默认线路【推荐】", url: "https://jx.xmflv.com/?url=" },
            { name: "线路一【推荐】", url: "https://jx.we-vip.com/?url=" },
            { name: "线路二【推荐】", url: "https://z1.m1907.top/?jx=" },
            { name: "线路三", url: "https://www.ckplayer.vip/jiexi/?url=" },
            { name: "线路五", url: "https://jx.jsonplayer.com/player/?url=" },
            { name: "线路六", url: "https://jx.4kdv.com/?url=" },
            { name: "线路七", url: "https://api.jiexi.la/?url=" },
            { name: "线路八", url: "https://jx.qqwtt.com/?url=" },
            { name: "线路九", url: "https://www.playm3u8.cn/jiexi.php?url=" },
            { name: "线路十", url: "https://www.8090g.cn/jiexi/?url=" }
        ];

        // 帮助信息
        const helpText = `
可用命令:

基础命令:
- help: 显示帮助信息
- clear: 清空终端
- history: 显示命令历史记录

搜索工具:
- search [关键词]: 使用夸克搜索引擎搜索
例如: search JavaScript教程

影视工具:
- video [url]: 解析并播放长视频(支持爱奇艺、腾讯、优酷等)
例如: video https://v.qq.com/x/cover/mzc00200mp8er9d.html
- shortvideo [url]: 解析短视频(支持抖音、快手、小红书)
例如: shortvideo https://v.douyin.com/xxxxxx

AI工具:
- ai [message]: 与AI助手对话
例如: ai 你好

图片工具:
- image [format]: 转换图片格式 (支持: jpg, png, webp, bmp)
例如: image png

天气工具:
- weather [ip]: 查询指定IP或当前位置的天气信息
例如: weather 或 weather 49.234.56.78

其他工具:
- calendar: 显示日历信息
- stats: 显示系统统计信息
`;

        // ================ 夸克搜索功能 ================
        function performQuarkSearch(query) {
            if (!query) {
                addAILine('请输入搜索关键词,例如: search JavaScript教程');
                return;
            }

            // 构建夸克搜索URL
            const searchUrl = new URL(quarkSearchConfig.baseUrl);
            searchUrl.searchParams.set('q', query);
            searchUrl.searchParams.set('safe', quarkSearchConfig.defaultParams.safe);
            searchUrl.searchParams.set('snum', quarkSearchConfig.defaultParams.snum);

            // 显示搜索状态
            addAILine(`正在使用夸克搜索引擎搜索: "${query}"`);

            // 创建搜索结果容器 - 使用统一的工具容器样式
            const searchContainer = document.createElement('div');
            searchContainer.className = 'tool-container';

            // 搜索结果头部 - 使用统一的工具头部样式
            const searchHeader = document.createElement('div');
            searchHeader.className = 'tool-header';

            const searchTitle = document.createElement('div');
            searchTitle.className = 'tool-title';
            searchTitle.innerHTML = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="11" cy="11" r="8"></circle>
            <path d="m21 21-4.35-4.35"></path>
        </svg>
        夸克搜索引擎
    `;

            const closeBtn = document.createElement('button');
            closeBtn.className = 'tool-close';
            closeBtn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
            closeBtn.addEventListener('click', () => searchContainer.remove());

            searchHeader.appendChild(searchTitle);
            searchHeader.appendChild(closeBtn);

            // 搜索结果内容区域 - 使用统一的工具内容样式
            const searchContent = document.createElement('div');
            searchContent.className = 'tool-content';

            // 添加搜索信息
            const searchInfo = document.createElement('div');
            searchInfo.className = 'tool-info';
            searchInfo.innerHTML = `
        <strong>搜索引擎:</strong> 夸克搜索<br>
        <strong>搜索关键词:</strong> ${query}<br>
        <strong>搜索结果:</strong> 实时搜索结果将在下方显示
    `;

            // 创建搜索结果预览容器
            const previewContainer = document.createElement('div');
            previewContainer.className = 'tool-preview-container';
            previewContainer.style.height = '500px';

            // 创建内嵌iframe显示搜索结果
            const searchFrame = document.createElement('iframe');
            searchFrame.src = searchUrl.toString();
            searchFrame.style.cssText = `
        width: 100%;
        height: 100%;
        border: none;
        border-radius: 8px;
        background: white;
    `;

            previewContainer.appendChild(searchFrame);

            // 操作按钮区域 - 使用统一的工具操作样式
            const actions = document.createElement('div');
            actions.className = 'tool-actions';

            const openInNewTab = document.createElement('button');
            openInNewTab.className = 'tool-btn';
            openInNewTab.innerHTML = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
            <polyline points="15 3 21 3 21 9"></polyline>
            <line x1="10" y1="14" x2="21" y2="3"></line>
        </svg>
        在新标签页打开
    `;
            openInNewTab.addEventListener('click', () => {
                window.open(searchUrl.toString(), '_blank');
            });

            const refreshBtn = document.createElement('button');
            refreshBtn.className = 'tool-btn';
            refreshBtn.innerHTML = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <polyline points="23 4 23 10 17 10"></polyline>
            <polyline points="1 20 1 14 7 14"></polyline>
            <path d="m3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
        </svg>
        刷新搜索
    `;
            refreshBtn.addEventListener('click', () => {
                searchFrame.src = searchFrame.src;
            });

            const copyUrlBtn = document.createElement('button');
            copyUrlBtn.className = 'tool-btn';
            copyUrlBtn.innerHTML = `
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
            <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
        </svg>
        复制链接
    `;
            copyUrlBtn.addEventListener('click', () => {
                navigator.clipboard.writeText(searchUrl.toString()).then(() => {
                    showAlert('搜索链接已复制到剪贴板');
                }).catch(() => {
                    showAlert('复制失败,请手动复制');
                });
            });

            actions.appendChild(openInNewTab);
            actions.appendChild(refreshBtn);
            actions.appendChild(copyUrlBtn);

            // 组装搜索结果容器
            searchContent.appendChild(searchInfo);
            searchContent.appendChild(previewContainer);
            searchContent.appendChild(actions);

            searchContainer.appendChild(searchHeader);
            searchContainer.appendChild(searchContent);

            // 添加到编辑器内容区
            editorContent.appendChild(searchContainer);
            editorContent.scrollTop = editorContent.scrollHeight;

            addAILine(`夸克搜索结果已加载,您可以在上方查看搜索结果或使用操作按钮。`);
        }

        // ================ 新的天气功能 - 集成IP天气API ================
        async function fetchWeatherByIP(ip = null) {
            try {
                let url = `${weatherApiConfig.endpoint}?id=${weatherApiConfig.id}&key=${weatherApiConfig.key}`;
                if (ip) {
                    url += `&ip=${encodeURIComponent(ip)}`;
                }
                
                const response = await fetch(url);
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                
                const data = await response.json();
                
                if (data.code === 200) {
                    return data;
                } else {
                    throw new Error(data.msg || 'API返回错误状态');
                }
            } catch (error) {
                console.error('天气API请求失败:', error);
                throw error;
            }
        }

        function getWeatherIcon(weather1, weather2) {
            const weather = weather1 + (weather2 ? weather2 : '');
            const iconMap = {
                '晴': 'fas fa-sun',
                '多云': 'fas fa-cloud-sun',
                '阴': 'fas fa-cloud',
                '小雨': 'fas fa-cloud-rain',
                '中雨': 'fas fa-cloud-rain',
                '大雨': 'fas fa-cloud-showers-heavy',
                '雷阵雨': 'fas fa-bolt',
                '雪': 'fas fa-snowflake',
                '雾': 'fas fa-smog',
                '霾': 'fas fa-smog',
                '云': 'fas fa-cloud'
            };
            
            for (const key in iconMap) {
                if (weather.includes(key)) {
                    return iconMap[key];
                }
            }
            return 'fas fa-cloud';
        }

        function getWindDescription(windDirection, windScale) {
            return `${windDirection} ${windScale}`;
        }

        async function updateWeatherWidget(ip = null) {
            const weatherWidget = document.getElementById('weatherWidget');
            
            // 显示加载状态
            weatherWidget.innerHTML = `
                <div class="weather-loading">
                    <div class="weather-loading-spinner"></div>
                    正在获取天气信息...
                </div>
            `;
            
            try {
                const weatherData = await fetchWeatherByIP(ip);
                
                // 解析天气数据
                const weatherIcon = getWeatherIcon(weatherData.weather1, weatherData.weather2);
                const weatherDesc = weatherData.weather1 + (weatherData.weather2 && weatherData.weather2 !== weatherData.weather1 ? '转' + weatherData.weather2 : '');
                const windDesc = getWindDescription(weatherData.windDirection, weatherData.windScale);
                
                // 更新天气组件 - 日历风格简约设计
                weatherWidget.innerHTML = `
                    <div class="weather-header">
                        <div class="weather-location">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
                                <circle cx="12" cy="10" r="3"></circle>
                            </svg>
                            ${weatherData.place}
                        </div>
                    </div>
                    <div class="weather-main">
                        <div class="weather-temp-section">
                            <i class="${weatherIcon} weather-icon"></i>
                            <div class="weather-temp-info">
                                <div class="weather-temp">${weatherData.temperature}°C</div>
                                <div class="weather-desc">${weatherDesc}</div>
                            </div>
                        </div>
                    </div>
                    <div class="weather-details">
                        <div class="weather-detail">
                            <span class="weather-detail-label">降水</span>
                            <span class="weather-detail-value">${weatherData.precipitation}mm</span>
                        </div>
                        <div class="weather-detail">
                            <span class="weather-detail-label">气压</span>
                            <span class="weather-detail-value">${weatherData.pressure}hPa</span>
                        </div>
                        <div class="weather-detail">
                            <span class="weather-detail-label">湿度</span>
                            <span class="weather-detail-value">${weatherData.humidity}%</span>
                        </div>
                        <div class="weather-detail">
                            <span class="weather-detail-label">风力</span>
                            <span class="weather-detail-value">${windDesc}</span>
                        </div>
                    </div>
                    <div class="weather-tip">
                        💡 基于位置自动获取天气信息
                    </div>
                `;
                
            } catch (error) {
                console.error('获取天气数据失败:', error);
                weatherWidget.innerHTML = `
                    <div class="weather-error">
                        获取天气信息失败<br>
                        <small>${error.message}</small><br>
                        <small>请检查网络连接或稍后重试</small>
                    </div>
                `;
            }
        }

        // ================ 日历功能 ================
        function renderCalendar() {
            const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
            const calendarTitle = document.getElementById('calendarTitle');
            const calendarGrid = document.getElementById('calendarGrid');
            
            calendarTitle.textContent = `${currentYear}年${monthNames[currentMonth]}`;
            
            // 清除现有日期
            const days = calendarGrid.querySelectorAll('.calendar-day');
            days.forEach(day => day.remove());
            
            const firstDay = new Date(currentYear, currentMonth, 1);
            const lastDay = new Date(currentYear, currentMonth + 1, 0);
            const prevMonthLastDay = new Date(currentYear, currentMonth, 0).getDate();
            const firstDayIndex = firstDay.getDay();
            const lastDate = lastDay.getDate();
            const today = new Date();
            
            // 上个月的日期
            for (let i = firstDayIndex; i > 0; i--) {
                const dayElem = document.createElement('div');
                dayElem.className = 'calendar-day other-month';
                dayElem.textContent = prevMonthLastDay - i + 1;
                calendarGrid.appendChild(dayElem);
            }
            
            // 当前月的日期
            for (let i = 1; i <= lastDate; i++) {
                const dayElem = document.createElement('div');
                dayElem.className = 'calendar-day';
                dayElem.textContent = i;
                
                if (i === today.getDate() && currentMonth === today.getMonth() && currentYear === today.getFullYear()) {
                    dayElem.classList.add('today');
                }
                
                if (i === selectedDate.getDate() && currentMonth === selectedDate.getMonth() && currentYear === selectedDate.getFullYear()) {
                    dayElem.classList.add('selected');
                }
                
                // 藤原生日标记
                if (i === 1 && currentMonth === 10) {
                    dayElem.style.color = 'var(--birthday-color)';
                    dayElem.style.fontWeight = 'bold';
                    dayElem.setAttribute('title', '藤原生日');
                }
                
                dayElem.addEventListener('click', () => {
                    const selectedDays = calendarGrid.querySelectorAll('.calendar-day.selected');
                    selectedDays.forEach(day => day.classList.remove('selected'));
                    
                    dayElem.classList.add('selected');
                    selectedDate = new Date(currentYear, currentMonth, i);
                });
                
                calendarGrid.appendChild(dayElem);
            }
            
            // 下个月的日期
            const daysNeeded = 42 - (firstDayIndex + lastDate);
            for (let i = 1; i <= daysNeeded; i++) {
                const dayElem = document.createElement('div');
                dayElem.className = 'calendar-day other-month';
                dayElem.textContent = i;
                calendarGrid.appendChild(dayElem);
            }
        }

        // 日历导航
        document.getElementById('prevMonth').addEventListener('click', () => {
            currentMonth--;
            if (currentMonth < 0) {
                currentMonth = 11;
                currentYear--;
            }
            renderCalendar();
        });

        document.getElementById('nextMonth').addEventListener('click', () => {
            currentMonth++;
            if (currentMonth > 11) {
                currentMonth = 0;
                currentYear++;
            }
            renderCalendar();
        });

        // 打字机效果函数
        function typeWriterEffect(element, text, speed = 10) {
            return new Promise((resolve) => {
                let i = 0;
                const typing = () => {
                    if (i < text.length) {
                        element.textContent += text.charAt(i);
                        i++;
                        setTimeout(typing, speed);
                    } else {
                        resolve();
                    }
                };
                typing();
            });
        }

        async function addAILine(text) {
            const line = document.createElement('div');
            line.className = 'line';
            
            const lineContent = document.createElement('div');
            lineContent.className = 'line-content ai-output';
            lineContent.textContent = '藤原: ';
            
            line.appendChild(lineContent);
            editorContent.appendChild(line);
            editorContent.scrollTop = editorContent.scrollHeight;
            
            await typeWriterEffect(lineContent, text);
            return line;
        }

        function addUserLine(text) {
            const line = document.createElement('div');
            line.className = 'line';
            
            const lineContent = document.createElement('div');
            lineContent.className = 'line-content user-input';
            lineContent.textContent = `> ${text}`;
            
            line.appendChild(lineContent);
            editorContent.appendChild(line);
            editorContent.scrollTop = editorContent.scrollHeight;
            return line;
        }

        function clearTerminal() {
            const lines = document.querySelectorAll('.line');
            
            lines.forEach(line => {
                const content = line.querySelector('.line-content').textContent;
                if (!content.includes('// 个人信息配置') &&
                    !content.includes('const profile') &&
                    !content.includes('name:') &&
                    !content.includes('title:') &&
                    !content.includes('contact:') &&
                    !content.includes('email:') &&
                    !content.includes('website:') &&
                    !content.includes('FileCodeBox:') &&
                    !content.includes('links:') &&
                    !content.includes('travel blog:') &&
                    !content.includes('birthday:') &&
                    !content.includes('motto:') &&
                    !content.includes('copyright:') &&
                    !content.includes('};') &&
                    !content.includes('// 终端交互') &&
                    !content.includes('console.log')) {
                    line.remove();
                }
            });
            
            // 移除视频、图片等组件
            const videoContainer = document.querySelector('.video-container');
            const imageConverter = document.querySelector('.tool-container');
            const shortVideoParser = document.querySelector('.tool-container');
            const searchResults = document.querySelector('.search-results');
            if (videoContainer) videoContainer.remove();
            if (imageConverter) imageConverter.remove();
            if (shortVideoParser) shortVideoParser.remove();
            if (searchResults) searchResults.remove();
        }

        // ============== 影视解析功能 ==============
        function parseVideo(url) {
            // 移除现有的播放器
            const existingPlayer = document.querySelector('.video-container');
            if (existingPlayer) {
                existingPlayer.remove();
            }

            // 增加解析次数统计
            totalParseCount++;
            updateParseStats();

            // 显示加载状态
            const loadingLine = document.createElement('div');
            loadingLine.className = 'line';
            const loadingContent = document.createElement('div');
            loadingContent.className = 'line-content ai-output';
            loadingContent.textContent = '藤原: 正在解析视频,请稍候...';
            loadingLine.appendChild(loadingContent);
            editorContent.appendChild(loadingLine);
            editorContent.scrollTop = editorContent.scrollHeight;

            // 检查URL是否有效
            if (!url || !url.startsWith('http')) {
                loadingContent.textContent = '藤原: 请输入有效的视频URL';
                return;
            }

            // 创建视频播放器容器
            const videoContainer = document.createElement('div');
            videoContainer.className = 'video-container';
            
            // 创建视频元素
            const videoPlayer = document.createElement('div');
            videoPlayer.className = 'video-player';
            
            // 使用iframe来播放解析后的视频
            const videoElement = document.createElement('iframe');
            videoElement.id = 'terminal-video';
            
            // 使用默认解析线路
            const defaultApi = videoApis[0];
            videoElement.src = defaultApi.url + encodeURIComponent(url);
            
            videoElement.frameBorder = '0';
            videoElement.allowFullscreen = true;
            videoElement.style.width = '100%';
            videoElement.style.height = '100%';
            
            videoPlayer.appendChild(videoElement);
            
            // 视频控制区域
            const videoControls = document.createElement('div');
            videoControls.className = 'video-controls';
            
            // 当前线路显示
            const currentLine = document.createElement('span');
            currentLine.style.cssText = 'color: #94a3b8; font-size: 12px; margin-right: 10px;';
            currentLine.textContent = `当前线路: ${defaultApi.name}`;
            
            // 刷新按钮
            const refreshButton = document.createElement('button');
            refreshButton.className = 'video-button';
            refreshButton.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="m3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg> 刷新';
            refreshButton.addEventListener('click', () => {
                videoElement.src = videoElement.src;
            });
            
            // 线路切换按钮
            const switchButton = document.createElement('button');
            switchButton.className = 'video-button';
            switchButton.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> 切换线路';
            switchButton.addEventListener('click', () => {
                showVideoApiSelector(url);
            });
            
            // 全屏按钮
            const fullscreenButton = document.createElement('button');
            fullscreenButton.className = 'video-button';
            fullscreenButton.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path></svg> 全屏';
            fullscreenButton.addEventListener('click', () => {
                if (videoElement.requestFullscreen) {
                    videoElement.requestFullscreen();
                }
            });
            
            // 关闭按钮
            const closeButton = document.createElement('button');
            closeButton.className = 'video-button';
            closeButton.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> 关闭';
            closeButton.addEventListener('click', () => videoContainer.remove());
            
            videoControls.appendChild(currentLine);
            videoControls.appendChild(refreshButton);
            videoControls.appendChild(switchButton);
            videoControls.appendChild(fullscreenButton);
            videoControls.appendChild(closeButton);
            
            // 组装整个播放器
            videoContainer.appendChild(videoPlayer);
            videoContainer.appendChild(videoControls);
            
            // 添加到编辑器内容区
            editorContent.appendChild(videoContainer);
            editorContent.scrollTop = editorContent.scrollHeight;
            
            // 更新加载状态
            loadingContent.textContent = '藤原: 视频解析完成!';
            
            // 增加成功统计
            successParseCount++;
            updateParseStats();
        }

        // 显示线路选择器
        function showVideoApiSelector(originalUrl) {
            addAILine('可用解析线路:');
            videoApis.forEach((api, index) => {
                const line = document.createElement('div');
                line.className = 'line';
                
                const lineContent = document.createElement('div');
                lineContent.className = 'line-content';
                lineContent.innerHTML = `<span class="ai-output">藤原: ${index + 1}. <span style="cursor: pointer; color: #818cf8; text-decoration: underline;" onclick="switchVideoApi('${originalUrl}', ${index})">${api.name}</span></span>`;
                
                line.appendChild(lineContent);
                editorContent.appendChild(line);
            });
            editorContent.scrollTop = editorContent.scrollHeight;
        }

        // 切换视频解析线路
        function switchVideoApi(originalUrl, apiIndex) {
            const api = videoApis[apiIndex];
            const apiUrl = api.url + encodeURIComponent(originalUrl);
            
            // 更新iframe的src
            const videoElement = document.getElementById('terminal-video');
            if (videoElement) {
                videoElement.src = apiUrl;
                
                // 更新当前线路显示
                const currentLine = document.querySelector('.video-controls span');
                if (currentLine) {
                    currentLine.textContent = `当前线路: ${api.name}`;
                }
                
                addAILine(`已切换到 ${api.name}`);
            }
        }

        // ============== 短视频解析功能 ==============
        function parseShortVideo(url) {
            // 移除现有的解析结果
            const existingResult = document.querySelector('.short-video-result');
            if (existingResult) {
                existingResult.remove();
            }

            // 增加解析次数统计
            totalParseCount++;
            updateParseStats();

            // 显示加载状态
            const loadingLine = document.createElement('div');
            loadingLine.className = 'line';
            const loadingContent = document.createElement('div');
            loadingContent.className = 'line-content ai-output';
            loadingContent.textContent = '藤原: 正在解析短视频,请稍候...';
            loadingLine.appendChild(loadingContent);
            editorContent.appendChild(loadingLine);
            editorContent.scrollTop = editorContent.scrollHeight;

            // 检查URL是否有效
            if (!url || !url.startsWith('http')) {
                loadingContent.textContent = '藤原: 请输入有效的短视频URL';
                return;
            }

            // 模拟解析结果
            setTimeout(() => {
                // 随机决定是视频还是图集
                const isVideo = Math.random() > 0.5;
                
                // 创建结果容器
                const resultContainer = document.createElement('div');
                resultContainer.className = 'tool-container short-video-result';
                
                // 头部
                const header = document.createElement('div');
                header.className = 'tool-header';
                
                const title = document.createElement('div');
                title.className = 'tool-title';
                title.innerHTML = `
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
                        <line x1="8" y1="21" x2="16" y2="21"></line>
                        <line x1="12" y1="17" x2="12" y2="21"></line>
                    </svg>
                    短视频解析结果
                `;
                
                const closeBtn = document.createElement('button');
                closeBtn.className = 'tool-close';
                closeBtn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
                closeBtn.addEventListener('click', () => resultContainer.remove());
                
                header.appendChild(title);
                header.appendChild(closeBtn);
                
                // 内容区域
                const content = document.createElement('div');
                content.className = 'tool-content';
                
                // 作者信息区域
                const authorInfo = `
                    <div style="display: flex; align-items: center; margin-bottom: 15px; padding: 12px; background: rgba(255, 255, 255, 0.05); border-radius: 8px;">
                        <img src="https://picsum.photos/100/100?random=${Math.floor(Math.random() * 100)}" style="width: 40px; height: 40px; border-radius: 50%; margin-right: 12px;">
                        <div>
                            <div style="font-weight: 600; color: var(--text-color); margin-bottom: 2px;">示例作者</div>
                            <div style="font-size: 12px; color: var(--line-color);">来自 ${url.includes('douyin') ? '抖音' : url.includes('kuaishou') ? '快手' : '小红书'}</div>
                        </div>
                    </div>
                `;
                
                let mediaContent = '';
                
                if (isVideo) {
                    // 视频内容
                    mediaContent = `
                        <div style="position: relative; padding-top: 56.25%; margin-bottom: 15px; border-radius: 8px; overflow: hidden;">
                            <video controls 
                                   style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
                                   crossorigin="anonymous">
                                <source src="https://example.com/video.mp4" type="video/mp4">
                                您的浏览器不支持视频播放
                            </video>
                        </div>
                        <div class="tool-actions">
                            <button class="tool-btn" onclick="downloadVideo('https://example.com/video.mp4', '示例短视频')">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
                                下载视频
                            </button>
                        </div>
                    `;
                } else {
                    // 图集内容
                    const images = [
                        'https://picsum.photos/800/1600?random=1',
                        'https://picsum.photos/800/1600?random=2',
                        'https://picsum.photos/800/1600?random=3'
                    ];
                    
                    const galleryHTML = images.map((img, index) => `
                        <div style="position: relative; margin-bottom: 10px;">
                            <img src="${img}" 
                                 alt="图片 ${index + 1}"
                                 style="width: 100%; border-radius: 8px; cursor: pointer;"
                                 onclick="showFullImage('${img}')">
                            <div style="position: absolute; top: 8px; right: 8px; background: rgba(0,0,0,0.7); color: white; padding: 4px 8px; border-radius: 12px; font-size: 12px;">
                                ${index + 1}/${images.length}
                            </div>
                        </div>
                    `).join('');
                    
                    mediaContent = `
                        <div style="max-height: 400px; overflow-y: auto; margin-bottom: 15px;">
                            ${galleryHTML}
                        </div>
                        <div class="tool-actions">
                            <button class="tool-btn" onclick="downloadAllImages(${JSON.stringify(images).replace(/"/g, '&quot;')}, '示例图集')">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
                                打包下��� (${images.length}张)
                            </button>
                        </div>
                    `;
                }
                
                // 音乐信息
                const musicInfo = `
                    <div style="margin-top: 15px; padding: 12px; background: rgba(255, 255, 255, 0.05); border-radius: 8px;">
                        <h4 style="color: var(--text-color); margin-bottom: 8px; display: flex; align-items: center; gap: 8px;">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 16px; height: 16px;">
                                <path d="M9 18V5l12-2v13"></path>
                                <circle cx="6" cy="18" r="3"></circle>
                                <circle cx="18" cy="16" r="3"></circle>
                            </svg>
                                背景音乐
                        </h4>
                        <div style="font-size: 14px; color: var(--line-color);">
                            示例音乐 - 示例作者
                        </div>
                    </div>
                `;
                
                content.innerHTML = authorInfo + mediaContent + musicInfo;
                resultContainer.appendChild(header);
                resultContainer.appendChild(content);
                
                // 添加到编辑器内容区
                editorContent.appendChild(resultContainer);
                editorContent.scrollTop = editorContent.scrollHeight;
                
                // 更新加载状态
                loadingContent.textContent = '藤原: 短视频解析完成!';
                
                // 增加成功统计
                successParseCount++;
                updateParseStats();
            }, 1500);
        }

        // ============== 图片转换功能 ==============
        function createImageConverter(targetFormat) {
            const existingConverter = document.querySelector('.image-converter');
            if (existingConverter) {
                existingConverter.remove();
                return;
            }
            
            const converter = document.createElement('div');
            converter.className = 'tool-container image-converter';
            
            // 头部
            const header = document.createElement('div');
            header.className = 'tool-header';
            
            const title = document.createElement('div');
            title.className = 'tool-title';
            title.innerHTML = `
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                    <circle cx="8.5" cy="8.5" r="1.5"></circle>
                    <polyline points="21 15 16 10 5 21"></polyline>
                </svg>
                图片格式转换器
            `;
            
            const closeBtn = document.createElement('button');
            closeBtn.className = 'tool-close';
            closeBtn.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
            closeBtn.addEventListener('click', () => converter.remove());
            
            header.appendChild(title);
            header.appendChild(closeBtn);
            
            // 内容区域
            const content = document.createElement('div');
            content.className = 'tool-content';
            
            // 预览区域
            const previewContainer = document.createElement('div');
            previewContainer.className = 'tool-preview-container';
            
            const previewImage = document.createElement('img');
            previewImage.className = 'tool-preview';
            
            const placeholder = document.createElement('div');
            placeholder.className = 'tool-placeholder';
            placeholder.innerHTML = `
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                    <circle cx="8.5" cy="8.5" r="1.5"></circle>
                    <polyline points="21 15 16 10 5 21"></polyline>
                </svg>
                <div>请选择要转换的图片</div>
                <div style="font-size:0.8em;margin-top:8px;opacity:0.7;">支持 JPG, PNG, WEBP, BMP 格式</div>
            `;
            
            previewContainer.appendChild(previewImage);
            previewContainer.appendChild(placeholder);
            
            // 格式信息
            const formatInfo = document.createElement('div');
            formatInfo.innerHTML = `
                <div class="tool-info">
                    <strong>目标格式:</strong>${targetFormat.toUpperCase()}<br>
                    <strong>支持格式:</strong>JPG, PNG, WEBP, BMP 等主流图片格式
                </div>
            `;
            
            // 操作按钮
            const actions = document.createElement('div');
            actions.className = 'tool-actions';
            
            const selectBtn = document.createElement('button');
            selectBtn.className = 'tool-btn';
            selectBtn.innerHTML = `
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7"></path>
                    <line x1="16" y1="5" x2="22" y2="5"></line>
                    <line x1="19" y1="2" x2="19" y2="8"></line>
                    <circle cx="9" cy="9" r="2"></circle>
                    <path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path>
                </svg>
                选择图片
            `;
            selectBtn.addEventListener('click', () => {
                fileInput.click();
            });

const convertBtn = document.createElement('button');
convertBtn.className = 'tool-btn';
convertBtn.innerHTML = `
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <polyline points="16 18 22 12 16 6"></polyline>
        <polyline points="8 6 2 12 8 18"></polyline>
    </svg>
    转换为 ${targetFormat.toUpperCase()}
`;
convertBtn.addEventListener('click', () => {
    if (!previewImage.src) {
        addAILine('请先选择要转换的图片');
        return;
    }
    convertImage(previewImage, targetFormat);
});

actions.appendChild(selectBtn);
actions.appendChild(convertBtn);

content.appendChild(previewContainer);
content.appendChild(formatInfo);
content.appendChild(actions);

converter.appendChild(header);
converter.appendChild(content);

editorContent.appendChild(converter);
editorContent.scrollTop = editorContent.scrollHeight;

// 文件选择处理
const handleFileSelect = (e) => {
    const file = e.target.files[0];
    if (!file) return;
    
    if (!file.type.match('image.*')) {
        addAILine('请选择有效的图片文件');
        return;
    }
    
    const reader = new FileReader();
    reader.onload = (event) => {
        previewImage.src = event.target.result;
        previewImage.classList.add('active');
        placeholder.style.display = 'none';
        
        // 显示图片信息
        const img = new Image();
        img.onload = () => {
            addAILine(`图片已加载: ${img.width}x${img.height}px, ${(file.size / 1024).toFixed(1)}KB`);
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(file);
    
    // 移除事件监听器避免重复绑定
    fileInput.removeEventListener('change', handleFileSelect);
};

fileInput.addEventListener('change', handleFileSelect);
}

// ============== 通用工具函数 ==============

// URL提取函数
function extractURL(text) {
    try {
        const urlRegex = /(https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))/g;
        const matches = text.match(urlRegex);
        return matches ? matches[0] : null;
    } catch (e) {
        console.error('URL提取错误:', e);
        return null;
    }
}

// 显示全屏图片
function showFullImage(url) {
    const overlay = document.createElement('div');
    overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0,0,0,0.9);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 9999;
        cursor: zoom-out;
    `;

    const img = document.createElement('img');
    img.src = url;
    img.style.maxWidth = '90%';
    img.style.maxHeight = '90%';
    img.style.borderRadius = '10px';

    overlay.onclick = () => overlay.remove();
    overlay.appendChild(img);
    document.body.appendChild(overlay);
}

// 下载所有图片
async function downloadAllImages(images, title) {
    if (!window.JSZip) {
        showAlert('打包下载功能需要JSZip库支持');
        return;
    }
    
    try {
        const zip = new JSZip();
        const imgFolder = zip.folder("images");
        
        showAlert('正在打包下载,请稍候...');
        
        const downloadPromises = images.map(async (imgUrl, index) => {
            try {
                const response = await fetch(imgUrl);
                if (!response.ok) throw new Error(`图片${index+1}下载失败`);
                const blob = await response.blob();
                imgFolder.file(`image_${index + 1}.jpg`, blob);
            } catch (error) {
                console.warn(`图片${index+1}下载失败:`, error);
            }
        });
        
        await Promise.all(downloadPromises);
        
        const zipBlob = await zip.generateAsync({
            type: "blob",
            compression: "DEFLATE",
            compressionOptions: { level: 6 }
        });
        
        const cleanTitle = title.replace(/[<>:"/\\|?*]/g, '');
        saveAs(zipBlob, `${cleanTitle}.zip`);
        
        showAlert('打包下载完成!');
        
    } catch (error) {
        console.error('打包下载失败:', error);
        showAlert('打包下载失败,请重试');
    }
}

// 下载视频
async function downloadVideo(url, title) {
    try {
        showAlert('正在下载视频,请稍候...');
        
        const response = await fetch(url);
        if (!response.ok) throw new Error(`下载失败: ${response.status}`);
        
        const blob = await response.blob();
        const cleanTitle = title.replace(/[<>:"/\\|?*]/g, '');
        saveAs(blob, `${cleanTitle}.mp4`);
        
        showAlert('视频下载完成!');
        
    } catch (error) {
        console.error('视频下载失败:', error);
        showAlert('视频下载失败,请重试');
    }
}

// 显示提示信息
function showAlert(message) {
    const alert = document.createElement('div');
    alert.style.cssText = `
        position: fixed;
        bottom: 30px;
        left: 50%;
        transform: translateX(-50%);
        background: rgba(30, 41, 59, 0.95);
        color: white;
        padding: 12px 24px;
        border-radius: 25px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        z-index: 9999;
        font-size: 14px;
        backdrop-filter: blur(10px);
        border: 1px solid rgba(255, 255, 255, 0.1);
    `;
    alert.textContent = message;
    
    document.body.appendChild(alert);
    setTimeout(() => alert.remove(), 3000);
}

// 转换图片
function convertImage(imgElement, format) {
    try {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        // 设置画布尺寸
        canvas.width = imgElement.naturalWidth;
        canvas.height = imgElement.naturalHeight;
        
        // 绘制图片
        ctx.drawImage(imgElement, 0, 0);
        
        // 确定MIME类型
        let mimeType;
        let quality = 0.9;
        
        switch (format.toLowerCase()) {
            case 'jpg':
            case 'jpeg':
                mimeType = 'image/jpeg';
                break;
            case 'png':
                mimeType = 'image/png';
                break;
            case 'webp':
                mimeType = 'image/webp';
                break;
            case 'bmp':
                mimeType = 'image/png';
                addAILine('注意:BMP格式将转换为PNG格式');
                break;
            default:
                mimeType = 'image/jpeg';
        }
        
        // 转换并下载
        canvas.toBlob((blob) => {
            if (!blob) {
                addAILine('图片转换失败,请重试');
                return;
            }
            
            const url = URL.createObjectURL(blob);
            const downloadLink = document.createElement('a');
            downloadLink.href = url;
            downloadLink.download = `converted-image-${Date.now()}.${format}`;
            
            // 触发下载
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);
            
            // 清理URL对象
            setTimeout(() => URL.revokeObjectURL(url), 1000);
            
            addAILine(`图片已成功转换为 ${format.toUpperCase()} 格式并开始下载!`);
            addAILine(`文件大小: ${(blob.size / 1024).toFixed(1)}KB`);
            
        }, mimeType, quality);
        
    } catch (error) {
        addAILine(`图片转换失败: ${error.message}`);
    }
}

// 创建天气组件 - 使用新的IP天气API
async function createWeather(ip = null) {
    try {
        addAILine(ip ? `正在查询IP ${ip} 的天气信息...` : '正在查询当前位置的天气信息...');
        
        const weatherData = await fetchWeatherByIP(ip);
        
        if (weatherData && weatherData.code === 200) {
            const weatherDesc = weatherData.weather1 + (weatherData.weather2 && weatherData.weather2 !== weatherData.weather1 ? '转' + weatherData.weather2 : '');
            const windDesc = getWindDescription(weatherData.windDirection, weatherData.windScale);
            
            addAILine(`${weatherData.place} 天气信息:`);
            addAILine(`🌤️ 天气: ${weatherDesc}`);
            addAILine(`🌡️ 温度: ${weatherData.temperature}°C`);
            addAILine(`💧 降水量: ${weatherData.precipitation}mm`);
            addAILine(`📊 气压: ${weatherData.pressure}hPa`);
            addAILine(`💨 湿度: ${weatherData.humidity}%`);
            addAILine(`🌪️ 风力: ${windDesc}`);
            addAILine(`🧭 风速: ${weatherData.windSpeed}m/s`);
            addAILine(`📍 风向角: ${weatherData.windDirectionDegree}°`);
            
            // 更新左侧天气组件
            updateWeatherWidget(ip);
        } else {
            addAILine(`获取天气数据失败: ${weatherData.msg || '未知错误'}`);
        }
        
    } catch (error) {
        addAILine(`获取天气数据失败: ${error.message}`);
        addAILine('请检查网络连接或稍后重试');
    }
}

// 创建日历
function createCalendar() {
    addAILine('日历已在左侧边栏显示,您可以查看当前月份并选择日期。');
    addAILine('使用左右箭头可以切换月份,点击日期可以选择特定日期。');
    if (currentMonth === 10) {
        addAILine('提示:11月1日是藤原的生日!🎂');
    }
}

// 保存命令历史
function saveToHistory(command) {
    if (commandHistoryArray.length === 0 || commandHistoryArray[commandHistoryArray.length - 1] !== command) {
        commandHistoryArray.push(command);
        if (commandHistoryArray.length > 20) {
            commandHistoryArray.shift();
        }
        localStorage.setItem('commandHistory', JSON.stringify(commandHistoryArray));
    }
    historyIndex = -1;
}

// 显示命令历史
function showCommandHistory() {
    if (commandHistoryArray.length === 0) {
        addAILine('暂无命令历史记录');
        return;
    }
    
    addAILine('命令历史记录:');
    commandHistoryArray.slice().reverse().forEach((cmd, index) => {
        addAILine(`${commandHistoryArray.length - index}. ${cmd}`);
    });
}

// AI对话功能
async function sendMessage(message) {
    if (!message) return;
    
    const thinkingLine = document.createElement('div');
    thinkingLine.className = 'line';
    
    const thinkingContent = document.createElement('div');
    thinkingContent.className = 'line-content ai-output';
    thinkingContent.textContent = '藤原: 正在思考中...';
    
    thinkingLine.appendChild(thinkingContent);
    editorContent.appendChild(thinkingLine);
    editorContent.scrollTop = editorContent.scrollHeight;
    
    try {
        const endpoint = `${apiConfig.endpoint}?id=${apiConfig.id}&key=${apiConfig.key}&words=${encodeURIComponent(message)}`;
        const response = await fetch(endpoint);
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const data = await response.json();
        thinkingLine.remove();
        
        if (data.code === 200 && data.msg) {
            const replyLine = document.createElement('div');
            replyLine.className = 'line';
            
            const replyContent = document.createElement('div');
            replyContent.className = 'line-content ai-output';
            replyContent.textContent = '藤原: ';
            
            replyLine.appendChild(replyContent);
            editorContent.appendChild(replyLine);
            editorContent.scrollTop = editorContent.scrollHeight;
            
            await typeWriterEffect(replyContent, data.msg);
        } else {
            addAILine(`AI回复失败: ${data.msg || '未知错误'}`);
        }
    } catch (error) {
        thinkingLine.remove();
        addAILine(`AI服务暂时不可用: ${error.message}`);
        console.error('AI API错误:', error);
    }
}

// 显示系统统计
function showStats() {
    addAILine('系统统计信息:');
    addAILine(`总解析次数: ${totalParseCount}`);
    addAILine(`成功解析次数: ${successParseCount}`);
    const rate = totalParseCount > 0 ? Math.round((successParseCount / totalParseCount) * 100) : 0;
    addAILine(`成功率: ${rate}%`);
    addAILine(`命令历史记录: ${commandHistoryArray.length} 条`);
    addAILine(`当前时间: ${new Date().toLocaleString()}`);
    addAILine(`浏览器: ${navigator.userAgent.split(' ')[0]}`);
}

// 处理命令输入
async function processCommand(input) {
    const command = input.trim().toLowerCase();
    const parts = input.trim().split(' ');
    const cmd = parts[0].toLowerCase();
    const args = parts.slice(1).join(' ');

    // 保存到历史记录
    saveToHistory(input.trim());

    // 添加用户输入行
    addUserLine(input);

    // 处理不同命令
    switch (cmd) {
        case 'help':
            addAILine(helpText);
            break;

        case 'clear':
            clearTerminal();
            addAILine('终端已清空');
            break;

        case 'history':
            showCommandHistory();
            break;

        case 'search':
            if (args) {
                performQuarkSearch(args);
            } else {
                addAILine('请提供搜索关键词,例如: search JavaScript教程');
                addAILine('将使用夸克搜索引擎进行搜索');
            }
            break;

        case 'video':
            if (args) {
                const url = extractURL(args) || args;
                parseVideo(url);
            } else {
                addAILine('请提供视频URL,例如: video https://v.qq.com/x/cover/xxx.html');
                addAILine('支持的平台: 爱奇艺、腾讯视频、优酷、芒果TV、哔哩哔哩等');
            }
            break;

        case 'shortvideo':
            if (args) {
                const url = extractURL(args) || args;
                parseShortVideo(url);
            } else {
                addAILine('请提供短视频URL,例如: shortvideo https://v.douyin.com/xxx');
                addAILine('支持的平台: 抖音、快手、小红书等');
            }
            break;

        case 'ai':
            if (args) {
                await sendMessage(args);
            } else {
                addAILine('请输入要对话的内容,例如: ai 你好');
            }
            break;

        case 'image':
            const format = args || 'jpg';
            const supportedFormats = ['jpg', 'jpeg', 'png', 'webp', 'bmp'];
            if (supportedFormats.includes(format.toLowerCase())) {
                createImageConverter(format.toLowerCase());
                addAILine(`图片转换器已启动,目标格式: ${format.toUpperCase()}`);
            } else {
                addAILine(`不支持的格式: ${format}`);
                addAILine(`支持的格式: ${supportedFormats.join(', ')}`);
            }
            break;

        case 'weather':
            const ip = args || null;
            await createWeather(ip);
            break;

        case 'calendar':
            createCalendar();
            break;

        case 'stats':
            showStats();
            break;

        default:
            // 检查是否包含URL,如果是则尝试解析
            const detectedUrl = extractURL(input);
            if (detectedUrl) {
                if (detectedUrl.includes('douyin.com') || detectedUrl.includes('kuaishou.com') || detectedUrl.includes('xiaohongshu.com')) {
                    parseShortVideo(detectedUrl);
                } else {
                    parseVideo(detectedUrl);
                }
            } else {
                addAILine(`未知命令: ${cmd}`);
                addAILine('输入 "help" 查看可用命令');
            }
            break;
    }
}

// 设置命令输入(从右侧面板点击)
function setCommandInput(command) {
    userInput.value = command;
    userInput.focus();
}

// 执行搜索功能 - 集成夸克搜索
function performSearch() {
    const query = mainSearchInput.value.trim();
    if (query) {
        addUserLine(`搜索: ${query}`);
        performQuarkSearch(query);
        mainSearchInput.value = ''; // 清空搜索框
    }
}

// 输入框事件处理
userInput.addEventListener('keydown', async (e) => {
    if (e.key === 'Enter') {
        e.preventDefault();
        const input = userInput.value.trim();
        if (input) {
            userInput.value = '';
            await processCommand(input);
        }
    } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        if (historyIndex < commandHistoryArray.length - 1) {
            historyIndex++;
            userInput.value = commandHistoryArray[commandHistoryArray.length - 1 - historyIndex];
        }
    } else if (e.key === 'ArrowDown') {
        e.preventDefault();
        if (historyIndex > 0) {
            historyIndex--;
            userInput.value = commandHistoryArray[commandHistoryArray.length - 1 - historyIndex];
        } else if (historyIndex === 0) {
            historyIndex = -1;
            userInput.value = '';
        }
    }
});

// 搜索功能事件处理
mainSearchInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
        performSearch();
    }
});

searchButton.addEventListener('click', performSearch);

// ================ 初始化 ================
document.addEventListener('DOMContentLoaded', function() {
    // 初始化日历
    renderCalendar();
    
    // 初始化天气(默认当前IP)
    updateWeatherWidget();
    
    // 聚焦到输入框
    userInput.focus();
    
    // 绑定滚动事件处理
    const mainContainer = document.getElementById('mainContainer');
    if (mainContainer) {
        mainContainer.addEventListener('scroll', throttle(handleScroll, 16));
    }
    
    // 显示欢迎信息
    setTimeout(() => {
        addAILine('欢迎使用藤原的个人终端!');
        addAILine('输入 "help" 查看可用命令,或直接粘贴视频链接进行解析。');
        addAILine('新功能:输入 "search 关键词" 使用夸克搜索引擎搜索!');
        addAILine('个人资料区域支持滚动隐藏/显示功能。');
    }, 500);
});

// 防止页面刷新时丢失焦点
window.addEventListener('beforeunload', () => {
    localStorage.setItem('commandHistory', JSON.stringify(commandHistoryArray));
});

// 页面可见性变化时重新聚焦
document.addEventListener('visibilitychange', () => {
    if (!document.hidden) {
        setTimeout(() => userInput.focus(), 100);
    }
});

// 点击终端区域时聚焦输入框
editorContent.addEventListener('click', () => {
    userInput.focus();
});

// 响应式处理
function handleResize() {
    if (window.innerWidth <= 768) {
        // 移动端优化
        document.body.style.fontSize = '14px';
    } else {
        document.body.style.fontSize = '16px';
    }
}

window.addEventListener('resize', handleResize);
handleResize(); // 初始调用

// 错误处理
window.addEventListener('error', (e) => {
    console.error('全局错误:', e.error);
});

window.addEventListener('unhandledrejection', (e) => {
    console.error('未处理的Promise拒绝:', e.reason);
});

// 性能监控
if ('performance' in window) {
    window.addEventListener('load', () => {
        setTimeout(() => {
            const perfData = performance.getEntriesByType('navigation')[0];
            console.log('页面加载时间:', perfData.loadEventEnd - perfData.loadEventStart, 'ms');
        }, 0);
    });
}

// Service Worker 注册(如果需要离线功能)
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        // 这里可以注册 Service Worker
        // navigator.serviceWorker.register('/sw.js');
    });
}

// 键盘快捷键
document.addEventListener('keydown', (e) => {
    // Ctrl/Cmd + K 清空终端
    if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
        e.preventDefault();
        clearTerminal();
        addAILine('终端已清空 (快捷键)');
    }
    
    // Ctrl/Cmd + L 聚焦输入框
    if ((e.ctrlKey || e.metaKey) && e.key === 'l') {
        e.preventDefault();
        userInput.focus();
        userInput.select();
    }
    
    // ESC 键清空当前输入
    if (e.key === 'Escape') {
        userInput.value = '';
        userInput.focus();
    }
});

// 粘贴处理
userInput.addEventListener('paste', (e) => {
    setTimeout(() => {
        const pastedText = userInput.value;
        const url = extractURL(pastedText);
        if (url && url === pastedText.trim()) {
            // 如果粘贴的是纯URL,自动识别类型
            setTimeout(() => {
                userInput.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
            }, 100);
        }
    }, 10);
});

// 触摸设备优化
if ('ontouchstart' in window) {
    // 防止双击缩放
    let lastTouchEnd = 0;
    document.addEventListener('touchend', (e) => {
        const now = (new Date()).getTime();
        if (now - lastTouchEnd <= 300) {
            e.preventDefault();
        }
        lastTouchEnd = now;
    }, false);
    
    // 优化滚动
    document.body.style.webkitOverflowScrolling = 'touch';
}

// 主题切换功能(预留)
function toggleTheme() {
    // 这里可以添加主题切换逻辑
    console.log('主题切换功能待实现');
}

// 导出功能(预留)
function exportHistory() {
    const history = {
        commands: commandHistoryArray,
        stats: {
            totalParseCount,
            successParseCount
        },
        timestamp: new Date().toISOString()
    };
    
    const blob = new Blob([JSON.stringify(history, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `tengyuan-terminal-history-${new Date().toISOString().split('T')[0]}.json`;
    a.click();
    URL.revokeObjectURL(url);
}

// 全局暴露一些函数供调试使用
window.terminalDebug = {
    clearTerminal,
    processCommand,
    showStats,
    exportHistory,
    toggleTheme,
    updateWeatherWidget,
    fetchWeatherByIP,
    handleScroll,
    performQuarkSearch
};
</script>
</body>
</html>

        
预览
控制台