{"id":2284,"date":"2026-07-27T11:50:37","date_gmt":"2026-07-27T03:50:37","guid":{"rendered":"https:\/\/ytubage.com\/?p=2284"},"modified":"2026-07-27T11:50:04","modified_gmt":"2026-07-27T03:50:04","slug":"zzjc","status":"publish","type":"post","link":"https:\/\/ytubage.com\/index.php\/2026\/07\/27\/zzjc\/","title":{"rendered":"\u829d\u829d\u5267\u573a"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u829d\u829d\u5267\u573a<\/title>\n    <!-- \u5f15\u5165 Tailwind CSS -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <!-- \u5f15\u5165 Font Awesome -->\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <!-- \u914d\u7f6e Tailwind \u4e3b\u9898 -->\n    <script>\n        tailwind.config = {\n            darkMode: 'class',\n            theme: {\n                extend: {\n                    colors: {\n                        primary: '#3b82f6',\n                        secondary: '#8b5cf6',\n                        dark: '#0f172a',\n                        light: '#f8fafc'\n                    },\n                    animation: {\n                        'fade-in': 'fadeIn 0.5s ease-out',\n                        'slide-up': 'slideUp 0.5s ease-out',\n                    },\n                    keyframes: {\n                        fadeIn: {\n                            '0%': { opacity: '0' },\n                            '100%': { opacity: '1' },\n                        },\n                        slideUp: {\n                            '0%': { transform: 'translateY(20px)', opacity: '0' },\n                            '100%': { transform: 'translateY(0)', opacity: '1' },\n                        }\n                    }\n                }\n            }\n        }\n    <\/script>\n    <style>\n        \/* \u81ea\u5b9a\u4e49\u6eda\u52a8\u6761 *\/\n        ::-webkit-scrollbar {\n            width: 8px;\n        }\n        ::-webkit-scrollbar-track {\n            background: transparent;\n        }\n        ::-webkit-scrollbar-thumb {\n            background: #cbd5e1;\n            border-radius: 4px;\n        }\n        .dark ::-webkit-scrollbar-thumb {\n            background: #334155;\n        }\n        \/* \u73bb\u7483\u62df\u6001\u6548\u679c *\/\n        .glass {\n            background: rgba(255, 255, 255, 0.7);\n            backdrop-filter: blur(10px);\n            -webkit-backdrop-filter: blur(10px);\n            border: 1px solid rgba(255, 255, 255, 0.3);\n        }\n        .dark .glass {\n            background: rgba(15, 23, 42, 0.7);\n            border: 1px solid rgba(255, 255, 255, 0.05);\n        }\n        \/* \u94fe\u63a5\u5361\u7247\u60ac\u505c\u6548\u679c *\/\n        .link-card {\n            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n        .link-card:hover {\n            transform: translateY(-5px);\n            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);\n        }\n    <\/style>\n<\/head>\n<body class=\"bg-gray-50 text-gray-800 dark:bg-dark dark:text-gray-100 transition-colors duration-300 min-h-screen flex flex-col font-sans\">\n\n    <!-- \u5934\u90e8\u5bfc\u822a -->\n    <header class=\"fixed w-full top-0 z-50 glass shadow-sm transition-all duration-300\" id=\"navbar\">\n        <div class=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n            <div class=\"flex justify-between items-center h-16\">\n                <!-- Logo -->\n                <div class=\"flex-shrink-0 flex items-center cursor-pointer\" onclick=\"window.scrollTo({top: 0, behavior: 'smooth'})\">\n                    <i class=\"fa-solid fa-compass text-2xl text-primary mr-2\"><\/i>\n                    <span class=\"font-bold text-xl tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary\">ZZTV<\/span>\n                <\/div>\n\n                <!-- \u641c\u7d22\u6846 (\u684c\u9762\u7aef) -->\n                <div class=\"hidden md:flex flex-1 max-w-lg mx-8 relative group\">\n                    <div class=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\n                        <i class=\"fa-solid fa-search text-gray-400 group-focus-within:text-primary transition-colors\"><\/i>\n                    <\/div>\n                    <input type=\"text\" id=\"searchInput\" \n                        class=\"block w-full pl-10 pr-3 py-2 border border-gray-300 dark:border-gray-700 rounded-full leading-5 bg-white dark:bg-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary sm:text-sm transition-all shadow-sm\" \n                        placeholder=\"\u641c\u7d22\u94fe\u63a5\u6216\u5206\u7c7b...\">\n                <\/div>\n\n                <!-- \u53f3\u4fa7\u5de5\u5177\u680f -->\n                <div class=\"flex items-center space-x-4\">\n                    <!-- \u4e3b\u9898\u5207\u6362\u6309\u94ae -->\n                    <button id=\"themeToggle\" class=\"p-2 rounded-full text-gray-500 hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors focus:outline-none\" aria-label=\"\u5207\u6362\u4e3b\u9898\">\n                        <i class=\"fa-solid fa-moon text-xl\" id=\"themeIcon\"><\/i>\n                    <\/button>\n                    \n                    <!-- \u8bbe\u7f6e\u6309\u94ae -->\n                    <button id=\"settingsBtn\" class=\"p-2 rounded-full text-gray-500 hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors focus:outline-none\" aria-label=\"\u6253\u5f00\u8bbe\u7f6e\">\n                        <i class=\"fa-solid fa-gear text-xl\"><\/i>\n                    <\/button>\n                <\/div>\n            <\/div>\n            \n            <!-- \u79fb\u52a8\u7aef\u641c\u7d22\u6846 (\u9ed8\u8ba4\u9690\u85cf\uff0c\u53ef\u901a\u8fc7JS\u6269\u5c55\uff0c\u6b64\u5904\u7b80\u5316\u4e3a\u4ec5\u684c\u9762\u663e\u793a\uff0c\u79fb\u52a8\u7aef\u4f9d\u9760\u5206\u7c7b\u7b5b\u9009) -->\n            <div class=\"md:hidden pb-3\">\n                 <input type=\"text\" id=\"mobileSearchInput\" \n                        class=\"block w-full px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-primary\" \n                        placeholder=\"\u641c\u7d22...\">\n            <\/div>\n        <\/div>\n    <\/header>\n\n    <!-- \u4e3b\u5185\u5bb9\u533a\u57df -->\n    <main class=\"flex-grow pt-24 pb-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto w-full\">\n        \n        <!-- \u6b22\u8fce\u8bed\u4e0e\u65f6\u95f4 -->\n        <div class=\"mb-10 text-center animate-fade-in\">\n            <h1 class=\"text-3xl md:text-4xl font-bold mb-2\" id=\"greeting\">\u4f60\u597d\uff0c\u8bbf\u5ba2<\/h1>\n            <p class=\"text-gray-500 dark:text-gray-400\" id=\"currentDate\">\u52a0\u8f7d\u4e2d&#8230;<\/p>\n        <\/div>\n\n        <!-- \u5206\u7c7b\u6807\u7b7e\u680f -->\n        <div class=\"flex overflow-x-auto pb-4 mb-8 space-x-2 scrollbar-hide justify-start md:justify-center\" id=\"categoryContainer\">\n            <!-- \u52a8\u6001\u751f\u6210\u5206\u7c7b\u6807\u7b7e -->\n            <button class=\"category-btn active px-4 py-2 rounded-full text-sm font-medium bg-primary text-white shadow-md transition-all whitespace-nowrap\" data-category=\"all\">\n                \u5168\u90e8\n            <\/button>\n            <!-- \u5176\u4ed6\u5206\u7c7b\u5c06\u7531 JS \u6ce8\u5165 -->\n        <\/div>\n\n        <!-- \u94fe\u63a5\u7f51\u683c -->\n        <div id=\"linksGrid\" class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\n            <!-- \u52a8\u6001\u751f\u6210\u94fe\u63a5\u5361\u7247 -->\n        <\/div>\n\n        <!-- \u7a7a\u72b6\u6001\u63d0\u793a -->\n        <div id=\"emptyState\" class=\"hidden flex-col items-center justify-center py-20 text-center\">\n            <i class=\"fa-regular fa-folder-open text-6xl text-gray-300 dark:text-gray-700 mb-4\"><\/i>\n            <p class=\"text-gray-500 dark:text-gray-400 text-lg\">\u672a\u627e\u5230\u76f8\u5173\u94fe\u63a5<\/p>\n            <button onclick=\"resetFilter()\" class=\"mt-4 text-primary hover:underline\">\u6e05\u9664\u7b5b\u9009<\/button>\n        <\/div>\n    <\/main>\n\n    <!-- \u9875\u811a -->\n    <footer class=\"bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-800 py-8\">\n        <div class=\"max-w-7xl mx-auto px-4 text-center\">\n            <p class=\"text-gray-500 dark:text-gray-400 text-sm\">\n                &copy; <span id=\"year\"><\/span> ZZ TV. Designed with <i class=\"fa-solid fa-heart text-red-500 mx-1\"><\/i> by You.\n            <\/p>\n            <div class=\"mt-2 space-x-4\">\n                <a href=\"#\" class=\"text-gray-400 hover:text-primary transition-colors\"><i class=\"fa-brands fa-github\"><\/i><\/a>\n                <a href=\"#\" class=\"text-gray-400 hover:text-primary transition-colors\"><i class=\"fa-brands fa-twitter\"><\/i><\/a>\n                <a href=\"#\" class=\"text-gray-400 hover:text-primary transition-colors\"><i class=\"fa-solid fa-envelope\"><\/i><\/a>\n            <\/div>\n        <\/div>\n    <\/footer>\n\n    <!-- \u6dfb\u52a0\u94fe\u63a5\u6a21\u6001\u6846 -->\n    <div id=\"addLinkModal\" class=\"fixed inset-0 z-[60] hidden overflow-y-auto\" aria-labelledby=\"modal-title\" role=\"dialog\" aria-modal=\"true\">\n        <div class=\"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0\">\n            <!-- \u80cc\u666f\u906e\u7f69 -->\n            <div class=\"fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity backdrop-blur-sm\" aria-hidden=\"true\" id=\"modalBackdrop\"><\/div>\n\n            <span class=\"hidden sm:inline-block sm:align-middle sm:h-screen\" aria-hidden=\"true\">&#8203;<\/span>\n\n            <div class=\"inline-block align-bottom bg-white dark:bg-gray-800 rounded-2xl text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full\">\n                <div class=\"bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4\">\n                    <div class=\"sm:flex sm:items-start\">\n                        <div class=\"mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-primary bg-opacity-10 sm:mx-0 sm:h-10 sm:w-10\">\n                            <i class=\"fa-solid fa-plus text-primary\"><\/i>\n                        <\/div>\n                        <div class=\"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full\">\n                            <h3 class=\"text-lg leading-6 font-medium text-gray-900 dark:text-white\" id=\"modal-title\">\u6dfb\u52a0\u65b0\u94fe\u63a5<\/h3>\n                            <div class=\"mt-4 space-y-4\">\n                                <div>\n                                    <label for=\"linkTitle\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\">\u540d\u79f0<\/label>\n                                    <input type=\"text\" id=\"linkTitle\" class=\"mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-primary focus:border-primary sm:text-sm dark:bg-gray-700 dark:text-white\">\n                                <\/div>\n                                <div>\n                                    <label for=\"linkUrl\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\">URL<\/label>\n                                    <input type=\"url\" id=\"linkUrl\" placeholder=\"https:\/\/\" class=\"mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-primary focus:border-primary sm:text-sm dark:bg-gray-700 dark:text-white\">\n                                <\/div>\n                                <div>\n                                    <label for=\"linkCategory\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\">\u5206\u7c7b<\/label>\n                                    <select id=\"linkCategory\" class=\"mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-primary focus:border-primary sm:text-sm dark:bg-gray-700 dark:text-white\">\n                                        <option value=\"\u6b63\u5728\u70ed\u64ad\">\u6b63\u5728\u70ed\u64ad<\/option>\n                                        <option value=\"\u63a8\u8350\">\u63a8\u8350<\/option>\n                                        <option value=\"\u53e4\u88c5\u5267\">\u53e4\u88c5\u5267<\/option>\n                                        <option value=\"\u90fd\u5e02\u5267\">\u90fd\u5e02\u5267<\/option>\n                                        <option value=\"\u9017\u5267\u573a\">\u9017\u5267\u573a<\/option>\n                                    <\/select>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse\">\n                    <button type=\"button\" id=\"saveLinkBtn\" class=\"w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary sm:ml-3 sm:w-auto sm:text-sm transition-colors\">\n                        \u4fdd\u5b58\n                    <\/button>\n                    <button type=\"button\" id=\"cancelAddBtn\" class=\"mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-500 shadow-sm px-4 py-2 bg-white dark:bg-gray-800 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm transition-colors\">\n                        \u53d6\u6d88\n                    <\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <!-- \u8bbe\u7f6e\u9762\u677f (\u4fa7\u8fb9\u680f) -->\n    <div id=\"settingsPanel\" class=\"fixed inset-y-0 right-0 w-80 bg-white dark:bg-gray-800 shadow-2xl transform translate-x-full transition-transform duration-300 z-[70] flex flex-col\">\n        <div class=\"p-6 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center\">\n            <h2 class=\"text-xl font-bold text-gray-900 dark:text-white\">\u8bbe\u7f6e<\/h2>\n            <button id=\"closeSettings\" class=\"text-gray-500 hover:text-gray-700 dark:hover:text-gray-300\">\n                <i class=\"fa-solid fa-times text-xl\"><\/i>\n            <\/button>\n        <\/div>\n        <div class=\"p-6 flex-1 overflow-y-auto space-y-6\">\n            <!-- \u5916\u89c2\u8bbe\u7f6e -->\n            <div>\n                <h3 class=\"text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3\">\u5916\u89c2<\/h3>\n                <div class=\"space-y-3\">\n                    <div class=\"flex items-center justify-between\">\n                        <span class=\"text-gray-700 dark:text-gray-300\">\u6df1\u8272\u6a21\u5f0f<\/span>\n                        <button id=\"darkModeToggleSwitch\" class=\"relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary bg-gray-200 dark:bg-primary\">\n                            <span aria-hidden=\"true\" class=\"pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 translate-x-0 dark:translate-x-5\"><\/span>\n                        <\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n            \n            <!-- \u6570\u636e\u7ba1\u7406 -->\n            <div>\n                <h3 class=\"text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3\">\u6570\u636e\u7ba1\u7406<\/h3>\n               \n <div class=\"space-y-3\">\n                    <!--  <button onclick=\"exportData()\" class=\"w-full flex items-center justify-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 transition-colors\">\n                        <i class=\"fa-solid fa-download mr-2\"> \u5bfc\u51fa\u914d\u7f6e\n                    <\/button>\n-->\n   <!--                  <label class=\"w-full flex items-center justify-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 transition-colors cursor-pointer\">\n                        <i class=\"fa-solid fa-upload mr-2\"><\/i> \u5bfc\u5165\u914d\u7f6e\n                        <input type=\"file\" id=\"importFile\" class=\"hidden\" accept=\".json\">\n                    <\/label>  -->\n\n                    <button onclick=\"clearAllData()\" class=\"w-full flex items-center justify-center px-4 py-2 border border-red-300 dark:border-red-800 rounded-md shadow-sm text-sm font-medium text-red-700 dark:text-red-400 bg-white dark:bg-gray-700 hover:bg-red-50 dark:hover:bg-red-900\/20 transition-colors\">\n                        <i class=\"fa-solid fa-trash mr-2\"><\/i> \u91cd\u7f6e\u6240\u6709\u6570\u636e\n                    <\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n        <div class=\"p-6 border-t border-gray-200 dark:border-gray-700\">\n             <button id=\"openAddLinkFromSettings\" class=\"w-full flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary hover:bg-blue-700 transition-colors\">\n                <i class=\"fa-solid fa-plus mr-2\"><\/i> \u6dfb\u52a0\u65b0\u94fe\u63a5\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <!-- JavaScript \u903b\u8f91 -->\n    <script>\n        \/\/ --- \u6570\u636e\u521d\u59cb\u5316 ---\n        const defaultLinks = [\n            { id: 1, title: '\u65b0\u767d\u5a18\u5b50\u4f20\u5947', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/xbnzqq\/', category: '\u6b63\u5728\u70ed\u64ad', icon: 'fa-google', color: 'text-blue-500' },\n            { id: 2, title: '\u64ad\u97f3\u4eba', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/byr\/', category: '\u63a8\u8350', icon: 'fa-github', color: 'text-gray-800 dark:text-white' },\n            { id: 3, title: '\u9b54\u57df\u6843\u6e90',url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/myty\/', category: '\u53e4\u88c5\u5267', icon: 'fa-tv', color: 'text-pink-400' },\n            { id: 4, title: '\u4e0a\u6d77\u6ee9', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/sht\/', category: '\u90fd\u5e02\u5267', icon: 'fa-zhihu', color: 'text-blue-600' }, \/\/ Note: fa-zhihu might not be in free FA, using generic or custom if needed, fallback to circle-question\n            { id: 5, title: '\u620f\u8bf4\u4e7e\u9686', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/xsql\/xsqlyb\/', category: '\u53e4\u88c5\u5267', icon: 'fa-youtube', color: 'text-red-600' },\n            { id: 6, title: '\u4e09\u82b1', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/shanhua\/', category: '\u63a8\u8350', icon: 'fa-stack-overflow', color: 'text-orange-500' },\n            { id: 7, title: '\u4e58\u98ce\u7834\u6d6a', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/cfpl\/', category: '\u90fd\u5e02\u5267', icon: 'fa-twitter', color: 'text-blue-400' },\n            { id: 8, title: '\u9752\u82b1', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/qinghua\/', category: '\u63a8\u8350', icon: 'fa-firefox-browser', color: 'text-black dark:text-white' },\n            { id: 9, title: '\u96ea\u5c71\u98de\u72d0', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/xshh\/', category: '\u53e4\u88c5\u5267', icon: 'fa-firefox-browser', color: 'text-black dark:text-white' },\n            { id: 10, title: '\u4eac\u534e\u70df\u4e91', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/jhyy\/', category: '\u63a8\u8350', icon: 'fa-firefox-browser', color: 'text-black dark:text-white' },\n            { id: 11, title: '\u89c2\u4e16\u97f3', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/gsy\/', category: '\u53e4\u88c5\u5267', icon: 'fa-firefox-browser', color: 'text-black dark:text-white' },\n            { id: 12, title: '\u5e1d\u5973\u82b1', url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/shanhua\/dnh1994\/', category: '\u53e4\u88c5\u5267', icon: 'fa-stack-overflow', color: 'text-orange-500' },\n          { id: 13, title: '\u72b6\u5143\u82b1',url:'https:\/\/ytubage.com\/index.php\/mxsp\/dsjc\/shanhua\/zrh\/', category: '\u53e4\u88c5\u5267', icon: 'fa-stack-overflow', color: 'text-orange-500' },\n        ];\n\n        \/\/ \u4fee\u6b63\u56fe\u6807\u6620\u5c04\uff0c\u786e\u4fdd Font Awesome Free \u652f\u6301\n        const iconMap = {\n            'Google': 'fa-google',\n            'GitHub': 'fa-github',\n            'Bilibili': 'fa-tv',\n            '\u77e5\u4e4e': 'fa-circle-question',\n            'YouTube': 'fa-youtube',\n            'Stack Overflow': 'fa-stack-overflow',\n            'Twitter': 'fa-twitter',\n            'MDN Web Docs': 'fa-code',\n            'Default': 'fa-link'\n        };\n\n        let links = [];\n        let currentCategory = 'all';\n        let searchQuery = '';\n\n        \/\/ --- DOM \u5143\u7d20 ---\n        const linksGrid = document.getElementById('linksGrid');\n        const categoryContainer = document.getElementById('categoryContainer');\n        const emptyState = document.getElementById('emptyState');\n        const searchInput = document.getElementById('searchInput');\n        const mobileSearchInput = document.getElementById('mobileSearchInput');\n        const themeToggle = document.getElementById('themeToggle');\n        const themeIcon = document.getElementById('themeIcon');\n        const darkModeToggleSwitch = document.getElementById('darkModeToggleSwitch');\n        const settingsBtn = document.getElementById('settingsBtn');\n        const settingsPanel = document.getElementById('settingsPanel');\n        const closeSettings = document.getElementById('closeSettings');\n        const addLinkModal = document.getElementById('addLinkModal');\n        const modalBackdrop = document.getElementById('modalBackdrop');\n        const cancelAddBtn = document.getElementById('cancelAddBtn');\n        const saveLinkBtn = document.getElementById('saveLinkBtn');\n        const openAddLinkFromSettings = document.getElementById('openAddLinkFromSettings');\n        const greetingEl = document.getElementById('greeting');\n        const dateEl = document.getElementById('currentDate');\n        const yearEl = document.getElementById('year');\n\n        \/\/ --- \u521d\u59cb\u5316 ---\n        document.addEventListener('DOMContentLoaded', () => {\n            loadData();\n            initTheme();\n            renderCategories();\n            renderLinks();\n            updateTimeAndGreeting();\n            setInterval(updateTimeAndGreeting, 1); \/\/ \u6bcf\u5206\u949f\u66f4\u65b0\n            yearEl.textContent = new Date().getFullYear();\n            \n            \/\/ \u7ed1\u5b9a\u4e8b\u4ef6\n            setupEventListeners();\n        });\n\n        \/\/ --- \u6570\u636e\u7ba1\u7406 ---\n        function loadData() {\n            const stored = localStorage.getItem('navHubLinks');\n            if (stored) {\n                links = JSON.parse(stored);\n            } else {\n                links = [...defaultLinks];\n                saveData();\n            }\n        }\n\n        function saveData() {\n            localStorage.setItem('navHubLinks', JSON.stringify(links));\n        }\n\n        function exportData() {\n            const dataStr = \"data:text\/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(links));\n            const downloadAnchorNode = document.createElement('a');\n            downloadAnchorNode.setAttribute(\"href\", dataStr);\n            downloadAnchorNode.setAttribute(\"download\", \"navhub_backup.json\");\n            document.body.appendChild(downloadAnchorNode);\n            downloadAnchorNode.click();\n            downloadAnchorNode.remove();\n        }\n\n        function importData(event) {\n            const file = event.target.files[0];\n            if (!file) return;\n            const reader = new FileReader();\n            reader.onload = function(e) {\n                try {\n                    const importedLinks = JSON.parse(e.target.result);\n                    if (Array.isArray(importedLinks)) {\n                        links = importedLinks;\n                        saveData();\n                        renderCategories();\n                        renderLinks();\n                        alert('\u914d\u7f6e\u5bfc\u5165\u6210\u529f\uff01');\n                    } else {\n                        alert('\u6587\u4ef6\u683c\u5f0f\u9519\u8bef');\n                    }\n                } catch (err) {\n                    alert('\u89e3\u6790\u6587\u4ef6\u5931\u8d25');\n                }\n            };\n            reader.readAsText(file);\n            \/\/ Reset input\n            event.target.value = '';\n        }\n\n        function clearAllData() {\n            if(confirm('\u786e\u5b9a\u8981\u6e05\u7a7a\u6240\u6709\u81ea\u5b9a\u4e49\u94fe\u63a5\u5e76\u6062\u590d\u9ed8\u8ba4\u5417\uff1f\u6b64\u64cd\u4f5c\u4e0d\u53ef\u64a4\u9500\u3002')) {\n                links = [...defaultLinks];\n                saveData();\n                renderCategories();\n                renderLinks();\n                toggleSettingsPanel(false);\n            }\n        }\n\n        \/\/ --- \u6e32\u67d3\u903b\u8f91 ---\n        function getUniqueCategories() {\n            const cats = new Set(links.map(l => l.category));\n            return Array.from(cats);\n        }\n\n        function renderCategories() {\n            const categories = getUniqueCategories();\n            \/\/ \u4fdd\u7559\u201c\u5168\u90e8\u201d\u6309\u94ae\n            categoryContainer.innerHTML = `\n                <button class=\"category-btn ${currentCategory === 'all' ? 'active bg-primary text-white shadow-md' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700'} px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap border border-transparent dark:border-gray-700\" data-category=\"all\">\n                    \u5168\u90e8\n                <\/button>\n            `;\n            \n            categories.forEach(cat => {\n                const btn = document.createElement('button');\n                btn.className = `category-btn ${currentCategory === cat ? 'active bg-primary text-white shadow-md' : 'bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700'} px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap border border-transparent dark:border-gray-700`;\n                btn.textContent = cat;\n                btn.dataset.category = cat;\n                btn.onclick = () => filterByCategory(cat);\n                categoryContainer.appendChild(btn);\n            });\n\n            \/\/ \u91cd\u65b0\u7ed1\u5b9a\u201c\u5168\u90e8\u201d\u4e8b\u4ef6\n            categoryContainer.querySelector('[data-category=\"all\"]').onclick = () => filterByCategory('all');\n        }\n\n        function renderLinks() {\n            linksGrid.innerHTML = '';\n            \n            const filtered = links.filter(link => {\n                const matchesCategory = currentCategory === 'all' || link.category === currentCategory;\n                const matchesSearch = link.title.toLowerCase().includes(searchQuery.toLowerCase()) || \n                                      link.url.toLowerCase().includes(searchQuery.toLowerCase());\n                return matchesCategory && matchesSearch;\n            });\n\n            if (filtered.length === 0) {\n                emptyState.classList.remove('hidden');\n                emptyState.classList.add('flex');\n            } else {\n                emptyState.classList.add('hidden');\n                emptyState.classList.remove('flex');\n                \n                filtered.forEach((link, index) => {\n                    const card = document.createElement('div');\n                    card.className = 'link-card bg-white dark:bg-gray-800 rounded-xl p-5 border border-gray-100 dark:border-gray-700 shadow-sm relative group animate-slide-up';\n                    card.style.animationDelay = `${index * 0.05}s`;\n                    \n                    \/\/ \u83b7\u53d6\u56fe\u6807\u7c7b\u540d\n                    const iconClass = iconMap[link.title] || iconMap['Default'];\n                    \/\/ \u7b80\u5355\u7684\u989c\u8272\u6620\u5c04\uff0c\u5b9e\u9645\u9879\u76ee\u4e2d\u53ef\u66f4\u590d\u6742\n                    let colorClass = 'text-gray-500';\n                    if(link.title.includes('Google')) colorClass = 'text-blue-500';\n                    else if(link.title.includes('Git')) colorClass = 'text-gray-800 dark:text-white';\n                    else if(link.title.includes('Bili')) colorClass = 'text-pink-400';\n                    else if(link.title.includes('You')) colorClass = 'text-red-600';\n                    else if(link.title.includes('Stack')) colorClass = 'text-orange-500';\n                    else if(link.title.includes('Twitter')) colorClass = 'text-blue-400';\n                    else if(link.title.includes('MDN')) colorClass = 'text-black dark:text-white';\n                    else if(link.title.includes('\u77e5\u4e4e')) colorClass = 'text-blue-600';\n\n                    card.innerHTML = `\n                        <div class=\"flex items-center justify-between mb-4\">\n                            <div class=\"h-12 w-12 rounded-lg bg-gray-50 dark:bg-gray-700 flex items-center justify-center text-2xl ${colorClass}\">\n                                <i class=\"fa-brands ${iconClass} ${!iconClass.includes('fa-brands') ? 'fa-solid' : ''}\"><\/i>\n                            <\/div>\n<!-- \n                            <div class=\"opacity-0 group-hover:opacity-100 transition-opacity flex space-x-2\">\n                                <button onclick=\"editLink(${link.id})\" class=\"text-gray-400 hover:text-primary p-1\" title=\"\u7f16\u8f91\">\n                                    <i class=\"fa-solid fa-pen-to-square\"><\/i>\n                                <\/button>\n                                <button onclick=\"deleteLink(${link.id})\" class=\"text-gray-400 hover:text-red-500 p-1\" title=\"\u5220\u9664\">\n                                    <i class=\"fa-solid fa-trash\"><\/i>\n                                <\/button>\n                            <\/div>\n-->\n                        <\/div>\n                        <h3 class=\"font-bold text-gray-900 dark:text-white truncate mb-1\" title=\"${link.title}\">${link.title}<\/h3>\n                        <p class=\"text-xs text-gray-500 dark:text-gray-400 truncate mb-3\">${link.category}<\/p>\n                        <a href=\"${link.url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"block w-full text-center py-2 px-4 bg-gray-50 dark:bg-gray-700 hover:bg-primary hover:text-white dark:hover:bg-primary text-gray-600 dark:text-gray-300 rounded-lg text-sm font-medium transition-colors\">\n                            \u8bbf\u95ee <i class=\"fa-solid fa-arrow-up-right-from-square ml-1 text-xs\"><\/i>\n                        <\/a>\n                    `;\n                    linksGrid.appendChild(card);\n                });\n            }\n        }\n\n        \/\/ --- \u4ea4\u4e92\u903b\u8f91 ---\n        function filterByCategory(category) {\n            currentCategory = category;\n            \/\/ \u66f4\u65b0\u6309\u94ae\u6837\u5f0f\n            const buttons = categoryContainer.querySelectorAll('.category-btn');\n            buttons.forEach(btn => {\n                if (btn.dataset.category === category) {\n                    btn.className = 'category-btn active bg-primary text-white shadow-md px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap border border-transparent';\n                } else {\n                    btn.className = 'category-btn bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap border border-transparent dark:border-gray-700';\n                }\n            });\n            renderLinks();\n        }\n\n        function resetFilter() {\n            searchQuery = '';\n            searchInput.value = '';\n            mobileSearchInput.value = '';\n            filterByCategory('all');\n        }\n\n        function deleteLink(id) {\n            if(confirm('\u786e\u5b9a\u5220\u9664\u6b64\u94fe\u63a5\u5417\uff1f')) {\n                links = links.filter(l => l.id !== id);\n                saveData();\n                renderCategories(); \/\/ \u53ef\u80fd\u5206\u7c7b\u4e3a\u7a7a\u4e86\n                renderLinks();\n            }\n        }\n\n        function editLink(id) {\n            const link = links.find(l => l.id === id);\n            if (!link) return;\n            \n            \/\/ \u586b\u5145\u8868\u5355\n            document.getElementById('linkTitle').value = link.title;\n            document.getElementById('linkUrl').value = link.url;\n            document.getElementById('linkCategory').value = link.category;\n            \n            \/\/ \u6807\u8bb0\u4e3a\u7f16\u8f91\u6a21\u5f0f\n            saveLinkBtn.dataset.editId = id;\n            saveLinkBtn.textContent = '\u66f4\u65b0';\n            \n            \/\/ \u663e\u793a\u6a21\u6001\u6846\n            toggleModal(true);\n        }\n\n        function addNewLink() {\n            \/\/ \u6e05\u7a7a\u8868\u5355\n            document.getElementById('linkTitle').value = '';\n            document.getElementById('linkUrl').value = '';\n            document.getElementById('linkCategory').value = '\u6b63\u5728\u70ed\u64ad';\n            \n            delete saveLinkBtn.dataset.editId;\n            saveLinkBtn.textContent = '\u4fdd\u5b58';\n            \n            toggleModal(true);\n        }\n\n        function saveLinkAction() {\n            const title = document.getElementById('linkTitle').value.trim();\n            let url = document.getElementById('linkUrl').value.trim();\n            const category = document.getElementById('linkCategory').value;\n            const editId = saveLinkBtn.dataset.editId;\n\n            if (!title || !url) {\n                alert('\u8bf7\u586b\u5199\u540d\u79f0\u548cURL');\n                return;\n            }\n\n            if (!url.startsWith('http:\/\/') && !url.startsWith('https:\/\/')) {\n                url = 'https:\/\/' + url;\n            }\n\n            if (editId) {\n                \/\/ \u66f4\u65b0\n                const index = links.findIndex(l => l.id == editId);\n                if (index !== -1) {\n                    links[index] = { ...links[index], title, url, category };\n                }\n            } else {\n                \/\/ \u65b0\u589e\n                const newId = links.length > 0 ? Math.max(...links.map(l => l.id)) + 1 : 1;\n                links.push({\n                    id: newId,\n                    title,\n                    url,\n                    category,\n                    icon: 'fa-link',\n                    color: 'text-gray-500'\n                });\n            }\n\n            saveData();\n            renderCategories();\n            renderLinks();\n            toggleModal(false);\n        }\n\n        \/\/ --- UI \u7ec4\u4ef6\u63a7\u5236 ---\n        function toggleModal(show) {\n            if (show) {\n                addLinkModal.classList.remove('hidden');\n                setTimeout(() => {\n                    addLinkModal.querySelector('div[class*=\"transform\"]').classList.remove('scale-95', 'opacity-0');\n                    addLinkModal.querySelector('div[class*=\"transform\"]').classList.add('scale-100', 'opacity-100');\n                }, 10);\n            } else {\n                addLinkModal.querySelector('div[class*=\"transform\"]').classList.remove('scale-100', 'opacity-100');\n                addLinkModal.querySelector('div[class*=\"transform\"]').classList.add('scale-95', 'opacity-0');\n                setTimeout(() => {\n                    addLinkModal.classList.add('hidden');\n                }, 200);\n            }\n        }\n\n        function toggleSettingsPanel(show) {\n            if (show) {\n                settingsPanel.classList.remove('translate-x-full');\n            } else {\n                settingsPanel.classList.add('translate-x-full');\n            }\n        }\n\n        \/\/ --- \u4e3b\u9898\u4e0e\u65f6\u95f4 ---\n        function initTheme() {\n            const savedTheme = localStorage.getItem('theme');\n            const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n            \n            if (savedTheme === 'dark' || (!savedTheme && systemDark)) {\n                document.documentElement.classList.add('dark');\n                updateThemeIcon(true);\n            } else {\n                document.documentElement.classList.remove('dark');\n                updateThemeIcon(false);\n            }\n        }\n\n        function toggleTheme() {\n            const isDark = document.documentElement.classList.toggle('dark');\n            localStorage.setItem('theme', isDark ? 'dark' : 'light');\n            updateThemeIcon(isDark);\n        }\n\n        function updateThemeIcon(isDark) {\n            if (isDark) {\n                themeIcon.classList.remove('fa-moon');\n                themeIcon.classList.add('fa-sun');\n                darkModeToggleSwitch.classList.remove('bg-gray-200');\n                darkModeToggleSwitch.classList.add('bg-primary');\n                darkModeToggleSwitch.querySelector('span').classList.add('translate-x-5');\n                darkModeToggleSwitch.querySelector('span').classList.remove('translate-x-0');\n            } else {\n                themeIcon.classList.remove('fa-sun');\n                themeIcon.classList.add('fa-moon');\n                darkModeToggleSwitch.classList.add('bg-gray-200');\n                darkModeToggleSwitch.classList.remove('bg-primary');\n                darkModeToggleSwitch.querySelector('span').classList.remove('translate-x-5');\n                darkModeToggleSwitch.querySelector('span').classList.add('translate-x-0');\n            }\n        }\n\n        function updateTimeAndGreeting() {\n            const now = new Date();\n            const hour = now.getHours();\n            let greet = '\u4f60\u597d';\n            if (hour < 6) greet = '\u591c\u6df1\u4e86';\n            else if (hour < 9) greet = '\u65e9\u4e0a\u597d';\n            else if (hour < 12) greet = '\u4e0a\u5348\u597d';\n            else if (hour < 14) greet = '\u4e2d\u5348\u597d';\n            else if (hour < 18) greet = '\u4e0b\u5348\u597d';\n            else greet = '\u665a\u4e0a\u597d';\n            \n            greetingEl.textContent = `${greet}\uff0c\u8bbf\u5ba2`;\n            \n            const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' };\n            dateEl.textContent = now.toLocaleDateString('zh-CN', options);\n        }\n\n        \/\/ --- \u4e8b\u4ef6\u76d1\u542c\u7ed1\u5b9a ---\n        function setupEventListeners() {\n            \/\/ \u641c\u7d22\n            const handleSearch = (e) => {\n                searchQuery = e.target.value;\n                renderLinks();\n            };\n            searchInput.addEventListener('input', handleSearch);\n            mobileSearchInput.addEventListener('input', handleSearch);\n\n            \/\/ \u4e3b\u9898\n            themeToggle.addEventListener('click', toggleTheme);\n            darkModeToggleSwitch.addEventListener('click', toggleTheme);\n\n            \/\/ \u8bbe\u7f6e\u9762\u677f\n            settingsBtn.addEventListener('click', () => toggleSettingsPanel(true));\n            closeSettings.addEventListener('click', () => toggleSettingsPanel(false));\n            modalBackdrop.addEventListener('click', () => toggleModal(false));\n            \n            \/\/ \u6a21\u6001\u6846\u64cd\u4f5c\n            cancelAddBtn.addEventListener('click', () => toggleModal(false));\n            saveLinkBtn.addEventListener('click', saveLinkAction);\n            openAddLinkFromSettings.addEventListener('click', () => {\n                toggleSettingsPanel(false);\n                setTimeout(addNewLink, 300);\n            });\n\n            \/\/ \u5bfc\u5165\u6587\u4ef6\n            document.getElementById('importFile').addEventListener('change', importData);\n        }\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>\u829d\u829d\u5267\u573a ZZTV \u4f60\u597d\uff0c\u8bbf\u5ba2 \u52a0\u8f7d\u4e2d&#8230; \u5168\u90e8 \u672a\u627e\u5230\u76f8\u5173\u94fe\u63a5 \u6e05\u9664\u7b5b\u9009 &copy; ZZ TV [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,1,8,5,7],"tags":[],"class_list":["post-2284","post","type-post","status-publish","format-standard","hentry","category-kzjp","category-uncategorized","category-updatefile","category-dujia","category-index"],"_links":{"self":[{"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/posts\/2284","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/comments?post=2284"}],"version-history":[{"count":53,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/posts\/2284\/revisions"}],"predecessor-version":[{"id":2571,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/posts\/2284\/revisions\/2571"}],"wp:attachment":[{"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/media?parent=2284"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/categories?post=2284"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ytubage.com\/index.php\/wp-json\/wp\/v2\/tags?post=2284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}