<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>阿飞的博客 Blog</title>
        <link>https://blog.jjdd.site/blog</link>
        <description>阿飞的博客 Blog</description>
        <lastBuildDate>Thu, 26 Feb 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-Hans</language>
        <item>
            <title><![CDATA[Agent Skills 简介]]></title>
            <link>https://blog.jjdd.site/blog/skills</link>
            <guid>https://blog.jjdd.site/blog/skills</guid>
            <pubDate>Thu, 26 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[介绍 Agent Skills 的概念与使用方法，通过包含指令、脚本和资源的文件夹为 AI Agent 扩展能力，实现更精准的任务执行。]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>Agent Skills 是一个简单、开放的格式，用于为 AI Agent 提供新的能力和专业知识。通过包含指令、脚本和资源的文件夹，Agent 可以发现并使用这些技能来更准确、高效地完成任务。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="什么是-agent-skills">什么是 Agent Skills<a href="https://blog.jjdd.site/blog/skills#%E4%BB%80%E4%B9%88%E6%98%AF-agent-skills" class="hash-link" aria-label="什么是 Agent Skills的直接链接" title="什么是 Agent Skills的直接链接" translate="no">​</a></h2>
<p>Agent Skills 是一个开放标准，定义了一种简单的方式来扩展 AI Agent 的能力。根据 <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer" class="">agentskills.io</a> 的定义，Agent Skills 是<strong>包含指令、脚本和资源的文件夹</strong>，Agent 可以发现并使用这些技能来更准确、高效地完成任务。</p>
<p>这个标准最初由 Anthropic 开发，现已作为开放标准发布，并被越来越多的 Agent 产品采用。它旨在解决 AI Agent 在实际工作中面临的上下文缺失问题。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="为什么需要-agent-skills">为什么需要 Agent Skills<a href="https://blog.jjdd.site/blog/skills#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-agent-skills" class="hash-link" aria-label="为什么需要 Agent Skills的直接链接" title="为什么需要 Agent Skills的直接链接" translate="no">​</a></h2>
<p>虽然 AI Agent 变得越来越强大，但它们往往<strong>缺乏完成实际工作所需的上下文</strong>。Agent Skills 通过以下方式解决这个问题：</p>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="对于技能作者">对于技能作者<a href="https://blog.jjdd.site/blog/skills#%E5%AF%B9%E4%BA%8E%E6%8A%80%E8%83%BD%E4%BD%9C%E8%80%85" class="hash-link" aria-label="对于技能作者的直接链接" title="对于技能作者的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>一次构建，多处部署</strong>：构建一次能力，可以在多个 Agent 产品中部署使用</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="对于兼容的-agent">对于兼容的 Agent<a href="https://blog.jjdd.site/blog/skills#%E5%AF%B9%E4%BA%8E%E5%85%BC%E5%AE%B9%E7%9A%84-agent" class="hash-link" aria-label="对于兼容的 Agent的直接链接" title="对于兼容的 Agent的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>开箱即用的能力</strong>：支持 Skills 让最终用户能够为 Agent 提供新的能力</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="对于团队和企业">对于团队和企业<a href="https://blog.jjdd.site/blog/skills#%E5%AF%B9%E4%BA%8E%E5%9B%A2%E9%98%9F%E5%92%8C%E4%BC%81%E4%B8%9A" class="hash-link" aria-label="对于团队和企业的直接链接" title="对于团队和企业的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>知识封装</strong>：将组织知识封装成可移植、版本控制的包</li>
<li class=""><strong>程序化知识</strong>：提供 Agent 可以按需加载的程序化知识</li>
<li class=""><strong>特定上下文</strong>：提供公司、团队和用户特定的上下文信息</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="agent-skills-能实现什么">Agent Skills 能实现什么<a href="https://blog.jjdd.site/blog/skills#agent-skills-%E8%83%BD%E5%AE%9E%E7%8E%B0%E4%BB%80%E4%B9%88" class="hash-link" aria-label="Agent Skills 能实现什么的直接链接" title="Agent Skills 能实现什么的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="1-领域专业知识">1. 领域专业知识<a href="https://blog.jjdd.site/blog/skills#1-%E9%A2%86%E5%9F%9F%E4%B8%93%E4%B8%9A%E7%9F%A5%E8%AF%86" class="hash-link" aria-label="1. 领域专业知识的直接链接" title="1. 领域专业知识的直接链接" translate="no">​</a></h3>
<p>将专业知识打包成可重用的指令，例如：</p>
<ul>
<li class="">法律审查流程</li>
<li class="">数据分析管道</li>
<li class="">行业特定的工作流程</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="2-新能力">2. 新能力<a href="https://blog.jjdd.site/blog/skills#2-%E6%96%B0%E8%83%BD%E5%8A%9B" class="hash-link" aria-label="2. 新能力的直接链接" title="2. 新能力的直接链接" translate="no">​</a></h3>
<p>为 Agent 提供全新的能力，例如：</p>
<ul>
<li class="">创建演示文稿</li>
<li class="">构建 MCP 服务器</li>
<li class="">分析数据集</li>
<li class="">处理特定格式的文件</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="3-可重复的工作流">3. 可重复的工作流<a href="https://blog.jjdd.site/blog/skills#3-%E5%8F%AF%E9%87%8D%E5%A4%8D%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81" class="hash-link" aria-label="3. 可重复的工作流的直接链接" title="3. 可重复的工作流的直接链接" translate="no">​</a></h3>
<p>将多步骤任务转化为一致且可审计的工作流，确保：</p>
<ul>
<li class="">任务执行的一致性</li>
<li class="">流程的可追溯性</li>
<li class="">结果的可靠性</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="4-互操作性">4. 互操作性<a href="https://blog.jjdd.site/blog/skills#4-%E4%BA%92%E6%93%8D%E4%BD%9C%E6%80%A7" class="hash-link" aria-label="4. 互操作性的直接链接" title="4. 互操作性的直接链接" translate="no">​</a></h3>
<p>同一个技能可以在不同的兼容 Agent 产品中重复使用，实现：</p>
<ul>
<li class="">跨平台兼容</li>
<li class="">技能生态系统的共享</li>
<li class="">减少重复开发</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="agent-skills-的采用">Agent Skills 的采用<a href="https://blog.jjdd.site/blog/skills#agent-skills-%E7%9A%84%E9%87%87%E7%94%A8" class="hash-link" aria-label="Agent Skills 的采用的直接链接" title="Agent Skills 的采用的直接链接" translate="no">​</a></h2>
<p>Agent Skills 标准已经被领先的 AI 开发工具支持，包括：</p>
<ul>
<li class=""><strong>Claude</strong>（Anthropic）：原生支持 Agent Skills</li>
<li class="">其他兼容的 Agent 产品</li>
</ul>
<p>这个开放标准正在被越来越多的 Agent 产品采用，形成了一个不断增长的生态系统。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="开放开发">开放开发<a href="https://blog.jjdd.site/blog/skills#%E5%BC%80%E6%94%BE%E5%BC%80%E5%8F%91" class="hash-link" aria-label="开放开发的直接链接" title="开放开发的直接链接" translate="no">​</a></h2>
<p>Agent Skills 格式最初由 Anthropic 开发，现已作为<strong>开放标准</strong>发布。该标准对更广泛的生态系统开放贡献，任何人都可以：</p>
<ul>
<li class="">查看标准规范</li>
<li class="">贡献改进建议</li>
<li class="">创建和分享技能</li>
<li class="">集成技能支持到自己的 Agent 产品</li>
</ul>
<p>你可以在 <a href="https://github.com/anthropics/skills" target="_blank" rel="noopener noreferrer" class="">GitHub</a> 上查看和参与开发。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="快速开始">快速开始<a href="https://blog.jjdd.site/blog/skills#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B" class="hash-link" aria-label="快速开始的直接链接" title="快速开始的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="了解-skills">了解 Skills<a href="https://blog.jjdd.site/blog/skills#%E4%BA%86%E8%A7%A3-skills" class="hash-link" aria-label="了解 Skills的直接链接" title="了解 Skills的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>什么是 Skills</strong>：了解技能的工作原理和重要性</li>
<li class=""><strong>规范文档</strong>：查看 SKILL.md 文件的完整格式规范</li>
<li class=""><strong>集成技能</strong>：学习如何为你的 Agent 或工具添加技能支持</li>
<li class=""><strong>示例技能</strong>：在 GitHub 上浏览示例技能</li>
<li class=""><strong>参考库</strong>：验证技能并生成提示 XML</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="核心资源">核心资源<a href="https://blog.jjdd.site/blog/skills#%E6%A0%B8%E5%BF%83%E8%B5%84%E6%BA%90" class="hash-link" aria-label="核心资源的直接链接" title="核心资源的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>官方网站</strong>：<a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer" class="">agentskills.io</a></li>
<li class=""><strong>GitHub 仓库</strong>：<a href="https://github.com/anthropics/skills" target="_blank" rel="noopener noreferrer" class="">github.com/anthropics/skills</a></li>
<li class=""><strong>规范文档</strong>：查看完整的格式规范</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="skill-的基本结构">Skill 的基本结构<a href="https://blog.jjdd.site/blog/skills#skill-%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84" class="hash-link" aria-label="Skill 的基本结构的直接链接" title="Skill 的基本结构的直接链接" translate="no">​</a></h2>
<p>一个 Agent Skill 通常包含：</p>
<div class="language-text codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-text codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">my-skill/</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ├── SKILL.md          # 技能的主要文件，包含 YAML frontmatter 和指令</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ├── scripts/          # 可选的脚本文件</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ├── resources/        # 可选的资源文件</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  └── ...</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="skillmd-文件">SKILL.md 文件<a href="https://blog.jjdd.site/blog/skills#skillmd-%E6%96%87%E4%BB%B6" class="hash-link" aria-label="SKILL.md 文件的直接链接" title="SKILL.md 文件的直接链接" translate="no">​</a></h3>
<p><code>SKILL.md</code> 文件是技能的核心，包含：</p>
<ol>
<li class="">
<p><strong>YAML Frontmatter</strong>：定义技能的基本信息</p>
<div class="language-yaml codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-yaml codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">skill</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">name</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> A clear description of what this skill does</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">---</span><br></span></code></pre></div></div>
</li>
<li class="">
<p><strong>Markdown 内容</strong>：包含详细的指令、示例和指南</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="使用场景示例">使用场景示例<a href="https://blog.jjdd.site/blog/skills#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="使用场景示例的直接链接" title="使用场景示例的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="企业场景">企业场景<a href="https://blog.jjdd.site/blog/skills#%E4%BC%81%E4%B8%9A%E5%9C%BA%E6%99%AF" class="hash-link" aria-label="企业场景的直接链接" title="企业场景的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>品牌指南</strong>：创建符合公司品牌标准的文档</li>
<li class=""><strong>工作流程</strong>：使用组织特定的工作流程分析数据</li>
<li class=""><strong>合规检查</strong>：按照公司政策进行代码审查</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="开发场景">开发场景<a href="https://blog.jjdd.site/blog/skills#%E5%BC%80%E5%8F%91%E5%9C%BA%E6%99%AF" class="hash-link" aria-label="开发场景的直接链接" title="开发场景的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>代码生成</strong>：根据团队规范生成代码</li>
<li class=""><strong>测试自动化</strong>：执行特定的测试流程</li>
<li class=""><strong>文档生成</strong>：按照模板生成技术文档</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="个人场景">个人场景<a href="https://blog.jjdd.site/blog/skills#%E4%B8%AA%E4%BA%BA%E5%9C%BA%E6%99%AF" class="hash-link" aria-label="个人场景的直接链接" title="个人场景的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>任务自动化</strong>：自动化个人重复性任务</li>
<li class=""><strong>知识管理</strong>：按照个人偏好组织和管理信息</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="优势总结">优势总结<a href="https://blog.jjdd.site/blog/skills#%E4%BC%98%E5%8A%BF%E6%80%BB%E7%BB%93" class="hash-link" aria-label="优势总结的直接链接" title="优势总结的直接链接" translate="no">​</a></h2>
<ol>
<li class=""><strong>简单性</strong>：基于文件夹和 Markdown 的简单格式</li>
<li class=""><strong>可移植性</strong>：技能可以在不同 Agent 产品间共享</li>
<li class=""><strong>版本控制</strong>：可以像代码一样进行版本管理</li>
<li class=""><strong>可扩展性</strong>：易于创建和分享新技能</li>
<li class=""><strong>标准化</strong>：遵循开放标准，确保兼容性</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="总结">总结<a href="https://blog.jjdd.site/blog/skills#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="总结的直接链接" title="总结的直接链接" translate="no">​</a></h2>
<p>Agent Skills 为 AI Agent 生态系统提供了一个强大而灵活的扩展机制。通过这个开放标准，开发者、团队和企业可以：</p>
<ul>
<li class="">封装专业知识为可重用的技能</li>
<li class="">为 Agent 提供新的能力</li>
<li class="">创建可重复、可审计的工作流</li>
<li class="">实现跨平台的技能互操作性</li>
</ul>
<p>随着越来越多的 Agent 产品采用这个标准，Agent Skills 正在成为 AI Agent 能力扩展的重要基础设施。</p>
<div class="theme-admonition theme-admonition-info admonition_lig3 alert alert--info"><div class="admonitionHeading_GNd1"><span class="admonitionIcon_DPBw"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_l625"><ul>
<li class=""><strong>官方网站</strong>：<a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer" class="">https://agentskills.io/</a></li>
<li class=""><strong>GitHub 仓库</strong>：<a href="https://github.com/anthropics/skills" target="_blank" rel="noopener noreferrer" class="">https://github.com/anthropics/skills</a></li>
<li class=""><strong>规范文档</strong>：查看 <a href="https://agentskills.io/" target="_blank" rel="noopener noreferrer" class="">agentskills.io</a> 获取完整的格式规范</li>
</ul></div></div>]]></content:encoded>
            <category>skills</category>
            <category>agent</category>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[OpenClaw：你的个人 AI 助手]]></title>
            <link>https://blog.jjdd.site/blog/openclaw</link>
            <guid>https://blog.jjdd.site/blog/openclaw</guid>
            <pubDate>Sat, 07 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenClaw 是一款可运行在本地设备的开源个人 AI 助手，支持多平台部署与多通道交互，让你随时随地与 AI 进行对话。]]></description>
            <content:encoded><![CDATA[<p>OpenClaw 是一个可以运行在自己设备上的个人 AI 助手，支持多平台、多通道，让你随时随地的与 AI 交互。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="什么是-openclaw">什么是 OpenClaw？<a href="https://blog.jjdd.site/blog/openclaw#%E4%BB%80%E4%B9%88%E6%98%AF-openclaw" class="hash-link" aria-label="什么是 OpenClaw？的直接链接" title="什么是 OpenClaw？的直接链接" translate="no">​</a></h2>
<p>OpenClaw 是一个<strong>个人 AI 助手</strong>，你可以运行在自己的设备上。它的核心理念是"Exfoliate! Exfoliate!"（去皮！去皮！），帮助你轻松地与 AI 进行交互。</p>
<p><img decoding="async" loading="lazy" src="https://img.shields.io/github/stars/openclaw/openclaw?style=social" alt="OpenClaw" class="img_Sxi7">
<img decoding="async" loading="lazy" src="https://img.shields.io/github/forks/openclaw/openclaw?style=social" alt="GitHub stars" class="img_Sxi7"></p>
<p><strong>GitHub</strong>: <a href="https://github.com/openclaw/openclaw" target="_blank" rel="noopener noreferrer" class="">https://github.com/openclaw/openclaw</a></p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="核心特性">核心特性<a href="https://blog.jjdd.site/blog/openclaw#%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7" class="hash-link" aria-label="核心特性的直接链接" title="核心特性的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="1-多通道支持">1. 多通道支持<a href="https://blog.jjdd.site/blog/openclaw#1-%E5%A4%9A%E9%80%9A%E9%81%93%E6%94%AF%E6%8C%81" class="hash-link" aria-label="1. 多通道支持的直接链接" title="1. 多通道支持的直接链接" translate="no">​</a></h3>
<p>OpenClaw 支持你已经在使用的各种聊天平台：</p>
<ul>
<li class=""><strong>WhatsApp</strong></li>
<li class=""><strong>Telegram</strong></li>
<li class=""><strong>Slack</strong></li>
<li class=""><strong>Discord</strong></li>
<li class=""><strong>Google Chat</strong></li>
<li class=""><strong>Signal</strong></li>
<li class=""><strong>iMessage</strong></li>
<li class=""><strong>Microsoft Teams</strong></li>
<li class=""><strong>Matrix</strong></li>
<li class=""><strong>Zalo</strong></li>
<li class=""><strong>WebChat</strong></li>
</ul>
<p>这意味着你可以在任何你习惯的平台上与 AI 助手对话，无需切换到专门的 AI 应用。</p>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="2-跨平台支持">2. 跨平台支持<a href="https://blog.jjdd.site/blog/openclaw#2-%E8%B7%A8%E5%B9%B3%E5%8F%B0%E6%94%AF%E6%8C%81" class="hash-link" aria-label="2. 跨平台支持的直接链接" title="2. 跨平台支持的直接链接" translate="no">​</a></h3>
<p>OpenClaw 可以在多种操作系统上运行：</p>
<ul>
<li class=""><strong>macOS</strong> - 支持 Voice Wake 和 Talk Mode</li>
<li class=""><strong>Linux</strong> - 适合作为远程 Gateway 运行</li>
<li class=""><strong>Windows</strong> - 通过 WSL2 支持</li>
<li class=""><strong>iOS/Android</strong> - 移动端节点支持</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="3-本地优先的设计">3. 本地优先的设计<a href="https://blog.jjdd.site/blog/openclaw#3-%E6%9C%AC%E5%9C%B0%E4%BC%98%E5%85%88%E7%9A%84%E8%AE%BE%E8%AE%A1" class="hash-link" aria-label="3. 本地优先的设计的直接链接" title="3. 本地优先的设计的直接链接" translate="no">​</a></h3>
<p>OpenClaw 采用本地优先的架构：</p>
<ul>
<li class=""><strong>Gateway</strong> 作为单一控制平面，管理会话、通道、工具和事件</li>
<li class="">支持多代理路由，可以为不同的通道/账户/对等端隔离代理</li>
<li class="">数据存储在你的设备上，保护隐私</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="4-语音交互">4. 语音交互<a href="https://blog.jjdd.site/blog/openclaw#4-%E8%AF%AD%E9%9F%B3%E4%BA%A4%E4%BA%92" class="hash-link" aria-label="4. 语音交互的直接链接" title="4. 语音交互的直接链接" translate="no">​</a></h3>
<ul>
<li class=""><strong>Voice Wake</strong> - 在 macOS/iOS/Android 上实现始终在线的语音唤醒</li>
<li class=""><strong>Talk Mode</strong> - 连续对话模式，支持 ElevenLabs 语音合成</li>
<li class=""><strong>推送对讲</strong> - 快速触发语音交互</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="5-live-canvas">5. Live Canvas<a href="https://blog.jjdd.site/blog/openclaw#5-live-canvas" class="hash-link" aria-label="5. Live Canvas的直接链接" title="5. Live Canvas的直接链接" translate="no">​</a></h3>
<p>Agent 驱动的可视化工作空间：</p>
<ul>
<li class="">A2UI 渲染引擎</li>
<li class="">实时 Canvas 控制</li>
<li class="">可视化工具和交互界面</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="6-丰富的工具集">6. 丰富的工具集<a href="https://blog.jjdd.site/blog/openclaw#6-%E4%B8%B0%E5%AF%8C%E7%9A%84%E5%B7%A5%E5%85%B7%E9%9B%86" class="hash-link" aria-label="6. 丰富的工具集的直接链接" title="6. 丰富的工具集的直接链接" translate="no">​</a></h3>
<p>OpenClaw 内置了许多实用工具：</p>
<ul>
<li class=""><strong>Browser</strong> - 控制 Chrome/Chromium 浏览器</li>
<li class=""><strong>Canvas</strong> - A2UI 推送/重置、评估、快照</li>
<li class=""><strong>Nodes</strong> - 相机、屏幕录制、位置、通知</li>
<li class=""><strong>Cron</strong> - 定时任务和唤醒</li>
<li class=""><strong>Webhooks</strong> - 外部触发器</li>
<li class=""><strong>Gmail Pub/Sub</strong> - 邮件触发</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="快速开始">快速开始<a href="https://blog.jjdd.site/blog/openclaw#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B" class="hash-link" aria-label="快速开始的直接链接" title="快速开始的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="安装">安装<a href="https://blog.jjdd.site/blog/openclaw#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h3>
<p>确保你的系统已安装 Node.js ≥ 22：</p>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">npm install -g openclaw@latest</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 或使用 pnpm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm add -g openclaw@latest</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="启动向导">启动向导<a href="https://blog.jjdd.site/blog/openclaw#%E5%90%AF%E5%8A%A8%E5%90%91%E5%AF%BC" class="hash-link" aria-label="启动向导的直接链接" title="启动向导的直接链接" translate="no">​</a></h3>
<p>运行向导完成配置：</p>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">openclaw onboard --install-daemon</span><br></span></code></pre></div></div>
<p>向导会引导你完成：</p>
<ul>
<li class="">Gateway 设置</li>
<li class="">工作区配置</li>
<li class="">通道连接</li>
<li class="">技能安装</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="启动-gateway">启动 Gateway<a href="https://blog.jjdd.site/blog/openclaw#%E5%90%AF%E5%8A%A8-gateway" class="hash-link" aria-label="启动 Gateway的直接链接" title="启动 Gateway的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">openclaw gateway --port 18789 --verbose</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="发送消息">发送消息<a href="https://blog.jjdd.site/blog/openclaw#%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF" class="hash-link" aria-label="发送消息的直接链接" title="发送消息的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain"># 通过 CLI 发送消息</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">openclaw message send --to +1234567890 --message "Hello from OpenClaw"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 直接与助手对话</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">openclaw agent --message "列出今天的任务" --thinking high</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="配置示例">配置示例<a href="https://blog.jjdd.site/blog/openclaw#%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="配置示例的直接链接" title="配置示例的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="基础配置">基础配置<a href="https://blog.jjdd.site/blog/openclaw#%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="基础配置的直接链接" title="基础配置的直接链接" translate="no">​</a></h3>
<p>在 <code>~/.openclaw/openclaw.json</code> 中配置：</p>
<div class="language-json codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-json codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"agent"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"model"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"anthropic/claude-opus-4-6"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="支持-ai-模型">支持 AI 模型<a href="https://blog.jjdd.site/blog/openclaw#%E6%94%AF%E6%8C%81-ai-%E6%A8%A1%E5%9E%8B" class="hash-link" aria-label="支持 AI 模型的直接链接" title="支持 AI 模型的直接链接" translate="no">​</a></h3>
<p>OpenClaw 支持多种 AI 模型：</p>
<ul>
<li class=""><strong>Anthropic</strong> - Claude Pro/Max（推荐）</li>
<li class=""><strong>OpenAI</strong> - ChatGPT/Codex</li>
</ul>
<p>推荐使用 Anthropic Pro/Max + Opus 4.6，以获得更好的长上下文能力和更强的抗提示注入能力。</p>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="配置示例-1">配置示例<a href="https://blog.jjdd.site/blog/openclaw#%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B-1" class="hash-link" aria-label="配置示例的直接链接" title="配置示例的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_osn3" id="telegram-配置">Telegram 配置<a href="https://blog.jjdd.site/blog/openclaw#telegram-%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="Telegram 配置的直接链接" title="Telegram 配置的直接链接" translate="no">​</a></h4>
<div class="language-json codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-json codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"channels"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"telegram"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"botToken"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123456:ABCDEF"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_osn3" id="discord-配置">Discord 配置<a href="https://blog.jjdd.site/blog/openclaw#discord-%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="Discord 配置的直接链接" title="Discord 配置的直接链接" translate="no">​</a></h4>
<div class="language-json codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-json codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"channels"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"discord"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"token"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"1234abcd"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_osn3" id="slack-配置">Slack 配置<a href="https://blog.jjdd.site/blog/openclaw#slack-%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="Slack 配置的直接链接" title="Slack 配置的直接链接" translate="no">​</a></h4>
<p>设置环境变量：</p>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">export SLACK_BOT_TOKEN="xoxb-..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export SLACK_APP_TOKEN="xapp-..."</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="安全特性">安全特性<a href="https://blog.jjdd.site/blog/openclaw#%E5%AE%89%E5%85%A8%E7%89%B9%E6%80%A7" class="hash-link" aria-label="安全特性的直接链接" title="安全特性的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="dm-访问控制">DM 访问控制<a href="https://blog.jjdd.site/blog/openclaw#dm-%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6" class="hash-link" aria-label="DM 访问控制的直接链接" title="DM 访问控制的直接链接" translate="no">​</a></h3>
<p>默认情况下，OpenClaw 对未知发送者实施配对策略：</p>
<ul>
<li class="">未知发送者会收到简短的配对码</li>
<li class="">只有批准后才能与助手交互</li>
<li class="">使用 <code>openclaw pairing approve &lt;channel&gt; &lt;code&gt;</code> 批准配对</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="沙盒模式">沙盒模式<a href="https://blog.jjdd.site/blog/openclaw#%E6%B2%99%E7%9B%92%E6%A8%A1%E5%BC%8F" class="hash-link" aria-label="沙盒模式的直接链接" title="沙盒模式的直接链接" translate="no">​</a></h3>
<p>对于群组/频道，可以启用沙盒模式：</p>
<div class="language-json codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-json codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"agents"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"defaults"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"sandbox"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"mode"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"non-main"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>这样非主会话将在 Docker 沙盒中运行，限制工具访问。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="聊天命令">聊天命令<a href="https://blog.jjdd.site/blog/openclaw#%E8%81%8A%E5%A4%A9%E5%91%BD%E4%BB%A4" class="hash-link" aria-label="聊天命令的直接链接" title="聊天命令的直接链接" translate="no">​</a></h2>
<p>在任何支持的聊天平台上，你可以使用以下命令：</p>
<ul>
<li class=""><code>/status</code> - 查看会话状态</li>
<li class=""><code>/new</code> 或 <code>/reset</code> - 重置会话</li>
<li class=""><code>/compact</code> - 压缩会话上下文</li>
<li class=""><code>/think &lt;level&gt;</code> - 设置思考级别</li>
<li class=""><code>/verbose on|off</code> - 切换详细输出</li>
<li class=""><code>/usage off|tokens|full</code> - 显示使用统计</li>
<li class=""><code>/restart</code> - 重启 Gateway（群组中仅限所有者）</li>
<li class=""><code>/activation mention|always</code> - 群组激活切换</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="高级功能">高级功能<a href="https://blog.jjdd.site/blog/openclaw#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD" class="hash-link" aria-label="高级功能的直接链接" title="高级功能的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="tailscale-集成">Tailscale 集成<a href="https://blog.jjdd.site/blog/openclaw#tailscale-%E9%9B%86%E6%88%90" class="hash-link" aria-label="Tailscale 集成的直接链接" title="Tailscale 集成的直接链接" translate="no">​</a></h3>
<p>OpenClaw 可以自动配置 Tailscale Serve/Funnel，实现远程访问：</p>
<div class="language-json codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-json codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"gateway"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"tailscale"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"mode"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"serve"</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 或 "funnel"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="远程-gateway">远程 Gateway<a href="https://blog.jjdd.site/blog/openclaw#%E8%BF%9C%E7%A8%8B-gateway" class="hash-link" aria-label="远程 Gateway的直接链接" title="远程 Gateway的直接链接" translate="no">​</a></h3>
<p>你可以在 Linux 实例上运行 Gateway，通过 Tailscale 或 SSH 隧道从客户端连接。Gateway 运行执行工具和通道连接，设备节点执行设备本地操作（如相机、屏幕录制）。</p>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="代理间通信">代理间通信<a href="https://blog.jjdd.site/blog/openclaw#%E4%BB%A3%E7%90%86%E9%97%B4%E9%80%9A%E4%BF%A1" class="hash-link" aria-label="代理间通信的直接链接" title="代理间通信的直接链接" translate="no">​</a></h3>
<p>使用 <code>sessions_*</code> 工具实现代理间通信：</p>
<ul>
<li class=""><code>sessions_list</code> - 发现活跃会话</li>
<li class=""><code>sessions_history</code> - 获取会话历史</li>
<li class=""><code>sessions_send</code> - 向其他会话发送消息</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="技能系统">技能系统<a href="https://blog.jjdd.site/blog/openclaw#%E6%8A%80%E8%83%BD%E7%B3%BB%E7%BB%9F" class="hash-link" aria-label="技能系统的直接链接" title="技能系统的直接链接" translate="no">​</a></h3>
<p>OpenClaw 支持技能扩展：</p>
<ul>
<li class=""><strong>Bundled Skills</strong> - 内置技能</li>
<li class=""><strong>Managed Skills</strong> - 托管技能</li>
<li class=""><strong>Workspace Skills</strong> - 工作区技能</li>
</ul>
<p>技能存储在 <code>~/.openclaw/workspace/skills/&lt;skill&gt;/SKILL.md</code></p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="配套应用">配套应用<a href="https://blog.jjdd.site/blog/openclaw#%E9%85%8D%E5%A5%97%E5%BA%94%E7%94%A8" class="hash-link" aria-label="配套应用的直接链接" title="配套应用的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="macos-app">macOS App<a href="https://blog.jjdd.site/blog/openclaw#macos-app" class="hash-link" aria-label="macOS App的直接链接" title="macOS App的直接链接" translate="no">​</a></h3>
<ul>
<li class="">菜单栏控制</li>
<li class="">Voice Wake 和 PTT</li>
<li class="">WebChat 和调试工具</li>
<li class="">远程 Gateway 控制</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="ios-node">iOS Node<a href="https://blog.jjdd.site/blog/openclaw#ios-node" class="hash-link" aria-label="iOS Node的直接链接" title="iOS Node的直接链接" translate="no">​</a></h3>
<ul>
<li class="">通过 Bridge 配对</li>
<li class="">语音触发和 Canvas</li>
<li class="">相机和屏幕录制</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="android-node">Android Node<a href="https://blog.jjdd.site/blog/openclaw#android-node" class="hash-link" aria-label="Android Node的直接链接" title="Android Node的直接链接" translate="no">​</a></h3>
<ul>
<li class="">Canvas、相机和屏幕捕获</li>
<li class="">可选 SMS 支持</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="开发">开发<a href="https://blog.jjdd.site/blog/openclaw#%E5%BC%80%E5%8F%91" class="hash-link" aria-label="开发的直接链接" title="开发的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="从源码构建">从源码构建<a href="https://blog.jjdd.site/blog/openclaw#%E4%BB%8E%E6%BA%90%E7%A0%81%E6%9E%84%E5%BB%BA" class="hash-link" aria-label="从源码构建的直接链接" title="从源码构建的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-bash codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">git clone https://github.com/openclaw/openclaw.git</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cd openclaw</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm install</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm ui:build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm openclaw onboard --install-daemon</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 开发模式（自动重载）</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pnpm gateway:watch</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="总结">总结<a href="https://blog.jjdd.site/blog/openclaw#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="总结的直接链接" title="总结的直接链接" translate="no">​</a></h2>
<p>OpenClaw 是一个功能强大的个人 AI 助手框架，具有以下优势：</p>
<p>✅ <strong>多平台支持</strong> - 覆盖主流聊天平台和操作系统</p>
<p>✅ <strong>本地优先</strong> - 数据存储在本地，保护隐私</p>
<p>✅ <strong>高度可定制</strong> - 支持多种配置和扩展</p>
<p>✅ <strong>开源免费</strong> - MIT 许可证，社区驱动</p>
<p>✅ <strong>安全可靠</strong> - 内置安全机制和沙盒支持</p>
<p>无论你是想要一个随时可用的 AI 助手，还是想要构建自己的 AI 应用，OpenClaw 都是一个值得尝试的选择。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="相关链接">相关链接<a href="https://blog.jjdd.site/blog/openclaw#%E7%9B%B8%E5%85%B3%E9%93%BE%E6%8E%A5" class="hash-link" aria-label="相关链接的直接链接" title="相关链接的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://openclaw.ai/" target="_blank" rel="noopener noreferrer" class="">官方网站</a></li>
<li class=""><a href="https://github.com/openclaw/openclaw" target="_blank" rel="noopener noreferrer" class="">GitHub 仓库</a></li>
<li class=""><a href="https://docs.openclaw.ai/" target="_blank" rel="noopener noreferrer" class="">文档</a></li>
<li class=""><a href="https://discord.gg/openclaw" target="_blank" rel="noopener noreferrer" class="">Discord 社区</a></li>
<li class=""><a href="https://docs.openclaw.ai/getting-started" target="_blank" rel="noopener noreferrer" class="">Getting Started</a></li>
</ul>
<hr>
<p><em>OpenClaw - Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞</em></p>]]></content:encoded>
            <category>openclaw</category>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[Electron 自定义协议]]></title>
            <link>https://blog.jjdd.site/blog/Electron 自定义协议</link>
            <guid>https://blog.jjdd.site/blog/Electron 自定义协议</guid>
            <pubDate>Tue, 22 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[介绍如何在 Electron 中注册自定义协议并使用 loadURL 加载本地静态文件，实现更灵活的资源加载方案。]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>注册自定义协议,使用 loadURL 加载静态文件。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="项目结构">项目结构<a href="https://blog.jjdd.site/blog/Electron%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="项目结构的直接链接" title="项目结构的直接链接" translate="no">​</a></h2>
