GitHub:https://github.com/IIIStudio/Copy-B
CNB:https://cnb.cool/IIIStudio/HTML/Copy-B
演示:https://iiistudio.github.io/Copy-B/
原理是选择通过 copy /b 命令合并的图片+视频文件
过于简单 ,就不写使用过程了。
点击头像可以更换图片,可以拖拽视频到里面也可以点击上传!
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Copy /B</title> <style> body { font-family: "Microsoft YaHei", sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; text-align: center; background-color: #f5f5f5; } .container { } .tab-container { display: flex; margin-bottom: 20px; } .tab { padding: 10px 20px; cursor: pointer; background-color: #e0e0e0; border-radius: 5px; margin-right: 5px; } .tab.active { background-color: #4CAF50; color: white; } .tab-content { display: none; padding: 20px; border: 1px solid #ddd; border-radius: 0 0 5px 5px; background-color: white; } .tab-content.active { display: block; border: 2px dashed #ccc; border-radius: 8px; } .media-preview { max-width: 100%; max-height: 300px; margin: 15px auto; border: 1px solid #ddd; border-radius: 5px; display: block; } .video-container { position: relative; width: 100%; max-width: 800px; margin: 15px auto; background-color: #000; border-radius: 5px; overflow: hidden; display: none; } .video-container video { width: 100%; height: auto; max-height: 500px; display: block; } .file-input-label, .btn { display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; min-width: 160px; box-sizing: border-box; white-space: nowrap; background-color: #4CAF50; color: white; border-radius: 4px; cursor: pointer; margin: 10px; text-align: center; border: none; transition: background-color 0.3s; } .file-input-label:hover, .btn:hover { background-color: #45a049; } .btn-secondary { background-color: #2196F3; } .btn-secondary:hover { background-color: #0b7dda; } .btn-danger { background-color: #f44336; } .btn-danger:hover { background-color: #da190b; } #status { margin: 15px 0; min-height: 20px; color: #666; } .progress-container { width: 100%; background-color: #f1f1f1; border-radius: 5px; margin: 10px 0; display: none; } .progress-bar { height: 20px; border-radius: 5px; background-color: #4CAF50; width: 0%; transition: width 0.3s; } input[type="text"] { padding: 10px; width: 80%; margin: 10px 0; border: 1px solid #ddd; border-radius: 4px; } .hidden { display: none; } .controls { margin-top: 20px; } [url=home.php?mod=space&uid=945662]@media[/url] (max-width: 600px) { .tab-container { flex-direction: column; } .tab { margin-right: 0; margin-bottom: 5px; border-radius: 5px; } input[type="text"] { width: 95%; } .video-container { max-height: 300px; } } #generate .file-input-label, #generate #generateBtn { width: 150px !important; min-width: 150px !important; height: 40px !important; padding: 0 !important; margin: 10px !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; box-sizing: border-box !important; line-height: 44px !important; font-size: 16px !important; white-space: nowrap !important; vertical-align: middle !important; } /* 拖拽高亮样式(作用于整个面板区域) */ .tab-content.drag-accept { position: relative; } .tab-content.drag-accept.dragover { border-color: #4CAF50 !important; box-shadow: 0 0 0 2px #4CAF50 inset; background: #f0fff4; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> </head> <body> <script> document.body.innerHTML = ''; // Create container const container = document.createElement('div'); container.className = 'container'; document.body.appendChild(container); // Create heading //const h1 = document.createElement('h1'); //h1.textContent = '隐藏视频播放器'; //container.appendChild(h1); // Create tab container const tabContainer = document.createElement('div'); tabContainer.className = 'tab-container'; container.appendChild(tabContainer); // Create tabs const tabs = [ { text: '文件生成', tab: 'generate', active: true }, { text: '本地文件', tab: 'local', active: false }, { text: 'URL转换', tab: 'url', active: false } ]; tabs.forEach(tabData => { const tab = document.createElement('div'); tab.className = `tab ${tabData.active ? 'active' : ''}`; tab.textContent = tabData.text; tab.setAttribute('data-tab', tabData.tab); tabContainer.appendChild(tab); }); // Create tab contents const tabContents = [ { id: 'local', active: false, title: '本地文件提取', description: '选择通过 copy /b 命令合并的图片+视频文件', content: ` <label for="localFile" id="localChooseLabel">选择本地文件</label> <input type="file" id="localFile" accept=".jpg,.jpeg,.png"> <div id="localStatus">等待选择文件...</div> <div id="localProgressContainer"> <div id="localProgress"></div> </div> <img id="localPreview" class="media-preview hidden"> <div id="localVideoContainer"> <video controls id="localVideoPlayer"></video> </div> <div> <button id="localDownloadBtn" class="btn btn-secondary hidden">下载视频</button> </div> ` }, { id: 'url', active: false, title: 'URL转换工具', description: '输入图片URL,提取隐藏视频', content: ` <input type="text" id="imageUrl" placeholder="输入图片URL (如: [img]https://example.com/image.jpg[/img])"> <button id="fetchUrlBtn">提取视频</button> <div id="urlStatus">等待输入URL...</div> <div id="urlProgressContainer"> <div id="urlProgress"></div> </div> <img id="urlPreview" class="media-preview hidden"> <div id="urlVideoContainer"> <video controls id="urlVideoPlayer"></video> </div> <div> <button id="urlDownloadBtn" class="btn btn-secondary hidden">下载视频</button> </div> ` }, { id: 'generate', active: true, title: '文件生成工具', description: '选择视频文件 ,生成合并的图片文件', content: ` <div> <img id="defaultPreview" src="./img/iii.jpg" title="点击更换图片"> </div> <!-- 隐藏的封面图片选择器 --> <input type="file" id="coverImageFile" accept="image/*"> <label for="videoFile">选择视频文件</label> <input type="file" id="videoFile" accept="video/*"> <button id="generateBtn">生成合并图片</button> <div id="generateStatus">等待选择视频文件...</div> <div id="generateProgressContainer"> <div id="generateProgress"></div> </div> <div> <button id="generateDownloadBtn" class="btn btn-secondary hidden">下载合并图片</button> </div> ` } ]; tabContents.forEach(contentData => { const content = document.createElement('div'); content.id = contentData.id; content.className = `tab-content ${contentData.active ? 'active' : ''}`; const h2 = document.createElement('h2'); h2.textContent = contentData.title; if (contentData.id === 'local') h2.id = 'localTitle'; if (contentData.id === 'url') h2.id = 'urlTitle'; content.appendChild(h2); const p = document.createElement('p'); p.textContent = contentData.description; if (contentData.id === 'local') p.id = 'localDesc'; if (contentData.id === 'url') p.id = 'urlDesc'; content.appendChild(p); content.innerHTML += contentData.content; container.appendChild(content); }); // Add tab switching functionality const tabsElements = document.querySelectorAll('.tab'); tabsElements.forEach(tab => { tab.addEventListener('click', () => { // Remove active class from all tabs and contents document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active')); // Add active class to clicked tab and corresponding content tab.classList.add('active'); const tabId = tab.getAttribute('data-tab'); document.getElementById(tabId).classList.add('active'); }); }); // 全局变量 let currentVideoBlob = null; let currentGeneratedBlob = null; let droppedVideoFile = null; // 拖拽到“文件生成工具 ”的视频文件 let customCoverImageBlob = null; // 用户自选的封面图片 // 切换选项卡 document.querySelectorAll('.tab').forEach(tab => { tab.addEventListener('click', () => { document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active')); tab.classList.add('active'); document.getElementById(tab.dataset.tab).classList.add('active'); }); }); // 本地文件处理 document.getElementById('localFile').addEventListener('change', async function(e) { const file = e.target.files[0]; if (!file) return; const statusEl = document.getElementById('localStatus'); const progressContainer = document.getElementById('localProgressContainer'); const progressEl = document.getElementById('localProgress'); const videoContainer = document.getElementById('localVideoContainer'); const videoPlayer = document.getElementById('localVideoPlayer'); const previewImg = document.getElementById('localPreview'); const downloadBtn = document.getElementById('localDownloadBtn'); // 重置状态 statusEl.textContent = "正在处理文件..."; progressContainer.style.display = 'block'; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; downloadBtn.classList.add('hidden'); currentVideoBlob = null; try { // 显示预览图片 previewImg.src = URL.createObjectURL(file); previewImg.classList.remove('hidden'); // 1. 读取文件内容 const arrayBuffer = await file.arrayBuffer(); progressEl.style.width = '20%'; // 2. 查找ZIP文件起始位置 statusEl.textContent = "正在查找隐藏内容..."; const uint8Array = new Uint8Array(arrayBuffer); let zipStart = -1; // 查找ZIP文件头 (PK\x03\x04) for (let i = 0; i < uint8Array.length - 4; i++) { if (uint8Array[i] === 0x50 && uint8Array[i+1] === 0x4B && uint8Array[i+2] === 0x03 && uint8Array[i+3] === 0x04) { zipStart = i; break; } } if (zipStart === -1) throw new Error("未检测到隐藏内容"); progressEl.style.width = '40%'; // 3. 提取ZIP部分 statusEl.textContent = "正在提取隐藏数据..."; const zipData = arrayBuffer.slice(zipStart); progressEl.style.width = '60%'; // 4. 使用JSZip解析ZIP statusEl.textContent = "正在解析内容..."; const zip = await JSZip.loadAsync(zipData); progressEl.style.width = '80%'; // 5. 查找视频文件 statusEl.textContent = "正在查找视频文件..."; let videoFile = null; const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']; for (const [name, file] of Object.entries(zip.files)) { if (!file.dir && videoExtensions.some(ext => name.toLowerCase().endsWith(ext))) { videoFile = file; break; } } if (!videoFile) throw new Error("未找到支持的视频文件"); // 6. 提取视频内容 statusEl.textContent = "正在提取视频..."; const videoData = await videoFile.async('blob'); currentVideoBlob = videoData; progressEl.style.width = '100%'; // 7. 播放视频 videoPlayer.src = URL.createObjectURL(videoData); videoContainer.style.display = 'block'; downloadBtn.classList.remove('hidden'); statusEl.textContent = `已加载: ${videoFile.name}`; // 成功后:隐藏标题 、描述、选择按钮与预览图,仅保留文件名与视频 const lt = document.getElementById('localTitle'); const ld = document.getElementById('localDesc'); const ll = document.getElementById('localChooseLabel'); if (lt) lt.style.display = 'none'; if (ld) ld.style.display = 'none'; if (ll) ll.style.display = 'none'; previewImg.classList.add('hidden'); // 自动播放 videoPlayer.play().catch(e => { statusEl.textContent += " (点击播放按钮开始播放)"; }); } catch (error) { console.error("处理失败:", error); statusEl.textContent = `错误: ${error.message}`; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; } finally { setTimeout(() => { progressContainer.style.display = 'none'; }, 500); } }); // 本地图片拖拽上传(整个面板区域可拖拽) (function() { const dropEl = document.getElementById('local'); if (!dropEl) return; dropEl.classList.add('drag-accept'); const isImage = (file) => { const name = (file.name || '').toLowerCase(); return file.type.startsWith('image/') || name.endsWith('.jpg') || name.endsWith('.jpeg') || name.endsWith('.png'); }; const prevent = (e) => { e.preventDefault(); e.stopPropagation(); }; ['dragenter','dragover'].forEach(ev => { dropEl.addEventListener(ev, (e) => { prevent(e); dropEl.classList.add('dragover'); }); }); ['dragleave','drop'].forEach(ev => { dropEl.addEventListener(ev, (e) => { prevent(e); dropEl.classList.remove('dragover'); }); }); dropEl.addEventListener('drop', async (e) => { const file = e.dataTransfer?.files?.[0]; if (!file) return; if (!isImage(file)) { alert('请拖入 JPG/PNG 图片文件'); return; } const statusEl = document.getElementById('localStatus'); const progressContainer = document.getElementById('localProgressContainer'); const progressEl = document.getElementById('localProgress'); const videoContainer = document.getElementById('localVideoContainer'); const videoPlayer = document.getElementById('localVideoPlayer'); const previewImg = document.getElementById('localPreview'); const downloadBtn = document.getElementById('localDownloadBtn'); currentVideoBlob = null; try { statusEl.textContent = "正在处理文件..."; progressContainer.style.display = 'block'; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; downloadBtn.classList.add('hidden'); // 预览图片 previewImg.src = URL.createObjectURL(file); previewImg.classList.remove('hidden'); // 读取内容 const arrayBuffer = await file.arrayBuffer(); progressEl.style.width = '20%'; // 查找 ZIP 头 statusEl.textContent = "正在查找隐藏内容..."; const uint8Array = new Uint8Array(arrayBuffer); let zipStart = -1; for (let i = 0; i < uint8Array.length - 4; i++) { if (uint8Array[i] === 0x50 && uint8Array[i+1] === 0x4B && uint8Array[i+2] === 0x03 && uint8Array[i+3] === 0x04) { zipStart = i; break; } } if (zipStart === -1) throw new Error("未检测到隐藏内容"); progressEl.style.width = '40%'; // 提取/解析 ZIP statusEl.textContent = "正在提取隐藏数据..."; const zipData = arrayBuffer.slice(zipStart); progressEl.style.width = '60%'; statusEl.textContent = "正在解析内容..."; const zip = await JSZip.loadAsync(zipData); progressEl.style.width = '80%'; // 查找视频 statusEl.textContent = "正在查找视频文件..."; let videoFile = null; const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']; for (const [name, zf] of Object.entries(zip.files)) { if (!zf.dir && videoExtensions.some(ext => name.toLowerCase().endsWith(ext))) { videoFile = zf; break; } } if (!videoFile) throw new Error("未找到支持的视频文件"); // 提取视频 statusEl.textContent = "正在提取视频..."; const videoData = await videoFile.async('blob'); currentVideoBlob = videoData; progressEl.style.width = '100%'; // 播放展示 videoPlayer.src = URL.createObjectURL(videoData); videoContainer.style.display = 'block'; downloadBtn.classList.remove('hidden'); statusEl.textContent = `已加载: ${videoFile.name}`; // 成功后:隐藏标题、描述 、选择按钮与预览图,仅保留文件名与视频 const lt = document.getElementById('localTitle'); const ld = document.getElementById('localDesc'); const ll = document.getElementById('localChooseLabel'); if (lt) lt.style.display = 'none'; if (ld) ld.style.display = 'none'; if (ll) ll.style.display = 'none'; previewImg.classList.add('hidden'); videoPlayer.play().catch(() => { statusEl.textContent += " (点击播放按钮开始播放)"; }); } catch (err) { console.error('拖拽处理失败:', err); statusEl.textContent = `错误: ${err.message}`; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; } finally { setTimeout(() => { progressContainer.style.display = 'none'; }, 500); } }); })(); // 本地文件下载 document.getElementById('localDownloadBtn').addEventListener('click', function() { if (currentVideoBlob) { saveAs(currentVideoBlob, 'extracted_video.mp4'); } }); // URL转换处理 document.getElementById('fetchUrlBtn').addEventListener('click', async function() { const imageUrl = document.getElementById('imageUrl').value.trim(); if (!imageUrl) { alert("请输入图片URL"); return; } const statusEl = document.getElementById('urlStatus'); const progressContainer = document.getElementById('urlProgressContainer'); const progressEl = document.getElementById('urlProgress'); const videoContainer = document.getElementById('urlVideoContainer'); const videoPlayer = document.getElementById('urlVideoPlayer'); const previewImg = document.getElementById('urlPreview'); const downloadBtn = document.getElementById('urlDownloadBtn'); // 重置状态 statusEl.textContent = "正在获取图片..."; progressContainer.style.display = 'block'; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; downloadBtn.classList.add('hidden'); currentVideoBlob = null; try { // 显示预览图片 previewImg.src = imageUrl; previewImg.classList.remove('hidden'); // 1. 获取图片 const response = await fetch(imageUrl); if (!response.ok) throw new Error(`获取图片失败: ${response.status}`); progressEl.style.width = '20%'; // 2. 读取图片内容 const arrayBuffer = await response.arrayBuffer(); progressEl.style.width = '40%'; // 3. 查找ZIP文件起始位置 statusEl.textContent = "正在查找隐藏内容..."; const uint8Array = new Uint8Array(arrayBuffer); let zipStart = -1; for (let i = 0; i < uint8Array.length - 4; i++) { if (uint8Array[i] === 0x50 && uint8Array[i+1] === 0x4B && uint8Array[i+2] === 0x03 && uint8Array[i+3] === 0x04) { zipStart = i; break; } } if (zipStart === -1) throw new Error("未检测到隐藏内容"); progressEl.style.width = '60%'; // 4. 提取ZIP部分 statusEl.textContent = "正在提取隐藏数据..."; const zipData = arrayBuffer.slice(zipStart); progressEl.style.width = '80%'; // 5. 使用JSZip解析ZIP statusEl.textContent = "正在解析内容..."; const zip = await JSZip.loadAsync(zipData); // 6. 查找视频文件 statusEl.textContent = "正在查找视频文件..."; let videoFile = null; const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv']; for (const [name, file] of Object.entries(zip.files)) { if (!file.dir && videoExtensions.some(ext => name.toLowerCase().endsWith(ext))) { videoFile = file; break; } } if (!videoFile) throw new Error("未找到支持的视频文件"); // 7. 提取视频内容 statusEl.textContent = "正在提取视频..."; const videoData = await videoFile.async('blob'); currentVideoBlob = videoData; progressEl.style.width = '100%'; // 8. 播放视频 videoPlayer.src = URL.createObjectURL(videoData); videoContainer.style.display = 'block'; statusEl.textContent = `已加载: ${videoFile.name}`; // 成功后:仅保留文件名与视频,隐藏其它控件 const ut = document.getElementById('urlTitle'); const ud = document.getElementById('urlDesc'); const urlInput = document.getElementById('imageUrl'); const fetchBtn = document.getElementById('fetchUrlBtn'); const urlPrev = document.getElementById('urlPreview'); const urlDl = document.getElementById('urlDownloadBtn'); if (ut) ut.style.display = 'none'; if (ud) ud.style.display = 'none'; if (urlInput) urlInput.style.display = 'none'; if (fetchBtn) fetchBtn.style.display = 'none'; if (urlPrev) urlPrev.classList.add('hidden'); if (urlDl) urlDl.classList.add('hidden'); // 自动播放 videoPlayer.play().catch(e => { statusEl.textContent += " (点击播放按钮开始播放)"; }); } catch (error) { console.error("处理失败:", error); statusEl.textContent = `错误: ${error.message}`; progressEl.style.width = '0%'; videoContainer.style.display = 'none'; } finally { setTimeout(() => { progressContainer.style.display = 'none'; }, 500); } }); // URL文件下载 document.getElementById('urlDownloadBtn').addEventListener('click', function() { if (currentVideoBlob) { saveAs(currentVideoBlob, 'extracted_video.mp4'); } }); // 点击生成面板图片以更换封面 (function() { const previewImg = document.getElementById('defaultPreview'); const coverInput = document.getElementById('coverImageFile'); if (!previewImg || !coverInput) return; previewImg.style.cursor = 'pointer'; previewImg.addEventListener('click', () => { // 提示并打开文件选择 coverInput.click(); }); coverInput.addEventListener('change', async () => { const file = coverInput.files && coverInput.files[0]; if (!file) return; // 保存自定义封面并更新预览 customCoverImageBlob = file; try { const objectUrl = URL.createObjectURL(file); previewImg.src = objectUrl; const statusEl = document.getElementById('generateStatus'); if (statusEl) statusEl.textContent = `已选择封面图片:${file.name}`; } catch (_) {} }); })(); // “文件生成工具”拖拽上传(整个面板区域可拖拽) (function() { const dropEl = document.getElementById('generate'); if (!dropEl) return; dropEl.classList.add('drag-accept'); const isVideo = (file) => file.type.startsWith('video/'); const prevent = (e) => { e.preventDefault(); e.stopPropagation(); }; ['dragenter','dragover'].forEach(ev => { dropEl.addEventListener(ev, (e) => { prevent(e); dropEl.classList.add('dragover'); }); }); ['dragleave','drop'].forEach(ev => { dropEl.addEventListener(ev, (e) => { prevent(e); dropEl.classList.remove('dragover'); }); }); dropEl.addEventListener('drop', (e) => { const file = e.dataTransfer?.files?.[0]; if (!file) return; if (!isVideo(file)) { alert('请拖入视频文件'); return; } droppedVideoFile = file; const statusEl = document.getElementById('generateStatus'); statusEl.textContent = `已选择(拖拽):${file.name}`; }); })(); // 文件生成处理 document.getElementById('generateBtn').addEventListener('click', async function() { const videoFileInput = document.getElementById('videoFile'); const statusEl = document.getElementById('generateStatus'); const progressEl = document.getElementById('generateProgress'); const progressContainer = document.getElementById('generateProgressContainer'); const downloadBtn = document.getElementById('generateDownloadBtn'); const videoFile = videoFileInput.files[0] || droppedVideoFile; if (!videoFile) { alert("请选择或拖拽视频文件"); return; } try { statusEl.textContent = "正在准备生成文件..."; progressContainer.style.display = 'block'; progressEl.style.width = '0%'; downloadBtn.classList.add('hidden'); // 1. 创建ZIP const zip = new JSZip(); zip.file(videoFile.name, videoFile); // 2. 生成ZIP statusEl.textContent = "正在生成ZIP文件..."; const zipBlob = await zip.generateAsync({type: 'blob'}, (metadata) => { progressEl.style.width = `${metadata.percent}%`; }); // 3. 获取封面图片(优先使用用户选择的图片) let imageBlob; if (customCoverImageBlob) { statusEl.textContent = "已选择自定义图片 ,正在读取..."; imageBlob = customCoverImageBlob; } else { statusEl.textContent = "正在获取默认图片..."; const imageResp = await fetch('./img/iii.jpg'); imageBlob = await imageResp.blob(); } // 4. 合并文件 statusEl.textContent = "正在合并文件..."; const mergedBlob = new Blob([ await imageBlob.arrayBuffer(), await zipBlob.arrayBuffer() ], { type: 'image/jpeg' }); currentGeneratedBlob = mergedBlob; statusEl.textContent = "生成成功!"; downloadBtn.classList.remove('hidden'); } catch (error) { console.error("生成失败:", error); statusEl.textContent = `错误: ${error.message}`; progressEl.style.width = '0%'; } finally { setTimeout(() => { progressContainer.style.display = 'none'; }, 500); } }); // 生成文件下载 document.getElementById('generateDownloadBtn').addEventListener('click', function() { if (currentGeneratedBlob) { saveAs(currentGeneratedBlob, 'merged_image.jpg'); } }); // 全局拦截,避免把文件拖到页面其它区域时被浏览器直接打开 (function() { const prevent = (e) => { e.preventDefault(); e.stopPropagation(); }; window.addEventListener('dragover', prevent); window.addEventListener('drop', prevent); })(); </script> <style> .corner-links { position: fixed; right: 20px; bottom: 20px; display: flex; align-items: center; z-index: 9999; } .corner-link { display: inline-flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 8px; color: #212529; text-decoration: none; transition: all 0.3s ease; } .corner-link:hover { transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0,0,0,0.15); } .corner-link img, .corner-link svg { width: 22px; height: 22px; } .corner-link .label { font-weight: 600; font-size: 0.95rem; } </style> <div aria-label="页面固定链接"> <a href="https://github.com/IIIStudio/Copy-B" target="_blank" rel="noopener noreferrer" aria-label="前往 GitHub 仓库"> <!-- 内联 GitHub 图标,避免外部资源依赖 --> <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"> <path fill="#24292F" d="M12 .5a12 12 0 0 0-3.79 23.41c.6.11.82-.26.82-.58v-2.02c-3.35.73-4.06-1.61-4.06-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.09-.75.08-.74.08-.74 1.2.09 1.83 1.23 1.83 1.23 1.07 1.83 2.8 1.3 3.49.99.11-.78.42-1.3.76-1.6-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.13-.3-.54-1.51.12-3.15 0 0 1.01-.32 3.3 1.23.96-.27 1.99-.4 3.01-.4s2.05.14 3.01.4c2.29-1.55 3.3-1.23 3.3-1.23.66 1.64.25 2.85.12 3.15.77.84 1.24 1.91 1.24 3.22 0 4.61-2.8 5.63-5.47 5.93.43.37.81 1.1.81 2.22v3.29c0 .32.22.7.83.58A12 12 0 0 0 12 .5Z"/> </svg> <span>Copy-B</span> </a> <a href="https://cnb.cool/IIIStudio/HTML/Copy-B/" target="_blank" rel="noopener noreferrer" aria-label="前往 Copy-B 文档页面"> <img src="https://docs.cnb.cool/images/logo/svg/LogoColorfulIcon.svg" alt="CNB Logo"> </a> </div> </body> </html>