<div class="language-sh codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-sh codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">|   package.json</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">| ---app</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|   |   main.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|   |   preload.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|   \---renderer</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|           index.html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|           renderer.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">|           styles.css</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_lig3 alert alert--success"><div class="admonitionHeading_GNd1"><span class="admonitionIcon_DPBw"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Electron 版本</div><div class="admonitionContent_l625"><p>本文基于 electron@37.2.3</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="appmainjs">app/main.js<a href="https://blog.jjdd.site/blog/Electron%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE#appmainjs" class="hash-link" aria-label="app/main.js的直接链接" title="app/main.js的直接链接" translate="no">​</a></h2>
<div class="language-js codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-js codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">BrowserWindow</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> protocol</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> net </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"electron"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> path </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"node:path"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"node:url"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mainWindow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">BrowserWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">width</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">800</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">height</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">webPreferences</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">preload</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"preload.js"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  mainWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">loadURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">app://renderer/index.html</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 首先声明自定义协议</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">protocol</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">registerSchemesAsPrivileged</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">scheme</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">privileges</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">standard</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">secure</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">supportFetchAPI</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">corsEnabled</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">stream</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">whenReady</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 处理协议</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  protocol</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">handle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> filePath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">slice</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"app://"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// mainWindow.loadURL(`app://index.html`) -&gt; filePath = index.html/  引起错误,需要再处理</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> net</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pathToFileURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filePath</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">createWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"activate"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">BrowserWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAllWindows</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"window-all-closed"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">platform</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"darwin"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">quit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="处理协议-tip">处理协议 TIP<a href="https://blog.jjdd.site/blog/Electron%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE#%E5%A4%84%E7%90%86%E5%8D%8F%E8%AE%AE-tip" class="hash-link" aria-label="处理协议 TIP的直接链接" title="处理协议 TIP的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_osn3" id="使用-url-解析">使用 URL 解析<a href="https://blog.jjdd.site/blog/Electron%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE#%E4%BD%BF%E7%94%A8-url-%E8%A7%A3%E6%9E%90" class="hash-link" aria-label="使用 URL 解析的直接链接" title="使用 URL 解析的直接链接" translate="no">​</a></h3>
<div class="language-js codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-js codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">protocol</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">handle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> filePath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">slice</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"app://"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> net</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pathToFileURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> requestUrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">host</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> requestUrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pathname</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>使用 URL 解析可以处理 hash 路由文件, 如 <code>app://renderer/index.html#about</code></p>
<h4 class="anchor anchorTargetStickyNavbar_osn3" id="spa-history-路由">SPA history 路由<a href="https://blog.jjdd.site/blog/Electron%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE#spa-history-%E8%B7%AF%E7%94%B1" class="hash-link" aria-label="SPA history 路由的直接链接" title="SPA history 路由的直接链接" translate="no">​</a></h4>
<p>需要像服务器一样重定向处理, 否则会报 404</p>
<div class="language-sh codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-sh codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">app://renderer -&gt; app://renderer/index.html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app://renderer/* -&gt; app://renderer/index.html</span><br></span></code></pre></div></div>]]></content:encoded>
            <category>electron</category>
            <category>protocol</category>
        </item>
        <item>
            <title><![CDATA[Electron Windows应用自签名]]></title>
            <link>https://blog.jjdd.site/blog/code-sign</link>
            <guid>https://blog.jjdd.site/blog/code-sign</guid>
            <pubDate>Thu, 03 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[详细讲解 Electron Windows 应用的自签名流程，包括获取证书、配置签名信息以及打包发布。]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>开发Electron Windows应用时，需要获取自签名证书，并配置签名信息。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="获取自签名证书">获取自签名证书<a href="https://blog.jjdd.site/blog/code-sign#%E8%8E%B7%E5%8F%96%E8%87%AA%E7%AD%BE%E5%90%8D%E8%AF%81%E4%B9%A6" class="hash-link" aria-label="获取自签名证书的直接链接" title="获取自签名证书的直接链接" translate="no">​</a></h2>
<div class="language-sh codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-sh codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token plain">electron-builder create-self-signed-cert -p publisher</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Create self-signed code signing cert for Windows apps</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Options:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#       --version    Show version number                                 [boolean]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#       --help       Show help                                           [boolean]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#   -p, --publisher  The publisher name                        [string] [required]</span><br></span></code></pre></div></div>
<p>密码选 None</p>
<p><img decoding="async" loading="lazy" alt="code-sign-pass" src="https://blog.jjdd.site/assets/images/code-sign-pass-6f3c4189fc42446fed20bb45b68f0e18.png" width="856" height="317" class="img_Sxi7"></p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="配置">配置<a href="https://blog.jjdd.site/blog/code-sign#%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="配置的直接链接" title="配置的直接链接" translate="no">​</a></h2>
<div class="language-js codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-js codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@type</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> </span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment class-name keyword" style="color:#00009f;font-style:italic">import</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">(</span><span class="token doc-comment comment class-name string" style="color:#e3116c;font-style:italic">'electron-builder'</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">)</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">.</span><span class="token doc-comment comment class-name" style="color:#999988;font-style:italic">Configuration</span><span class="token doc-comment comment class-name punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment keyword" style="color:#00009f;font-style:italic">@see</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"> https://www.electron.build/configuration/configuration</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 省略</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">signtoolOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">certificateFile</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"resources/certificate.pfx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// signingHashAlgorithms: ["sha256"],</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_lig3 alert alert--info"><div class="admonitionHeading_GNd1"><span class="admonitionIcon_DPBw"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>信息</div><div class="admonitionContent_l625"><p>electron-builder@25.1.8 版本下适用</p></div></div>]]></content:encoded>
            <category>electron</category>
        </item>
        <item>
            <title><![CDATA[useState 原理]]></title>
            <link>https://blog.jjdd.site/blog/useState 原理</link>
            <guid>https://blog.jjdd.site/blog/useState 原理</guid>
            <pubDate>Wed, 02 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[深入解析 React useState 的工作原理，从 Fiber 架构到链表更新机制，全面理解 Hook 的内部实现与使用规则。]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>React Hooks 的设计目的，就是加强版函数组件，完全不使用"类"，就能写出一个全功能的组件。</p>
</blockquote>
<blockquote>
<p>React Hooks 的意思是，组件尽量写成纯函数，如果需要外部功能和副作用，就用钩子把外部代码"钩"进来。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="hooks-规则">Hooks 规则<a href="https://blog.jjdd.site/blog/useState%20%E5%8E%9F%E7%90%86#hooks-%E8%A7%84%E5%88%99" class="hash-link" aria-label="Hooks 规则的直接链接" title="Hooks 规则的直接链接" translate="no">​</a></h2>
<ol>
<li class="">只在顶层调用 Hook</li>
</ol>
<p>不要在循环、条件语句、嵌套函数或 try/catch/finally 代码块中调用 Hook。</p>
<ul>
<li class="">
<p>✅ 在 函数组件主体 的顶层调用它们。</p>
</li>
<li class="">
<p>✅ 在 自定义 Hook 主体 的顶层调用它们。</p>
</li>
<li class="">
<p>🔴 不要在条件语句或循环中调用 Hook。</p>
</li>
<li class="">
<p>🔴 不要在条件性的 return 语句之后调用 Hook。</p>
</li>
<li class="">
<p>🔴 不要在事件处理函数中调用 Hook。</p>
</li>
<li class="">
<p>🔴 不要在类组件中调用 Hook。</p>
</li>
<li class="">
<p>🔴 不要在传递给 useMemo、useReducer 或 useEffect 的函数内部调用 Hook。</p>
</li>
<li class="">
<p>🔴 不要在 try/catch/finally 代码块中调用 Hook。</p>
</li>
</ul>
<ol start="2">
<li class="">仅在 React 函数中调用 Hook</li>
</ol>
<ul>
<li class="">在 React 函数组件中调用 Hook。</li>
<li class="">在 自定义 Hook 中调用 Hook。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="usestate-原理">useState 原理<a href="https://blog.jjdd.site/blog/useState%20%E5%8E%9F%E7%90%86#usestate-%E5%8E%9F%E7%90%86" class="hash-link" aria-label="useState 原理的直接链接" title="useState 原理的直接链接" translate="no">​</a></h2>
<blockquote>
<p>React Hooks: not magic, just arrays</p>
</blockquote>
<p>useState 在调用时没有任何关于它引用的是哪个 state 变量的信息。没有传递给 useState 的“标识符”，它是如何知道要返回哪个 state 变量呢？它是否依赖于解析函数之类的魔法？答案是否定的。</p>
<p>相反，为了使语法更简洁，在同一组件的每次渲染中，Hooks 都依托于一个稳定的调用顺序。这在实践中很有效，因为如果你遵循上面的规则（“只在顶层调用 Hooks”），Hooks 将始终以相同的顺序被调用。此外，linter 插件也可以捕获大多数错误。</p>
<p>在 React 内部，为每个组件保存了一个数组，其中每一项都是一个 state 对。它维护当前 state 对的索引值，在渲染之前将其设置为 “0”。每次调用 useState 时，React 都会为你提供一个 state 对并增加索引值。你可以在文章 <a href="https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e" target="_blank" rel="noopener noreferrer" class="">React Hooks: not magic, just arrays</a> 中阅读有关此机制的更多信息。</p>
<h2 class="anchor anchorTargetStickyNavbar_osn3" id="实现usestate">实现useState<a href="https://blog.jjdd.site/blog/useState%20%E5%8E%9F%E7%90%86#%E5%AE%9E%E7%8E%B0usestate" class="hash-link" aria-label="实现useState的直接链接" title="实现useState的直接链接" translate="no">​</a></h2>
<div class="language-js codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-js codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> componentHooks </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> currentHookIndex </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// useState 在 React 中是如何工作的（简化版）</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">useState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">initialState</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> pair </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> componentHooks</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">currentHookIndex</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pair</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 这不是第一次渲染</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 所以 state pair 已经存在</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 将其返回并为下一次 hook 的调用做准备</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    currentHookIndex</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> pair</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 这是我们第一次进行渲染</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 所以新建一个 state pair 然后存储它</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  pair </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">initialState</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> setState</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">nextState</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 当用户发起 state 的变更，</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 把新的值放入 pair 中</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    pair</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> nextState</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">updateDOM</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 存储这个 pair 用于将来的渲染</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 并且为下一次 hook 的调用做准备</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  componentHooks</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">currentHookIndex</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> pair</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  currentHookIndex</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> pair</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">Gallery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 每次调用 useState() 都会得到新的 pair</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> setIndex</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">useState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">showMore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> setShowMore</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">useState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">handleNextClick</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">setIndex</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">handleMoreClick</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">setShowMore</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">showMore</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sculpture </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> sculptureList</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 这个例子没有使用 React，所以</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 返回一个对象而不是 JSX</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">onNextClick</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> handleNextClick</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">onMoreClick</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> handleMoreClick</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">header</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">sculpture</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">name</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> by </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">sculpture</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">artist</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">counter</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">index </span><span class="token template-string interpolation operator" style="color:#393A34">+</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation number" style="color:#36acaa">1</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> of </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">sculptureList</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">length</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">more</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">showMore </span><span class="token template-string interpolation operator" style="color:#393A34">?</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#e3116c">'Hide'</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#393A34">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#e3116c">'Show'</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> details</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> showMore </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> sculpture</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">description</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">imageSrc</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> sculpture</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">imageAlt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> sculpture</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">alt</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">updateDOM</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 在渲染组件之前</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 重置当前 Hook 的下标</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  currentHookIndex </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> output </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">Gallery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 更新 DOM 以匹配输出结果</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 这部分工作由 React 为你完成</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  nextButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">onclick</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">onNextClick</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">textContent</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">header</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  moreButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">onclick</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">onMoreClick</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  moreButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">textContent</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">more</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">src</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">imageSrc</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">alt</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">imageAlt</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">description</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    description</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">textContent</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">description</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    description</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">style</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">display</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    description</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">style</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">display</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'none'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> nextButton </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'nextButton'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> header </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'header'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> moreButton </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'moreButton'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> description </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'description'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> image </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'image'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sculptureList </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Homenaje a la Neurocirugía'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Marta Colvin Andrade'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/Mx7dA2Y.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Floralis Genérica'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Eduardo Catalano'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'This enormous (75 ft. or 23m) silver flower is located in Buenos Aires. It is designed to move, closing its petals in the evening or when strong winds blow and opening them in the morning.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/ZF6s192m.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A gigantic metallic flower sculpture with reflective mirror-like petals and strong stamens.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Eternal Presence'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'John Woodrow Wilson'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Wilson was known for his preoccupation with equality, social justice, as well as the essential and spiritual qualities of humankind. This massive (7ft. or 2,13m) bronze represents what he described as "a symbolic Black presence infused with a sense of universal humanity."'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/aTtVpES.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'The sculpture depicting a human head seems ever-present and solemn. It radiates calm and serenity.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Moai'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Unknown Artist'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Located on the Easter Island, there are 1,000 moai, or extant monumental statues, created by the early Rapa Nui people, which some believe represented deified ancestors.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/RCwLEoQm.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Three monumental stone busts with the heads that are disproportionately large with somber faces.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Blue Nana'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Niki de Saint Phalle'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'The Nanas are triumphant creatures, symbols of femininity and maternity. Initially, Saint Phalle used fabric and found objects for the Nanas, and later on introduced polyester to achieve a more vibrant effect.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/Sd1AgUOm.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A large mosaic sculpture of a whimsical dancing female figure in a colorful costume emanating joy.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Ultimate Form'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Barbara Hepworth'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'This abstract bronze sculpture is a part of The Family of Man series located at Yorkshire Sculpture Park. Hepworth chose not to create literal representations of the world but developed abstract forms inspired by people and landscapes.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/2heNQDcm.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A tall sculpture made of three elements stacked on each other reminding of a human figure.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Cavaliere'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Lamidi Olonade Fakeye'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Descended from four generations of woodcarvers, Fakeye's work blended traditional and contemporary Yoruba themes."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/wIdGuZwm.png'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'An intricate wood sculpture of a warrior with a focused face on a horse adorned with patterns.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Big Bellies'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Alina Szapocznikow'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Szapocznikow is known for her sculptures of the fragmented body as a metaphor for the fragility and impermanence of youth and beauty. This sculpture depicts two very realistic large bellies stacked on top of each other, each around five feet (1,5m) tall."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/AlHTAdDm.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'The sculpture reminds a cascade of folds, quite different from bellies in classical sculptures.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Terracotta Army'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Unknown Artist'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'The Terracotta Army is a collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China. The army consisted of more than 8,000 soldiers, 130 chariots with 520 horses, and 150 cavalry horses.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/HMFmH6m.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'12 terracotta sculptures of solemn warriors, each with a unique facial expression and armor.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Lunar Landscape'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Louise Nevelson'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Nevelson was known for scavenging objects from New York City debris, which she would later assemble into monumental constructions. In this one, she used disparate parts like a bedpost, juggling pin, and seat fragment, nailing and gluing them into boxes that reflect the influence of Cubism’s geometric abstraction of space and form.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/rN7hY6om.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A black matte sculpture where the individual elements are initially indistinguishable.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Aureole'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Ranjani Shettar'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Shettar merges the traditional and the modern, the natural and the industrial. Her art focuses on the relationship between man and nature. Her work was described as compelling both abstractly and figuratively, gravity defying, and a "fine synthesis of unlikely materials."'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/okTpbHhm.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A pale wire-like sculpture mounted on concrete wall and descending on the floor. It appears light.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Hippos'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">artist</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Taipei Zoo'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'The Taipei Zoo commissioned a Hippo Square featuring submerged hippos at play.'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://i.imgur.com/6o5Vuyu.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">alt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'A group of bronze hippo sculptures emerging from the sett sidewalk as if they were swimming.'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 使 UI 匹配当前 state</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">updateDOM</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<div class="language-html codeBlockContainer_kVrh theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Fn4y"><pre tabindex="0" class="prism-code language-html codeBlock_CyQv thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_iPvw"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">button</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">nextButton</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Next</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">button</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">h3</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">header</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">h3</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">button</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">moreButton</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">button</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">p</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">description</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">p</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">img</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">image</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">style</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:#393A34"><span class="token style language-css"></span><span class="token style language-css selector" style="color:#00009f">*</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">{</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">box-sizing</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> border-box</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">}</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:#393A34"><span class="token style language-css"></span><span class="token style language-css selector" style="color:#00009f">body</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">{</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">font-family</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> sans-serif</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">margin</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> </span><span class="token style language-css number" style="color:#36acaa">20</span><span class="token style language-css unit">px</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">padding</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> </span><span class="token style language-css number" style="color:#36acaa">0</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">}</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:#393A34"><span class="token style language-css"></span><span class="token style language-css selector" style="color:#00009f">button</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">{</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">display</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> block</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css property" style="color:#36acaa">margin-bottom</span><span class="token style language-css punctuation" style="color:#393A34">:</span><span class="token style language-css"> </span><span class="token style language-css number" style="color:#36acaa">10</span><span class="token style language-css unit">px</span><span class="token style language-css punctuation" style="color:#393A34">;</span><span class="token style language-css"> </span><span class="token style language-css punctuation" style="color:#393A34">}</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:#393A34"><span class="token style language-css"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">style</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>]]></content:encoded>
            <category>react</category>
            <category>hooks</category>
        </item>
    </channel>
</rss>