[{"data":1,"prerenderedAt":22765},["ShallowReactive",2],{"allBlog":3,"hotBlog":11900,"recommendBlog":21297},[4,1031,6722,7528,8236,8730,9054,9938,10848],{"id":5,"title":6,"articleId":7,"articleThumb":8,"body":9,"categoryId":691,"categoryInfo":991,"createDate":994,"description":995,"excerpt":996,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1003,"meta":1004,"navigation":1003,"path":1005,"rawbody":1006,"readingTime":1007,"seo":1008,"sitemap":1009,"stem":1022,"tagIds":1023,"tagInfo":1024,"updateDate":1028,"wordCount":1029,"__hash__":1030},"blog\u002Fblog\u002F1.Algolia DocSearch快速开启网站全文检索功能.md","Algolia DocSearch快速开启网站全文检索功能","algolia-docSearch","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327202906034.webp",{"type":10,"value":11,"toc":971},"minimark",[12,16,21,60,64,97,101,111,122,127,185,189,215,219,222,231,235,238,252,256,259,394,398,402,416,423,444,450,454,472,498,504,510,528,533,539,549,554,557,565,571,576,586,604,607,617,622,632,652,656,671,675,738,742,764,912,916,923,962,967],[13,14,15],"p",{},"Algolia 的服务支持多种语言支持 Ruby、Rails、Python、PHP、JS、Java、Android、Objective-C 等多种语言，具备关键字输入智能容错功能，并提供有搜索排名配置，并具有实时快速的特点(Algolia 在全球 12 个数据中心均有部署)。Algolia 还为移动设备提供了离线搜索引擎，其 C++ SDK 可以嵌入到应用服务器端，这样即便没有网络连接应用也能提供搜索功能。",[17,18,20],"h2",{"id":19},"_1-相关导航链接","1. 相关导航链接",[22,23,24,34,46,53],"card-group",{},[25,26,31],"card",{"icon":27,"target":28,"title":29,"to":30},"i-simple-icons-github","_blank","DocSearch免费服务申请页面","https:\u002F\u002Fdocsearch.algolia.com\u002Fapply\u002F",[13,32,33],{},"点击跳转DocSearch免费搜索服务申请页面，申请通过后，可快速集成DocSearch到项目中。",[25,35,38],{"icon":27,"target":28,"title":36,"to":37},"Algolia管理后台页面","https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Fdashboard",[13,39,40,41,45],{},"点击跳转Algolia管理后台，查看应用",[42,43,44],"code",{},"keys","，管理Algolia应用，索引和记录数据。",[25,47,50],{"icon":27,"target":28,"title":48,"to":49},"algolia\u002Fdocsearch 源码仓库","https:\u002F\u002Fgithub.com\u002Falgolia\u002Fdocsearch",[13,51,52],{},"点击跳转docsearch源码仓库，查看不同框架中docsearch的集成步骤和使用方式。",[25,54,57],{"icon":27,"target":28,"title":55,"to":56},"Algolia爬虫后台页面","https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Fcrawler\u002Fcrawlers",[13,58,59],{},"点击跳转Algolia爬虫管理后台，查看爬虫程序执行结果，手动重新触发爬虫任务或者自定义爬虫程序。",[17,61,63],{"id":62},"_2-algolia功能和特点","2. Algolia功能和特点",[65,66,67,75,81,87],"ol",{},[68,69,70,74],"li",{},[71,72,73],"strong",{},"托管式全文搜索："," Algolia 提供完整的搜索服务后端，无需部署，API即用。开发者无需自行构建搜索引擎架构，只需调用API即可实现实时搜索、模糊匹配、多语言支持等功能，轻量级集成。API响应速度快，低延迟、精准度高、有免费计划支持以及易于集成。",[68,76,77,80],{},[71,78,79],{},"性能与扩展性‌："," 支持每秒处理数千次查询，延迟低至20毫秒；‌‌可扩展至数十亿条数据，适用于电商、内容平台等高并发场景;",[68,82,83,86],{},[71,84,85],{},"‌开发者友好性‌："," 提供JavaScript、Python、Java等主流语言的SDK; 支持与Hexo、Hugo、Apifox、VuePress、VitePress等开发工具无缝集成，配置时间可缩短至数分钟；",[68,88,89,92,93,96],{},[71,90,91],{},"使用成本：","  免费版支持1万条索引和1万次\u002F月搜索请求，个人用户基本无需付费；技术文档与开源项目‌，通过申请免费",[42,94,95],{},"DocSearch","计划，自动化索引生成和搜索服务部署，显著提升文档用户体验；‌‌",[17,98,100],{"id":99},"_3-algolia-docsearch","3. Algolia DocSearch",[13,102,103,110],{},[104,105,109],"a",{"href":106,"rel":107,"target":28},"https:\u002F\u002Fdocsearch.algolia.com\u002Fdocs\u002Fwhat-is-docsearch",[108],"nofollow","Algolia DocSearch"," 是Algolia提供的免费的自动化全文搜索服务，旨在帮助开发者为他们的文档网站提供高效、精确的搜索体验。它通过智能爬虫抓取和索引在线文档，定时爬取指定网站，自动构建搜索索引，并结合Algolia的高性能搜索技术，提供即时的、上下文相关的搜索结果‌。",[13,112,113,114,117,118,121],{},"对于开发者而言，不需要繁琐的配置，只需要申请",[42,115,109],{"color":116},"primary","服务的免费计划后，用相关的 API 直接调用服务就行了。目前前端框架都有相对成熟的",[42,119,120],{"color":116},"Algolia DocSearch API","快速集成的第三方库，使用非常简单。对于使用者，只需要在网站检索框输入关键字，即可快速的搜索相应结果。",[123,124,126],"h3",{"id":125},"_31-功能和特点","3.1. 功能和特点",[128,129,130,137,143,149,155,161,167,173,179],"ul",{},[68,131,132,133,136],{},"‌",[71,134,135],{},"智能爬虫‌："," Algolia DocSearch使用定制的爬虫技术，能够深入到网站结构中，有效地抓取和提取文档信息。用户可以通过配置文件指导爬虫的工作，包括要抓取的页面、字段和过滤规则‌.",[68,138,132,139,142],{},[71,140,141],{},"数据索引‌："," 爬虫抓取的信息会被上传至Algolia的搜索索引，这是一个经过优化的数据存储，适合快速查询。Algolia支持丰富的搜索功能，如拼写纠错、部分匹配和布尔运算等‌.",[68,144,132,145,148],{},[71,146,147],{},"自定义搜索界面‌："," Algolia提供了JavaScript SDK，允许用户在自己的网站上轻松嵌入搜索框，并自定义搜索结果显示样式和交互体验‌.",[68,150,132,151,154],{},[71,152,153],{},"持续更新‌："," 配合 GitCode 上的配置仓库，每次更新文档时，DocSearch可以自动或按需重新索引，确保搜索结果始终与最新内容同步‌.",[68,156,157,160],{},[71,158,159],{},"即时性‌："," Algolia搜索引擎设计用于提供毫秒级的响应速度‌.",[68,162,163,166],{},[71,164,165],{},"准确性‌："," 通过深度学习和自然语言处理技术，提高搜索结果的相关度‌.",[68,168,169,172],{},[71,170,171],{},"可定制化‌："," 搜索框和结果展示样式可根据品牌和需求进行个性化定制‌.",[68,174,175,178],{},[71,176,177],{},"自动化‌："," 配置好后，自动化的索引更新减少了手动维护的工作量‌.",[68,180,181,184],{},[71,182,183],{},"社区支持‌："," 配置文件存储在GitCode上，方便分享和协作，同时也便于社区贡献者共同改进‌.",[123,186,188],{"id":187},"_32-应用场景","3.2 应用场景",[128,190,191,197,203,209],{},[68,192,193,196],{},[71,194,195],{},"开发文档："," 无论是开源项目的API参考，还是商业产品的用户指南，都能受益于DocSearch提供的强大搜索功能‌.",[68,198,199,202],{},[71,200,201],{},"教育平台‌："," 教学资源的查找可以通过DocSearch变得更简单快捷‌.",[68,204,205,208],{},[71,206,207],{},"博客聚合‌："," 博客聚合站点可以利用此服务提升读者的阅读体验‌.",[68,210,211,214],{},[71,212,213],{},"任何需要高效内部搜索的网站‌："," 无论大小，只要网站有大量文本内容，DocSearch都是理想选择‌.",[123,216,218],{"id":217},"_33-基本原理","3.3 基本原理",[13,220,221],{},"Algolia服务器会定期抓取我们指定的文档地址中的内容进行分析并建立索引，这样在网站搜索框中输入关键词后，前端会调用 Algolia DocSearch 的接口并显示搜索结果。这些请求、结果显示的相关逻辑都封装好了，我们要做的就是按要求插入代码、配置好网站样式以及搜索框。",[223,224,225],"note",{},[13,226,227,228,230],{},"根据 ",[42,229,109],{}," 的官方文档，默认情况下它通常一周爬取一次网站内容，用户也可自行触发爬取.",[123,232,234],{"id":233},"_34-使用要求","3.4 使用要求",[13,236,237],{},"Algolia DocSearch 提供的免费服务是需要申请的，当我们的网站满足下列条件时，Algolia 那边的工作人员才会让我们的申请通过：",[65,239,240,243,246,249],{},[68,241,242],{},"我们必须是云文档网站的所有者，网站必须是公开的。",[68,244,245],{},"网站内容必须是开源项目的技术文档或技术博客。",[68,247,248],{},"网站申请服务时必须有完整稳定的设计和内容，即确认网站做好生产准备。",[68,250,251],{},"免费计划限制，仅支持公开可访问的网站（如博客、开源项目文档），需通过简单申请流程获取API密钥。 ‌",[17,253,255],{"id":254},"_4-algolia和docsearch区别","4. Algolia和DocSearch区别",[13,257,258],{},"Algolia 是一个‌完整的商业搜索服务平台‌，而 DocSearch 是其旗下专门为‌技术文档场景定制的自动化搜索解决方案‌。两者的核心区别如下：",[260,261,262,277],"table",{},[263,264,265],"thead",{},[266,267,268,272,275],"tr",{},[269,270,271],"th",{},"对比项",[269,273,274],{},"Algolia",[269,276,95],{},[278,279,280,311,328,345,377],"tbody",{},[266,281,282,286,299],{},[283,284,285],"td",{},"定位与功能范围",[283,287,288,289,292,293,295,296,298],{},"通用型搜索引擎服务平台，支持电商、APP、企业数据等多种场景。核心功能为:",[290,291],"br",{},"  1. 分布式架构实现毫秒级响应‌。",[290,294],{}," 2. 智能排序、拼写纠错、同义词处理等算法‌。",[290,297],{}," 3.  开发者可自由定制索引规则和搜索交互‌。",[283,300,301,302,304,305,307,308,310],{},"Algolia 为‌技术文档\u002F博客‌设计的“开箱即用”方案。核心功能为：",[290,303],{}," 1. 自动爬取网站内容并构建索引‌。",[290,306],{}," 2. 提供预设的前端搜索组件(搜索框+结果页)。",[290,309],{}," 3. 仅适用于公开的技术文档类网站‌。",[266,312,313,316,322],{},[283,314,315],{},"数据接入方式",[283,317,318,319,321],{},"1. 需手动上传数据(如通过API或SDK)",[290,320],{}," 2. 使用官方爬虫工具 ‌Algolia Crawler‌ 自定义抓取逻辑‌。",[283,323,324,325,327],{},"1. 完全自动化,提交网站URL后，Algolia ‌自动定期爬取‌(默认每周一次)，可自定义定时任务执行时间。",[290,326],{},"2. 无需手动配置数据管道，适合文档更新频繁的场景‌。",[266,329,330,333,339],{},[283,331,332],{},"成本与适用性",[283,334,335,336,338],{},"1. 免费版限制 10,000 条记录‌。",[290,337],{}," 2. 高阶功能（如个性化排序）需付费‌",[283,340,341,342,344],{},"1. 对技术文档完全免费‌，无记录数量限制‌。",[290,343],{}," 2. 但需通过人工审核(网站需为公开技术内容)。",[266,346,347,350,365],{},[283,348,349],{},"集成复杂度",[283,351,352,353,355,356,358,359,361,362,364],{},"需自主开发，自行配置。",[290,354],{}," 1. 需要自己手动创建应用，认证爬取站点域名。",[290,357],{}," 2. 需要自己手动创建索引名称，自动导入数据。",[290,360],{}," 3. 需要自己编写爬虫代码。",[290,363],{},"4. 自己编写前端交互组件‌。",[283,366,367,368,370,371,373,374,376],{},"极简集成。",[290,369],{}," 1. DocSearch免费计划申请通过后，系统自行创建索引名称，认证站点域名，编写爬虫脚本。",[290,372],{},"2. 通过CDN引入CSS\u002FJS文件。",[290,375],{}," 3. 添加预设的搜索框HTML标签即可实现页面检索框弹框效果。",[266,378,379,382,385],{},[283,380,381],{},"搜索体验差异",[283,383,384],{},"需通过API参数和UI库手动实现同等效果‌。",[283,386,387,388,390,391,393],{},"1. 结果页自动高亮标题层级(h1 > h2 > h3)。",[290,389],{}," 2. 针对文档结构优化相关性排序(如优先匹配章节标题)。",[290,392],{}," 3. 内置响应式UI，适配移动端‌。",[17,395,397],{"id":396},"_5-docsearch使用说明","5. DocSearch使用说明",[123,399,401],{"id":400},"_51-申请免费资格","5.1 申请免费资格",[13,403,404,405,407,408,410,411,415],{},"首先，你需要申请 ",[42,406,274],{}," 免费的 ",[42,409,95],{},"计划资格。打开 ",[104,412,109],{"href":413,"rel":414,"target":28},"https:\u002F\u002Fdocsearch.algolia.com\u002F",[108]," 官网，点击 “Apply” 按钮，在表单项中填写你的项目信息，包括文档站的 URL（需包含协议头 https:\u002F\u002F）、邮箱、是否开源等。",[13,417,418],{},[419,420],"img",{"alt":421,"src":422},"申请表单","https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605174653671.webp",[13,424,425,426,428,429,431,432,435,436,439,440,443],{},"提交表单后，",[42,427,274],{}," 团队会审核你的申请(工作日一般是当天或者隔天就可申请通过,最迟不超过一周）。如果符合条件，他们会发邮件通知你，切记你需要回复邮件，确认你是网站站长，并且能够修改代码。通过确认后，他们会为你开通免费的 ",[42,430,95],{},"服务，Algolia DocSearch 会再发一封使用邮件，其中包含",[42,433,434],{},"appId","、",[42,437,438],{},"apiKey"," 和 ",[42,441,442],{},"indexName","，用于在网站生成框架中配置。若未回复，视为放弃请求。",[13,445,446],{},[419,447],{"alt":448,"src":449},"申请成功","https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605175441185.webp",[123,451,453],{"id":452},"_52-algolia管理后台","5.2 Algolia管理后台",[13,455,456,457,459,460,464,465,468,469,471],{},"免费的",[42,458,109],{},"计划申请通过后，我们也可以前往",[104,461,274],{"href":462,"rel":463,"target":28},"https:\u002F\u002Fdashboard.algolia.com\u002Fusers\u002Fsign_in",[108],"管理自己的后台数据，查询对应的",[42,466,467],{},"key","信息。",[42,470,109],{},"审核通过后，控制面板中会自动生成申请通过邮件返回的应用名称和应用id，默认索引名称，默认爬取程序。默认索引名称可以删除，系统审核通过时，已对申请域名进行了认证，认证后索引数据才能生效。默认爬取程序无法删除。",[65,473,474],{},[68,475,476,477,482,483,486,487,489,490,493,494,497],{},"进入",[104,478,481],{"href":479,"rel":480},"https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Findices",[108],"控制面板","后，点击左上角",[42,484,485],{},"Application","，切换申请通过的",[42,488,95],{},"应用。通过左侧",[42,491,492],{},"search","按钮查看应用索引信息，下方",[42,495,496],{}," Go To Crawler","进入爬虫程序页面",[13,499,500],{},[419,501],{"alt":502,"src":503},"","https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702162222617.webp",[65,505,507],{"start":506},2,[68,508,509],{},"索引数据页面",[13,511,512,513,516,517,519,520,523,524,527],{},"点击左侧选项栏里的",[42,514,515],{},"Search","进入索引页面，查看对应的",[42,518,442],{}," 数据，如果",[42,521,522],{},"Browse","这里没有显示数据，那说明爬取的数据可能有问题，导致没有生成对应的",[42,525,526],{},"Records","，那我们就需要排查第三步爬虫程序是否有问题。",[13,529,530],{},[419,531],{"alt":502,"src":532},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702162609300.webp",[65,534,536],{"start":535},3,[68,537,538],{},"爬虫程序页面",[13,540,541,542,544,545,548],{},"点击控制面板的",[42,543,496],{},"按钮或者左下方的",[42,546,547],{},"Data Source","按钮都可以进入爬虫程序页面。",[13,550,551],{},[419,552],{"alt":502,"src":553},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702164213759.webp",[13,555,556],{},"点击索引名称，进入爬虫配置页面",[13,558,559,562],{},[419,560],{"alt":502,"src":561},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165152222.webp",[419,563],{"alt":502,"src":564},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165158121.webp",[13,566,567,568,497],{},"点击",[42,569,570],{},"Editor",[13,572,573],{},[419,574],{"alt":502,"src":575},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165622704.webp",[13,577,578,579,582,583,585],{},"如果爬虫监控台显示成功爬取，也有",[42,580,581],{},"Monitoring Success"," 的数据，但 ",[42,584,526],{}," 为 0，那大概是爬虫提取数据的逻辑有问题，查看上图代码，查看具体的爬虫逻辑，查看是否存在错误信息。",[13,587,588,589,592,593,595,596,599,600,603],{},"像",[42,590,591],{},"pathsToMatch"," 这里是最容易出错的地方，比如: ",[42,594,591],{}," 如果是",[42,597,598],{},"https:\u002F\u002Fanyfork.github.io\u002Fblog-docs\u002Fdocs\u002F**","，但你的网址都是",[42,601,602],{},"https:\u002F\u002Fanyfork.github.io\u002Fblog-docs\u002F**","开头，那这里大概就是会提取错误，修改一下，然后点击右侧的数据进行测试。",[13,605,606],{},"一般情况下，基本都是爬虫程序爬取的域名或者路径不对导致爬虫失败，因此需要认真核对一下是否配置正确。",[65,608,610],{"start":609},4,[68,611,612,613,616],{},"点击左下角的",[42,614,615],{},"setting","查看应用配置信息。",[13,618,619],{},[419,620],{"alt":502,"src":621},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605190630560.webp",[65,623,625],{"start":624},5,[68,626,627,628,631],{},"点击右侧",[42,629,630],{},"API Keys","，查看应用的所有key信息，项目中集成会用到几个关键的key。",[13,633,634,637,638,641,642,644,645,648,649,651],{},[419,635],{"alt":502,"src":636},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605190902912.webp","\n目前项目使用",[42,639,640],{},"docSearch","只需要",[42,643,438],{},"，",[42,646,647],{},"applicationId","和",[42,650,442],{},"这3个key。",[17,653,655],{"id":654},"_6-nuxt3集成docsearch","6. Nuxt3集成DocSearch",[13,657,658,663,664,667,668,670],{},[104,659,662],{"href":660,"rel":661,"target":28},"https:\u002F\u002Falgolia.nuxtjs.org\u002Fadvanced\u002Fdocsearch\u002F",[108],"nuxt\u002Falgolia","是专为 Nuxt.js 框架设计的模块，用于简化与 Algolia 搜索引擎的集成。它提供了快速、灵活的搜索功能集成方案，适用于电商网站、博客平台、文档站点等场景，其中提供了在",[42,665,666],{},"Nuxt3","项目中使用",[42,669,95],{},"的配置教程。大概使用流畅如下：",[123,672,674],{"id":673},"_61-安装依赖","6.1 安装依赖",[676,677,678,705,721],"code-group",{},[679,680,685],"pre",{"className":681,"code":682,"filename":683,"language":684,"meta":502,"style":502},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @docsearch\u002Fjs @docsearch\u002Fcss\n","pnpm","bash",[42,686,687],{"__ignoreMap":502},[688,689,692,695,699,702],"span",{"class":690,"line":691},"line",1,[688,693,683],{"class":694},"sBMFI",[688,696,698],{"class":697},"sfazB"," add",[688,700,701],{"class":697}," @docsearch\u002Fjs",[688,703,704],{"class":697}," @docsearch\u002Fcss\n",[679,706,709],{"className":681,"code":707,"filename":708,"language":684,"meta":502,"style":502},"yarn add @docsearch\u002Fjs @docsearch\u002Fcss\n","yarn",[42,710,711],{"__ignoreMap":502},[688,712,713,715,717,719],{"class":690,"line":691},[688,714,708],{"class":694},[688,716,698],{"class":697},[688,718,701],{"class":697},[688,720,704],{"class":697},[679,722,725],{"className":681,"code":723,"filename":724,"language":684,"meta":502,"style":502},"npm install @docsearch\u002Fjs @docsearch\u002Fcss\n","npm",[42,726,727],{"__ignoreMap":502},[688,728,729,731,734,736],{"class":690,"line":691},[688,730,724],{"class":694},[688,732,733],{"class":697}," install",[688,735,701],{"class":697},[688,737,704],{"class":697},[123,739,741],{"id":740},"_62-安装模块","6.2 安装模块",[13,743,744,745,748,749,752,753,755,756,644,759,648,761,763],{},"将",[42,746,747],{"color":116},"@nuxtjs\u002Falgolia","安装到",[42,750,751],{},"nuxt","的模块中，并配置",[42,754,95],{},"申请成功后邮件返回的",[42,757,758],{},"apikey",[42,760,434],{},[42,762,442],{},"这3个key信息。",[679,765,770],{"className":766,"code":767,"filename":768,"language":769,"meta":502,"style":502},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules:['@nuxtjs\u002Falgolia']\n  algolia: {\n    apiKey: 'apiKey',\n    applicationId: 'applicationId',\n    \u002F\u002F DocSearch key is used to configure DocSearch extension.\n    docSearch: {\n      indexName: 'indexName',\n    }\n  }  \n})\n","nuxt.config.ts","ts",[42,771,772,793,815,822,839,854,861,872,888,894,903],{"__ignoreMap":502},[688,773,774,778,781,785,789],{"class":690,"line":691},[688,775,777],{"class":776},"s7zQu","export",[688,779,780],{"class":776}," default",[688,782,784],{"class":783},"s2Zo4"," defineNuxtConfig",[688,786,788],{"class":787},"sTEyZ","(",[688,790,792],{"class":791},"sMK4o","{\n",[688,794,795,799,802,805,808,810,812],{"class":690,"line":506},[688,796,798],{"class":797},"swJcz","  modules",[688,800,801],{"class":791},":",[688,803,804],{"class":787},"[",[688,806,807],{"class":791},"'",[688,809,747],{"class":697},[688,811,807],{"class":791},[688,813,814],{"class":787},"]\n",[688,816,817,820],{"class":690,"line":535},[688,818,819],{"class":787},"  algolia: ",[688,821,792],{"class":791},[688,823,824,827,829,832,834,836],{"class":690,"line":609},[688,825,826],{"class":797},"    apiKey",[688,828,801],{"class":791},[688,830,831],{"class":791}," '",[688,833,438],{"class":697},[688,835,807],{"class":791},[688,837,838],{"class":791},",\n",[688,840,841,844,846,848,850,852],{"class":690,"line":624},[688,842,843],{"class":797},"    applicationId",[688,845,801],{"class":791},[688,847,831],{"class":791},[688,849,647],{"class":697},[688,851,807],{"class":791},[688,853,838],{"class":791},[688,855,857],{"class":690,"line":856},6,[688,858,860],{"class":859},"sHwdD","    \u002F\u002F DocSearch key is used to configure DocSearch extension.\n",[688,862,864,867,869],{"class":690,"line":863},7,[688,865,866],{"class":797},"    docSearch",[688,868,801],{"class":791},[688,870,871],{"class":791}," {\n",[688,873,875,878,880,882,884,886],{"class":690,"line":874},8,[688,876,877],{"class":797},"      indexName",[688,879,801],{"class":791},[688,881,831],{"class":791},[688,883,442],{"class":697},[688,885,807],{"class":791},[688,887,838],{"class":791},[688,889,891],{"class":690,"line":890},9,[688,892,893],{"class":791},"    }\n",[688,895,897,900],{"class":690,"line":896},10,[688,898,899],{"class":791},"  }",[688,901,902],{"class":787},"  \n",[688,904,906,909],{"class":690,"line":905},11,[688,907,908],{"class":791},"}",[688,910,911],{"class":787},")\n",[123,913,915],{"id":914},"_63-使用组件","6.3 使用组件",[13,917,918,919,922],{},"将组件",[42,920,921],{},"\u003CAlgoliaDocSearch \u002F>","放置在需要展示搜索的地方，页面上就会展示出搜索框，点击弹出一个模态框，输入关键字，即可全局进行文本搜索。",[679,924,929],{"className":925,"code":926,"filename":927,"language":928,"meta":502,"style":502},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003CAlgoliaDocSearch \u002F>\n\u003C\u002Ftemplate>\n","index.vue","vue",[42,930,931,942,953],{"__ignoreMap":502},[688,932,933,936,939],{"class":690,"line":691},[688,934,935],{"class":791},"\u003C",[688,937,938],{"class":797},"template",[688,940,941],{"class":791},">\n",[688,943,944,947,950],{"class":690,"line":506},[688,945,946],{"class":791},"  \u003C",[688,948,949],{"class":797},"AlgoliaDocSearch",[688,951,952],{"class":791}," \u002F>\n",[688,954,955,958,960],{"class":690,"line":535},[688,956,957],{"class":791},"\u003C\u002F",[688,959,938],{"class":797},[688,961,941],{"class":791},[13,963,964],{},[419,965],{"alt":502,"src":966},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702182342087.webp",[968,969,970],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":502,"searchDepth":535,"depth":535,"links":972},[973,974,975,981,982,986],{"id":19,"depth":506,"text":20},{"id":62,"depth":506,"text":63},{"id":99,"depth":506,"text":100,"children":976},[977,978,979,980],{"id":125,"depth":535,"text":126},{"id":187,"depth":535,"text":188},{"id":217,"depth":535,"text":218},{"id":233,"depth":535,"text":234},{"id":254,"depth":506,"text":255},{"id":396,"depth":506,"text":397,"children":983},[984,985],{"id":400,"depth":535,"text":401},{"id":452,"depth":535,"text":453},{"id":654,"depth":506,"text":655,"children":987},[988,989,990],{"id":673,"depth":535,"text":674},{"id":740,"depth":535,"text":741},{"id":914,"depth":535,"text":915},{"name":992,"symbol":492,"icon":993,"id":691},"全文检索","line-md:file-search","2025-06-05 15:34:23","‌ Algolia DocSearch为网站提供了高效、精准、免费的文档搜索服务功能，可以快速实现网站全文检索，尤其适合技术文档、博客等需要大量文本内容检索的站点，集成简单，使用方便。本文将系统的介绍Nuxt3项目中如何快速集成和使用DocSearch。",{"type":10,"value":997},[998],[13,999,1000],{},"Algolia 是一家专注于提供托管式搜索和实时数据查询服务的云服务平台‌，主要帮助网站、移动应用及技术文档快速集成高效、精准的搜索功能。其核心技术优势包括毫秒级响应速度、高度可定制的搜索算法、易用性强的API接口，以及对开源项目和非商业用途的免费支持。","md",false,true,{},"\u002Fblog\u002Falgolia-docsearch","---\ntitle: Algolia DocSearch快速开启网站全文检索功能\ndescription: ‌ Algolia DocSearch为网站提供了高效、精准、免费的文档搜索服务功能，可以快速实现网站全文检索，尤其适合技术文档、博客等需要大量文本内容检索的站点，集成简单，使用方便。本文将系统的介绍Nuxt3项目中如何快速集成和使用DocSearch。\narticleId: algolia-docSearch\ncreateDate: \"2025-06-05 15:34:23\"\nupdateDate: \"2026-03-11 22:22:52\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327202906034.webp\ntagIds: \n    - 1\ncategoryId: 1\nisTop: true\nisRecommend: true\nisHot: true\nisHidden: false\nnavigation: true\n---\n\nAlgolia 是一家专注于提供托管式搜索和实时数据查询服务的云服务平台‌，主要帮助网站、移动应用及技术文档快速集成高效、精准的搜索功能。其核心技术优势包括毫秒级响应速度、高度可定制的搜索算法、易用性强的API接口，以及对开源项目和非商业用途的免费支持。\n\u003C!--more-->\n\nAlgolia 的服务支持多种语言支持 Ruby、Rails、Python、PHP、JS、Java、Android、Objective-C 等多种语言，具备关键字输入智能容错功能，并提供有搜索排名配置，并具有实时快速的特点(Algolia 在全球 12 个数据中心均有部署)。Algolia 还为移动设备提供了离线搜索引擎，其 C++ SDK 可以嵌入到应用服务器端，这样即便没有网络连接应用也能提供搜索功能。\n\n## 1. 相关导航链接\n::card-group\n\n::card\n---\ntitle: DocSearch免费服务申请页面\nicon: i-simple-icons-github\nto: https:\u002F\u002Fdocsearch.algolia.com\u002Fapply\u002F\ntarget: _blank\n---\n点击跳转DocSearch免费搜索服务申请页面，申请通过后，可快速集成DocSearch到项目中。\n::\n\n::card\n---\ntitle: Algolia管理后台页面\nicon: i-simple-icons-github\nto: https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Fdashboard\ntarget: _blank\n---\n点击跳转Algolia管理后台，查看应用`keys`，管理Algolia应用，索引和记录数据。\n::\n\n::card\n---\ntitle: algolia\u002Fdocsearch 源码仓库\nicon: i-simple-icons-github\nto: https:\u002F\u002Fgithub.com\u002Falgolia\u002Fdocsearch\ntarget: _blank\n---\n点击跳转docsearch源码仓库，查看不同框架中docsearch的集成步骤和使用方式。\n::\n\n::card\n---\ntitle: Algolia爬虫后台页面\nicon: i-simple-icons-github\nto: https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Fcrawler\u002Fcrawlers\ntarget: _blank\n---\n点击跳转Algolia爬虫管理后台，查看爬虫程序执行结果，手动重新触发爬虫任务或者自定义爬虫程序。\n::\n\n::\n\n## 2. Algolia功能和特点\n1. **托管式全文搜索：** Algolia 提供完整的搜索服务后端，无需部署，API即用。开发者无需自行构建搜索引擎架构，只需调用API即可实现实时搜索、模糊匹配、多语言支持等功能，轻量级集成。API响应速度快，低延迟、精准度高、有免费计划支持以及易于集成。\n\n2. **性能与扩展性‌：** 支持每秒处理数千次查询，延迟低至20毫秒；‌‌可扩展至数十亿条数据，适用于电商、内容平台等高并发场景;\n\n3. **‌开发者友好性‌：** 提供JavaScript、Python、Java等主流语言的SDK; 支持与Hexo、Hugo、Apifox、VuePress、VitePress等开发工具无缝集成，配置时间可缩短至数分钟；\n\n4. **使用成本：**  免费版支持1万条索引和1万次\u002F月搜索请求，个人用户基本无需付费；技术文档与开源项目‌，通过申请免费`DocSearch`计划，自动化索引生成和搜索服务部署，显著提升文档用户体验；‌‌\n\n## 3. Algolia DocSearch\n[Algolia DocSearch](https:\u002F\u002Fdocsearch.algolia.com\u002Fdocs\u002Fwhat-is-docsearch){target=_blank} 是Algolia提供的免费的自动化全文搜索服务，旨在帮助开发者为他们的文档网站提供高效、精确的搜索体验。它通过智能爬虫抓取和索引在线文档，定时爬取指定网站，自动构建搜索索引，并结合Algolia的高性能搜索技术，提供即时的、上下文相关的搜索结果‌。\n\n对于开发者而言，不需要繁琐的配置，只需要申请`Algolia DocSearch`{color=primary}服务的免费计划后，用相关的 API 直接调用服务就行了。目前前端框架都有相对成熟的`Algolia DocSearch API`{color=primary}快速集成的第三方库，使用非常简单。对于使用者，只需要在网站检索框输入关键字，即可快速的搜索相应结果。\n\n\n### 3.1. 功能和特点\n- ‌**智能爬虫‌：** Algolia DocSearch使用定制的爬虫技术，能够深入到网站结构中，有效地抓取和提取文档信息。用户可以通过配置文件指导爬虫的工作，包括要抓取的页面、字段和过滤规则‌.\n- ‌**数据索引‌：** 爬虫抓取的信息会被上传至Algolia的搜索索引，这是一个经过优化的数据存储，适合快速查询。Algolia支持丰富的搜索功能，如拼写纠错、部分匹配和布尔运算等‌.\n- ‌**自定义搜索界面‌：** Algolia提供了JavaScript SDK，允许用户在自己的网站上轻松嵌入搜索框，并自定义搜索结果显示样式和交互体验‌.\n- ‌**持续更新‌：** 配合 GitCode 上的配置仓库，每次更新文档时，DocSearch可以自动或按需重新索引，确保搜索结果始终与最新内容同步‌.\n- **即时性‌：** Algolia搜索引擎设计用于提供毫秒级的响应速度‌.\n- **准确性‌：** 通过深度学习和自然语言处理技术，提高搜索结果的相关度‌.\n- **可定制化‌：** 搜索框和结果展示样式可根据品牌和需求进行个性化定制‌.\n- **自动化‌：** 配置好后，自动化的索引更新减少了手动维护的工作量‌.\n- **社区支持‌：** 配置文件存储在GitCode上，方便分享和协作，同时也便于社区贡献者共同改进‌.\n### 3.2 应用场景\n- **开发文档：** 无论是开源项目的API参考，还是商业产品的用户指南，都能受益于DocSearch提供的强大搜索功能‌.\n- **教育平台‌：** 教学资源的查找可以通过DocSearch变得更简单快捷‌.\n- **博客聚合‌：** 博客聚合站点可以利用此服务提升读者的阅读体验‌.\n- **任何需要高效内部搜索的网站‌：** 无论大小，只要网站有大量文本内容，DocSearch都是理想选择‌.\n\n\n### 3.3 基本原理\nAlgolia服务器会定期抓取我们指定的文档地址中的内容进行分析并建立索引，这样在网站搜索框中输入关键词后，前端会调用 Algolia DocSearch 的接口并显示搜索结果。这些请求、结果显示的相关逻辑都封装好了，我们要做的就是按要求插入代码、配置好网站样式以及搜索框。\n::note\n根据 `Algolia DocSearch` 的官方文档，默认情况下它通常一周爬取一次网站内容，用户也可自行触发爬取.\n::\n\n### 3.4 使用要求\nAlgolia DocSearch 提供的免费服务是需要申请的，当我们的网站满足下列条件时，Algolia 那边的工作人员才会让我们的申请通过：\n1. 我们必须是云文档网站的所有者，网站必须是公开的。\n2. 网站内容必须是开源项目的技术文档或技术博客。\n3. 网站申请服务时必须有完整稳定的设计和内容，即确认网站做好生产准备。\n4. 免费计划限制，仅支持公开可访问的网站（如博客、开源项目文档），需通过简单申请流程获取API密钥。 ‌\n\n## 4. Algolia和DocSearch区别\nAlgolia 是一个‌完整的商业搜索服务平台‌，而 DocSearch 是其旗下专门为‌技术文档场景定制的自动化搜索解决方案‌。两者的核心区别如下：\n| 对比项    | Algolia   | DocSearch                    |\n|---------|-----------|--------------------------|\n| 定位与功能范围  |    通用型搜索引擎服务平台，支持电商、APP、企业数据等多种场景。核心功能为:\u003C\u002Fbr>  1. 分布式架构实现毫秒级响应‌。\u003C\u002Fbr> 2. 智能排序、拼写纠错、同义词处理等算法‌。\u003C\u002Fbr> 3.  开发者可自由定制索引规则和搜索交互‌。    | Algolia 为‌技术文档\u002F博客‌设计的“开箱即用”方案。核心功能为：\u003C\u002Fbr> 1. 自动爬取网站内容并构建索引‌。\u003C\u002Fbr> 2. 提供预设的前端搜索组件(搜索框+结果页)。\u003C\u002Fbr> 3. 仅适用于公开的技术文档类网站‌。 |\n| 数据接入方式  | 1. 需手动上传数据(如通过API或SDK)\u003C\u002Fbr> 2. 使用官方爬虫工具 ‌Algolia Crawler‌ 自定义抓取逻辑‌。    | 1. 完全自动化,提交网站URL后，Algolia ‌自动定期爬取‌(默认每周一次)，可自定义定时任务执行时间。\u003C\u002Fbr>2. 无需手动配置数据管道，适合文档更新频繁的场景‌。 |\n| 成本与适用性 | 1. 免费版限制 10,000 条记录‌。\u003C\u002Fbr> 2. 高阶功能（如个性化排序）需付费‌ | 1. 对技术文档完全免费‌，无记录数量限制‌。\u003C\u002Fbr> 2. 但需通过人工审核(网站需为公开技术内容)。 |\n| 集成复杂度 | 需自主开发，自行配置。\u003Cbr\u002F> 1. 需要自己手动创建应用，认证爬取站点域名。\u003Cbr\u002F> 2. 需要自己手动创建索引名称，自动导入数据。\u003Cbr> 3. 需要自己编写爬虫代码。\u003Cbr\u002F>4. 自己编写前端交互组件‌。 | 极简集成。\u003Cbr> 1. DocSearch免费计划申请通过后，系统自行创建索引名称，认证站点域名，编写爬虫脚本。\u003Cbr\u002F>2. 通过CDN引入CSS\u002FJS文件。\u003Cbr\u002F> 3. 添加预设的搜索框HTML标签即可实现页面检索框弹框效果。 |\n| 搜索体验差异 | 需通过API参数和UI库手动实现同等效果‌。 | 1. 结果页自动高亮标题层级(h1 > h2 > h3)。\u003Cbr\u002F> 2. 针对文档结构优化相关性排序(如优先匹配章节标题)。\u003Cbr\u002F> 3. 内置响应式UI，适配移动端‌。 |\n\n\n## 5. DocSearch使用说明\n### 5.1 申请免费资格\n首先，你需要申请 `Algolia` 免费的 `DocSearch`计划资格。打开 [Algolia DocSearch](https:\u002F\u002Fdocsearch.algolia.com\u002F){target=_blank} 官网，点击 “Apply” 按钮，在表单项中填写你的项目信息，包括文档站的 URL（需包含协议头 https:\u002F\u002F）、邮箱、是否开源等。\n\n![申请表单](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605174653671.webp)\n\n提交表单后，`Algolia` 团队会审核你的申请(工作日一般是当天或者隔天就可申请通过,最迟不超过一周）。如果符合条件，他们会发邮件通知你，切记你需要回复邮件，确认你是网站站长，并且能够修改代码。通过确认后，他们会为你开通免费的 `DocSearch`服务，Algolia DocSearch 会再发一封使用邮件，其中包含`appId`、`apiKey` 和 `indexName`，用于在网站生成框架中配置。若未回复，视为放弃请求。\n\n![申请成功](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605175441185.webp)\n### 5.2 Algolia管理后台\n免费的`Algolia DocSearch`计划申请通过后，我们也可以前往[Algolia](https:\u002F\u002Fdashboard.algolia.com\u002Fusers\u002Fsign_in){target=_blank}管理自己的后台数据，查询对应的`key`信息。`Algolia DocSearch`审核通过后，控制面板中会自动生成申请通过邮件返回的应用名称和应用id，默认索引名称，默认爬取程序。默认索引名称可以删除，系统审核通过时，已对申请域名进行了认证，认证后索引数据才能生效。默认爬取程序无法删除。\n\n1. 进入[控制面板](https:\u002F\u002Fdashboard.algolia.com\u002Fapps\u002FOBYO5BJ5I3\u002Findices)后，点击左上角`Application`，切换申请通过的`DocSearch`应用。通过左侧`search`按钮查看应用索引信息，下方` Go To Crawler`进入爬虫程序页面\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702162222617.webp)\n\n\n2. 索引数据页面\n\n\n点击左侧选项栏里的`Search`进入索引页面，查看对应的`indexName` 数据，如果`Browse`这里没有显示数据，那说明爬取的数据可能有问题，导致没有生成对应的`Records`，那我们就需要排查第三步爬虫程序是否有问题。\n\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702162609300.webp)\n\n\n3. 爬虫程序页面\n\n\n点击控制面板的` Go To Crawler`按钮或者左下方的`Data Source`按钮都可以进入爬虫程序页面。\n\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702164213759.webp)\n\n\n点击索引名称，进入爬虫配置页面\n\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165152222.webp)\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165158121.webp)\n\n\n点击`Editor`进入爬虫程序页面\n\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702165622704.webp)\n\n\n如果爬虫监控台显示成功爬取，也有`Monitoring Success` 的数据，但 `Records` 为 0，那大概是爬虫提取数据的逻辑有问题，查看上图代码，查看具体的爬虫逻辑，查看是否存在错误信息。\n\n\n像`pathsToMatch` 这里是最容易出错的地方，比如: `pathsToMatch` 如果是`https:\u002F\u002Fanyfork.github.io\u002Fblog-docs\u002Fdocs\u002F**`，但你的网址都是`https:\u002F\u002Fanyfork.github.io\u002Fblog-docs\u002F**`开头，那这里大概就是会提取错误，修改一下，然后点击右侧的数据进行测试。\n\n\n一般情况下，基本都是爬虫程序爬取的域名或者路径不对导致爬虫失败，因此需要认真核对一下是否配置正确。\n\n\n\n4. 点击左下角的`setting`查看应用配置信息。\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605190630560.webp)\n\n5. 点击右侧`API Keys`，查看应用的所有key信息，项目中集成会用到几个关键的key。\n\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250605190902912.webp)\n目前项目使用`docSearch`只需要`apiKey`，`applicationId`和`indexName`这3个key。\n\n\n## 6. Nuxt3集成DocSearch\n\n[nuxt\u002Falgolia](https:\u002F\u002Falgolia.nuxtjs.org\u002Fadvanced\u002Fdocsearch\u002F){target=_blank}是专为 Nuxt.js 框架设计的模块，用于简化与 Algolia 搜索引擎的集成。它提供了快速、灵活的搜索功能集成方案，适用于电商网站、博客平台、文档站点等场景，其中提供了在`Nuxt3`项目中使用`DocSearch`的配置教程。大概使用流畅如下：\n\n\n### 6.1 安装依赖\n::code-group\n\n```bash [pnpm]\npnpm add @docsearch\u002Fjs @docsearch\u002Fcss\n```\n\n```bash [yarn]\nyarn add @docsearch\u002Fjs @docsearch\u002Fcss\n```\n\n```bash [npm]\nnpm install @docsearch\u002Fjs @docsearch\u002Fcss\n```\n::\n\n\n### 6.2 安装模块\n将`@nuxtjs\u002Falgolia`{color=primary}安装到`nuxt`的模块中，并配置`DocSearch`申请成功后邮件返回的`apikey`，`appId`和`indexName`这3个key信息。\n```ts[nuxt.config.ts]\nexport default defineNuxtConfig({\n  modules:['@nuxtjs\u002Falgolia']\n  algolia: {\n    apiKey: 'apiKey',\n    applicationId: 'applicationId',\n    \u002F\u002F DocSearch key is used to configure DocSearch extension.\n    docSearch: {\n      indexName: 'indexName',\n    }\n  }  \n})\n```\n### 6.3 使用组件\n将组件`\u003CAlgoliaDocSearch \u002F>`放置在需要展示搜索的地方，页面上就会展示出搜索框，点击弹出一个模态框，输入关键字，即可全局进行文本搜索。\n```vue[index.vue]\n\u003Ctemplate>\n  \u003CAlgoliaDocSearch \u002F>\n\u003C\u002Ftemplate>\n```\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250702182342087.webp)",19.4,{"title":6,"description":995},{"loc":1005,"images":1010},[1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021],{"loc":422},{"loc":449},{"loc":503},{"loc":532},{"loc":553},{"loc":561},{"loc":564},{"loc":575},{"loc":621},{"loc":636},{"loc":966},"blog\u002F1.Algolia DocSearch快速开启网站全文检索功能",[691],[1025],{"name":274,"icon":1026,"symbol":1027,"id":691},"devicon:algolia","algolia","2026-03-11 22:22:52",3488,"nkMbsKJW2vlLELpQgBwRgA5nr7Mv_B9uLj-IijWdPAk",{"id":1032,"title":1033,"articleId":1034,"articleThumb":1035,"body":1036,"categoryId":896,"categoryInfo":6693,"createDate":6697,"description":1044,"excerpt":6698,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":6706,"navigation":1003,"path":6707,"rawbody":6708,"readingTime":6709,"seo":6710,"sitemap":6711,"stem":6712,"tagIds":6713,"tagInfo":6714,"updateDate":6719,"wordCount":6720,"__hash__":6721},"blog\u002Fblog\u002F9.Web Crypto API浏览器原生加密的终极指南.md","Web Crypto API 浏览器原生加密的终极指南","web-crypto-api","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260825111119031.webp",{"type":10,"value":1037,"toc":6669},[1038,1042,1045,1048,1051,1054,1057,1063,1067,1070,1078,1092,1099,1113,1121,1135,1142,1155,1162,1176,1180,1183,1197,1201,1204,1208,1211,1244,1248,1251,1307,1311,1314,1356,1360,1363,1389,1393,1396,1428,1432,1511,1515,1522,1582,1593,1600,1630,1633,1640,1710,1721,1728,1784,1787,1794,1851,1862,1866,1915,1919,1922,1926,1929,1932,1940,2322,2330,2487,2495,2798,2806,3055,3061,3065,3068,3075,3278,3285,3431,3438,3575,3579,3582,3589,3754,3761,3917,3924,4100,4104,4107,4110,4117,4227,4234,4403,4407,4414,4441,4448,4482,4489,4500,4504,4511,4514,4602,4605,4677,4683,4689,4696,4699,4710,4714,4717,4720,6207,6210,6213,6666],[17,1039,1041],{"id":1040},"_1-什么是-web-crypto-api","1. 什么是 Web Crypto API？",[13,1043,1044],{},"Web Crypto API 是浏览器原生提供的一套加密接口，允许 JavaScript 脚本使用密码学原语来构建基于加密的系统。它自 2015 年 7 月起已得到各大浏览器的广泛支持，是一个相当成熟且稳定的 Web 标准。",[13,1046,1047],{},"在 Web Crypto 规范诞生前，部分浏览器为了满足加密需求，在全局实现了一个名为 Crypto 的接口(即 window.crypto)。但正由于这样，当时各大浏览器的实现缺乏统一的 W3C 标准，定义模糊，且在密码学意义上是不够严谨和安全的（not cryptographically sound）。",[13,1049,1050],{},"当正式的 Web Crypto API 标准（支持 encrypt、decrypt、sign、verify 等现代异步加密操作）推出时，为了彻底避免和老旧、不安全的旧接口方法发生命名混淆与冲突，W3C 规范决定将这些低底层的密码学核心方法群全部打包进一个全新的独立接口中，这就是 SubtleCrypto。你可以通过全局对象的 crypto.subtle 属性来访问它。",[13,1052,1053],{},"由于旧的全局 crypto 对象并没有被废除（它依然保留了诸如密码学安全的伪随机数生成器 crypto.getRandomValues() 和 crypto.randomUUID() 等简单的同步方法），因此所有新版的 SubtleCrypto 复杂加密算法全部被挂载到了它的下级属性中。你必须通过 crypto.subtle 属性才能访问到这一整套现代加解密方法。",[13,1055,1056],{},"Node.js 最早在 v15.0.0 引入了 Web Crypto API 接口。直到 Node.js 19.0.0，官方正式去掉了实验性警告，将其标记为 稳定版本（Stable），并且默认在全局作用域挂载了 globalThis.crypto。",[1058,1059,1060],"warning",{},[13,1061,1062],{},"重要提示：在现代浏览器中，为了保障密钥安全，crypto.subtle 属性被限制为只能在安全上下文（HTTPS 协议或 localhost）下才能被成功访问。如果你在普通的非加密 HTTP 网页里调用 crypto.subtle，它会直接返回 undefined。",[17,1064,1066],{"id":1065},"_2-为什么选择-web-crypto-api","2. 为什么选择 Web Crypto API？",[13,1068,1069],{},"在决定是否在 Web 项目中使用 Web Crypto API 时，通常是因为它相比传统的第三方加密库（如 CryptoJS, jsencrypt, forge 等）在安全性、性能和原生支持度上带来了降维打击的优势。",[65,1071,1072],{},[68,1073,1074,1077],{},[71,1075,1076],{},"防 XSS 攻击的“密钥黑盒”机制（核心安全优势）"," : 这是选择Web Crypto API最关键的安全理由。",[128,1079,1080,1086],{},[68,1081,1082,1085],{},[71,1083,1084],{},"传统加密库的痛点："," 如果你用 CryptoJS，密钥必须以明文字符串或 Uint8Array 的形式存在于 JavaScript 变量、localStorage 或 sessionStorage 中。一旦网站遭受 XSS（跨站脚本）攻击，黑客可以直接读取并盗走你的密钥。",[68,1087,1088,1091],{},[71,1089,1090],{},"Web Crypto 的解决办法："," 它引入了 CryptoKey 对象。在生成或导入密钥时，如果设置 extractable: false，这个密钥在创建后将永远无法通过 JavaScript 读取、打印或导出。它被死死封锁在浏览器的底层安全内存中。黑客即使通过 XSS 控制了你的页面，也拿不到密钥本身，只能在本地调用它，大大降低了密钥泄露的风险。",[65,1093,1094],{"start":506},[68,1095,1096],{},[71,1097,1098],{},"硬件级的高性能与非阻塞（异步原生）",[128,1100,1101,1107],{},[68,1102,1103,1106],{},[71,1104,1105],{},"原生 C++ \u002F 汇编实现："," Web Crypto API 是由浏览器底层（基于 OpenSSL 或操作系统自带的密码学库）用原生代码实现的。相比纯 JavaScript 编写的加密库，它的运行速度快了数十倍到上百倍。",[68,1108,1109,1112],{},[71,1110,1111],{},"异步非阻塞："," 传统的加密库（如 CryptoJS）大都是同步执行的。当计算大文件哈希，或者进行复杂的 RSA 大素数生成时，会直接卡死浏览器的 UI 主线程，导致页面瞬间卡顿或未响应。而 Web Crypto 的所有核心方法（如 encrypt、digest）全部是异步 Promise 机制，浏览器会将其交给底层的系统线程去算，完全不影响前端界面的流畅度。",[65,1114,1115],{"start":535},[68,1116,1117,1120],{},[71,1118,1119],{},"密码学安全的伪随机数生成器 (CSPRNG)",": 在密码学中，随机数的质量决定了加密的生死。",[128,1122,1123,1129],{},[68,1124,1125,1128],{},[71,1126,1127],{},"传统的隐患："," JavaScript 原生的 Math.random() 是非密码学安全的，它的随机轨迹可以被算法预测，绝不能用于生成加密密钥、IV（初始化向量）或盐值。",[68,1130,1131,1134],{},[71,1132,1133],{},"Web Crypto 的保障："," 提供了 crypto.getRandomValues()，它直接调用操作系统底层的硬件熵源（如系统的 \u002Fdev\u002Furandom 或 CAPI），生成密码学安全的高强度真随机数，保障加密系统的根基不可被破解。",[65,1136,1137],{"start":609},[68,1138,1139],{},[71,1140,1141],{},"零依赖，极致减小打包体积 (Zero-Bundle)",[128,1143,1144,1149],{},[68,1145,1146,1148],{},[71,1147,1084],{}," 引入 CryptoJS、JSEncrypt 或 Forge 会让前端的 Vendor 打包体积（Bundle Size）平白无故增加几十 KB 甚至几百 KB，影响首屏加载速度。",[68,1150,1151,1154],{},[71,1152,1153],{},"Web Crypto 的优势："," 它是现代浏览器的标准内置 API，不需要 npm install 任何第三方包。直接开箱即用，让前端工程更加轻量、纯净。",[65,1156,1157],{"start":624},[68,1158,1159],{},[71,1160,1161],{},"行业标准规范，跨端兼容性完美",[128,1163,1164,1170],{},[68,1165,1166,1169],{},[71,1167,1168],{},"大厂和 W3C 背书："," 它遵循严格的 W3C 规范，由各大浏览器厂商共同维护和不断优化。",[68,1171,1172,1175],{},[71,1173,1174],{},"环境通用性："," 目前 Web Crypto API 的覆盖率已接近 100%。不仅在 Chrome、Safari、Edge、Firefox 浏览器中完美支持，在现代的 Node.js (v15+)、Deno、Bun 以及 Cloudflare Workers 等服务端\u002F边缘计算环境中也实现了完全一致的 API。这使得你写的一套加解密代码，可以无缝在前端和服务端之间复用。",[17,1177,1179],{"id":1178},"_3-什么时候不应该选择它","3. 什么时候不应该选择它？",[13,1181,1182],{},"使用 Web Crypto API 有唯一的限制条件：",[128,1184,1185,1191],{},[68,1186,1187,1190],{},[71,1188,1189],{},"非安全上下文限制："," 它强制要求 HTTPS 环境（本地开发支持 localhost 或 127.0.0.1）。如果你的网站部署在纯 HTTP 生产环境下，crypto.subtle 会直接返回 undefined 无法工作。",[68,1192,1193,1196],{},[71,1194,1195],{},"需要高层封装："," 它提供的是非常底层的“密码学原语”（Raw Primitives），不提供像“一键生成 JWT”或者“一键做密码信封”这样的高级功能，开发者需要自己处理字节对齐、IV 传递等微秒的细节。",[17,1198,1200],{"id":1199},"_4-web-crypto-api核心接口","4. Web Crypto API核心接口",[13,1202,1203],{},"Web Crypto API（通常称为 crypto.subtle）的核心接口主要由以下 5 个标准接口（Interfaces） 和 1 个全局入口 组成。它们构成了浏览器原生密码学生态的基石。",[123,1205,1207],{"id":1206},"_41-全局入口对象crypto","4.1 全局入口对象Crypto",[13,1209,1210],{},"虽然这不是单独的加解密接口，但它是所有 Web 加密功能的总入口，挂载在全局 window.crypto（或 globalThis.crypto）上。Crypto提供基础的加密功能，主要包括：",[128,1212,1213,1219],{},[68,1214,1215,1218],{},[71,1216,1217],{},"核心作用："," 提供基础的同步安全原语。",[68,1220,1221,1224],{},[71,1222,1223],{},"常用方法：",[128,1225,1226,1232,1238],{},[68,1227,1228,1231],{},[71,1229,1230],{},"crypto.getRandomValues()："," 生成密码学安全的伪随机数（常用于生成 IV 或盐）。",[68,1233,1234,1237],{},[71,1235,1236],{},"crypto.randomUUID()："," 快速生成一个符合 RFC 4122 标准的随机 UUID 字符串。",[68,1239,1240,1243],{},[71,1241,1242],{},"crypto.subtle："," 指向核心异步加密接口 SubtleCrypto 的指针。",[123,1245,1247],{"id":1246},"_42-核心操作员subtlecrypto","4.2  核心操作员SubtleCrypto",[13,1249,1250],{},"这是整个 Web Crypto API 中最重要、最核心的接口。所有的实际异步加解密、签名、密钥派生等操作都在这里执行。SubtleCrypto 提供的主要方法包括：",[128,1252,1253,1258],{},[68,1254,1255,1257],{},[71,1256,1217],{}," 提供一系列底层、底层的异步密码学原语方法（全部返回 Promise）。",[68,1259,1260,1263],{},[71,1261,1262],{},"核心方法（按功能分类）：",[128,1264,1265,1271,1277,1283,1289,1295,1301],{},[68,1266,1267,1270],{},[71,1268,1269],{},"加密与解密："," encrypt() \u002F decrypt()",[68,1272,1273,1276],{},[71,1274,1275],{},"签名与验证："," sign() \u002F verify()",[68,1278,1279,1282],{},[71,1280,1281],{},"哈希计算："," digest()",[68,1284,1285,1288],{},[71,1286,1287],{},"密钥生成："," generateKey()",[68,1290,1291,1294],{},[71,1292,1293],{},"密钥导入与导出："," importKey() \u002F exportKey()",[68,1296,1297,1300],{},[71,1298,1299],{},"密钥包装与解包："," wrapKey() \u002F unwrapKey()",[68,1302,1303,1306],{},[71,1304,1305],{},"密钥派生："," deriveKey() \u002F deriveBits()",[123,1308,1310],{"id":1309},"_43-密钥实体cryptokey","4.3 密钥实体CryptoKey",[13,1312,1313],{},"该接口代表一个在浏览器中生成的、受保护的密钥对象。为了安全，浏览器的 SubtleCrypto 方法不直接操作纯文本的密钥字符串（如 \"my-secret-key\"），而是操作 CryptoKey 实例。",[128,1315,1316,1321],{},[68,1317,1318,1320],{},[71,1319,1217],{}," 作为参数传递给 SubtleCrypto 的各项方法。",[68,1322,1323,1326],{},[71,1324,1325],{},"核心属性（只读）：",[128,1327,1328,1334,1340,1346],{},[68,1329,1330,1333],{},[71,1331,1332],{},"type："," 密钥类型（\"secret\" 对称加密、\"private\" 私钥、\"public\" 公钥）。",[68,1335,1336,1339],{},[71,1337,1338],{},"extractable："," 布尔值。如果为 false，该密钥在创建后绝对无法从内存中被导出或用 JS 打印出来，防止 XSS 攻击窃取密钥。",[68,1341,1342,1345],{},[71,1343,1344],{},"algorithm："," 绑定该密钥的算法对象（例如绑定的 AES-GCM 或 RSA-PSS 等参数）。",[68,1347,1348,1351,1352,1355],{},[71,1349,1350],{},"usages："," 该密钥被允许的用途数组（例如 ",[688,1353,1354],{},"'encrypt', 'decrypt'","）。",[123,1357,1359],{"id":1358},"_44-非对称密钥对cryptokeypair","4.4 非对称密钥对CryptoKeyPair",[13,1361,1362],{},"当使用 RSA、ECDSA 等非对称加密算法时，crypto.subtle.generateKey() 返回的不是单个密钥，而是一个包含公钥和私钥的 CryptoKeyPair 对象。",[128,1364,1365,1370],{},[68,1366,1367,1369],{},[71,1368,1217],{}," 容器对象，封装非对称密钥对。",[68,1371,1372,1375],{},[71,1373,1374],{},"核心属性：",[128,1376,1377,1383],{},[68,1378,1379,1382],{},[71,1380,1381],{},"publicKey："," 一个 CryptoKey 实例，代表公钥（用于加密或验证签名）。",[68,1384,1385,1388],{},[71,1386,1387],{},"privateKey："," 一个 CryptoKey 实例，代表私钥（用于解密或生成签名）。",[123,1390,1392],{"id":1391},"_45-算法配置对象algorithmidentifier","4.5 算法配置对象AlgorithmIdentifier",[13,1394,1395],{},"虽然它在技术上是一个规范定义的字典对象（Dictionary），而不是传统的类或接口，但它是每个 API 都必传的灵魂参数。",[128,1397,1398,1403],{},[68,1399,1400,1402],{},[71,1401,1217],{}," 用来指定具体的密码学算法名称以及其特有的初始化附加参数（如 IV、盐值、计数器等）。",[68,1404,1405,1408],{},[71,1406,1407],{},"常见表现形式：",[128,1409,1410,1416,1422],{},[68,1411,1412,1415],{},[71,1413,1414],{},"哈希配置："," { name: \"SHA-256\" }",[68,1417,1418,1421],{},[71,1419,1420],{},"AES-GCM 配置："," { name: \"AES-GCM\", iv: Uint8Array, tagLength: 128 }",[68,1423,1424,1427],{},[71,1425,1426],{},"PBKDF2（密码派生）配置："," { name: \"PBKDF2\", salt: Uint8Array, iterations: 100000, hash: \"SHA-256\" }",[123,1429,1431],{"id":1430},"_46-核心接口对比速查表","4.6 核心接口对比速查表",[260,1433,1434,1450],{},[263,1435,1436],{},[266,1437,1438,1441,1444,1447],{},[269,1439,1440],{},"接口名称",[269,1442,1443],{},"角色定位",[269,1445,1446],{},"非安全上下文（HTTP）使用规则",[269,1448,1449],{},"典型返回值 \u002F 用途",[278,1451,1452,1466,1484,1498],{},[266,1453,1454,1457,1460,1463],{},[283,1455,1456],{},"Crypto",[283,1458,1459],{},"全局大管家",[283,1461,1462],{},"是（部分方法受限）",[283,1464,1465],{},"提供crypto.subtle入口、用于生成UUID",[266,1467,1468,1471,1474,1477],{},[283,1469,1470],{},"SubtleCrypto",[283,1472,1473],{},"核心工具库",[283,1475,1476],{},"否（必须在HTTPS\u002Flocalhost环境下使用）",[283,1478,1479,1480,1483],{},"返回",[42,1481,1482],{},"Promise\u003CArrayBuffer>","，用于生成密文、哈希等加密核心操作",[266,1485,1486,1489,1492,1495],{},[283,1487,1488],{},"CryptoKey",[283,1490,1491],{},"密钥黑盒",[283,1493,1494],{},"否",[283,1496,1497],{},"作为安全载体，直接传递给加解密函数使用",[266,1499,1500,1503,1506,1508],{},[283,1501,1502],{},"CryptoKeyPair",[283,1504,1505],{},"密钥对容器",[283,1507,1494],{},[283,1509,1510],{},"封装返回包含publicKey和privateKey的密钥对对象",[17,1512,1514],{"id":1513},"_5-web-crypto-api支持的主流算法","5. Web Crypto API支持的主流算法",[65,1516,1517],{},[68,1518,1519],{},[71,1520,1521],{},"对称加密（Symmetric）表",[260,1523,1524,1540],{},[263,1525,1526],{},[266,1527,1528,1531,1534,1537],{},[269,1529,1530],{},"算法标识符",[269,1532,1533],{},"支持的操作",[269,1535,1536],{},"推荐搭配与技术参数",[269,1538,1539],{},"典型应用场景",[278,1541,1542,1556,1569],{},[266,1543,1544,1547,1550,1553],{},[283,1545,1546],{},"AES-GCM（强烈推荐）",[283,1548,1549],{},"encrypt、decrypt、generateKey、importKey、exportKey、wrapKey、unwrapKey",[283,1551,1552],{},"密钥支持128\u002F192\u002F256位，IV推荐96位（12字节）",[283,1554,1555],{},"传输数据加解密、本地缓存加密，自带防篡改认证标签",[266,1557,1558,1561,1563,1566],{},[283,1559,1560],{},"AES-CBC",[283,1562,1549],{},[283,1564,1565],{},"密钥支持128\u002F192\u002F256位，IV固定128位（16字节）",[283,1567,1568],{},"兼容老旧遗留系统的对称加解密业务",[266,1570,1571,1574,1576,1579],{},[283,1572,1573],{},"AES-CTR",[283,1575,1549],{},[283,1577,1578],{},"计数器模式，支持流式处理",[283,1580,1581],{},"高频非对齐的流式数据区块加解密",[128,1583,1584,1587,1590],{},[68,1585,1586],{},"AES-GCM 是当前Web场景下的首选方案，硬件加速支持度高，同时自带消息认证能力，无需额外实现哈希校验逻辑，安全性和开发效率都更优。",[68,1588,1589],{},"不同算法的IV长度要求严格，比如AES-CBC必须使用固定16字节的IV，否则会直接触发解密失败。",[68,1591,1592],{},"三款算法都完整覆盖了密钥生成、导入导出、包裹\u002F解包裹密钥的全流程操作，完全适配Web Crypto的全场景开发需求。",[65,1594,1595],{"start":506},[68,1596,1597],{},[71,1598,1599],{},"非对称加密算法（Asymmetric）表",[260,1601,1602,1614],{},[263,1603,1604],{},[266,1605,1606,1608,1610,1612],{},[269,1607,1530],{},[269,1609,1533],{},[269,1611,1536],{},[269,1613,1539],{},[278,1615,1616],{},[266,1617,1618,1621,1624,1627],{},[283,1619,1620],{},"RSA-OAEP（强烈推荐）",[283,1622,1623],{},"encrypt, decrypt, generateKey, importKey, exportKey, wrapKey, unwrapKey",[283,1625,1626],{},"模数：2048, 4096 位哈希：推荐 SHA-256",[283,1628,1629],{},"混合加密体系中用于加密“对称密钥”，或加密超短敏感字段",[13,1631,1632],{},"RSA-OAEP是Web场景下非对称加密的首选方案，它通过最优非对称加密填充机制，解决了传统“教科书RSA”的密文可延展性安全缺陷，在随机预言模型下可以抵御适应性选择密文攻击。由于非对称加密的特性，它不适合直接加密大体积数据，行业通用的最佳实践就是用它加密AES等对称密钥，再用对称算法加密实际业务数据，兼顾安全性和性能效率。",[65,1634,1635],{"start":535},[68,1636,1637],{},[71,1638,1639],{},"数字签名算法（Signature）表",[260,1641,1642,1655],{},[263,1643,1644],{},[266,1645,1646,1649,1651,1653],{},[269,1647,1648],{},"算法名称",[269,1650,1533],{},[269,1652,1536],{},[269,1654,1539],{},[278,1656,1657,1671,1684,1697],{},[266,1658,1659,1662,1665,1668],{},[283,1660,1661],{},"ECDSA（强烈推荐）",[283,1663,1664],{},"sign、verify、generateKey、importKey、exportKey",[283,1666,1667],{},"椭圆曲线：P-256、P-384、P-521",[283,1669,1670],{},"现代高并发身份验签、JWT签名、区块链节点验签",[266,1672,1673,1676,1678,1681],{},[283,1674,1675],{},"RSASSA-PKCS1-v1_5",[283,1677,1664],{},[283,1679,1680],{},"模数≥2048位，哈希推荐SHA-256",[283,1682,1683],{},"传统企业级API签名、老旧版本JWT签名验签",[266,1685,1686,1689,1691,1694],{},[283,1687,1688],{},"RSA-PSS",[283,1690,1664],{},[283,1692,1693],{},"RSA概率签名方案，密码学严谨度极高",[283,1695,1696],{},"金融级或司法级等高安全要求的数字签名场景",[266,1698,1699,1702,1704,1707],{},[283,1700,1701],{},"HMAC",[283,1703,1664],{},[283,1705,1706],{},"基于哈希的密钥消息认证码",[283,1708,1709],{},"前后端API请求防篡改哈希签名，如AWS签名机制",[128,1711,1712,1715,1718],{},[68,1713,1714],{},"ECDSA 是Web场景下的首选签名方案，密钥体积小、验签速度快，非常适配高并发的现代Web服务。",[68,1716,1717],{},"RSA系列算法兼容性极强，适合需要对接老旧系统的业务场景，其中RSA-PSS的抗攻击能力远高于传统的RSASSA-PKCS1-v1_5。",[68,1719,1720],{},"HMAC实现成本低，是轻量API防篡改签名的最优选择。",[65,1722,1723],{"start":609},[68,1724,1725],{},[71,1726,1727],{},"单向哈希算法（Digest）表",[260,1729,1730,1742],{},[263,1731,1732],{},[266,1733,1734,1736,1738,1740],{},[269,1735,1648],{},[269,1737,1533],{},[269,1739,1536],{},[269,1741,1539],{},[278,1743,1744,1758,1771],{},[266,1745,1746,1749,1752,1755],{},[283,1747,1748],{},"SHA-256",[283,1750,1751],{},"digest",[283,1753,1754],{},"无需密钥，单向不可逆",[283,1756,1757],{},"文件完整性校验（秒传场景）、数据防篡改指纹生成",[266,1759,1760,1763,1765,1768],{},[283,1761,1762],{},"SHA-384",[283,1764,1751],{},[283,1766,1767],{},"无需密钥，单向不可逆，安全强度高于SHA-256",[283,1769,1770],{},"高敏感数据校验、金融级业务的完整性验证",[266,1772,1773,1776,1778,1781],{},[283,1774,1775],{},"SHA-512",[283,1777,1751],{},[283,1779,1780],{},"无需密钥，单向不可逆，安全强度最高",[283,1782,1783],{},"司法级、军工级等高安全要求场景的哈希校验",[13,1785,1786],{},"这三款同属SHA-2家族哈希算法，都具备单向不可逆的核心特性，无法从最终哈希值反推原始输入内容，仅用于生成数据唯一指纹，不能直接用于加解密还原原始数据。安全强度随输出位数提升而升高，同时计算性能也会小幅下降，普通业务场景优先选择SHA-256即可满足需求。",[65,1788,1789],{"start":624},[68,1790,1791],{},[71,1792,1793],{},"密钥派生算法（Key Derivation）表",[260,1795,1796,1808],{},[263,1797,1798],{},[266,1799,1800,1802,1804,1806],{},[269,1801,1648],{},[269,1803,1533],{},[269,1805,1536],{},[269,1807,1539],{},[278,1809,1810,1824,1838],{},[266,1811,1812,1815,1818,1821],{},[283,1813,1814],{},"ECDH",[283,1816,1817],{},"deriveKey、deriveBits、generateKey、importKey、exportKey",[283,1819,1820],{},"椭圆曲线：Diffie-Hellman",[283,1822,1823],{},"两个终端在不安全信道中，安全地协商出一致的对称密钥",[266,1825,1826,1829,1832,1835],{},[283,1827,1828],{},"PBKDF2",[283,1830,1831],{},"deriveKey、deriveBits、importKey",[283,1833,1834],{},"基于密码的密钥派生，推荐迭代≥100000次",[283,1836,1837],{},"将用户输入的简短文明密码，转换为符合AES标准的高强度密钥",[266,1839,1840,1843,1845,1848],{},[283,1841,1842],{},"HKDF",[283,1844,1831],{},[283,1846,1847],{},"基于HMAC的密钥扩展算法",[283,1849,1850],{},"从一个基础主密钥，安全地扩展派生出多个子密钥",[128,1852,1853,1856,1859],{},[68,1854,1855],{},"ECDH 是现代网络通信中密钥协商的核心方案，双方全程不需要直接传输最终的共享密钥，仅通过交换椭圆曲线公钥就能各自计算出完全一致的会话密钥，安全性极高。",[68,1857,1858],{},"PBKDF2 专门针对低熵的用户密码设计，通过高迭代次数大幅提升暴力破解的成本，是密码类密钥衍生的行业标准方案。",[68,1860,1861],{},"HKDF 面向已经具备高熵的主密钥材料，能高效地将单个主密钥拆分扩展为多个用途独立的子密钥，广泛应用于TLS等现代加密协议中。",[17,1863,1865],{"id":1864},"_6-web-crypto-api-不支持的主流算法","6. Web Crypto API 不支持的主流算法",[260,1867,1868,1880],{},[263,1869,1870],{},[266,1871,1872,1874,1877],{},[269,1873,1648],{},[269,1875,1876],{},"不支持原因",[269,1878,1879],{},"替代实现方案",[278,1881,1882,1893,1904],{},[266,1883,1884,1887,1890],{},[283,1885,1886],{},"MD5",[283,1888,1889],{},"已被密码学界证实存在碰撞漏洞，安全性完全失效",[283,1891,1892],{},"引入crypto-js等第三方库实现或使用 SHA-256",[266,1894,1895,1898,1901],{},[283,1896,1897],{},"SM2\u002FSM3\u002FSM4国密系列",[283,1899,1900],{},"浏览器国际标准未原生内置国密算法",[283,1902,1903],{},"引入sm-crypto等国密第三方库实现",[266,1905,1906,1909,1912],{},[283,1907,1908],{},"ChaCha20-Poly1305\u002FEd25519",[283,1910,1911],{},"目前尚未完全普及到所有主流浏览器的 crypto.subtle 中",[283,1913,1914],{},"引入第三方加密库补充实现",[17,1916,1918],{"id":1917},"_7-常用操作示例","7. 常用操作示例",[13,1920,1921],{},"以下是整理的 Web Crypto API (crypto.subtle) 最核心、最常用的四大标准代码示例（哈希生成、密钥生成、加密、解密）。需要特别提醒的是：所有 crypto.subtle 的操作都是异步的，都会返回一个 Promise，因此必须配合 async\u002Fawait 使用。",[123,1923,1925],{"id":1924},"_71-对称加密aes-gcm示例","7.1 对称加密AES-GCM示例",[13,1927,1928],{},"AES-GCM (Galois\u002FCounter Mode) 是一种非常流行且强大的认证加密（AEAD, Authenticated Encryption with Associated Data） 模式。你可以把它理解为一种“二合一”的加密模式：它在高效加密数据的同时，还能确保数据没有被篡改。",[13,1930,1931],{},"AES-GCM 是兼具高性能和高安全性的认证加密模式，特别适合在 Web Crypto API 这类原生环境中使用。它的安全性高度依赖于每次加密都使用唯一且不可预测的 IV。遵循这一核心原则，并妥善管理密钥、认真验证认证标签，就能为你的 Web 应用构建起一道坚实的数据安全防线。",[65,1933,1934],{},[68,1935,1936,1939],{},[71,1937,1938],{},"计算文本哈希摘要 (Digest)","：这是最简单的操作，常用于生成文件的 SHA-256。它不需要密钥。",[679,1941,1945],{"className":1942,"code":1943,"language":1944,"meta":502,"style":502},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F**\n * 计算字符串的 SHA-256 哈希值\n * @param {string} text - 输入的文本\n * @returns {Promise\u003Cstring>} Hex 格式的哈希字符串\n *\u002F\nasync function generateHash(text) {\n    \u002F\u002F 1. 将文本编码为 Uint8Array 字节流\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    \u002F\u002F 2. 使用 crypto.subtle.digest 生成哈希（返回 ArrayBuffer）\n    const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\n    \u002F\u002F 3. 将 ArrayBuffer 转换为常见的十六进制 (Hex) 字符串\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\n    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n    \n    return hashHex;\n}\n\n\u002F\u002F 使用示例：\nconst sha256Result = await generateHash(\"Hello World\");\n","js",[42,1946,1947,1952,1957,1985,2004,2009,2031,2036,2059,2084,2089,2094,2136,2141,2147,2183,2259,2265,2275,2281,2286,2292],{"__ignoreMap":502},[688,1948,1949],{"class":690,"line":691},[688,1950,1951],{"class":859},"\u002F**\n",[688,1953,1954],{"class":690,"line":506},[688,1955,1956],{"class":859}," * 计算字符串的 SHA-256 哈希值\n",[688,1958,1959,1962,1965,1969,1972,1976,1978,1982],{"class":690,"line":535},[688,1960,1961],{"class":859}," * ",[688,1963,1964],{"class":776},"@",[688,1966,1968],{"class":1967},"s6hCs","param",[688,1970,1971],{"class":776}," {",[688,1973,1975],{"class":1974},"sFweD","string",[688,1977,908],{"class":776},[688,1979,1981],{"class":1980},"sHdIc"," text",[688,1983,1984],{"class":859}," - 输入的文本\n",[688,1986,1987,1989,1991,1994,1996,1999,2001],{"class":690,"line":609},[688,1988,1961],{"class":859},[688,1990,1964],{"class":776},[688,1992,1993],{"class":1967},"returns",[688,1995,1971],{"class":776},[688,1997,1998],{"class":1974},"Promise\u003Cstring>",[688,2000,908],{"class":776},[688,2002,2003],{"class":859}," Hex 格式的哈希字符串\n",[688,2005,2006],{"class":690,"line":624},[688,2007,2008],{"class":859}," *\u002F\n",[688,2010,2011,2015,2018,2021,2023,2026,2029],{"class":690,"line":856},[688,2012,2014],{"class":2013},"spNyl","async",[688,2016,2017],{"class":2013}," function",[688,2019,2020],{"class":783}," generateHash",[688,2022,788],{"class":791},[688,2024,2025],{"class":1980},"text",[688,2027,2028],{"class":791},")",[688,2030,871],{"class":791},[688,2032,2033],{"class":690,"line":863},[688,2034,2035],{"class":859},"    \u002F\u002F 1. 将文本编码为 Uint8Array 字节流\n",[688,2037,2038,2041,2044,2047,2050,2053,2056],{"class":690,"line":874},[688,2039,2040],{"class":2013},"    const",[688,2042,2043],{"class":787}," encoder",[688,2045,2046],{"class":791}," =",[688,2048,2049],{"class":791}," new",[688,2051,2052],{"class":783}," TextEncoder",[688,2054,2055],{"class":797},"()",[688,2057,2058],{"class":791},";\n",[688,2060,2061,2063,2066,2068,2070,2073,2076,2078,2080,2082],{"class":690,"line":890},[688,2062,2040],{"class":2013},[688,2064,2065],{"class":787}," data",[688,2067,2046],{"class":791},[688,2069,2043],{"class":787},[688,2071,2072],{"class":791},".",[688,2074,2075],{"class":783},"encode",[688,2077,788],{"class":797},[688,2079,2025],{"class":787},[688,2081,2028],{"class":797},[688,2083,2058],{"class":791},[688,2085,2086],{"class":690,"line":896},[688,2087,2088],{"emptyLinePlaceholder":1003},"\n",[688,2090,2091],{"class":690,"line":905},[688,2092,2093],{"class":859},"    \u002F\u002F 2. 使用 crypto.subtle.digest 生成哈希（返回 ArrayBuffer）\n",[688,2095,2097,2099,2102,2104,2107,2110,2112,2115,2117,2119,2121,2123,2125,2127,2130,2132,2134],{"class":690,"line":2096},12,[688,2098,2040],{"class":2013},[688,2100,2101],{"class":787}," hashBuffer",[688,2103,2046],{"class":791},[688,2105,2106],{"class":776}," await",[688,2108,2109],{"class":787}," crypto",[688,2111,2072],{"class":791},[688,2113,2114],{"class":787},"subtle",[688,2116,2072],{"class":791},[688,2118,1751],{"class":783},[688,2120,788],{"class":797},[688,2122,807],{"class":791},[688,2124,1748],{"class":697},[688,2126,807],{"class":791},[688,2128,2129],{"class":791},",",[688,2131,2065],{"class":787},[688,2133,2028],{"class":797},[688,2135,2058],{"class":791},[688,2137,2139],{"class":690,"line":2138},13,[688,2140,2088],{"emptyLinePlaceholder":1003},[688,2142,2144],{"class":690,"line":2143},14,[688,2145,2146],{"class":859},"    \u002F\u002F 3. 将 ArrayBuffer 转换为常见的十六进制 (Hex) 字符串\n",[688,2148,2150,2152,2155,2157,2160,2162,2165,2167,2170,2173,2175,2178,2181],{"class":690,"line":2149},15,[688,2151,2040],{"class":2013},[688,2153,2154],{"class":787}," hashArray",[688,2156,2046],{"class":791},[688,2158,2159],{"class":787}," Array",[688,2161,2072],{"class":791},[688,2163,2164],{"class":783},"from",[688,2166,788],{"class":797},[688,2168,2169],{"class":791},"new",[688,2171,2172],{"class":783}," Uint8Array",[688,2174,788],{"class":797},[688,2176,2177],{"class":787},"hashBuffer",[688,2179,2180],{"class":797},"))",[688,2182,2058],{"class":791},[688,2184,2186,2188,2191,2193,2195,2197,2200,2202,2205,2208,2211,2213,2216,2218,2222,2224,2226,2229,2231,2234,2236,2238,2241,2243,2245,2247,2250,2252,2255,2257],{"class":690,"line":2185},16,[688,2187,2040],{"class":2013},[688,2189,2190],{"class":787}," hashHex",[688,2192,2046],{"class":791},[688,2194,2154],{"class":787},[688,2196,2072],{"class":791},[688,2198,2199],{"class":783},"map",[688,2201,788],{"class":797},[688,2203,2204],{"class":1980},"b",[688,2206,2207],{"class":2013}," =>",[688,2209,2210],{"class":787}," b",[688,2212,2072],{"class":791},[688,2214,2215],{"class":783},"toString",[688,2217,788],{"class":797},[688,2219,2221],{"class":2220},"sbssI","16",[688,2223,2028],{"class":797},[688,2225,2072],{"class":791},[688,2227,2228],{"class":783},"padStart",[688,2230,788],{"class":797},[688,2232,2233],{"class":2220},"2",[688,2235,2129],{"class":791},[688,2237,831],{"class":791},[688,2239,2240],{"class":697},"0",[688,2242,807],{"class":791},[688,2244,2180],{"class":797},[688,2246,2072],{"class":791},[688,2248,2249],{"class":783},"join",[688,2251,788],{"class":797},[688,2253,2254],{"class":791},"''",[688,2256,2028],{"class":797},[688,2258,2058],{"class":791},[688,2260,2262],{"class":690,"line":2261},17,[688,2263,2264],{"class":797},"    \n",[688,2266,2268,2271,2273],{"class":690,"line":2267},18,[688,2269,2270],{"class":776},"    return",[688,2272,2190],{"class":787},[688,2274,2058],{"class":791},[688,2276,2278],{"class":690,"line":2277},19,[688,2279,2280],{"class":791},"}\n",[688,2282,2284],{"class":690,"line":2283},20,[688,2285,2088],{"emptyLinePlaceholder":1003},[688,2287,2289],{"class":690,"line":2288},21,[688,2290,2291],{"class":859},"\u002F\u002F 使用示例：\n",[688,2293,2295,2298,2301,2304,2306,2308,2310,2313,2316,2318,2320],{"class":690,"line":2294},22,[688,2296,2297],{"class":2013},"const",[688,2299,2300],{"class":787}," sha256Result ",[688,2302,2303],{"class":791},"=",[688,2305,2106],{"class":776},[688,2307,2020],{"class":783},[688,2309,788],{"class":787},[688,2311,2312],{"class":791},"\"",[688,2314,2315],{"class":697},"Hello World",[688,2317,2312],{"class":791},[688,2319,2028],{"class":787},[688,2321,2058],{"class":791},[65,2323,2324],{"start":506},[68,2325,2326,2329],{},[71,2327,2328],{},"生成对称加密密钥 (Generate Key)","：在加密数据之前，必须先通过 subtle 算法生成一个标准的加密密钥对象（CryptoKey）。这里以主流的 AES-GCM 算法为例：",[679,2331,2333],{"className":1942,"code":2332,"language":1944,"meta":502,"style":502},"\u002F**\n * 生成一个用于 AES-GCM 加密的 256 位随机密钥\n * @returns {Promise\u003CCryptoKey>} 返回 CryptoKey 对象\n *\u002F\nasync function generateAESKey() {\n    return await crypto.subtle.generateKey(\n        {\n        name: 'AES-GCM',\n        length: 256 \u002F\u002F 密钥长度支持 128, 192, 或 256 位\n        },\n        false, \u002F\u002F 是否允许该密钥被导出（如果设为 false，密钥无法脱离当前浏览器，安全性极高）\n        ['encrypt', 'decrypt'] \u002F\u002F 该密钥被允许用来做什么操作\n    );\n}\n\n",[42,2334,2335,2339,2344,2362,2366,2379,2399,2404,2420,2433,2438,2449,2476,2483],{"__ignoreMap":502},[688,2336,2337],{"class":690,"line":691},[688,2338,1951],{"class":859},[688,2340,2341],{"class":690,"line":506},[688,2342,2343],{"class":859}," * 生成一个用于 AES-GCM 加密的 256 位随机密钥\n",[688,2345,2346,2348,2350,2352,2354,2357,2359],{"class":690,"line":535},[688,2347,1961],{"class":859},[688,2349,1964],{"class":776},[688,2351,1993],{"class":1967},[688,2353,1971],{"class":776},[688,2355,2356],{"class":1974},"Promise\u003CCryptoKey>",[688,2358,908],{"class":776},[688,2360,2361],{"class":859}," 返回 CryptoKey 对象\n",[688,2363,2364],{"class":690,"line":609},[688,2365,2008],{"class":859},[688,2367,2368,2370,2372,2375,2377],{"class":690,"line":624},[688,2369,2014],{"class":2013},[688,2371,2017],{"class":2013},[688,2373,2374],{"class":783}," generateAESKey",[688,2376,2055],{"class":791},[688,2378,871],{"class":791},[688,2380,2381,2383,2385,2387,2389,2391,2393,2396],{"class":690,"line":856},[688,2382,2270],{"class":776},[688,2384,2106],{"class":776},[688,2386,2109],{"class":787},[688,2388,2072],{"class":791},[688,2390,2114],{"class":787},[688,2392,2072],{"class":791},[688,2394,2395],{"class":783},"generateKey",[688,2397,2398],{"class":797},"(\n",[688,2400,2401],{"class":690,"line":863},[688,2402,2403],{"class":791},"        {\n",[688,2405,2406,2409,2411,2413,2416,2418],{"class":690,"line":874},[688,2407,2408],{"class":797},"        name",[688,2410,801],{"class":791},[688,2412,831],{"class":791},[688,2414,2415],{"class":697},"AES-GCM",[688,2417,807],{"class":791},[688,2419,838],{"class":791},[688,2421,2422,2425,2427,2430],{"class":690,"line":890},[688,2423,2424],{"class":797},"        length",[688,2426,801],{"class":791},[688,2428,2429],{"class":2220}," 256",[688,2431,2432],{"class":859}," \u002F\u002F 密钥长度支持 128, 192, 或 256 位\n",[688,2434,2435],{"class":690,"line":896},[688,2436,2437],{"class":791},"        },\n",[688,2439,2440,2444,2446],{"class":690,"line":905},[688,2441,2443],{"class":2442},"sfNiH","        false",[688,2445,2129],{"class":791},[688,2447,2448],{"class":859}," \u002F\u002F 是否允许该密钥被导出（如果设为 false，密钥无法脱离当前浏览器，安全性极高）\n",[688,2450,2451,2454,2456,2459,2461,2463,2465,2468,2470,2473],{"class":690,"line":2096},[688,2452,2453],{"class":797},"        [",[688,2455,807],{"class":791},[688,2457,2458],{"class":697},"encrypt",[688,2460,807],{"class":791},[688,2462,2129],{"class":791},[688,2464,831],{"class":791},[688,2466,2467],{"class":697},"decrypt",[688,2469,807],{"class":791},[688,2471,2472],{"class":797},"] ",[688,2474,2475],{"class":859},"\u002F\u002F 该密钥被允许用来做什么操作\n",[688,2477,2478,2481],{"class":690,"line":2138},[688,2479,2480],{"class":797},"    )",[688,2482,2058],{"class":791},[688,2484,2485],{"class":690,"line":2143},[688,2486,2280],{"class":791},[65,2488,2489],{"start":535},[68,2490,2491,2494],{},[71,2492,2493],{},"数据加密 Encrypt","：使用生成的密钥和 AES-GCM 算法对敏感文本进行加密。为了安全，AES-GCM 要求每次加密必须配合一个随机的初始化向量 (IV)。",[679,2496,2498],{"className":1942,"code":2497,"language":1944,"meta":502,"style":502},"\u002F**\n * 对文本进行 AES-GCM 加密\n * @param {string} text - 待加密的明文\n * @param {CryptoKey} key - 上一步生成的 CryptoKey 对象\n * @returns {Promise\u003C{cipherText: ArrayBuffer, iv: Uint8Array}>} 返回密文和IV\n *\u002F\nasync function encryptText(text, key) {\n    const encoder = new TextEncoder();\n    const encodedText = encoder.encode(text);\n\n    \u002F\u002F AES-GCM 推荐使用 12位（96位）的高安全伪随机数作为 IV\n    \u002F\u002F 注意：这里使用的是外部同步方法 getRandomValues 生成随机数\n    const iv = crypto.getRandomValues(new Uint8Array(12));\n\n    \u002F\u002F 执行加密\n    const cipherText = await crypto.subtle.encrypt(\n        {\n        name: 'AES-GCM',\n        iv: iv \u002F\u002F 加密参数必须包含 IV\n        },\n        key, \u002F\u002F 密钥\n        encodedText \u002F\u002F 明文数据\n    );\n\n    \u002F\u002F 需要同时把密文和 IV 返回，因为解密时必须提供一模一样的 IV\n    return { cipherText, iv };\n}\n\n",[42,2499,2500,2504,2509,2528,2548,2566,2570,2591,2607,2630,2634,2639,2644,2675,2679,2684,2707,2711,2725,2737,2741,2751,2759,2766,2771,2777,2793],{"__ignoreMap":502},[688,2501,2502],{"class":690,"line":691},[688,2503,1951],{"class":859},[688,2505,2506],{"class":690,"line":506},[688,2507,2508],{"class":859}," * 对文本进行 AES-GCM 加密\n",[688,2510,2511,2513,2515,2517,2519,2521,2523,2525],{"class":690,"line":535},[688,2512,1961],{"class":859},[688,2514,1964],{"class":776},[688,2516,1968],{"class":1967},[688,2518,1971],{"class":776},[688,2520,1975],{"class":1974},[688,2522,908],{"class":776},[688,2524,1981],{"class":1980},[688,2526,2527],{"class":859}," - 待加密的明文\n",[688,2529,2530,2532,2534,2536,2538,2540,2542,2545],{"class":690,"line":609},[688,2531,1961],{"class":859},[688,2533,1964],{"class":776},[688,2535,1968],{"class":1967},[688,2537,1971],{"class":776},[688,2539,1488],{"class":1974},[688,2541,908],{"class":776},[688,2543,2544],{"class":1980}," key",[688,2546,2547],{"class":859}," - 上一步生成的 CryptoKey 对象\n",[688,2549,2550,2552,2554,2556,2558,2561,2563],{"class":690,"line":624},[688,2551,1961],{"class":859},[688,2553,1964],{"class":776},[688,2555,1993],{"class":1967},[688,2557,1971],{"class":776},[688,2559,2560],{"class":1974},"Promise\u003C{cipherText: ArrayBuffer, iv: Uint8Array}>",[688,2562,908],{"class":776},[688,2564,2565],{"class":859}," 返回密文和IV\n",[688,2567,2568],{"class":690,"line":856},[688,2569,2008],{"class":859},[688,2571,2572,2574,2576,2579,2581,2583,2585,2587,2589],{"class":690,"line":863},[688,2573,2014],{"class":2013},[688,2575,2017],{"class":2013},[688,2577,2578],{"class":783}," encryptText",[688,2580,788],{"class":791},[688,2582,2025],{"class":1980},[688,2584,2129],{"class":791},[688,2586,2544],{"class":1980},[688,2588,2028],{"class":791},[688,2590,871],{"class":791},[688,2592,2593,2595,2597,2599,2601,2603,2605],{"class":690,"line":874},[688,2594,2040],{"class":2013},[688,2596,2043],{"class":787},[688,2598,2046],{"class":791},[688,2600,2049],{"class":791},[688,2602,2052],{"class":783},[688,2604,2055],{"class":797},[688,2606,2058],{"class":791},[688,2608,2609,2611,2614,2616,2618,2620,2622,2624,2626,2628],{"class":690,"line":890},[688,2610,2040],{"class":2013},[688,2612,2613],{"class":787}," encodedText",[688,2615,2046],{"class":791},[688,2617,2043],{"class":787},[688,2619,2072],{"class":791},[688,2621,2075],{"class":783},[688,2623,788],{"class":797},[688,2625,2025],{"class":787},[688,2627,2028],{"class":797},[688,2629,2058],{"class":791},[688,2631,2632],{"class":690,"line":896},[688,2633,2088],{"emptyLinePlaceholder":1003},[688,2635,2636],{"class":690,"line":905},[688,2637,2638],{"class":859},"    \u002F\u002F AES-GCM 推荐使用 12位（96位）的高安全伪随机数作为 IV\n",[688,2640,2641],{"class":690,"line":2096},[688,2642,2643],{"class":859},"    \u002F\u002F 注意：这里使用的是外部同步方法 getRandomValues 生成随机数\n",[688,2645,2646,2648,2651,2653,2655,2657,2660,2662,2664,2666,2668,2671,2673],{"class":690,"line":2138},[688,2647,2040],{"class":2013},[688,2649,2650],{"class":787}," iv",[688,2652,2046],{"class":791},[688,2654,2109],{"class":787},[688,2656,2072],{"class":791},[688,2658,2659],{"class":783},"getRandomValues",[688,2661,788],{"class":797},[688,2663,2169],{"class":791},[688,2665,2172],{"class":783},[688,2667,788],{"class":797},[688,2669,2670],{"class":2220},"12",[688,2672,2180],{"class":797},[688,2674,2058],{"class":791},[688,2676,2677],{"class":690,"line":2143},[688,2678,2088],{"emptyLinePlaceholder":1003},[688,2680,2681],{"class":690,"line":2149},[688,2682,2683],{"class":859},"    \u002F\u002F 执行加密\n",[688,2685,2686,2688,2691,2693,2695,2697,2699,2701,2703,2705],{"class":690,"line":2185},[688,2687,2040],{"class":2013},[688,2689,2690],{"class":787}," cipherText",[688,2692,2046],{"class":791},[688,2694,2106],{"class":776},[688,2696,2109],{"class":787},[688,2698,2072],{"class":791},[688,2700,2114],{"class":787},[688,2702,2072],{"class":791},[688,2704,2458],{"class":783},[688,2706,2398],{"class":797},[688,2708,2709],{"class":690,"line":2261},[688,2710,2403],{"class":791},[688,2712,2713,2715,2717,2719,2721,2723],{"class":690,"line":2267},[688,2714,2408],{"class":797},[688,2716,801],{"class":791},[688,2718,831],{"class":791},[688,2720,2415],{"class":697},[688,2722,807],{"class":791},[688,2724,838],{"class":791},[688,2726,2727,2730,2732,2734],{"class":690,"line":2277},[688,2728,2729],{"class":797},"        iv",[688,2731,801],{"class":791},[688,2733,2650],{"class":787},[688,2735,2736],{"class":859}," \u002F\u002F 加密参数必须包含 IV\n",[688,2738,2739],{"class":690,"line":2283},[688,2740,2437],{"class":791},[688,2742,2743,2746,2748],{"class":690,"line":2288},[688,2744,2745],{"class":787},"        key",[688,2747,2129],{"class":791},[688,2749,2750],{"class":859}," \u002F\u002F 密钥\n",[688,2752,2753,2756],{"class":690,"line":2294},[688,2754,2755],{"class":787},"        encodedText",[688,2757,2758],{"class":859}," \u002F\u002F 明文数据\n",[688,2760,2762,2764],{"class":690,"line":2761},23,[688,2763,2480],{"class":797},[688,2765,2058],{"class":791},[688,2767,2769],{"class":690,"line":2768},24,[688,2770,2088],{"emptyLinePlaceholder":1003},[688,2772,2774],{"class":690,"line":2773},25,[688,2775,2776],{"class":859},"    \u002F\u002F 需要同时把密文和 IV 返回，因为解密时必须提供一模一样的 IV\n",[688,2778,2780,2782,2784,2786,2788,2790],{"class":690,"line":2779},26,[688,2781,2270],{"class":776},[688,2783,1971],{"class":791},[688,2785,2690],{"class":787},[688,2787,2129],{"class":791},[688,2789,2650],{"class":787},[688,2791,2792],{"class":791}," };\n",[688,2794,2796],{"class":690,"line":2795},27,[688,2797,2280],{"class":791},[65,2799,2800],{"start":609},[68,2801,2802,2805],{},[71,2803,2804],{},"数据解密 Decrypt","：传入加密时使用的 CryptoKey、IV 和密文数组，将其还原为人类可读的明文字符串。",[679,2807,2809],{"className":1942,"code":2808,"language":1944,"meta":502,"style":502},"\u002F**\n * 对 AES-GCM 密文进行解密\n * @param {ArrayBuffer} cipherText - 密文数据\n * @param {CryptoKey} key - 加密时使用的同一个密钥\n * @param {Uint8Array} iv - 加密时对应的随机 IV\n * @returns {Promise\u003Cstring>} 解密后的明文字符串\n *\u002F\nasync function decryptText(cipherText, key, iv) {\n    \u002F\u002F 执行解密\n    const decryptedBuffer = await crypto.subtle.decrypt(\n        {\n        name: 'AES-GCM',\n        iv: iv \u002F\u002F 必须传入与加密时完全相同的 IV\n        },\n        key,\n        cipherText\n    );\n\n    \u002F\u002F 将 ArrayBuffer 字节解码还原为字符串\n    const decoder = new TextDecoder();\n    return decoder.decode(decryptedBuffer);\n}\n",[42,2810,2811,2815,2820,2840,2859,2879,2896,2900,2926,2931,2954,2958,2972,2983,2987,2993,2998,3004,3008,3013,3031,3051],{"__ignoreMap":502},[688,2812,2813],{"class":690,"line":691},[688,2814,1951],{"class":859},[688,2816,2817],{"class":690,"line":506},[688,2818,2819],{"class":859}," * 对 AES-GCM 密文进行解密\n",[688,2821,2822,2824,2826,2828,2830,2833,2835,2837],{"class":690,"line":535},[688,2823,1961],{"class":859},[688,2825,1964],{"class":776},[688,2827,1968],{"class":1967},[688,2829,1971],{"class":776},[688,2831,2832],{"class":1974},"ArrayBuffer",[688,2834,908],{"class":776},[688,2836,2690],{"class":1980},[688,2838,2839],{"class":859}," - 密文数据\n",[688,2841,2842,2844,2846,2848,2850,2852,2854,2856],{"class":690,"line":609},[688,2843,1961],{"class":859},[688,2845,1964],{"class":776},[688,2847,1968],{"class":1967},[688,2849,1971],{"class":776},[688,2851,1488],{"class":1974},[688,2853,908],{"class":776},[688,2855,2544],{"class":1980},[688,2857,2858],{"class":859}," - 加密时使用的同一个密钥\n",[688,2860,2861,2863,2865,2867,2869,2872,2874,2876],{"class":690,"line":624},[688,2862,1961],{"class":859},[688,2864,1964],{"class":776},[688,2866,1968],{"class":1967},[688,2868,1971],{"class":776},[688,2870,2871],{"class":1974},"Uint8Array",[688,2873,908],{"class":776},[688,2875,2650],{"class":1980},[688,2877,2878],{"class":859}," - 加密时对应的随机 IV\n",[688,2880,2881,2883,2885,2887,2889,2891,2893],{"class":690,"line":856},[688,2882,1961],{"class":859},[688,2884,1964],{"class":776},[688,2886,1993],{"class":1967},[688,2888,1971],{"class":776},[688,2890,1998],{"class":1974},[688,2892,908],{"class":776},[688,2894,2895],{"class":859}," 解密后的明文字符串\n",[688,2897,2898],{"class":690,"line":863},[688,2899,2008],{"class":859},[688,2901,2902,2904,2906,2909,2911,2914,2916,2918,2920,2922,2924],{"class":690,"line":874},[688,2903,2014],{"class":2013},[688,2905,2017],{"class":2013},[688,2907,2908],{"class":783}," decryptText",[688,2910,788],{"class":791},[688,2912,2913],{"class":1980},"cipherText",[688,2915,2129],{"class":791},[688,2917,2544],{"class":1980},[688,2919,2129],{"class":791},[688,2921,2650],{"class":1980},[688,2923,2028],{"class":791},[688,2925,871],{"class":791},[688,2927,2928],{"class":690,"line":890},[688,2929,2930],{"class":859},"    \u002F\u002F 执行解密\n",[688,2932,2933,2935,2938,2940,2942,2944,2946,2948,2950,2952],{"class":690,"line":896},[688,2934,2040],{"class":2013},[688,2936,2937],{"class":787}," decryptedBuffer",[688,2939,2046],{"class":791},[688,2941,2106],{"class":776},[688,2943,2109],{"class":787},[688,2945,2072],{"class":791},[688,2947,2114],{"class":787},[688,2949,2072],{"class":791},[688,2951,2467],{"class":783},[688,2953,2398],{"class":797},[688,2955,2956],{"class":690,"line":905},[688,2957,2403],{"class":791},[688,2959,2960,2962,2964,2966,2968,2970],{"class":690,"line":2096},[688,2961,2408],{"class":797},[688,2963,801],{"class":791},[688,2965,831],{"class":791},[688,2967,2415],{"class":697},[688,2969,807],{"class":791},[688,2971,838],{"class":791},[688,2973,2974,2976,2978,2980],{"class":690,"line":2138},[688,2975,2729],{"class":797},[688,2977,801],{"class":791},[688,2979,2650],{"class":787},[688,2981,2982],{"class":859}," \u002F\u002F 必须传入与加密时完全相同的 IV\n",[688,2984,2985],{"class":690,"line":2143},[688,2986,2437],{"class":791},[688,2988,2989,2991],{"class":690,"line":2149},[688,2990,2745],{"class":787},[688,2992,838],{"class":791},[688,2994,2995],{"class":690,"line":2185},[688,2996,2997],{"class":787},"        cipherText\n",[688,2999,3000,3002],{"class":690,"line":2261},[688,3001,2480],{"class":797},[688,3003,2058],{"class":791},[688,3005,3006],{"class":690,"line":2267},[688,3007,2088],{"emptyLinePlaceholder":1003},[688,3009,3010],{"class":690,"line":2277},[688,3011,3012],{"class":859},"    \u002F\u002F 将 ArrayBuffer 字节解码还原为字符串\n",[688,3014,3015,3017,3020,3022,3024,3027,3029],{"class":690,"line":2283},[688,3016,2040],{"class":2013},[688,3018,3019],{"class":787}," decoder",[688,3021,2046],{"class":791},[688,3023,2049],{"class":791},[688,3025,3026],{"class":783}," TextDecoder",[688,3028,2055],{"class":797},[688,3030,2058],{"class":791},[688,3032,3033,3035,3037,3039,3042,3044,3047,3049],{"class":690,"line":2288},[688,3034,2270],{"class":776},[688,3036,3019],{"class":787},[688,3038,2072],{"class":791},[688,3040,3041],{"class":783},"decode",[688,3043,788],{"class":797},[688,3045,3046],{"class":787},"decryptedBuffer",[688,3048,2028],{"class":797},[688,3050,2058],{"class":791},[688,3052,3053],{"class":690,"line":2294},[688,3054,2280],{"class":791},[3056,3057,3058],"tip",{},[13,3059,3060],{},"如果要在项目中保存或传输生成的密钥和密文，通常需要通过 crypto.subtle.exportKey('raw', key) 将密钥导出成字节，再用 btoa() 或 Base64 方案 转换成可传输的字符串格式。",[123,3062,3064],{"id":3063},"_72-非对称加密rsa-oaep示例","7.2 非对称加密RSA-OAEP示例",[13,3066,3067],{},"非对称加密使用公钥加密、私钥解密，常用于非对称场景或加密对称密钥（如密钥交换）。这里使用最安全的 RSA-OAEP 算法。",[65,3069,3070],{},[68,3071,3072],{},[71,3073,3074],{},"生成 RSA 密钥对",[679,3076,3078],{"className":1942,"code":3077,"language":1944,"meta":502,"style":502},"\u002F**\n * 生成用于 RSA-OAEP 加解密的 2048 位密钥对\n * @returns {Promise\u003CCryptoKeyPair>} 返回包含公钥和私钥的对象\n *\u002F\nasync function generateRSAKeyPair() {\n    return await crypto.subtle.generateKey(\n        {\n            name: \"RSA-OAEP\",\n            modulusLength: 2048, \u002F\u002F 密钥长度，2048 位是目前的标准安全线\n            publicExponent: new Uint8Array([1, 0, 1]), \u002F\u002F 等于 65537，固定的密码学标准常数\n            hash: \"SHA-256\", \u002F\u002F 内部使用的哈希算法\n        },\n        true, \u002F\u002F 是否允许导出\n        [\"encrypt\", \"decrypt\"] \u002F\u002F 用途分配\n    );\n}\n",[42,3079,3080,3084,3089,3107,3111,3124,3142,3146,3163,3178,3213,3231,3235,3245,3268,3274],{"__ignoreMap":502},[688,3081,3082],{"class":690,"line":691},[688,3083,1951],{"class":859},[688,3085,3086],{"class":690,"line":506},[688,3087,3088],{"class":859}," * 生成用于 RSA-OAEP 加解密的 2048 位密钥对\n",[688,3090,3091,3093,3095,3097,3099,3102,3104],{"class":690,"line":535},[688,3092,1961],{"class":859},[688,3094,1964],{"class":776},[688,3096,1993],{"class":1967},[688,3098,1971],{"class":776},[688,3100,3101],{"class":1974},"Promise\u003CCryptoKeyPair>",[688,3103,908],{"class":776},[688,3105,3106],{"class":859}," 返回包含公钥和私钥的对象\n",[688,3108,3109],{"class":690,"line":609},[688,3110,2008],{"class":859},[688,3112,3113,3115,3117,3120,3122],{"class":690,"line":624},[688,3114,2014],{"class":2013},[688,3116,2017],{"class":2013},[688,3118,3119],{"class":783}," generateRSAKeyPair",[688,3121,2055],{"class":791},[688,3123,871],{"class":791},[688,3125,3126,3128,3130,3132,3134,3136,3138,3140],{"class":690,"line":856},[688,3127,2270],{"class":776},[688,3129,2106],{"class":776},[688,3131,2109],{"class":787},[688,3133,2072],{"class":791},[688,3135,2114],{"class":787},[688,3137,2072],{"class":791},[688,3139,2395],{"class":783},[688,3141,2398],{"class":797},[688,3143,3144],{"class":690,"line":863},[688,3145,2403],{"class":791},[688,3147,3148,3151,3153,3156,3159,3161],{"class":690,"line":874},[688,3149,3150],{"class":797},"            name",[688,3152,801],{"class":791},[688,3154,3155],{"class":791}," \"",[688,3157,3158],{"class":697},"RSA-OAEP",[688,3160,2312],{"class":791},[688,3162,838],{"class":791},[688,3164,3165,3168,3170,3173,3175],{"class":690,"line":890},[688,3166,3167],{"class":797},"            modulusLength",[688,3169,801],{"class":791},[688,3171,3172],{"class":2220}," 2048",[688,3174,2129],{"class":791},[688,3176,3177],{"class":859}," \u002F\u002F 密钥长度，2048 位是目前的标准安全线\n",[688,3179,3180,3183,3185,3187,3189,3192,3195,3197,3200,3202,3205,3208,3210],{"class":690,"line":896},[688,3181,3182],{"class":797},"            publicExponent",[688,3184,801],{"class":791},[688,3186,2049],{"class":791},[688,3188,2172],{"class":783},[688,3190,3191],{"class":797},"([",[688,3193,3194],{"class":2220},"1",[688,3196,2129],{"class":791},[688,3198,3199],{"class":2220}," 0",[688,3201,2129],{"class":791},[688,3203,3204],{"class":2220}," 1",[688,3206,3207],{"class":797},"])",[688,3209,2129],{"class":791},[688,3211,3212],{"class":859}," \u002F\u002F 等于 65537，固定的密码学标准常数\n",[688,3214,3215,3218,3220,3222,3224,3226,3228],{"class":690,"line":905},[688,3216,3217],{"class":797},"            hash",[688,3219,801],{"class":791},[688,3221,3155],{"class":791},[688,3223,1748],{"class":697},[688,3225,2312],{"class":791},[688,3227,2129],{"class":791},[688,3229,3230],{"class":859}," \u002F\u002F 内部使用的哈希算法\n",[688,3232,3233],{"class":690,"line":2096},[688,3234,2437],{"class":791},[688,3236,3237,3240,3242],{"class":690,"line":2138},[688,3238,3239],{"class":2442},"        true",[688,3241,2129],{"class":791},[688,3243,3244],{"class":859}," \u002F\u002F 是否允许导出\n",[688,3246,3247,3249,3251,3253,3255,3257,3259,3261,3263,3265],{"class":690,"line":2143},[688,3248,2453],{"class":797},[688,3250,2312],{"class":791},[688,3252,2458],{"class":697},[688,3254,2312],{"class":791},[688,3256,2129],{"class":791},[688,3258,3155],{"class":791},[688,3260,2467],{"class":697},[688,3262,2312],{"class":791},[688,3264,2472],{"class":797},[688,3266,3267],{"class":859},"\u002F\u002F 用途分配\n",[688,3269,3270,3272],{"class":690,"line":2149},[688,3271,2480],{"class":797},[688,3273,2058],{"class":791},[688,3275,3276],{"class":690,"line":2185},[688,3277,2280],{"class":791},[65,3279,3280],{"start":506},[68,3281,3282],{},[71,3283,3284],{},"使用公钥加密",[679,3286,3288],{"className":1942,"code":3287,"language":1944,"meta":502,"style":502},"\u002F**\n * 使用 RSA 公钥加密文本\n *\u002F\nasync function rsaEncrypt(text, publicKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    \u002F\u002F 返回 ArrayBuffer 格式的密文\n    return await crypto.subtle.encrypt(\n        { name: \"RSA-OAEP\" },\n        publicKey,\n        data\n    );\n}\n",[42,3289,3290,3294,3299,3303,3325,3341,3363,3367,3372,3390,3409,3416,3421,3427],{"__ignoreMap":502},[688,3291,3292],{"class":690,"line":691},[688,3293,1951],{"class":859},[688,3295,3296],{"class":690,"line":506},[688,3297,3298],{"class":859}," * 使用 RSA 公钥加密文本\n",[688,3300,3301],{"class":690,"line":535},[688,3302,2008],{"class":859},[688,3304,3305,3307,3309,3312,3314,3316,3318,3321,3323],{"class":690,"line":609},[688,3306,2014],{"class":2013},[688,3308,2017],{"class":2013},[688,3310,3311],{"class":783}," rsaEncrypt",[688,3313,788],{"class":791},[688,3315,2025],{"class":1980},[688,3317,2129],{"class":791},[688,3319,3320],{"class":1980}," publicKey",[688,3322,2028],{"class":791},[688,3324,871],{"class":791},[688,3326,3327,3329,3331,3333,3335,3337,3339],{"class":690,"line":624},[688,3328,2040],{"class":2013},[688,3330,2043],{"class":787},[688,3332,2046],{"class":791},[688,3334,2049],{"class":791},[688,3336,2052],{"class":783},[688,3338,2055],{"class":797},[688,3340,2058],{"class":791},[688,3342,3343,3345,3347,3349,3351,3353,3355,3357,3359,3361],{"class":690,"line":856},[688,3344,2040],{"class":2013},[688,3346,2065],{"class":787},[688,3348,2046],{"class":791},[688,3350,2043],{"class":787},[688,3352,2072],{"class":791},[688,3354,2075],{"class":783},[688,3356,788],{"class":797},[688,3358,2025],{"class":787},[688,3360,2028],{"class":797},[688,3362,2058],{"class":791},[688,3364,3365],{"class":690,"line":863},[688,3366,2088],{"emptyLinePlaceholder":1003},[688,3368,3369],{"class":690,"line":874},[688,3370,3371],{"class":859},"    \u002F\u002F 返回 ArrayBuffer 格式的密文\n",[688,3373,3374,3376,3378,3380,3382,3384,3386,3388],{"class":690,"line":890},[688,3375,2270],{"class":776},[688,3377,2106],{"class":776},[688,3379,2109],{"class":787},[688,3381,2072],{"class":791},[688,3383,2114],{"class":787},[688,3385,2072],{"class":791},[688,3387,2458],{"class":783},[688,3389,2398],{"class":797},[688,3391,3392,3395,3398,3400,3402,3404,3406],{"class":690,"line":896},[688,3393,3394],{"class":791},"        {",[688,3396,3397],{"class":797}," name",[688,3399,801],{"class":791},[688,3401,3155],{"class":791},[688,3403,3158],{"class":697},[688,3405,2312],{"class":791},[688,3407,3408],{"class":791}," },\n",[688,3410,3411,3414],{"class":690,"line":905},[688,3412,3413],{"class":787},"        publicKey",[688,3415,838],{"class":791},[688,3417,3418],{"class":690,"line":2096},[688,3419,3420],{"class":787},"        data\n",[688,3422,3423,3425],{"class":690,"line":2138},[688,3424,2480],{"class":797},[688,3426,2058],{"class":791},[688,3428,3429],{"class":690,"line":2143},[688,3430,2280],{"class":791},[65,3432,3433],{"start":535},[68,3434,3435],{},[71,3436,3437],{},"使用私钥解密",[679,3439,3441],{"className":1942,"code":3440,"language":1944,"meta":502,"style":502},"\u002F**\n * 使用 RSA 私钥解密文本\n *\u002F\nasync function rsaDecrypt(cipherText, privateKey) {\n    const decryptedBuffer = await crypto.subtle.decrypt(\n        { name: \"RSA-OAEP\" },\n        privateKey,\n        cipherText\n    );\n\n    const decoder = new TextDecoder();\n    return decoder.decode(decryptedBuffer);\n}\n",[42,3442,3443,3447,3452,3456,3478,3500,3516,3523,3527,3533,3537,3553,3571],{"__ignoreMap":502},[688,3444,3445],{"class":690,"line":691},[688,3446,1951],{"class":859},[688,3448,3449],{"class":690,"line":506},[688,3450,3451],{"class":859}," * 使用 RSA 私钥解密文本\n",[688,3453,3454],{"class":690,"line":535},[688,3455,2008],{"class":859},[688,3457,3458,3460,3462,3465,3467,3469,3471,3474,3476],{"class":690,"line":609},[688,3459,2014],{"class":2013},[688,3461,2017],{"class":2013},[688,3463,3464],{"class":783}," rsaDecrypt",[688,3466,788],{"class":791},[688,3468,2913],{"class":1980},[688,3470,2129],{"class":791},[688,3472,3473],{"class":1980}," privateKey",[688,3475,2028],{"class":791},[688,3477,871],{"class":791},[688,3479,3480,3482,3484,3486,3488,3490,3492,3494,3496,3498],{"class":690,"line":624},[688,3481,2040],{"class":2013},[688,3483,2937],{"class":787},[688,3485,2046],{"class":791},[688,3487,2106],{"class":776},[688,3489,2109],{"class":787},[688,3491,2072],{"class":791},[688,3493,2114],{"class":787},[688,3495,2072],{"class":791},[688,3497,2467],{"class":783},[688,3499,2398],{"class":797},[688,3501,3502,3504,3506,3508,3510,3512,3514],{"class":690,"line":856},[688,3503,3394],{"class":791},[688,3505,3397],{"class":797},[688,3507,801],{"class":791},[688,3509,3155],{"class":791},[688,3511,3158],{"class":697},[688,3513,2312],{"class":791},[688,3515,3408],{"class":791},[688,3517,3518,3521],{"class":690,"line":863},[688,3519,3520],{"class":787},"        privateKey",[688,3522,838],{"class":791},[688,3524,3525],{"class":690,"line":874},[688,3526,2997],{"class":787},[688,3528,3529,3531],{"class":690,"line":890},[688,3530,2480],{"class":797},[688,3532,2058],{"class":791},[688,3534,3535],{"class":690,"line":896},[688,3536,2088],{"emptyLinePlaceholder":1003},[688,3538,3539,3541,3543,3545,3547,3549,3551],{"class":690,"line":905},[688,3540,2040],{"class":2013},[688,3542,3019],{"class":787},[688,3544,2046],{"class":791},[688,3546,2049],{"class":791},[688,3548,3026],{"class":783},[688,3550,2055],{"class":797},[688,3552,2058],{"class":791},[688,3554,3555,3557,3559,3561,3563,3565,3567,3569],{"class":690,"line":2096},[688,3556,2270],{"class":776},[688,3558,3019],{"class":787},[688,3560,2072],{"class":791},[688,3562,3041],{"class":783},[688,3564,788],{"class":797},[688,3566,3046],{"class":787},[688,3568,2028],{"class":797},[688,3570,2058],{"class":791},[688,3572,3573],{"class":690,"line":2138},[688,3574,2280],{"class":791},[123,3576,3578],{"id":3577},"_73-数字签名与验证-rsassa-pkcs1-v1_5","7.3  数字签名与验证 (RSASSA-PKCS1-v1_5)",[13,3580,3581],{},"数字签名常用于防止数据被篡改并确认发送者身份。其逻辑是：私钥签名、公钥验证。这里使用最通用的 RSASSA-PKCS1-v1_5 算法。",[65,3583,3584],{},[68,3585,3586],{},[71,3587,3588],{},"生成数字签名的 RSA 密钥对",[679,3590,3592],{"className":1942,"code":3591,"language":1944,"meta":502,"style":502},"\u002F**\n * 生成用于数字签名的 RSA 密钥对\n *\u002F\nasync function generateSignKeyPair() {\n    return await crypto.subtle.generateKey(\n        {\n        name: \"RSASSA-PKCS1-v1_5\",\n        modulusLength: 2048,\n        publicExponent: new Uint8Array([1, 0, 1]),\n        hash: \"SHA-256\",\n        },\n        true,\n        [\"sign\", \"verify\"] \u002F\u002F 注意：这里的用途是签名和验证\n    );\n}\n",[42,3593,3594,3598,3603,3607,3620,3638,3642,3656,3667,3694,3709,3713,3719,3744,3750],{"__ignoreMap":502},[688,3595,3596],{"class":690,"line":691},[688,3597,1951],{"class":859},[688,3599,3600],{"class":690,"line":506},[688,3601,3602],{"class":859}," * 生成用于数字签名的 RSA 密钥对\n",[688,3604,3605],{"class":690,"line":535},[688,3606,2008],{"class":859},[688,3608,3609,3611,3613,3616,3618],{"class":690,"line":609},[688,3610,2014],{"class":2013},[688,3612,2017],{"class":2013},[688,3614,3615],{"class":783}," generateSignKeyPair",[688,3617,2055],{"class":791},[688,3619,871],{"class":791},[688,3621,3622,3624,3626,3628,3630,3632,3634,3636],{"class":690,"line":624},[688,3623,2270],{"class":776},[688,3625,2106],{"class":776},[688,3627,2109],{"class":787},[688,3629,2072],{"class":791},[688,3631,2114],{"class":787},[688,3633,2072],{"class":791},[688,3635,2395],{"class":783},[688,3637,2398],{"class":797},[688,3639,3640],{"class":690,"line":856},[688,3641,2403],{"class":791},[688,3643,3644,3646,3648,3650,3652,3654],{"class":690,"line":863},[688,3645,2408],{"class":797},[688,3647,801],{"class":791},[688,3649,3155],{"class":791},[688,3651,1675],{"class":697},[688,3653,2312],{"class":791},[688,3655,838],{"class":791},[688,3657,3658,3661,3663,3665],{"class":690,"line":874},[688,3659,3660],{"class":797},"        modulusLength",[688,3662,801],{"class":791},[688,3664,3172],{"class":2220},[688,3666,838],{"class":791},[688,3668,3669,3672,3674,3676,3678,3680,3682,3684,3686,3688,3690,3692],{"class":690,"line":890},[688,3670,3671],{"class":797},"        publicExponent",[688,3673,801],{"class":791},[688,3675,2049],{"class":791},[688,3677,2172],{"class":783},[688,3679,3191],{"class":797},[688,3681,3194],{"class":2220},[688,3683,2129],{"class":791},[688,3685,3199],{"class":2220},[688,3687,2129],{"class":791},[688,3689,3204],{"class":2220},[688,3691,3207],{"class":797},[688,3693,838],{"class":791},[688,3695,3696,3699,3701,3703,3705,3707],{"class":690,"line":896},[688,3697,3698],{"class":797},"        hash",[688,3700,801],{"class":791},[688,3702,3155],{"class":791},[688,3704,1748],{"class":697},[688,3706,2312],{"class":791},[688,3708,838],{"class":791},[688,3710,3711],{"class":690,"line":905},[688,3712,2437],{"class":791},[688,3714,3715,3717],{"class":690,"line":2096},[688,3716,3239],{"class":2442},[688,3718,838],{"class":791},[688,3720,3721,3723,3725,3728,3730,3732,3734,3737,3739,3741],{"class":690,"line":2138},[688,3722,2453],{"class":797},[688,3724,2312],{"class":791},[688,3726,3727],{"class":697},"sign",[688,3729,2312],{"class":791},[688,3731,2129],{"class":791},[688,3733,3155],{"class":791},[688,3735,3736],{"class":697},"verify",[688,3738,2312],{"class":791},[688,3740,2472],{"class":797},[688,3742,3743],{"class":859},"\u002F\u002F 注意：这里的用途是签名和验证\n",[688,3745,3746,3748],{"class":690,"line":2143},[688,3747,2480],{"class":797},[688,3749,2058],{"class":791},[688,3751,3752],{"class":690,"line":2149},[688,3753,2280],{"class":791},[65,3755,3756],{"start":506},[68,3757,3758],{},[71,3759,3760],{},"使用私钥对数据生成签名",[679,3762,3764],{"className":1942,"code":3763,"language":1944,"meta":502,"style":502},"\n\u002F**\n * 使用私钥对数据生成签名\n * @returns {Promise\u003CArrayBuffer>} 返回签名摘要\n *\u002F\nasync function signData(text, privateKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    return await crypto.subtle.sign(\n        { name: \"RSASSA-PKCS1-v1_5\" },\n        privateKey,\n        data\n    );\n}\n",[42,3765,3766,3770,3774,3779,3796,3800,3821,3837,3859,3863,3881,3897,3903,3907,3913],{"__ignoreMap":502},[688,3767,3768],{"class":690,"line":691},[688,3769,2088],{"emptyLinePlaceholder":1003},[688,3771,3772],{"class":690,"line":506},[688,3773,1951],{"class":859},[688,3775,3776],{"class":690,"line":535},[688,3777,3778],{"class":859}," * 使用私钥对数据生成签名\n",[688,3780,3781,3783,3785,3787,3789,3791,3793],{"class":690,"line":609},[688,3782,1961],{"class":859},[688,3784,1964],{"class":776},[688,3786,1993],{"class":1967},[688,3788,1971],{"class":776},[688,3790,1482],{"class":1974},[688,3792,908],{"class":776},[688,3794,3795],{"class":859}," 返回签名摘要\n",[688,3797,3798],{"class":690,"line":624},[688,3799,2008],{"class":859},[688,3801,3802,3804,3806,3809,3811,3813,3815,3817,3819],{"class":690,"line":856},[688,3803,2014],{"class":2013},[688,3805,2017],{"class":2013},[688,3807,3808],{"class":783}," signData",[688,3810,788],{"class":791},[688,3812,2025],{"class":1980},[688,3814,2129],{"class":791},[688,3816,3473],{"class":1980},[688,3818,2028],{"class":791},[688,3820,871],{"class":791},[688,3822,3823,3825,3827,3829,3831,3833,3835],{"class":690,"line":863},[688,3824,2040],{"class":2013},[688,3826,2043],{"class":787},[688,3828,2046],{"class":791},[688,3830,2049],{"class":791},[688,3832,2052],{"class":783},[688,3834,2055],{"class":797},[688,3836,2058],{"class":791},[688,3838,3839,3841,3843,3845,3847,3849,3851,3853,3855,3857],{"class":690,"line":874},[688,3840,2040],{"class":2013},[688,3842,2065],{"class":787},[688,3844,2046],{"class":791},[688,3846,2043],{"class":787},[688,3848,2072],{"class":791},[688,3850,2075],{"class":783},[688,3852,788],{"class":797},[688,3854,2025],{"class":787},[688,3856,2028],{"class":797},[688,3858,2058],{"class":791},[688,3860,3861],{"class":690,"line":890},[688,3862,2088],{"emptyLinePlaceholder":1003},[688,3864,3865,3867,3869,3871,3873,3875,3877,3879],{"class":690,"line":896},[688,3866,2270],{"class":776},[688,3868,2106],{"class":776},[688,3870,2109],{"class":787},[688,3872,2072],{"class":791},[688,3874,2114],{"class":787},[688,3876,2072],{"class":791},[688,3878,3727],{"class":783},[688,3880,2398],{"class":797},[688,3882,3883,3885,3887,3889,3891,3893,3895],{"class":690,"line":905},[688,3884,3394],{"class":791},[688,3886,3397],{"class":797},[688,3888,801],{"class":791},[688,3890,3155],{"class":791},[688,3892,1675],{"class":697},[688,3894,2312],{"class":791},[688,3896,3408],{"class":791},[688,3898,3899,3901],{"class":690,"line":2096},[688,3900,3520],{"class":787},[688,3902,838],{"class":791},[688,3904,3905],{"class":690,"line":2138},[688,3906,3420],{"class":787},[688,3908,3909,3911],{"class":690,"line":2143},[688,3910,2480],{"class":797},[688,3912,2058],{"class":791},[688,3914,3915],{"class":690,"line":2149},[688,3916,2280],{"class":791},[65,3918,3919],{"start":535},[68,3920,3921],{},[71,3922,3923],{},"公钥验证签名是否有效",[679,3925,3927],{"className":1942,"code":3926,"language":1944,"meta":502,"style":502},"\n\u002F**\n * 使用公钥验证签名是否有效\n * @returns {Promise\u003Cboolean>} 验证成功返回 true，被篡改则返回 false\n *\u002F\nasync function verifyData(text, signature, publicKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    return await crypto.subtle.verify(\n        { name: \"RSASSA-PKCS1-v1_5\" },\n        publicKey,\n        signature, \u002F\u002F 之前生成的签名 ArrayBuffer\n        data \u002F\u002F 原始数据\n    );\n}\n",[42,3928,3929,3933,3937,3942,3960,3964,3990,4006,4028,4032,4050,4066,4072,4082,4090,4096],{"__ignoreMap":502},[688,3930,3931],{"class":690,"line":691},[688,3932,2088],{"emptyLinePlaceholder":1003},[688,3934,3935],{"class":690,"line":506},[688,3936,1951],{"class":859},[688,3938,3939],{"class":690,"line":535},[688,3940,3941],{"class":859}," * 使用公钥验证签名是否有效\n",[688,3943,3944,3946,3948,3950,3952,3955,3957],{"class":690,"line":609},[688,3945,1961],{"class":859},[688,3947,1964],{"class":776},[688,3949,1993],{"class":1967},[688,3951,1971],{"class":776},[688,3953,3954],{"class":1974},"Promise\u003Cboolean>",[688,3956,908],{"class":776},[688,3958,3959],{"class":859}," 验证成功返回 true，被篡改则返回 false\n",[688,3961,3962],{"class":690,"line":624},[688,3963,2008],{"class":859},[688,3965,3966,3968,3970,3973,3975,3977,3979,3982,3984,3986,3988],{"class":690,"line":856},[688,3967,2014],{"class":2013},[688,3969,2017],{"class":2013},[688,3971,3972],{"class":783}," verifyData",[688,3974,788],{"class":791},[688,3976,2025],{"class":1980},[688,3978,2129],{"class":791},[688,3980,3981],{"class":1980}," signature",[688,3983,2129],{"class":791},[688,3985,3320],{"class":1980},[688,3987,2028],{"class":791},[688,3989,871],{"class":791},[688,3991,3992,3994,3996,3998,4000,4002,4004],{"class":690,"line":863},[688,3993,2040],{"class":2013},[688,3995,2043],{"class":787},[688,3997,2046],{"class":791},[688,3999,2049],{"class":791},[688,4001,2052],{"class":783},[688,4003,2055],{"class":797},[688,4005,2058],{"class":791},[688,4007,4008,4010,4012,4014,4016,4018,4020,4022,4024,4026],{"class":690,"line":874},[688,4009,2040],{"class":2013},[688,4011,2065],{"class":787},[688,4013,2046],{"class":791},[688,4015,2043],{"class":787},[688,4017,2072],{"class":791},[688,4019,2075],{"class":783},[688,4021,788],{"class":797},[688,4023,2025],{"class":787},[688,4025,2028],{"class":797},[688,4027,2058],{"class":791},[688,4029,4030],{"class":690,"line":890},[688,4031,2088],{"emptyLinePlaceholder":1003},[688,4033,4034,4036,4038,4040,4042,4044,4046,4048],{"class":690,"line":896},[688,4035,2270],{"class":776},[688,4037,2106],{"class":776},[688,4039,2109],{"class":787},[688,4041,2072],{"class":791},[688,4043,2114],{"class":787},[688,4045,2072],{"class":791},[688,4047,3736],{"class":783},[688,4049,2398],{"class":797},[688,4051,4052,4054,4056,4058,4060,4062,4064],{"class":690,"line":905},[688,4053,3394],{"class":791},[688,4055,3397],{"class":797},[688,4057,801],{"class":791},[688,4059,3155],{"class":791},[688,4061,1675],{"class":697},[688,4063,2312],{"class":791},[688,4065,3408],{"class":791},[688,4067,4068,4070],{"class":690,"line":2096},[688,4069,3413],{"class":787},[688,4071,838],{"class":791},[688,4073,4074,4077,4079],{"class":690,"line":2138},[688,4075,4076],{"class":787},"        signature",[688,4078,2129],{"class":791},[688,4080,4081],{"class":859}," \u002F\u002F 之前生成的签名 ArrayBuffer\n",[688,4083,4084,4087],{"class":690,"line":2143},[688,4085,4086],{"class":787},"        data",[688,4088,4089],{"class":859}," \u002F\u002F 原始数据\n",[688,4091,4092,4094],{"class":690,"line":2149},[688,4093,2480],{"class":797},[688,4095,2058],{"class":791},[688,4097,4098],{"class":690,"line":2185},[688,4099,2280],{"class":791},[123,4101,4103],{"id":4102},"_74-密钥的导入与导出-import-export","7.4 密钥的导入与导出 (Import \u002F Export)",[13,4105,4106],{},"在实际业务中，密钥不能只存在于浏览器内存中，我们需要将其导出为字符串传给后端，或者将后端的字符串密钥导入为浏览器可识别的 CryptoKey 对象。",[13,4108,4109],{},"Web Crypto 支持多种格式，最常用的是 JWK (JSON Web Key) 格式（易读、跨平台）和 raw\u002Fspki\u002Fpkcs8（二进制字节流）。",[65,4111,4112],{},[68,4113,4114],{},[71,4115,4116],{},"导出密钥为 JSON (JWK 格式)",[679,4118,4120],{"className":1942,"code":4119,"language":1944,"meta":502,"style":502},"\u002F**\n * 将 CryptoKey 密钥对象导出为标准的 JSON 对象 (JWK)\n * @param {CryptoKey} key \n * @returns {Promise\u003CObject>} 可直接用于传输或 JSON.stringify 的对象\n *\u002F\nasync function exportKeyToJWK(key) {\n    return await crypto.subtle.exportKey(\"jwk\", key);\n}\n",[42,4121,4122,4126,4131,4150,4168,4172,4189,4223],{"__ignoreMap":502},[688,4123,4124],{"class":690,"line":691},[688,4125,1951],{"class":859},[688,4127,4128],{"class":690,"line":506},[688,4129,4130],{"class":859}," * 将 CryptoKey 密钥对象导出为标准的 JSON 对象 (JWK)\n",[688,4132,4133,4135,4137,4139,4141,4143,4145,4147],{"class":690,"line":535},[688,4134,1961],{"class":859},[688,4136,1964],{"class":776},[688,4138,1968],{"class":1967},[688,4140,1971],{"class":776},[688,4142,1488],{"class":1974},[688,4144,908],{"class":776},[688,4146,2544],{"class":1980},[688,4148,4149],{"class":859}," \n",[688,4151,4152,4154,4156,4158,4160,4163,4165],{"class":690,"line":609},[688,4153,1961],{"class":859},[688,4155,1964],{"class":776},[688,4157,1993],{"class":1967},[688,4159,1971],{"class":776},[688,4161,4162],{"class":1974},"Promise\u003CObject>",[688,4164,908],{"class":776},[688,4166,4167],{"class":859}," 可直接用于传输或 JSON.stringify 的对象\n",[688,4169,4170],{"class":690,"line":624},[688,4171,2008],{"class":859},[688,4173,4174,4176,4178,4181,4183,4185,4187],{"class":690,"line":856},[688,4175,2014],{"class":2013},[688,4177,2017],{"class":2013},[688,4179,4180],{"class":783}," exportKeyToJWK",[688,4182,788],{"class":791},[688,4184,467],{"class":1980},[688,4186,2028],{"class":791},[688,4188,871],{"class":791},[688,4190,4191,4193,4195,4197,4199,4201,4203,4206,4208,4210,4213,4215,4217,4219,4221],{"class":690,"line":863},[688,4192,2270],{"class":776},[688,4194,2106],{"class":776},[688,4196,2109],{"class":787},[688,4198,2072],{"class":791},[688,4200,2114],{"class":787},[688,4202,2072],{"class":791},[688,4204,4205],{"class":783},"exportKey",[688,4207,788],{"class":797},[688,4209,2312],{"class":791},[688,4211,4212],{"class":697},"jwk",[688,4214,2312],{"class":791},[688,4216,2129],{"class":791},[688,4218,2544],{"class":787},[688,4220,2028],{"class":797},[688,4222,2058],{"class":791},[688,4224,4225],{"class":690,"line":874},[688,4226,2280],{"class":791},[65,4228,4229],{"start":506},[68,4230,4231],{},[71,4232,4233],{},"将 JSON 导入回密钥对象",[679,4235,4237],{"className":1942,"code":4236,"language":1944,"meta":502,"style":502},"\u002F**\n * 将 JWK 格式的 JSON 对象导入还原为可用的 AES-GCM 密钥\n * @param {Object} jwkObject \n * @returns {Promise\u003CCryptoKey>}\n *\u002F\nasync function importKeyFromJWK(jwkObject) {\n    return await crypto.subtle.importKey(\n        \"jwk\",\n        jwkObject,\n        { name: \"AES-GCM\" }, \u002F\u002F 必须指定对应的算法\n        true, \u002F\u002F 是否允许再次导出\n        [\"encrypt\", \"decrypt\"] \u002F\u002F 该密钥允许的用途\n    );\n}\n",[42,4238,4239,4243,4248,4268,4282,4286,4304,4323,4334,4341,4361,4370,4393,4399],{"__ignoreMap":502},[688,4240,4241],{"class":690,"line":691},[688,4242,1951],{"class":859},[688,4244,4245],{"class":690,"line":506},[688,4246,4247],{"class":859}," * 将 JWK 格式的 JSON 对象导入还原为可用的 AES-GCM 密钥\n",[688,4249,4250,4252,4254,4256,4258,4261,4263,4266],{"class":690,"line":535},[688,4251,1961],{"class":859},[688,4253,1964],{"class":776},[688,4255,1968],{"class":1967},[688,4257,1971],{"class":776},[688,4259,4260],{"class":1974},"Object",[688,4262,908],{"class":776},[688,4264,4265],{"class":1980}," jwkObject",[688,4267,4149],{"class":859},[688,4269,4270,4272,4274,4276,4278,4280],{"class":690,"line":609},[688,4271,1961],{"class":859},[688,4273,1964],{"class":776},[688,4275,1993],{"class":1967},[688,4277,1971],{"class":776},[688,4279,2356],{"class":1974},[688,4281,2280],{"class":776},[688,4283,4284],{"class":690,"line":624},[688,4285,2008],{"class":859},[688,4287,4288,4290,4292,4295,4297,4300,4302],{"class":690,"line":856},[688,4289,2014],{"class":2013},[688,4291,2017],{"class":2013},[688,4293,4294],{"class":783}," importKeyFromJWK",[688,4296,788],{"class":791},[688,4298,4299],{"class":1980},"jwkObject",[688,4301,2028],{"class":791},[688,4303,871],{"class":791},[688,4305,4306,4308,4310,4312,4314,4316,4318,4321],{"class":690,"line":863},[688,4307,2270],{"class":776},[688,4309,2106],{"class":776},[688,4311,2109],{"class":787},[688,4313,2072],{"class":791},[688,4315,2114],{"class":787},[688,4317,2072],{"class":791},[688,4319,4320],{"class":783},"importKey",[688,4322,2398],{"class":797},[688,4324,4325,4328,4330,4332],{"class":690,"line":874},[688,4326,4327],{"class":791},"        \"",[688,4329,4212],{"class":697},[688,4331,2312],{"class":791},[688,4333,838],{"class":791},[688,4335,4336,4339],{"class":690,"line":890},[688,4337,4338],{"class":787},"        jwkObject",[688,4340,838],{"class":791},[688,4342,4343,4345,4347,4349,4351,4353,4355,4358],{"class":690,"line":896},[688,4344,3394],{"class":791},[688,4346,3397],{"class":797},[688,4348,801],{"class":791},[688,4350,3155],{"class":791},[688,4352,2415],{"class":697},[688,4354,2312],{"class":791},[688,4356,4357],{"class":791}," },",[688,4359,4360],{"class":859}," \u002F\u002F 必须指定对应的算法\n",[688,4362,4363,4365,4367],{"class":690,"line":905},[688,4364,3239],{"class":2442},[688,4366,2129],{"class":791},[688,4368,4369],{"class":859}," \u002F\u002F 是否允许再次导出\n",[688,4371,4372,4374,4376,4378,4380,4382,4384,4386,4388,4390],{"class":690,"line":2096},[688,4373,2453],{"class":797},[688,4375,2312],{"class":791},[688,4377,2458],{"class":697},[688,4379,2312],{"class":791},[688,4381,2129],{"class":791},[688,4383,3155],{"class":791},[688,4385,2467],{"class":697},[688,4387,2312],{"class":791},[688,4389,2472],{"class":797},[688,4391,4392],{"class":859},"\u002F\u002F 该密钥允许的用途\n",[688,4394,4395,4397],{"class":690,"line":2138},[688,4396,2480],{"class":797},[688,4398,2058],{"class":791},[688,4400,4401],{"class":690,"line":2143},[688,4402,2280],{"class":791},[17,4404,4406],{"id":4405},"_8-避坑指南","8 避坑指南",[65,4408,4409],{},[68,4410,4411],{},[71,4412,4413],{},"陷阱一：IV 重复使用",[128,4415,4416,4422],{},[68,4417,4418,4421],{},[71,4419,4420],{},"问题："," 在 AES-GCM 等对称加密中，重复使用相同的初始化向量（IV）会导致密钥流重复，严重破坏加密安全性。",[68,4423,4424,4427],{},[71,4425,4426],{},"正确做法：",[128,4428,4429,4432,4435,4438],{},[68,4430,4431],{},"每次加密都使用 crypto.getRandomValues() 生成新的随机 IV",[68,4433,4434],{},"AES-GCM 模式推荐使用 12 字节（非 16 字节！）的 IV",[68,4436,4437],{},"同一密钥下 IV 重复概率应低于 2⁻³²",[68,4439,4440],{},"IV 不需要保密，但必须唯一——记得将 IV 与密文一起存储",[65,4442,4443],{"start":506},[68,4444,4445],{},[71,4446,4447],{},"陷阱二：密钥管理不当",[128,4449,4450,4466],{},[68,4451,4452,4455],{},[71,4453,4454],{},"常见错误：",[128,4456,4457,4460,4463],{},[68,4458,4459],{},"将密钥存储在 localStorage 或 Cookie 中",[68,4461,4462],{},"使用不安全的密钥传输方式",[68,4464,4465],{},"未设置适当的密钥使用限制",[68,4467,4468,4471],{},[71,4469,4470],{},"安全建议：",[128,4472,4473,4476,4479],{},[68,4474,4475],{},"敏感会话密钥存储在 Web Worker 内存中",[68,4477,4478],{},"需要持久化的密钥使用 IndexedDB",[68,4480,4481],{},"使用 exportKey 和 importKey 安全地传输公钥",[65,4483,4484],{"start":535},[68,4485,4486],{},[71,4487,4488],{},"陷阱三：算法选择失误",[128,4490,4491,4494,4497],{},[68,4492,4493],{},"不要使用 SHA-1 或 MD5 进行哈希",[68,4495,4496],{},"不要使用 ECB 模式的 AES 加密",[68,4498,4499],{},"RSA 密钥长度至少 2048 位",[17,4501,4503],{"id":4502},"_9-最佳实践","9 最佳实践",[65,4505,4506],{},[68,4507,4508],{},[71,4509,4510],{},"使用方式选型指南推荐",[13,4512,4513],{},"自 Node.js 19+ 起，Web Crypto API 已成为内置标准，可通过以下方式访问：",[679,4515,4517],{"className":1942,"code":4516,"language":1944,"meta":502,"style":502},"\u002F\u002F 方式一：使用 globalThis\nconst { subtle } = globalThis.crypto;\n\n\u002F\u002F 方式二：使用 Node.js 模块\nconst { webcrypto } = require('node:crypto');\nconst { subtle } = webcrypto;\n",[42,4518,4519,4524,4547,4551,4556,4585],{"__ignoreMap":502},[688,4520,4521],{"class":690,"line":691},[688,4522,4523],{"class":859},"\u002F\u002F 方式一：使用 globalThis\n",[688,4525,4526,4528,4530,4533,4535,4537,4540,4542,4545],{"class":690,"line":506},[688,4527,2297],{"class":2013},[688,4529,1971],{"class":791},[688,4531,4532],{"class":787}," subtle ",[688,4534,908],{"class":791},[688,4536,2046],{"class":791},[688,4538,4539],{"class":787}," globalThis",[688,4541,2072],{"class":791},[688,4543,4544],{"class":787},"crypto",[688,4546,2058],{"class":791},[688,4548,4549],{"class":690,"line":535},[688,4550,2088],{"emptyLinePlaceholder":1003},[688,4552,4553],{"class":690,"line":609},[688,4554,4555],{"class":859},"\u002F\u002F 方式二：使用 Node.js 模块\n",[688,4557,4558,4560,4562,4565,4567,4569,4572,4574,4576,4579,4581,4583],{"class":690,"line":624},[688,4559,2297],{"class":2013},[688,4561,1971],{"class":791},[688,4563,4564],{"class":787}," webcrypto ",[688,4566,908],{"class":791},[688,4568,2046],{"class":791},[688,4570,4571],{"class":783}," require",[688,4573,788],{"class":787},[688,4575,807],{"class":791},[688,4577,4578],{"class":697},"node:crypto",[688,4580,807],{"class":791},[688,4582,2028],{"class":787},[688,4584,2058],{"class":791},[688,4586,4587,4589,4591,4593,4595,4597,4600],{"class":690,"line":856},[688,4588,2297],{"class":2013},[688,4590,1971],{"class":791},[688,4592,4532],{"class":787},[688,4594,908],{"class":791},[688,4596,2046],{"class":791},[688,4598,4599],{"class":787}," webcrypto",[688,4601,2058],{"class":791},[13,4603,4604],{},"这两种方式虽然最终都能让你获取到 subtle 接口，但它们在设计哲学、模块机制、环境通用性以及底层依赖上有着本质的区别。",[260,4606,4607,4620],{},[263,4608,4609],{},[266,4610,4611,4614,4617],{},[269,4612,4613],{},"对比维度",[269,4615,4616],{},"方式一：globalThis.crypto",[269,4618,4619],{},"方式二：require('node:crypto')",[278,4621,4622,4633,4644,4655,4666],{},[266,4623,4624,4627,4630],{},[283,4625,4626],{},"本质定位",[283,4628,4629],{},"Web标准API（与浏览器对齐）",[283,4631,4632],{},"Node.js原生模块API（特定服务端）",[266,4634,4635,4638,4641],{},[283,4636,4637],{},"引入方式",[283,4639,4640],{},"零依赖，直接全局访问",[283,4642,4643],{},"需要显式通过require引入模块",[266,4645,4646,4649,4652],{},[283,4647,4648],{},"跨端通用性",[283,4650,4651],{},"极高（同构JavaScript）",[283,4653,4654],{},"极低（只能在Node.js运行）",[266,4656,4657,4660,4663],{},[283,4658,4659],{},"底层实现",[283,4661,4662],{},"浏览器内核（前端）\u002F Node V8底层封装（后端）",[283,4664,4665],{},"强依赖Node.js内置的OpenSSL库",[266,4667,4668,4671,4674],{},[283,4669,4670],{},"执行上下文",[283,4672,4673],{},"必须在安全上下文（前端限制）",[283,4675,4676],{},"服务端环境，无任何安全上下文限制",[13,4678,4679,4682],{},[71,4680,4681],{},"推荐使用\"globalThis.crypto\"的场景："," 正在编写纯前端项目、前后端全栈通用工具库（Isomorphic Lib），或者代码需要部署在 Cloudflare Workers、Vercel Edge 等现代边缘计算架构中。",[13,4684,4685,4688],{},[71,4686,4687],{},"推荐使用\"require('node:crypto')\"的场景："," 正在编写纯 Node.js 服务端项目（如大型后端服务、CLI 工具），且除了 Web Crypto 之外，还需要用到 Node.js 特有的高级安全特性（如流式加密大文件、硬件安全模块 HSM 交互等）。",[65,4690,4691],{"start":506},[68,4692,4693],{},[71,4694,4695],{},"使用细节建议",[13,4697,4698],{},"Web Crypto API 是浏览器原生加密的黄金标准。它以零依赖、高性能、高安全性的优势，正在逐步取代各种第三方加密库。然而，正如其名 \"subtle\" 所警示的，加密是一个极其专业的领域，细微的错误就可能导致整个系统安全性完全失效。在使用 Web Crypto API 时：",[128,4700,4701,4704,4707],{},[68,4702,4703],{},"始终在 HTTPS 环境下使用",[68,4705,4706],{},"选择正确的算法和参数（如 AES-GCM + 12 字节 IV）",[68,4708,4709],{},"妥善管理密钥的生命周期",[17,4711,4713],{"id":4712},"_10-加解密模板工具","10 加解密模板工具",[13,4715,4716],{},"以下为您编写的这一套 AES-GCM 高级对称加密与解密工具函数。它做到了100% 零依赖、纯原生，通过 globalThis.crypto 实现完美同构。你不需要进行任何环境判断，同一段代码可以无缝运行在浏览器（安全上下文）、Node.js（19+）、Deno、Bun 以及边缘计算（如 Cloudflare Workers）中。",[13,4718,4719],{},"为了解决数据传输与存储的问题，工具函数内部自动处理了 ArrayBuffer 与 Base64 字符串之间的相互转换。可以直接复制使用，代码如下：",[679,4721,4724],{"className":766,"code":4722,"filename":4723,"language":769,"meta":502,"style":502},"\u002F**\n * 完美的同构 Web Crypto 安全加解密工具库 (TypeScript 箭头函数版本)\n * 适用环境：Browser (HTTPS), Node.js 19+, Deno, Bun, Cloudflare Workers\n *\u002F\n\n\u002F\u002F 1. 获取全局同构的 subtle 对象\nconst cryptoProvider = globalThis.crypto\nif (!cryptoProvider) {\n    throw new Error('当前运行环境不支持 Web Crypto API。请确保在 HTTPS、localhost 或现代 Node.js 19+ 环境下运行。')\n}\nconst subtle: SubtleCrypto = cryptoProvider.subtle\n\n\u002F**\n * 辅助函数：将 ArrayBuffer 转换为可传输的 Base64 字符串\n * 使用现代批处理写法apply，100% 消除严格模式下的 undefined 类型报错\n *\u002F\nconst bufferToBase64 = (buffer: ArrayBuffer): string => {\n    const bytes = new Uint8Array(buffer)\n    const binary = String.fromCharCode.apply(null, bytes as unknown as number[])\n    return btoa(binary)\n}\n\n\u002F**\n * 辅助函数：将 Base64 字符串还原为 ArrayBuffer\n * 使用 Array.from 映射，确保严格类型安全\n *\u002F\nconst base64ToBuffer = (base64: string): ArrayBuffer => {\n    const binaryString = atob(base64)\n    const bytes = Uint8Array.from(binaryString, (char) => char.charCodeAt(0))\n    return bytes.buffer\n}\n\n\u002F**\n * [同构] 生成 AES-GCM 256位加密密钥\n *\u002F\nexport const generateAESKey = async (): Promise\u003CCryptoKey> => {\n    return await subtle.generateKey(\n        { name: 'AES-GCM', length: 256 },\n        true, \u002F\u002F 允许导出\n        ['encrypt', 'decrypt']\n    )\n}\n\n\u002F**\n * [同构] 导出 CryptoKey 密钥为可传输的 Base64 字符串\n * @param cryptoKey - 浏览器或服务端生成的 CryptoKey 实体\n *\u002F\nexport const exportKeyToBase64 = async (cryptoKey: CryptoKey): Promise\u003Cstring> => {\n    const exported = await subtle.exportKey('raw', cryptoKey)\n    return bufferToBase64(exported)\n}\n\n\u002F**\n * [同构] 从 Base64 字符串导入还原为 CryptoKey 密钥对象\n * @param base64Key - Base64 格式的密钥字符串\n *\u002F\nexport const importKeyFromBase64 = async (base64Key: string): Promise\u003CCryptoKey> => {\n    const rawKeyBuffer = base64ToBuffer(base64Key)\n    return await subtle.importKey('raw', rawKeyBuffer, { name: 'AES-GCM' }, true, ['encrypt', 'decrypt'])\n}\n\n\u002F**\n * [同构] 使用 AES-GCM 算法加密字符串文本\n * @param text - 待加密的明文文本\n * @param key - CryptoKey 密钥对象\n * @returns 返回打包了 \"IV\" 和 \"密文\" 的统一 Base64 字符串\n *\u002F\nexport const encryptText = async (text: string, key: CryptoKey): Promise\u003Cstring> => {\n    const encoder = new TextEncoder()\n    const encodedText: Uint8Array\u003CArrayBuffer> = encoder.encode(text)\n    \u002F\u002F 生成 12 字节的密码学安全伪随机数作为 IV (AES-GCM 标准推荐)\n    const iv: Uint8Array\u003CArrayBuffer> = cryptoProvider.getRandomValues(new Uint8Array(12))\n    \u002F\u002F 执行加密，返回密文 ArrayBuffer\n    const cipherBuffer: ArrayBuffer = await subtle.encrypt({ name: 'AES-GCM', iv: iv }, key, encodedText)\n    \u002F\u002F 将 IV（12字节）和密文拼接，方便单字符串传输\n    const combined = new Uint8Array(iv.length + cipherBuffer.byteLength)\n    combined.set(iv, 0)\n    combined.set(new Uint8Array(cipherBuffer), iv.length)\n    return bufferToBase64(combined.buffer)\n}\n\n\u002F**\n * [同构] 使用 AES-GCM 算法解密文本\n * @param combinedBase64 - 由 encryptText 生成的统一加密 Base64 字符串（内部含 IV）\n * @param key - 对应的 CryptoKey 密钥对象\n *\u002F\nexport const decryptText = async (combinedBase64: string, key: CryptoKey): Promise\u003Cstring> => {\n    const combinedBuffer = base64ToBuffer(combinedBase64)\n    const combinedBytes = new Uint8Array(combinedBuffer)\n    \u002F\u002F 从头部切出前 12 字节作为 IV\n    const iv: Uint8Array\u003CArrayBuffer> = combinedBytes.slice(0, 12)\n    \u002F\u002F 剩下的部分作为真正的密文\n    const cipherText: Uint8Array\u003CArrayBuffer> = combinedBytes.slice(12)\n    \u002F\u002F 执行解密\n    const decryptedBuffer: ArrayBuffer = await subtle.decrypt({ name: 'AES-GCM', iv: iv }, key, cipherText.buffer)\n    const decoder = new TextDecoder()\n    return decoder.decode(decryptedBuffer)\n}\n","crypto.ts",[42,4725,4726,4730,4735,4740,4744,4748,4753,4769,4785,4806,4810,4832,4836,4840,4845,4850,4854,4883,4902,4945,4959,4963,4967,4971,4976,4981,4985,5011,5030,5076,5088,5093,5098,5103,5109,5114,5147,5162,5188,5198,5219,5225,5230,5235,5240,5246,5261,5266,5304,5337,5352,5357,5362,5367,5373,5388,5393,5430,5449,5515,5520,5525,5530,5536,5550,5564,5576,5581,5625,5641,5672,5678,5715,5721,5776,5782,5818,5839,5871,5889,5894,5899,5904,5910,5925,5939,5944,5989,6007,6028,6034,6071,6077,6108,6113,6170,6185,6202],{"__ignoreMap":502},[688,4727,4728],{"class":690,"line":691},[688,4729,1951],{"class":859},[688,4731,4732],{"class":690,"line":506},[688,4733,4734],{"class":859}," * 完美的同构 Web Crypto 安全加解密工具库 (TypeScript 箭头函数版本)\n",[688,4736,4737],{"class":690,"line":535},[688,4738,4739],{"class":859}," * 适用环境：Browser (HTTPS), Node.js 19+, Deno, Bun, Cloudflare Workers\n",[688,4741,4742],{"class":690,"line":609},[688,4743,2008],{"class":859},[688,4745,4746],{"class":690,"line":624},[688,4747,2088],{"emptyLinePlaceholder":1003},[688,4749,4750],{"class":690,"line":856},[688,4751,4752],{"class":859},"\u002F\u002F 1. 获取全局同构的 subtle 对象\n",[688,4754,4755,4757,4760,4762,4764,4766],{"class":690,"line":863},[688,4756,2297],{"class":2013},[688,4758,4759],{"class":787}," cryptoProvider ",[688,4761,2303],{"class":791},[688,4763,4539],{"class":787},[688,4765,2072],{"class":791},[688,4767,4768],{"class":787},"crypto\n",[688,4770,4771,4774,4777,4780,4783],{"class":690,"line":874},[688,4772,4773],{"class":776},"if",[688,4775,4776],{"class":787}," (",[688,4778,4779],{"class":791},"!",[688,4781,4782],{"class":787},"cryptoProvider) ",[688,4784,792],{"class":791},[688,4786,4787,4790,4792,4795,4797,4799,4802,4804],{"class":690,"line":890},[688,4788,4789],{"class":776},"    throw",[688,4791,2049],{"class":791},[688,4793,4794],{"class":783}," Error",[688,4796,788],{"class":797},[688,4798,807],{"class":791},[688,4800,4801],{"class":697},"当前运行环境不支持 Web Crypto API。请确保在 HTTPS、localhost 或现代 Node.js 19+ 环境下运行。",[688,4803,807],{"class":791},[688,4805,911],{"class":797},[688,4807,4808],{"class":690,"line":896},[688,4809,2280],{"class":791},[688,4811,4812,4814,4817,4819,4822,4824,4827,4829],{"class":690,"line":905},[688,4813,2297],{"class":2013},[688,4815,4816],{"class":787}," subtle",[688,4818,801],{"class":791},[688,4820,4821],{"class":694}," SubtleCrypto",[688,4823,2046],{"class":791},[688,4825,4826],{"class":787}," cryptoProvider",[688,4828,2072],{"class":791},[688,4830,4831],{"class":787},"subtle\n",[688,4833,4834],{"class":690,"line":2096},[688,4835,2088],{"emptyLinePlaceholder":1003},[688,4837,4838],{"class":690,"line":2138},[688,4839,1951],{"class":859},[688,4841,4842],{"class":690,"line":2143},[688,4843,4844],{"class":859}," * 辅助函数：将 ArrayBuffer 转换为可传输的 Base64 字符串\n",[688,4846,4847],{"class":690,"line":2149},[688,4848,4849],{"class":859}," * 使用现代批处理写法apply，100% 消除严格模式下的 undefined 类型报错\n",[688,4851,4852],{"class":690,"line":2185},[688,4853,2008],{"class":859},[688,4855,4856,4858,4861,4863,4865,4868,4870,4873,4876,4879,4881],{"class":690,"line":2261},[688,4857,2297],{"class":2013},[688,4859,4860],{"class":787}," bufferToBase64 ",[688,4862,2303],{"class":791},[688,4864,4776],{"class":791},[688,4866,4867],{"class":1980},"buffer",[688,4869,801],{"class":791},[688,4871,4872],{"class":694}," ArrayBuffer",[688,4874,4875],{"class":791},"):",[688,4877,4878],{"class":694}," string",[688,4880,2207],{"class":2013},[688,4882,871],{"class":791},[688,4884,4885,4887,4890,4892,4894,4896,4898,4900],{"class":690,"line":2267},[688,4886,2040],{"class":2013},[688,4888,4889],{"class":787}," bytes",[688,4891,2046],{"class":791},[688,4893,2049],{"class":791},[688,4895,2172],{"class":783},[688,4897,788],{"class":797},[688,4899,4867],{"class":787},[688,4901,911],{"class":797},[688,4903,4904,4906,4909,4911,4914,4916,4919,4921,4924,4926,4929,4931,4934,4937,4939,4942],{"class":690,"line":2277},[688,4905,2040],{"class":2013},[688,4907,4908],{"class":787}," binary",[688,4910,2046],{"class":791},[688,4912,4913],{"class":787}," String",[688,4915,2072],{"class":791},[688,4917,4918],{"class":787},"fromCharCode",[688,4920,2072],{"class":791},[688,4922,4923],{"class":783},"apply",[688,4925,788],{"class":797},[688,4927,4928],{"class":791},"null,",[688,4930,4889],{"class":787},[688,4932,4933],{"class":776}," as",[688,4935,4936],{"class":694}," unknown",[688,4938,4933],{"class":776},[688,4940,4941],{"class":694}," number",[688,4943,4944],{"class":797},"[])\n",[688,4946,4947,4949,4952,4954,4957],{"class":690,"line":2283},[688,4948,2270],{"class":776},[688,4950,4951],{"class":783}," btoa",[688,4953,788],{"class":797},[688,4955,4956],{"class":787},"binary",[688,4958,911],{"class":797},[688,4960,4961],{"class":690,"line":2288},[688,4962,2280],{"class":791},[688,4964,4965],{"class":690,"line":2294},[688,4966,2088],{"emptyLinePlaceholder":1003},[688,4968,4969],{"class":690,"line":2761},[688,4970,1951],{"class":859},[688,4972,4973],{"class":690,"line":2768},[688,4974,4975],{"class":859}," * 辅助函数：将 Base64 字符串还原为 ArrayBuffer\n",[688,4977,4978],{"class":690,"line":2773},[688,4979,4980],{"class":859}," * 使用 Array.from 映射，确保严格类型安全\n",[688,4982,4983],{"class":690,"line":2779},[688,4984,2008],{"class":859},[688,4986,4987,4989,4992,4994,4996,4999,5001,5003,5005,5007,5009],{"class":690,"line":2795},[688,4988,2297],{"class":2013},[688,4990,4991],{"class":787}," base64ToBuffer ",[688,4993,2303],{"class":791},[688,4995,4776],{"class":791},[688,4997,4998],{"class":1980},"base64",[688,5000,801],{"class":791},[688,5002,4878],{"class":694},[688,5004,4875],{"class":791},[688,5006,4872],{"class":694},[688,5008,2207],{"class":2013},[688,5010,871],{"class":791},[688,5012,5014,5016,5019,5021,5024,5026,5028],{"class":690,"line":5013},28,[688,5015,2040],{"class":2013},[688,5017,5018],{"class":787}," binaryString",[688,5020,2046],{"class":791},[688,5022,5023],{"class":783}," atob",[688,5025,788],{"class":797},[688,5027,4998],{"class":787},[688,5029,911],{"class":797},[688,5031,5033,5035,5037,5039,5041,5043,5045,5047,5050,5052,5054,5057,5059,5061,5064,5066,5069,5071,5073],{"class":690,"line":5032},29,[688,5034,2040],{"class":2013},[688,5036,4889],{"class":787},[688,5038,2046],{"class":791},[688,5040,2172],{"class":787},[688,5042,2072],{"class":791},[688,5044,2164],{"class":783},[688,5046,788],{"class":797},[688,5048,5049],{"class":787},"binaryString",[688,5051,2129],{"class":791},[688,5053,4776],{"class":791},[688,5055,5056],{"class":1980},"char",[688,5058,2028],{"class":791},[688,5060,2207],{"class":2013},[688,5062,5063],{"class":787}," char",[688,5065,2072],{"class":791},[688,5067,5068],{"class":783},"charCodeAt",[688,5070,788],{"class":797},[688,5072,2240],{"class":2220},[688,5074,5075],{"class":797},"))\n",[688,5077,5079,5081,5083,5085],{"class":690,"line":5078},30,[688,5080,2270],{"class":776},[688,5082,4889],{"class":787},[688,5084,2072],{"class":791},[688,5086,5087],{"class":787},"buffer\n",[688,5089,5091],{"class":690,"line":5090},31,[688,5092,2280],{"class":791},[688,5094,5096],{"class":690,"line":5095},32,[688,5097,2088],{"emptyLinePlaceholder":1003},[688,5099,5101],{"class":690,"line":5100},33,[688,5102,1951],{"class":859},[688,5104,5106],{"class":690,"line":5105},34,[688,5107,5108],{"class":859}," * [同构] 生成 AES-GCM 256位加密密钥\n",[688,5110,5112],{"class":690,"line":5111},35,[688,5113,2008],{"class":859},[688,5115,5117,5119,5122,5125,5127,5130,5133,5136,5138,5140,5143,5145],{"class":690,"line":5116},36,[688,5118,777],{"class":776},[688,5120,5121],{"class":2013}," const",[688,5123,5124],{"class":787}," generateAESKey ",[688,5126,2303],{"class":791},[688,5128,5129],{"class":2013}," async",[688,5131,5132],{"class":791}," ():",[688,5134,5135],{"class":694}," Promise",[688,5137,935],{"class":791},[688,5139,1488],{"class":694},[688,5141,5142],{"class":791},">",[688,5144,2207],{"class":2013},[688,5146,871],{"class":791},[688,5148,5150,5152,5154,5156,5158,5160],{"class":690,"line":5149},37,[688,5151,2270],{"class":776},[688,5153,2106],{"class":776},[688,5155,4816],{"class":787},[688,5157,2072],{"class":791},[688,5159,2395],{"class":783},[688,5161,2398],{"class":797},[688,5163,5165,5167,5169,5171,5173,5175,5177,5179,5182,5184,5186],{"class":690,"line":5164},38,[688,5166,3394],{"class":791},[688,5168,3397],{"class":797},[688,5170,801],{"class":791},[688,5172,831],{"class":791},[688,5174,2415],{"class":697},[688,5176,807],{"class":791},[688,5178,2129],{"class":791},[688,5180,5181],{"class":797}," length",[688,5183,801],{"class":791},[688,5185,2429],{"class":2220},[688,5187,3408],{"class":791},[688,5189,5191,5193,5195],{"class":690,"line":5190},39,[688,5192,3239],{"class":2442},[688,5194,2129],{"class":791},[688,5196,5197],{"class":859}," \u002F\u002F 允许导出\n",[688,5199,5201,5203,5205,5207,5209,5211,5213,5215,5217],{"class":690,"line":5200},40,[688,5202,2453],{"class":797},[688,5204,807],{"class":791},[688,5206,2458],{"class":697},[688,5208,807],{"class":791},[688,5210,2129],{"class":791},[688,5212,831],{"class":791},[688,5214,2467],{"class":697},[688,5216,807],{"class":791},[688,5218,814],{"class":797},[688,5220,5222],{"class":690,"line":5221},41,[688,5223,5224],{"class":797},"    )\n",[688,5226,5228],{"class":690,"line":5227},42,[688,5229,2280],{"class":791},[688,5231,5233],{"class":690,"line":5232},43,[688,5234,2088],{"emptyLinePlaceholder":1003},[688,5236,5238],{"class":690,"line":5237},44,[688,5239,1951],{"class":859},[688,5241,5243],{"class":690,"line":5242},45,[688,5244,5245],{"class":859}," * [同构] 导出 CryptoKey 密钥为可传输的 Base64 字符串\n",[688,5247,5249,5251,5253,5255,5258],{"class":690,"line":5248},46,[688,5250,1961],{"class":859},[688,5252,1964],{"class":776},[688,5254,1968],{"class":1967},[688,5256,5257],{"class":1980}," cryptoKey",[688,5259,5260],{"class":859}," - 浏览器或服务端生成的 CryptoKey 实体\n",[688,5262,5264],{"class":690,"line":5263},47,[688,5265,2008],{"class":859},[688,5267,5269,5271,5273,5276,5278,5280,5282,5285,5287,5290,5292,5294,5296,5298,5300,5302],{"class":690,"line":5268},48,[688,5270,777],{"class":776},[688,5272,5121],{"class":2013},[688,5274,5275],{"class":787}," exportKeyToBase64 ",[688,5277,2303],{"class":791},[688,5279,5129],{"class":2013},[688,5281,4776],{"class":791},[688,5283,5284],{"class":1980},"cryptoKey",[688,5286,801],{"class":791},[688,5288,5289],{"class":694}," CryptoKey",[688,5291,4875],{"class":791},[688,5293,5135],{"class":694},[688,5295,935],{"class":791},[688,5297,1975],{"class":694},[688,5299,5142],{"class":791},[688,5301,2207],{"class":2013},[688,5303,871],{"class":791},[688,5305,5307,5309,5312,5314,5316,5318,5320,5322,5324,5326,5329,5331,5333,5335],{"class":690,"line":5306},49,[688,5308,2040],{"class":2013},[688,5310,5311],{"class":787}," exported",[688,5313,2046],{"class":791},[688,5315,2106],{"class":776},[688,5317,4816],{"class":787},[688,5319,2072],{"class":791},[688,5321,4205],{"class":783},[688,5323,788],{"class":797},[688,5325,807],{"class":791},[688,5327,5328],{"class":697},"raw",[688,5330,807],{"class":791},[688,5332,2129],{"class":791},[688,5334,5257],{"class":787},[688,5336,911],{"class":797},[688,5338,5340,5342,5345,5347,5350],{"class":690,"line":5339},50,[688,5341,2270],{"class":776},[688,5343,5344],{"class":783}," bufferToBase64",[688,5346,788],{"class":797},[688,5348,5349],{"class":787},"exported",[688,5351,911],{"class":797},[688,5353,5355],{"class":690,"line":5354},51,[688,5356,2280],{"class":791},[688,5358,5360],{"class":690,"line":5359},52,[688,5361,2088],{"emptyLinePlaceholder":1003},[688,5363,5365],{"class":690,"line":5364},53,[688,5366,1951],{"class":859},[688,5368,5370],{"class":690,"line":5369},54,[688,5371,5372],{"class":859}," * [同构] 从 Base64 字符串导入还原为 CryptoKey 密钥对象\n",[688,5374,5376,5378,5380,5382,5385],{"class":690,"line":5375},55,[688,5377,1961],{"class":859},[688,5379,1964],{"class":776},[688,5381,1968],{"class":1967},[688,5383,5384],{"class":1980}," base64Key",[688,5386,5387],{"class":859}," - Base64 格式的密钥字符串\n",[688,5389,5391],{"class":690,"line":5390},56,[688,5392,2008],{"class":859},[688,5394,5396,5398,5400,5403,5405,5407,5409,5412,5414,5416,5418,5420,5422,5424,5426,5428],{"class":690,"line":5395},57,[688,5397,777],{"class":776},[688,5399,5121],{"class":2013},[688,5401,5402],{"class":787}," importKeyFromBase64 ",[688,5404,2303],{"class":791},[688,5406,5129],{"class":2013},[688,5408,4776],{"class":791},[688,5410,5411],{"class":1980},"base64Key",[688,5413,801],{"class":791},[688,5415,4878],{"class":694},[688,5417,4875],{"class":791},[688,5419,5135],{"class":694},[688,5421,935],{"class":791},[688,5423,1488],{"class":694},[688,5425,5142],{"class":791},[688,5427,2207],{"class":2013},[688,5429,871],{"class":791},[688,5431,5433,5435,5438,5440,5443,5445,5447],{"class":690,"line":5432},58,[688,5434,2040],{"class":2013},[688,5436,5437],{"class":787}," rawKeyBuffer",[688,5439,2046],{"class":791},[688,5441,5442],{"class":783}," base64ToBuffer",[688,5444,788],{"class":797},[688,5446,5411],{"class":787},[688,5448,911],{"class":797},[688,5450,5452,5454,5456,5458,5460,5462,5464,5466,5468,5470,5472,5474,5476,5478,5480,5482,5484,5486,5488,5490,5493,5495,5498,5500,5502,5504,5506,5508,5510,5512],{"class":690,"line":5451},59,[688,5453,2270],{"class":776},[688,5455,2106],{"class":776},[688,5457,4816],{"class":787},[688,5459,2072],{"class":791},[688,5461,4320],{"class":783},[688,5463,788],{"class":797},[688,5465,807],{"class":791},[688,5467,5328],{"class":697},[688,5469,807],{"class":791},[688,5471,2129],{"class":791},[688,5473,5437],{"class":787},[688,5475,2129],{"class":791},[688,5477,1971],{"class":791},[688,5479,3397],{"class":797},[688,5481,801],{"class":791},[688,5483,831],{"class":791},[688,5485,2415],{"class":697},[688,5487,807],{"class":791},[688,5489,4357],{"class":791},[688,5491,5492],{"class":2442}," true",[688,5494,2129],{"class":791},[688,5496,5497],{"class":797}," [",[688,5499,807],{"class":791},[688,5501,2458],{"class":697},[688,5503,807],{"class":791},[688,5505,2129],{"class":791},[688,5507,831],{"class":791},[688,5509,2467],{"class":697},[688,5511,807],{"class":791},[688,5513,5514],{"class":797},"])\n",[688,5516,5518],{"class":690,"line":5517},60,[688,5519,2280],{"class":791},[688,5521,5523],{"class":690,"line":5522},61,[688,5524,2088],{"emptyLinePlaceholder":1003},[688,5526,5528],{"class":690,"line":5527},62,[688,5529,1951],{"class":859},[688,5531,5533],{"class":690,"line":5532},63,[688,5534,5535],{"class":859}," * [同构] 使用 AES-GCM 算法加密字符串文本\n",[688,5537,5539,5541,5543,5545,5547],{"class":690,"line":5538},64,[688,5540,1961],{"class":859},[688,5542,1964],{"class":776},[688,5544,1968],{"class":1967},[688,5546,1981],{"class":1980},[688,5548,5549],{"class":859}," - 待加密的明文文本\n",[688,5551,5553,5555,5557,5559,5561],{"class":690,"line":5552},65,[688,5554,1961],{"class":859},[688,5556,1964],{"class":776},[688,5558,1968],{"class":1967},[688,5560,2544],{"class":1980},[688,5562,5563],{"class":859}," - CryptoKey 密钥对象\n",[688,5565,5567,5569,5571,5573],{"class":690,"line":5566},66,[688,5568,1961],{"class":859},[688,5570,1964],{"class":776},[688,5572,1993],{"class":1967},[688,5574,5575],{"class":859}," 返回打包了 \"IV\" 和 \"密文\" 的统一 Base64 字符串\n",[688,5577,5579],{"class":690,"line":5578},67,[688,5580,2008],{"class":859},[688,5582,5584,5586,5588,5591,5593,5595,5597,5599,5601,5603,5605,5607,5609,5611,5613,5615,5617,5619,5621,5623],{"class":690,"line":5583},68,[688,5585,777],{"class":776},[688,5587,5121],{"class":2013},[688,5589,5590],{"class":787}," encryptText ",[688,5592,2303],{"class":791},[688,5594,5129],{"class":2013},[688,5596,4776],{"class":791},[688,5598,2025],{"class":1980},[688,5600,801],{"class":791},[688,5602,4878],{"class":694},[688,5604,2129],{"class":791},[688,5606,2544],{"class":1980},[688,5608,801],{"class":791},[688,5610,5289],{"class":694},[688,5612,4875],{"class":791},[688,5614,5135],{"class":694},[688,5616,935],{"class":791},[688,5618,1975],{"class":694},[688,5620,5142],{"class":791},[688,5622,2207],{"class":2013},[688,5624,871],{"class":791},[688,5626,5628,5630,5632,5634,5636,5638],{"class":690,"line":5627},69,[688,5629,2040],{"class":2013},[688,5631,2043],{"class":787},[688,5633,2046],{"class":791},[688,5635,2049],{"class":791},[688,5637,2052],{"class":783},[688,5639,5640],{"class":797},"()\n",[688,5642,5644,5646,5648,5650,5652,5654,5656,5658,5660,5662,5664,5666,5668,5670],{"class":690,"line":5643},70,[688,5645,2040],{"class":2013},[688,5647,2613],{"class":787},[688,5649,801],{"class":791},[688,5651,2172],{"class":694},[688,5653,935],{"class":791},[688,5655,2832],{"class":694},[688,5657,5142],{"class":791},[688,5659,2046],{"class":791},[688,5661,2043],{"class":787},[688,5663,2072],{"class":791},[688,5665,2075],{"class":783},[688,5667,788],{"class":797},[688,5669,2025],{"class":787},[688,5671,911],{"class":797},[688,5673,5675],{"class":690,"line":5674},71,[688,5676,5677],{"class":859},"    \u002F\u002F 生成 12 字节的密码学安全伪随机数作为 IV (AES-GCM 标准推荐)\n",[688,5679,5681,5683,5685,5687,5689,5691,5693,5695,5697,5699,5701,5703,5705,5707,5709,5711,5713],{"class":690,"line":5680},72,[688,5682,2040],{"class":2013},[688,5684,2650],{"class":787},[688,5686,801],{"class":791},[688,5688,2172],{"class":694},[688,5690,935],{"class":791},[688,5692,2832],{"class":694},[688,5694,5142],{"class":791},[688,5696,2046],{"class":791},[688,5698,4826],{"class":787},[688,5700,2072],{"class":791},[688,5702,2659],{"class":783},[688,5704,788],{"class":797},[688,5706,2169],{"class":791},[688,5708,2172],{"class":783},[688,5710,788],{"class":797},[688,5712,2670],{"class":2220},[688,5714,5075],{"class":797},[688,5716,5718],{"class":690,"line":5717},73,[688,5719,5720],{"class":859},"    \u002F\u002F 执行加密，返回密文 ArrayBuffer\n",[688,5722,5724,5726,5729,5731,5733,5735,5737,5739,5741,5743,5745,5748,5750,5752,5754,5756,5758,5760,5762,5764,5766,5768,5770,5772,5774],{"class":690,"line":5723},74,[688,5725,2040],{"class":2013},[688,5727,5728],{"class":787}," cipherBuffer",[688,5730,801],{"class":791},[688,5732,4872],{"class":694},[688,5734,2046],{"class":791},[688,5736,2106],{"class":776},[688,5738,4816],{"class":787},[688,5740,2072],{"class":791},[688,5742,2458],{"class":783},[688,5744,788],{"class":797},[688,5746,5747],{"class":791},"{",[688,5749,3397],{"class":797},[688,5751,801],{"class":791},[688,5753,831],{"class":791},[688,5755,2415],{"class":697},[688,5757,807],{"class":791},[688,5759,2129],{"class":791},[688,5761,2650],{"class":797},[688,5763,801],{"class":791},[688,5765,2650],{"class":787},[688,5767,4357],{"class":791},[688,5769,2544],{"class":787},[688,5771,2129],{"class":791},[688,5773,2613],{"class":787},[688,5775,911],{"class":797},[688,5777,5779],{"class":690,"line":5778},75,[688,5780,5781],{"class":859},"    \u002F\u002F 将 IV（12字节）和密文拼接，方便单字符串传输\n",[688,5783,5785,5787,5790,5792,5794,5796,5798,5801,5803,5806,5809,5811,5813,5816],{"class":690,"line":5784},76,[688,5786,2040],{"class":2013},[688,5788,5789],{"class":787}," combined",[688,5791,2046],{"class":791},[688,5793,2049],{"class":791},[688,5795,2172],{"class":783},[688,5797,788],{"class":797},[688,5799,5800],{"class":787},"iv",[688,5802,2072],{"class":791},[688,5804,5805],{"class":787},"length",[688,5807,5808],{"class":791}," +",[688,5810,5728],{"class":787},[688,5812,2072],{"class":791},[688,5814,5815],{"class":787},"byteLength",[688,5817,911],{"class":797},[688,5819,5821,5824,5826,5829,5831,5833,5835,5837],{"class":690,"line":5820},77,[688,5822,5823],{"class":787},"    combined",[688,5825,2072],{"class":791},[688,5827,5828],{"class":783},"set",[688,5830,788],{"class":797},[688,5832,5800],{"class":787},[688,5834,2129],{"class":791},[688,5836,3199],{"class":2220},[688,5838,911],{"class":797},[688,5840,5842,5844,5846,5848,5850,5852,5854,5856,5859,5861,5863,5865,5867,5869],{"class":690,"line":5841},78,[688,5843,5823],{"class":787},[688,5845,2072],{"class":791},[688,5847,5828],{"class":783},[688,5849,788],{"class":797},[688,5851,2169],{"class":791},[688,5853,2172],{"class":783},[688,5855,788],{"class":797},[688,5857,5858],{"class":787},"cipherBuffer",[688,5860,2028],{"class":797},[688,5862,2129],{"class":791},[688,5864,2650],{"class":787},[688,5866,2072],{"class":791},[688,5868,5805],{"class":787},[688,5870,911],{"class":797},[688,5872,5874,5876,5878,5880,5883,5885,5887],{"class":690,"line":5873},79,[688,5875,2270],{"class":776},[688,5877,5344],{"class":783},[688,5879,788],{"class":797},[688,5881,5882],{"class":787},"combined",[688,5884,2072],{"class":791},[688,5886,4867],{"class":787},[688,5888,911],{"class":797},[688,5890,5892],{"class":690,"line":5891},80,[688,5893,2280],{"class":791},[688,5895,5897],{"class":690,"line":5896},81,[688,5898,2088],{"emptyLinePlaceholder":1003},[688,5900,5902],{"class":690,"line":5901},82,[688,5903,1951],{"class":859},[688,5905,5907],{"class":690,"line":5906},83,[688,5908,5909],{"class":859}," * [同构] 使用 AES-GCM 算法解密文本\n",[688,5911,5913,5915,5917,5919,5922],{"class":690,"line":5912},84,[688,5914,1961],{"class":859},[688,5916,1964],{"class":776},[688,5918,1968],{"class":1967},[688,5920,5921],{"class":1980}," combinedBase64",[688,5923,5924],{"class":859}," - 由 encryptText 生成的统一加密 Base64 字符串（内部含 IV）\n",[688,5926,5928,5930,5932,5934,5936],{"class":690,"line":5927},85,[688,5929,1961],{"class":859},[688,5931,1964],{"class":776},[688,5933,1968],{"class":1967},[688,5935,2544],{"class":1980},[688,5937,5938],{"class":859}," - 对应的 CryptoKey 密钥对象\n",[688,5940,5942],{"class":690,"line":5941},86,[688,5943,2008],{"class":859},[688,5945,5947,5949,5951,5954,5956,5958,5960,5963,5965,5967,5969,5971,5973,5975,5977,5979,5981,5983,5985,5987],{"class":690,"line":5946},87,[688,5948,777],{"class":776},[688,5950,5121],{"class":2013},[688,5952,5953],{"class":787}," decryptText ",[688,5955,2303],{"class":791},[688,5957,5129],{"class":2013},[688,5959,4776],{"class":791},[688,5961,5962],{"class":1980},"combinedBase64",[688,5964,801],{"class":791},[688,5966,4878],{"class":694},[688,5968,2129],{"class":791},[688,5970,2544],{"class":1980},[688,5972,801],{"class":791},[688,5974,5289],{"class":694},[688,5976,4875],{"class":791},[688,5978,5135],{"class":694},[688,5980,935],{"class":791},[688,5982,1975],{"class":694},[688,5984,5142],{"class":791},[688,5986,2207],{"class":2013},[688,5988,871],{"class":791},[688,5990,5992,5994,5997,5999,6001,6003,6005],{"class":690,"line":5991},88,[688,5993,2040],{"class":2013},[688,5995,5996],{"class":787}," combinedBuffer",[688,5998,2046],{"class":791},[688,6000,5442],{"class":783},[688,6002,788],{"class":797},[688,6004,5962],{"class":787},[688,6006,911],{"class":797},[688,6008,6010,6012,6015,6017,6019,6021,6023,6026],{"class":690,"line":6009},89,[688,6011,2040],{"class":2013},[688,6013,6014],{"class":787}," combinedBytes",[688,6016,2046],{"class":791},[688,6018,2049],{"class":791},[688,6020,2172],{"class":783},[688,6022,788],{"class":797},[688,6024,6025],{"class":787},"combinedBuffer",[688,6027,911],{"class":797},[688,6029,6031],{"class":690,"line":6030},90,[688,6032,6033],{"class":859},"    \u002F\u002F 从头部切出前 12 字节作为 IV\n",[688,6035,6037,6039,6041,6043,6045,6047,6049,6051,6053,6055,6057,6060,6062,6064,6066,6069],{"class":690,"line":6036},91,[688,6038,2040],{"class":2013},[688,6040,2650],{"class":787},[688,6042,801],{"class":791},[688,6044,2172],{"class":694},[688,6046,935],{"class":791},[688,6048,2832],{"class":694},[688,6050,5142],{"class":791},[688,6052,2046],{"class":791},[688,6054,6014],{"class":787},[688,6056,2072],{"class":791},[688,6058,6059],{"class":783},"slice",[688,6061,788],{"class":797},[688,6063,2240],{"class":2220},[688,6065,2129],{"class":791},[688,6067,6068],{"class":2220}," 12",[688,6070,911],{"class":797},[688,6072,6074],{"class":690,"line":6073},92,[688,6075,6076],{"class":859},"    \u002F\u002F 剩下的部分作为真正的密文\n",[688,6078,6080,6082,6084,6086,6088,6090,6092,6094,6096,6098,6100,6102,6104,6106],{"class":690,"line":6079},93,[688,6081,2040],{"class":2013},[688,6083,2690],{"class":787},[688,6085,801],{"class":791},[688,6087,2172],{"class":694},[688,6089,935],{"class":791},[688,6091,2832],{"class":694},[688,6093,5142],{"class":791},[688,6095,2046],{"class":791},[688,6097,6014],{"class":787},[688,6099,2072],{"class":791},[688,6101,6059],{"class":783},[688,6103,788],{"class":797},[688,6105,2670],{"class":2220},[688,6107,911],{"class":797},[688,6109,6111],{"class":690,"line":6110},94,[688,6112,2930],{"class":859},[688,6114,6116,6118,6120,6122,6124,6126,6128,6130,6132,6134,6136,6138,6140,6142,6144,6146,6148,6150,6152,6154,6156,6158,6160,6162,6164,6166,6168],{"class":690,"line":6115},95,[688,6117,2040],{"class":2013},[688,6119,2937],{"class":787},[688,6121,801],{"class":791},[688,6123,4872],{"class":694},[688,6125,2046],{"class":791},[688,6127,2106],{"class":776},[688,6129,4816],{"class":787},[688,6131,2072],{"class":791},[688,6133,2467],{"class":783},[688,6135,788],{"class":797},[688,6137,5747],{"class":791},[688,6139,3397],{"class":797},[688,6141,801],{"class":791},[688,6143,831],{"class":791},[688,6145,2415],{"class":697},[688,6147,807],{"class":791},[688,6149,2129],{"class":791},[688,6151,2650],{"class":797},[688,6153,801],{"class":791},[688,6155,2650],{"class":787},[688,6157,4357],{"class":791},[688,6159,2544],{"class":787},[688,6161,2129],{"class":791},[688,6163,2690],{"class":787},[688,6165,2072],{"class":791},[688,6167,4867],{"class":787},[688,6169,911],{"class":797},[688,6171,6173,6175,6177,6179,6181,6183],{"class":690,"line":6172},96,[688,6174,2040],{"class":2013},[688,6176,3019],{"class":787},[688,6178,2046],{"class":791},[688,6180,2049],{"class":791},[688,6182,3026],{"class":783},[688,6184,5640],{"class":797},[688,6186,6188,6190,6192,6194,6196,6198,6200],{"class":690,"line":6187},97,[688,6189,2270],{"class":776},[688,6191,3019],{"class":787},[688,6193,2072],{"class":791},[688,6195,3041],{"class":783},[688,6197,788],{"class":797},[688,6199,3046],{"class":787},[688,6201,911],{"class":797},[688,6203,6205],{"class":690,"line":6204},98,[688,6206,2280],{"class":791},[13,6208,6209],{},"TS 测试脚本",[13,6211,6212],{},"如果你在 Vite\u002FNuxt\u002FNext.js 项目或者使用了 ts-node \u002F bun \u002F deno 的后端环境中，可以直接引入并运行这段强类型的测试代码：",[679,6214,6217],{"className":766,"code":6215,"filename":6216,"language":769,"meta":502,"style":502},"import { decryptText, encryptText, exportKeyToBase64, generateAESKey, importKeyFromBase64 } from 'crypto'\n;(async () => {\n    try {\n        const rawData: string = '前后端全平台无缝传输的敏感数据 1234-abcd-TS-VERSION'\n        console.log('🔒 原始待加解密明文:', rawData)\n\n        \u002F\u002F ==========================================\n        \u002F\u002F 阶段一：在 A 端（例如 Node.js 后端）生成密钥并加密\n        \u002F\u002F ==========================================\n        const originalKey: CryptoKey = await generateAESKey()\n\n        \u002F\u002F 导出密钥为 Base64 字符串\n        const transportableKeyStr: string = await exportKeyToBase64(originalKey)\n        console.log('🔑 [传输中] 密钥已安全序列化为 Base64:', transportableKeyStr)\n\n        \u002F\u002F 对数据进行加密\n        const secureCipherText: string = await encryptText(rawData, originalKey)\n        console.log('📦 [传输中] 密文已安全打包（含IV）为 Base64:', secureCipherText)\n\n        \u002F\u002F ==========================================\n        \u002F\u002F 阶段二：在 B 端（例如现代 Web 浏览器前端）收到数据解密\n        \u002F\u002F ==========================================\n        console.log('\\n--- 数据已通过网络无缝抵达另一端 ---')\n\n        \u002F\u002F 1. 恢复强类型的 CryptoKey 实体\n        const receivedKey: CryptoKey = await importKeyFromBase64(transportableKeyStr)\n\n        \u002F\u002F 2. 还原数据内容\n        const decryptedOutput: string = await decryptText(secureCipherText, receivedKey)\n        console.log('🔓 [还原成功] 解密后的最终明文结果:', decryptedOutput)\n    } catch (error) {\n        console.error('❌ 密码学同构解密链路失败，错误原因: ', error)\n    }\n})()\n\n","test-crypto.ts",[42,6218,6219,6259,6275,6282,6303,6328,6332,6337,6342,6346,6365,6369,6374,6398,6421,6425,6430,6458,6481,6485,6489,6494,6498,6520,6524,6529,6553,6557,6562,6590,6613,6631,6655,6659],{"__ignoreMap":502},[688,6220,6221,6224,6226,6228,6230,6232,6234,6237,6239,6241,6243,6246,6249,6252,6254,6256],{"class":690,"line":691},[688,6222,6223],{"class":776},"import",[688,6225,1971],{"class":791},[688,6227,2908],{"class":787},[688,6229,2129],{"class":791},[688,6231,2578],{"class":787},[688,6233,2129],{"class":791},[688,6235,6236],{"class":787}," exportKeyToBase64",[688,6238,2129],{"class":791},[688,6240,2374],{"class":787},[688,6242,2129],{"class":791},[688,6244,6245],{"class":787}," importKeyFromBase64",[688,6247,6248],{"class":791}," }",[688,6250,6251],{"class":776}," from",[688,6253,831],{"class":791},[688,6255,4544],{"class":697},[688,6257,6258],{"class":791},"'\n",[688,6260,6261,6264,6266,6268,6271,6273],{"class":690,"line":506},[688,6262,6263],{"class":791},";",[688,6265,788],{"class":787},[688,6267,2014],{"class":2013},[688,6269,6270],{"class":791}," ()",[688,6272,2207],{"class":2013},[688,6274,871],{"class":791},[688,6276,6277,6280],{"class":690,"line":535},[688,6278,6279],{"class":776},"    try",[688,6281,871],{"class":791},[688,6283,6284,6287,6290,6292,6294,6296,6298,6301],{"class":690,"line":609},[688,6285,6286],{"class":2013},"        const",[688,6288,6289],{"class":787}," rawData",[688,6291,801],{"class":791},[688,6293,4878],{"class":694},[688,6295,2046],{"class":791},[688,6297,831],{"class":791},[688,6299,6300],{"class":697},"前后端全平台无缝传输的敏感数据 1234-abcd-TS-VERSION",[688,6302,6258],{"class":791},[688,6304,6305,6308,6310,6313,6315,6317,6320,6322,6324,6326],{"class":690,"line":624},[688,6306,6307],{"class":787},"        console",[688,6309,2072],{"class":791},[688,6311,6312],{"class":783},"log",[688,6314,788],{"class":797},[688,6316,807],{"class":791},[688,6318,6319],{"class":697},"🔒 原始待加解密明文:",[688,6321,807],{"class":791},[688,6323,2129],{"class":791},[688,6325,6289],{"class":787},[688,6327,911],{"class":797},[688,6329,6330],{"class":690,"line":856},[688,6331,2088],{"emptyLinePlaceholder":1003},[688,6333,6334],{"class":690,"line":863},[688,6335,6336],{"class":859},"        \u002F\u002F ==========================================\n",[688,6338,6339],{"class":690,"line":874},[688,6340,6341],{"class":859},"        \u002F\u002F 阶段一：在 A 端（例如 Node.js 后端）生成密钥并加密\n",[688,6343,6344],{"class":690,"line":890},[688,6345,6336],{"class":859},[688,6347,6348,6350,6353,6355,6357,6359,6361,6363],{"class":690,"line":896},[688,6349,6286],{"class":2013},[688,6351,6352],{"class":787}," originalKey",[688,6354,801],{"class":791},[688,6356,5289],{"class":694},[688,6358,2046],{"class":791},[688,6360,2106],{"class":776},[688,6362,2374],{"class":783},[688,6364,5640],{"class":797},[688,6366,6367],{"class":690,"line":905},[688,6368,2088],{"emptyLinePlaceholder":1003},[688,6370,6371],{"class":690,"line":2096},[688,6372,6373],{"class":859},"        \u002F\u002F 导出密钥为 Base64 字符串\n",[688,6375,6376,6378,6381,6383,6385,6387,6389,6391,6393,6396],{"class":690,"line":2138},[688,6377,6286],{"class":2013},[688,6379,6380],{"class":787}," transportableKeyStr",[688,6382,801],{"class":791},[688,6384,4878],{"class":694},[688,6386,2046],{"class":791},[688,6388,2106],{"class":776},[688,6390,6236],{"class":783},[688,6392,788],{"class":797},[688,6394,6395],{"class":787},"originalKey",[688,6397,911],{"class":797},[688,6399,6400,6402,6404,6406,6408,6410,6413,6415,6417,6419],{"class":690,"line":2143},[688,6401,6307],{"class":787},[688,6403,2072],{"class":791},[688,6405,6312],{"class":783},[688,6407,788],{"class":797},[688,6409,807],{"class":791},[688,6411,6412],{"class":697},"🔑 [传输中] 密钥已安全序列化为 Base64:",[688,6414,807],{"class":791},[688,6416,2129],{"class":791},[688,6418,6380],{"class":787},[688,6420,911],{"class":797},[688,6422,6423],{"class":690,"line":2149},[688,6424,2088],{"emptyLinePlaceholder":1003},[688,6426,6427],{"class":690,"line":2185},[688,6428,6429],{"class":859},"        \u002F\u002F 对数据进行加密\n",[688,6431,6432,6434,6437,6439,6441,6443,6445,6447,6449,6452,6454,6456],{"class":690,"line":2261},[688,6433,6286],{"class":2013},[688,6435,6436],{"class":787}," secureCipherText",[688,6438,801],{"class":791},[688,6440,4878],{"class":694},[688,6442,2046],{"class":791},[688,6444,2106],{"class":776},[688,6446,2578],{"class":783},[688,6448,788],{"class":797},[688,6450,6451],{"class":787},"rawData",[688,6453,2129],{"class":791},[688,6455,6352],{"class":787},[688,6457,911],{"class":797},[688,6459,6460,6462,6464,6466,6468,6470,6473,6475,6477,6479],{"class":690,"line":2267},[688,6461,6307],{"class":787},[688,6463,2072],{"class":791},[688,6465,6312],{"class":783},[688,6467,788],{"class":797},[688,6469,807],{"class":791},[688,6471,6472],{"class":697},"📦 [传输中] 密文已安全打包（含IV）为 Base64:",[688,6474,807],{"class":791},[688,6476,2129],{"class":791},[688,6478,6436],{"class":787},[688,6480,911],{"class":797},[688,6482,6483],{"class":690,"line":2277},[688,6484,2088],{"emptyLinePlaceholder":1003},[688,6486,6487],{"class":690,"line":2283},[688,6488,6336],{"class":859},[688,6490,6491],{"class":690,"line":2288},[688,6492,6493],{"class":859},"        \u002F\u002F 阶段二：在 B 端（例如现代 Web 浏览器前端）收到数据解密\n",[688,6495,6496],{"class":690,"line":2294},[688,6497,6336],{"class":859},[688,6499,6500,6502,6504,6506,6508,6510,6513,6516,6518],{"class":690,"line":2761},[688,6501,6307],{"class":787},[688,6503,2072],{"class":791},[688,6505,6312],{"class":783},[688,6507,788],{"class":797},[688,6509,807],{"class":791},[688,6511,6512],{"class":787},"\\n",[688,6514,6515],{"class":697},"--- 数据已通过网络无缝抵达另一端 ---",[688,6517,807],{"class":791},[688,6519,911],{"class":797},[688,6521,6522],{"class":690,"line":2768},[688,6523,2088],{"emptyLinePlaceholder":1003},[688,6525,6526],{"class":690,"line":2773},[688,6527,6528],{"class":859},"        \u002F\u002F 1. 恢复强类型的 CryptoKey 实体\n",[688,6530,6531,6533,6536,6538,6540,6542,6544,6546,6548,6551],{"class":690,"line":2779},[688,6532,6286],{"class":2013},[688,6534,6535],{"class":787}," receivedKey",[688,6537,801],{"class":791},[688,6539,5289],{"class":694},[688,6541,2046],{"class":791},[688,6543,2106],{"class":776},[688,6545,6245],{"class":783},[688,6547,788],{"class":797},[688,6549,6550],{"class":787},"transportableKeyStr",[688,6552,911],{"class":797},[688,6554,6555],{"class":690,"line":2795},[688,6556,2088],{"emptyLinePlaceholder":1003},[688,6558,6559],{"class":690,"line":5013},[688,6560,6561],{"class":859},"        \u002F\u002F 2. 还原数据内容\n",[688,6563,6564,6566,6569,6571,6573,6575,6577,6579,6581,6584,6586,6588],{"class":690,"line":5032},[688,6565,6286],{"class":2013},[688,6567,6568],{"class":787}," decryptedOutput",[688,6570,801],{"class":791},[688,6572,4878],{"class":694},[688,6574,2046],{"class":791},[688,6576,2106],{"class":776},[688,6578,2908],{"class":783},[688,6580,788],{"class":797},[688,6582,6583],{"class":787},"secureCipherText",[688,6585,2129],{"class":791},[688,6587,6535],{"class":787},[688,6589,911],{"class":797},[688,6591,6592,6594,6596,6598,6600,6602,6605,6607,6609,6611],{"class":690,"line":5078},[688,6593,6307],{"class":787},[688,6595,2072],{"class":791},[688,6597,6312],{"class":783},[688,6599,788],{"class":797},[688,6601,807],{"class":791},[688,6603,6604],{"class":697},"🔓 [还原成功] 解密后的最终明文结果:",[688,6606,807],{"class":791},[688,6608,2129],{"class":791},[688,6610,6568],{"class":787},[688,6612,911],{"class":797},[688,6614,6615,6618,6621,6623,6626,6629],{"class":690,"line":5090},[688,6616,6617],{"class":791},"    }",[688,6619,6620],{"class":776}," catch",[688,6622,4776],{"class":797},[688,6624,6625],{"class":787},"error",[688,6627,6628],{"class":797},") ",[688,6630,792],{"class":791},[688,6632,6633,6635,6637,6639,6641,6643,6646,6648,6650,6653],{"class":690,"line":5095},[688,6634,6307],{"class":787},[688,6636,2072],{"class":791},[688,6638,6625],{"class":783},[688,6640,788],{"class":797},[688,6642,807],{"class":791},[688,6644,6645],{"class":697},"❌ 密码学同构解密链路失败，错误原因: ",[688,6647,807],{"class":791},[688,6649,2129],{"class":791},[688,6651,6652],{"class":787}," error",[688,6654,911],{"class":797},[688,6656,6657],{"class":690,"line":5100},[688,6658,893],{"class":791},[688,6660,6661,6663],{"class":690,"line":5105},[688,6662,908],{"class":791},[688,6664,6665],{"class":787},")()\n",[968,6667,6668],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s6hCs, html code.shiki .s6hCs{--shiki-light:#9C3EDA;--shiki-light-font-style:italic;--shiki-default:#C792EA;--shiki-default-font-style:italic;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .sFweD, html code.shiki .sFweD{--shiki-light:#E2931D;--shiki-light-font-style:italic;--shiki-default:#FFCB6B;--shiki-default-font-style:italic;--shiki-dark:#FFCB6B;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":502,"searchDepth":535,"depth":535,"links":6670},[6671,6672,6673,6674,6682,6683,6684,6690,6691,6692],{"id":1040,"depth":506,"text":1041},{"id":1065,"depth":506,"text":1066},{"id":1178,"depth":506,"text":1179},{"id":1199,"depth":506,"text":1200,"children":6675},[6676,6677,6678,6679,6680,6681],{"id":1206,"depth":535,"text":1207},{"id":1246,"depth":535,"text":1247},{"id":1309,"depth":535,"text":1310},{"id":1358,"depth":535,"text":1359},{"id":1391,"depth":535,"text":1392},{"id":1430,"depth":535,"text":1431},{"id":1513,"depth":506,"text":1514},{"id":1864,"depth":506,"text":1865},{"id":1917,"depth":506,"text":1918,"children":6685},[6686,6687,6688,6689],{"id":1924,"depth":535,"text":1925},{"id":3063,"depth":535,"text":3064},{"id":3577,"depth":535,"text":3578},{"id":4102,"depth":535,"text":4103},{"id":4405,"depth":506,"text":4406},{"id":4502,"depth":506,"text":4503},{"id":4712,"depth":506,"text":4713},{"name":6694,"symbol":6695,"icon":6696,"id":896},"Node.js","node","material-icon-theme:nodejs-alt","2026-08-25 15:59:25",{"type":10,"value":6699},[6700,6703],[13,6701,6702],{},"在过去很长一段时间里，只要一提到在前端进行加密、解密、生成哈希（MD5\u002FSHA）或生成随机数，绝大多数开发者的第一反应就是 npm install crypto-js。作为曾经的功勋库，crypto-js 陪伴我们度过了无数个项目。",[13,6704,6705],{},"然而，随着 Web 标准的演进，现代浏览器早已内置了一个更强大、更安全、性能也更恐怖的官方武器——Web Crypto API。时至今日，如果你还在新项目里打包第三方的加密库，是时候了解一下为什么要换成原生 API 了。",{},"\u002Fblog\u002Fweb-crypto-api","---\ntitle: Web Crypto API 浏览器原生加密的终极指南\ndescription: Web Crypto API 是浏览器原生提供的一套加密接口，允许 JavaScript 脚本使用密码学原语来构建基于加密的系统。它自 2015 年 7 月起已得到各大浏览器的广泛支持，是一个相当成熟且稳定的 Web 标准。\narticleId: web-crypto-api\ncreateDate: \"2026-08-25 15:59:25\"\nupdateDate: \"2026-08-26 10:46:16\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260825111119031.webp\ntagIds: \n    - 12\ncategoryId: 10\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n在过去很长一段时间里，只要一提到在前端进行加密、解密、生成哈希（MD5\u002FSHA）或生成随机数，绝大多数开发者的第一反应就是 npm install crypto-js。作为曾经的功勋库，crypto-js 陪伴我们度过了无数个项目。\n\n然而，随着 Web 标准的演进，现代浏览器早已内置了一个更强大、更安全、性能也更恐怖的官方武器——Web Crypto API。时至今日，如果你还在新项目里打包第三方的加密库，是时候了解一下为什么要换成原生 API 了。\n\u003C!--more-->\n\n## 1. 什么是 Web Crypto API？\nWeb Crypto API 是浏览器原生提供的一套加密接口，允许 JavaScript 脚本使用密码学原语来构建基于加密的系统。它自 2015 年 7 月起已得到各大浏览器的广泛支持，是一个相当成熟且稳定的 Web 标准。\n\n在 Web Crypto 规范诞生前，部分浏览器为了满足加密需求，在全局实现了一个名为 Crypto 的接口(即 window.crypto)。但正由于这样，当时各大浏览器的实现缺乏统一的 W3C 标准，定义模糊，且在密码学意义上是不够严谨和安全的（not cryptographically sound）。\n\n当正式的 Web Crypto API 标准（支持 encrypt、decrypt、sign、verify 等现代异步加密操作）推出时，为了彻底避免和老旧、不安全的旧接口方法发生命名混淆与冲突，W3C 规范决定将这些低底层的密码学核心方法群全部打包进一个全新的独立接口中，这就是 SubtleCrypto。你可以通过全局对象的 crypto.subtle 属性来访问它。\n\n由于旧的全局 crypto 对象并没有被废除（它依然保留了诸如密码学安全的伪随机数生成器 crypto.getRandomValues() 和 crypto.randomUUID() 等简单的同步方法），因此所有新版的 SubtleCrypto 复杂加密算法全部被挂载到了它的下级属性中。你必须通过 crypto.subtle 属性才能访问到这一整套现代加解密方法。\n\nNode.js 最早在 v15.0.0 引入了 Web Crypto API 接口。直到 Node.js 19.0.0，官方正式去掉了实验性警告，将其标记为 稳定版本（Stable），并且默认在全局作用域挂载了 globalThis.crypto。\n\n::warning\n重要提示：在现代浏览器中，为了保障密钥安全，crypto.subtle 属性被限制为只能在安全上下文（HTTPS 协议或 localhost）下才能被成功访问。如果你在普通的非加密 HTTP 网页里调用 crypto.subtle，它会直接返回 undefined。\n::\n## 2. 为什么选择 Web Crypto API？\n在决定是否在 Web 项目中使用 Web Crypto API 时，通常是因为它相比传统的第三方加密库（如 CryptoJS, jsencrypt, forge 等）在安全性、性能和原生支持度上带来了降维打击的优势。\n1. **防 XSS 攻击的“密钥黑盒”机制（核心安全优势）** : 这是选择Web Crypto API最关键的安全理由。\n- **传统加密库的痛点：** 如果你用 CryptoJS，密钥必须以明文字符串或 Uint8Array 的形式存在于 JavaScript 变量、localStorage 或 sessionStorage 中。一旦网站遭受 XSS（跨站脚本）攻击，黑客可以直接读取并盗走你的密钥。\n- **Web Crypto 的解决办法：** 它引入了 CryptoKey 对象。在生成或导入密钥时，如果设置 extractable: false，这个密钥在创建后将永远无法通过 JavaScript 读取、打印或导出。它被死死封锁在浏览器的底层安全内存中。黑客即使通过 XSS 控制了你的页面，也拿不到密钥本身，只能在本地调用它，大大降低了密钥泄露的风险。\n2. **硬件级的高性能与非阻塞（异步原生）**\n- **原生 C++ \u002F 汇编实现：** Web Crypto API 是由浏览器底层（基于 OpenSSL 或操作系统自带的密码学库）用原生代码实现的。相比纯 JavaScript 编写的加密库，它的运行速度快了数十倍到上百倍。\n- **异步非阻塞：** 传统的加密库（如 CryptoJS）大都是同步执行的。当计算大文件哈希，或者进行复杂的 RSA 大素数生成时，会直接卡死浏览器的 UI 主线程，导致页面瞬间卡顿或未响应。而 Web Crypto 的所有核心方法（如 encrypt、digest）全部是异步 Promise 机制，浏览器会将其交给底层的系统线程去算，完全不影响前端界面的流畅度。\n3. **密码学安全的伪随机数生成器 (CSPRNG)**: 在密码学中，随机数的质量决定了加密的生死。\n- **传统的隐患：** JavaScript 原生的 Math.random() 是非密码学安全的，它的随机轨迹可以被算法预测，绝不能用于生成加密密钥、IV（初始化向量）或盐值。\n- **Web Crypto 的保障：** 提供了 crypto.getRandomValues()，它直接调用操作系统底层的硬件熵源（如系统的 \u002Fdev\u002Furandom 或 CAPI），生成密码学安全的高强度真随机数，保障加密系统的根基不可被破解。\n4. **零依赖，极致减小打包体积 (Zero-Bundle)**\n- **传统加密库的痛点：** 引入 CryptoJS、JSEncrypt 或 Forge 会让前端的 Vendor 打包体积（Bundle Size）平白无故增加几十 KB 甚至几百 KB，影响首屏加载速度。\n- **Web Crypto 的优势：** 它是现代浏览器的标准内置 API，不需要 npm install 任何第三方包。直接开箱即用，让前端工程更加轻量、纯净。\n5. **行业标准规范，跨端兼容性完美**\n- **大厂和 W3C 背书：** 它遵循严格的 W3C 规范，由各大浏览器厂商共同维护和不断优化。\n- **环境通用性：** 目前 Web Crypto API 的覆盖率已接近 100%。不仅在 Chrome、Safari、Edge、Firefox 浏览器中完美支持，在现代的 Node.js (v15+)、Deno、Bun 以及 Cloudflare Workers 等服务端\u002F边缘计算环境中也实现了完全一致的 API。这使得你写的一套加解密代码，可以无缝在前端和服务端之间复用。\n## 3. 什么时候不应该选择它？\n使用 Web Crypto API 有唯一的限制条件：\n- **非安全上下文限制：** 它强制要求 HTTPS 环境（本地开发支持 localhost 或 127.0.0.1）。如果你的网站部署在纯 HTTP 生产环境下，crypto.subtle 会直接返回 undefined 无法工作。\n- **需要高层封装：** 它提供的是非常底层的“密码学原语”（Raw Primitives），不提供像“一键生成 JWT”或者“一键做密码信封”这样的高级功能，开发者需要自己处理字节对齐、IV 传递等微秒的细节。\n## 4. Web Crypto API核心接口\nWeb Crypto API（通常称为 crypto.subtle）的核心接口主要由以下 5 个标准接口（Interfaces） 和 1 个全局入口 组成。它们构成了浏览器原生密码学生态的基石。\n### 4.1 全局入口对象Crypto\n虽然这不是单独的加解密接口，但它是所有 Web 加密功能的总入口，挂载在全局 window.crypto（或 globalThis.crypto）上。Crypto提供基础的加密功能，主要包括：\n- **核心作用：** 提供基础的同步安全原语。\n- **常用方法：**\n   - **crypto.getRandomValues()：** 生成密码学安全的伪随机数（常用于生成 IV 或盐）。\n   - **crypto.randomUUID()：** 快速生成一个符合 RFC 4122 标准的随机 UUID 字符串。\n   - **crypto.subtle：** 指向核心异步加密接口 SubtleCrypto 的指针。\n### 4.2  核心操作员SubtleCrypto\n这是整个 Web Crypto API 中最重要、最核心的接口。所有的实际异步加解密、签名、密钥派生等操作都在这里执行。SubtleCrypto 提供的主要方法包括：\n- **核心作用：** 提供一系列底层、底层的异步密码学原语方法（全部返回 Promise）。\n- **核心方法（按功能分类）：**\n    - **加密与解密：** encrypt() \u002F decrypt()\n    - **签名与验证：** sign() \u002F verify()\n    - **哈希计算：** digest()\n    - **密钥生成：** generateKey()\n    - **密钥导入与导出：** importKey() \u002F exportKey()\n    - **密钥包装与解包：** wrapKey() \u002F unwrapKey()\n    - **密钥派生：** deriveKey() \u002F deriveBits()\n### 4.3 密钥实体CryptoKey\n该接口代表一个在浏览器中生成的、受保护的密钥对象。为了安全，浏览器的 SubtleCrypto 方法不直接操作纯文本的密钥字符串（如 \"my-secret-key\"），而是操作 CryptoKey 实例。\n- **核心作用：** 作为参数传递给 SubtleCrypto 的各项方法。\n- **核心属性（只读）：**\n   - **type：** 密钥类型（\"secret\" 对称加密、\"private\" 私钥、\"public\" 公钥）。\n   - **extractable：** 布尔值。如果为 false，该密钥在创建后绝对无法从内存中被导出或用 JS 打印出来，防止 XSS 攻击窃取密钥。\n   - **algorithm：** 绑定该密钥的算法对象（例如绑定的 AES-GCM 或 RSA-PSS 等参数）。\n   - **usages：** 该密钥被允许的用途数组（例如 ['encrypt', 'decrypt']）。\n### 4.4 非对称密钥对CryptoKeyPair\n当使用 RSA、ECDSA 等非对称加密算法时，crypto.subtle.generateKey() 返回的不是单个密钥，而是一个包含公钥和私钥的 CryptoKeyPair 对象。\n- **核心作用：** 容器对象，封装非对称密钥对。\n- **核心属性：**\n   - **publicKey：** 一个 CryptoKey 实例，代表公钥（用于加密或验证签名）。\n   - **privateKey：** 一个 CryptoKey 实例，代表私钥（用于解密或生成签名）。\n### 4.5 算法配置对象AlgorithmIdentifier\n虽然它在技术上是一个规范定义的字典对象（Dictionary），而不是传统的类或接口，但它是每个 API 都必传的灵魂参数。\n- **核心作用：** 用来指定具体的密码学算法名称以及其特有的初始化附加参数（如 IV、盐值、计数器等）。\n- **常见表现形式：** \n   - **哈希配置：** { name: \"SHA-256\" }\n   - **AES-GCM 配置：** { name: \"AES-GCM\", iv: Uint8Array, tagLength: 128 }\n   - **PBKDF2（密码派生）配置：** { name: \"PBKDF2\", salt: Uint8Array, iterations: 100000, hash: \"SHA-256\" }\n\n### 4.6 核心接口对比速查表\n| 接口名称 | 角色定位 | 非安全上下文（HTTP）使用规则 | 典型返回值 \u002F 用途 |\n| --- | --- | --- | --- |\n| Crypto | 全局大管家 | 是（部分方法受限） | 提供crypto.subtle入口、用于生成UUID |\n| SubtleCrypto | 核心工具库 | 否（必须在HTTPS\u002Flocalhost环境下使用） | 返回`Promise\u003CArrayBuffer>`，用于生成密文、哈希等加密核心操作 |\n| CryptoKey | 密钥黑盒 | 否 | 作为安全载体，直接传递给加解密函数使用 |\n| CryptoKeyPair | 密钥对容器 | 否 | 封装返回包含publicKey和privateKey的密钥对对象 |\n## 5. Web Crypto API支持的主流算法\n1. **对称加密（Symmetric）表**\n\n| 算法标识符 | 支持的操作 | 推荐搭配与技术参数 | 典型应用场景 |\n| --- | --- | --- | --- |\n| AES-GCM（强烈推荐） | encrypt、decrypt、generateKey、importKey、exportKey、wrapKey、unwrapKey | 密钥支持128\u002F192\u002F256位，IV推荐96位（12字节） | 传输数据加解密、本地缓存加密，自带防篡改认证标签 |\n| AES-CBC | encrypt、decrypt、generateKey、importKey、exportKey、wrapKey、unwrapKey | 密钥支持128\u002F192\u002F256位，IV固定128位（16字节） | 兼容老旧遗留系统的对称加解密业务 |\n| AES-CTR | encrypt、decrypt、generateKey、importKey、exportKey、wrapKey、unwrapKey | 计数器模式，支持流式处理 | 高频非对齐的流式数据区块加解密 |\n\n- AES-GCM 是当前Web场景下的首选方案，硬件加速支持度高，同时自带消息认证能力，无需额外实现哈希校验逻辑，安全性和开发效率都更优。\n- 不同算法的IV长度要求严格，比如AES-CBC必须使用固定16字节的IV，否则会直接触发解密失败。\n- 三款算法都完整覆盖了密钥生成、导入导出、包裹\u002F解包裹密钥的全流程操作，完全适配Web Crypto的全场景开发需求。\n\n2. **非对称加密算法（Asymmetric）表**\n\n| 算法标识符 | 支持的操作 | 推荐搭配与技术参数 | 典型应用场景 |\n| --- | --- | --- | --- |\n| RSA-OAEP（强烈推荐） | encrypt, decrypt, generateKey, importKey, exportKey, wrapKey, unwrapKey | 模数：2048, 4096 位哈希：推荐 SHA-256 | 混合加密体系中用于加密“对称密钥”，或加密超短敏感字段 |\n\nRSA-OAEP是Web场景下非对称加密的首选方案，它通过最优非对称加密填充机制，解决了传统“教科书RSA”的密文可延展性安全缺陷，在随机预言模型下可以抵御适应性选择密文攻击。由于非对称加密的特性，它不适合直接加密大体积数据，行业通用的最佳实践就是用它加密AES等对称密钥，再用对称算法加密实际业务数据，兼顾安全性和性能效率。\n\n3. **数字签名算法（Signature）表**\n\n| 算法名称 | 支持的操作 | 推荐搭配与技术参数| 典型应用场景 |\n| --- | --- | --- | --- |\n| ECDSA（强烈推荐） | sign、verify、generateKey、importKey、exportKey | 椭圆曲线：P-256、P-384、P-521 | 现代高并发身份验签、JWT签名、区块链节点验签 |\n| RSASSA-PKCS1-v1_5 | sign、verify、generateKey、importKey、exportKey | 模数≥2048位，哈希推荐SHA-256 | 传统企业级API签名、老旧版本JWT签名验签 |\n| RSA-PSS | sign、verify、generateKey、importKey、exportKey | RSA概率签名方案，密码学严谨度极高 | 金融级或司法级等高安全要求的数字签名场景 |\n| HMAC | sign、verify、generateKey、importKey、exportKey | 基于哈希的密钥消息认证码 | 前后端API请求防篡改哈希签名，如AWS签名机制 |\n\n- ECDSA 是Web场景下的首选签名方案，密钥体积小、验签速度快，非常适配高并发的现代Web服务。\n- RSA系列算法兼容性极强，适合需要对接老旧系统的业务场景，其中RSA-PSS的抗攻击能力远高于传统的RSASSA-PKCS1-v1_5。\n- HMAC实现成本低，是轻量API防篡改签名的最优选择。\n\n4. **单向哈希算法（Digest）表**\n\n| 算法名称 | 支持的操作 | 推荐搭配与技术参数 | 典型应用场景 |\n| --- | --- | --- | --- |\n| SHA-256 | digest | 无需密钥，单向不可逆 | 文件完整性校验（秒传场景）、数据防篡改指纹生成 |\n| SHA-384 | digest | 无需密钥，单向不可逆，安全强度高于SHA-256 | 高敏感数据校验、金融级业务的完整性验证 |\n| SHA-512 | digest | 无需密钥，单向不可逆，安全强度最高 | 司法级、军工级等高安全要求场景的哈希校验 |\n\n这三款同属SHA-2家族哈希算法，都具备单向不可逆的核心特性，无法从最终哈希值反推原始输入内容，仅用于生成数据唯一指纹，不能直接用于加解密还原原始数据。安全强度随输出位数提升而升高，同时计算性能也会小幅下降，普通业务场景优先选择SHA-256即可满足需求。\n\n5. **密钥派生算法（Key Derivation）表**\n\n| 算法名称 | 支持的操作 | 推荐搭配与技术参数 | 典型应用场景 |\n| --- | --- | --- | --- |\n| ECDH | deriveKey、deriveBits、generateKey、importKey、exportKey | 椭圆曲线：Diffie-Hellman | 两个终端在不安全信道中，安全地协商出一致的对称密钥 |\n| PBKDF2 | deriveKey、deriveBits、importKey | 基于密码的密钥派生，推荐迭代≥100000次 | 将用户输入的简短文明密码，转换为符合AES标准的高强度密钥 |\n| HKDF | deriveKey、deriveBits、importKey | 基于HMAC的密钥扩展算法 | 从一个基础主密钥，安全地扩展派生出多个子密钥 |\n\n- ECDH 是现代网络通信中密钥协商的核心方案，双方全程不需要直接传输最终的共享密钥，仅通过交换椭圆曲线公钥就能各自计算出完全一致的会话密钥，安全性极高。\n- PBKDF2 专门针对低熵的用户密码设计，通过高迭代次数大幅提升暴力破解的成本，是密码类密钥衍生的行业标准方案。\n- HKDF 面向已经具备高熵的主密钥材料，能高效地将单个主密钥拆分扩展为多个用途独立的子密钥，广泛应用于TLS等现代加密协议中。\n## 6. Web Crypto API 不支持的主流算法\n| 算法名称 | 不支持原因 | 替代实现方案 |\n| --- | --- | --- |\n| MD5 | 已被密码学界证实存在碰撞漏洞，安全性完全失效 | 引入crypto-js等第三方库实现或使用 SHA-256 |\n| SM2\u002FSM3\u002FSM4国密系列 | 浏览器国际标准未原生内置国密算法 | 引入sm-crypto等国密第三方库实现 |\n| ChaCha20-Poly1305\u002FEd25519 | 目前尚未完全普及到所有主流浏览器的 crypto.subtle 中 | 引入第三方加密库补充实现 |\n## 7. 常用操作示例\n以下是整理的 Web Crypto API (crypto.subtle) 最核心、最常用的四大标准代码示例（哈希生成、密钥生成、加密、解密）。需要特别提醒的是：所有 crypto.subtle 的操作都是异步的，都会返回一个 Promise，因此必须配合 async\u002Fawait 使用。\n### 7.1 对称加密AES-GCM示例\nAES-GCM (Galois\u002FCounter Mode) 是一种非常流行且强大的认证加密（AEAD, Authenticated Encryption with Associated Data） 模式。你可以把它理解为一种“二合一”的加密模式：它在高效加密数据的同时，还能确保数据没有被篡改。\n\nAES-GCM 是兼具高性能和高安全性的认证加密模式，特别适合在 Web Crypto API 这类原生环境中使用。它的安全性高度依赖于每次加密都使用唯一且不可预测的 IV。遵循这一核心原则，并妥善管理密钥、认真验证认证标签，就能为你的 Web 应用构建起一道坚实的数据安全防线。\n\n1. **计算文本哈希摘要 (Digest)**：这是最简单的操作，常用于生成文件的 SHA-256。它不需要密钥。\n```js\n\u002F**\n * 计算字符串的 SHA-256 哈希值\n * @param {string} text - 输入的文本\n * @returns {Promise\u003Cstring>} Hex 格式的哈希字符串\n *\u002F\nasync function generateHash(text) {\n    \u002F\u002F 1. 将文本编码为 Uint8Array 字节流\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    \u002F\u002F 2. 使用 crypto.subtle.digest 生成哈希（返回 ArrayBuffer）\n    const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\n    \u002F\u002F 3. 将 ArrayBuffer 转换为常见的十六进制 (Hex) 字符串\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\n    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n    \n    return hashHex;\n}\n\n\u002F\u002F 使用示例：\nconst sha256Result = await generateHash(\"Hello World\");\n```\n2. **生成对称加密密钥 (Generate Key)**：在加密数据之前，必须先通过 subtle 算法生成一个标准的加密密钥对象（CryptoKey）。这里以主流的 AES-GCM 算法为例：\n```js\n\u002F**\n * 生成一个用于 AES-GCM 加密的 256 位随机密钥\n * @returns {Promise\u003CCryptoKey>} 返回 CryptoKey 对象\n *\u002F\nasync function generateAESKey() {\n    return await crypto.subtle.generateKey(\n        {\n        name: 'AES-GCM',\n        length: 256 \u002F\u002F 密钥长度支持 128, 192, 或 256 位\n        },\n        false, \u002F\u002F 是否允许该密钥被导出（如果设为 false，密钥无法脱离当前浏览器，安全性极高）\n        ['encrypt', 'decrypt'] \u002F\u002F 该密钥被允许用来做什么操作\n    );\n}\n\n```\n3. **数据加密 Encrypt**：使用生成的密钥和 AES-GCM 算法对敏感文本进行加密。为了安全，AES-GCM 要求每次加密必须配合一个随机的初始化向量 (IV)。\n```js\n\u002F**\n * 对文本进行 AES-GCM 加密\n * @param {string} text - 待加密的明文\n * @param {CryptoKey} key - 上一步生成的 CryptoKey 对象\n * @returns {Promise\u003C{cipherText: ArrayBuffer, iv: Uint8Array}>} 返回密文和IV\n *\u002F\nasync function encryptText(text, key) {\n    const encoder = new TextEncoder();\n    const encodedText = encoder.encode(text);\n\n    \u002F\u002F AES-GCM 推荐使用 12位（96位）的高安全伪随机数作为 IV\n    \u002F\u002F 注意：这里使用的是外部同步方法 getRandomValues 生成随机数\n    const iv = crypto.getRandomValues(new Uint8Array(12));\n\n    \u002F\u002F 执行加密\n    const cipherText = await crypto.subtle.encrypt(\n        {\n        name: 'AES-GCM',\n        iv: iv \u002F\u002F 加密参数必须包含 IV\n        },\n        key, \u002F\u002F 密钥\n        encodedText \u002F\u002F 明文数据\n    );\n\n    \u002F\u002F 需要同时把密文和 IV 返回，因为解密时必须提供一模一样的 IV\n    return { cipherText, iv };\n}\n\n```\n4. **数据解密 Decrypt**：传入加密时使用的 CryptoKey、IV 和密文数组，将其还原为人类可读的明文字符串。\n```js\n\u002F**\n * 对 AES-GCM 密文进行解密\n * @param {ArrayBuffer} cipherText - 密文数据\n * @param {CryptoKey} key - 加密时使用的同一个密钥\n * @param {Uint8Array} iv - 加密时对应的随机 IV\n * @returns {Promise\u003Cstring>} 解密后的明文字符串\n *\u002F\nasync function decryptText(cipherText, key, iv) {\n    \u002F\u002F 执行解密\n    const decryptedBuffer = await crypto.subtle.decrypt(\n        {\n        name: 'AES-GCM',\n        iv: iv \u002F\u002F 必须传入与加密时完全相同的 IV\n        },\n        key,\n        cipherText\n    );\n\n    \u002F\u002F 将 ArrayBuffer 字节解码还原为字符串\n    const decoder = new TextDecoder();\n    return decoder.decode(decryptedBuffer);\n}\n```\n::tip\n如果要在项目中保存或传输生成的密钥和密文，通常需要通过 crypto.subtle.exportKey('raw', key) 将密钥导出成字节，再用 btoa() 或 Base64 方案 转换成可传输的字符串格式。\n::\n### 7.2 非对称加密RSA-OAEP示例\n非对称加密使用公钥加密、私钥解密，常用于非对称场景或加密对称密钥（如密钥交换）。这里使用最安全的 RSA-OAEP 算法。\n\n1. **生成 RSA 密钥对**\n```js\n\u002F**\n * 生成用于 RSA-OAEP 加解密的 2048 位密钥对\n * @returns {Promise\u003CCryptoKeyPair>} 返回包含公钥和私钥的对象\n *\u002F\nasync function generateRSAKeyPair() {\n    return await crypto.subtle.generateKey(\n        {\n            name: \"RSA-OAEP\",\n            modulusLength: 2048, \u002F\u002F 密钥长度，2048 位是目前的标准安全线\n            publicExponent: new Uint8Array([1, 0, 1]), \u002F\u002F 等于 65537，固定的密码学标准常数\n            hash: \"SHA-256\", \u002F\u002F 内部使用的哈希算法\n        },\n        true, \u002F\u002F 是否允许导出\n        [\"encrypt\", \"decrypt\"] \u002F\u002F 用途分配\n    );\n}\n```\n2. **使用公钥加密**\n```js\n\u002F**\n * 使用 RSA 公钥加密文本\n *\u002F\nasync function rsaEncrypt(text, publicKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    \u002F\u002F 返回 ArrayBuffer 格式的密文\n    return await crypto.subtle.encrypt(\n        { name: \"RSA-OAEP\" },\n        publicKey,\n        data\n    );\n}\n```\n3. **使用私钥解密**\n```js\n\u002F**\n * 使用 RSA 私钥解密文本\n *\u002F\nasync function rsaDecrypt(cipherText, privateKey) {\n    const decryptedBuffer = await crypto.subtle.decrypt(\n        { name: \"RSA-OAEP\" },\n        privateKey,\n        cipherText\n    );\n\n    const decoder = new TextDecoder();\n    return decoder.decode(decryptedBuffer);\n}\n```\n### 7.3  数字签名与验证 (RSASSA-PKCS1-v1_5)\n数字签名常用于防止数据被篡改并确认发送者身份。其逻辑是：私钥签名、公钥验证。这里使用最通用的 RSASSA-PKCS1-v1_5 算法。\n\n1. **生成数字签名的 RSA 密钥对**\n```js\n\u002F**\n * 生成用于数字签名的 RSA 密钥对\n *\u002F\nasync function generateSignKeyPair() {\n    return await crypto.subtle.generateKey(\n        {\n        name: \"RSASSA-PKCS1-v1_5\",\n        modulusLength: 2048,\n        publicExponent: new Uint8Array([1, 0, 1]),\n        hash: \"SHA-256\",\n        },\n        true,\n        [\"sign\", \"verify\"] \u002F\u002F 注意：这里的用途是签名和验证\n    );\n}\n```\n2. **使用私钥对数据生成签名**\n```js\n\n\u002F**\n * 使用私钥对数据生成签名\n * @returns {Promise\u003CArrayBuffer>} 返回签名摘要\n *\u002F\nasync function signData(text, privateKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    return await crypto.subtle.sign(\n        { name: \"RSASSA-PKCS1-v1_5\" },\n        privateKey,\n        data\n    );\n}\n```\n3. **公钥验证签名是否有效**\n```js\n\n\u002F**\n * 使用公钥验证签名是否有效\n * @returns {Promise\u003Cboolean>} 验证成功返回 true，被篡改则返回 false\n *\u002F\nasync function verifyData(text, signature, publicKey) {\n    const encoder = new TextEncoder();\n    const data = encoder.encode(text);\n\n    return await crypto.subtle.verify(\n        { name: \"RSASSA-PKCS1-v1_5\" },\n        publicKey,\n        signature, \u002F\u002F 之前生成的签名 ArrayBuffer\n        data \u002F\u002F 原始数据\n    );\n}\n```\n### 7.4 密钥的导入与导出 (Import \u002F Export)\n在实际业务中，密钥不能只存在于浏览器内存中，我们需要将其导出为字符串传给后端，或者将后端的字符串密钥导入为浏览器可识别的 CryptoKey 对象。\n\nWeb Crypto 支持多种格式，最常用的是 JWK (JSON Web Key) 格式（易读、跨平台）和 raw\u002Fspki\u002Fpkcs8（二进制字节流）。\n\n1. **导出密钥为 JSON (JWK 格式)**\n```js\n\u002F**\n * 将 CryptoKey 密钥对象导出为标准的 JSON 对象 (JWK)\n * @param {CryptoKey} key \n * @returns {Promise\u003CObject>} 可直接用于传输或 JSON.stringify 的对象\n *\u002F\nasync function exportKeyToJWK(key) {\n    return await crypto.subtle.exportKey(\"jwk\", key);\n}\n```\n2. **将 JSON 导入回密钥对象**\n```js\n\u002F**\n * 将 JWK 格式的 JSON 对象导入还原为可用的 AES-GCM 密钥\n * @param {Object} jwkObject \n * @returns {Promise\u003CCryptoKey>}\n *\u002F\nasync function importKeyFromJWK(jwkObject) {\n    return await crypto.subtle.importKey(\n        \"jwk\",\n        jwkObject,\n        { name: \"AES-GCM\" }, \u002F\u002F 必须指定对应的算法\n        true, \u002F\u002F 是否允许再次导出\n        [\"encrypt\", \"decrypt\"] \u002F\u002F 该密钥允许的用途\n    );\n}\n```\n## 8 避坑指南\n1. **陷阱一：IV 重复使用**\n- **问题：** 在 AES-GCM 等对称加密中，重复使用相同的初始化向量（IV）会导致密钥流重复，严重破坏加密安全性。\n- **正确做法：**\n    - 每次加密都使用 crypto.getRandomValues() 生成新的随机 IV\n    - AES-GCM 模式推荐使用 12 字节（非 16 字节！）的 IV\n    - 同一密钥下 IV 重复概率应低于 2⁻³²\n    - IV 不需要保密，但必须唯一——记得将 IV 与密文一起存储\n\n2. **陷阱二：密钥管理不当**\n- **常见错误：**\n    - 将密钥存储在 localStorage 或 Cookie 中\n    - 使用不安全的密钥传输方式\n    - 未设置适当的密钥使用限制\n- **安全建议：**\n    - 敏感会话密钥存储在 Web Worker 内存中\n    - 需要持久化的密钥使用 IndexedDB\n    - 使用 exportKey 和 importKey 安全地传输公钥\n\n3. **陷阱三：算法选择失误**\n- 不要使用 SHA-1 或 MD5 进行哈希\n- 不要使用 ECB 模式的 AES 加密\n- RSA 密钥长度至少 2048 位\n\n## 9 最佳实践\n1. **使用方式选型指南推荐**\n\n自 Node.js 19+ 起，Web Crypto API 已成为内置标准，可通过以下方式访问：\n```js\n\u002F\u002F 方式一：使用 globalThis\nconst { subtle } = globalThis.crypto;\n\n\u002F\u002F 方式二：使用 Node.js 模块\nconst { webcrypto } = require('node:crypto');\nconst { subtle } = webcrypto;\n```\n这两种方式虽然最终都能让你获取到 subtle 接口，但它们在设计哲学、模块机制、环境通用性以及底层依赖上有着本质的区别。\n\n| 对比维度 | 方式一：globalThis.crypto | 方式二：require('node:crypto') |\n| --- | --- | --- |\n| 本质定位 | Web标准API（与浏览器对齐） | Node.js原生模块API（特定服务端） |\n| 引入方式 | 零依赖，直接全局访问 | 需要显式通过require引入模块 |\n| 跨端通用性 | 极高（同构JavaScript） | 极低（只能在Node.js运行） |\n| 底层实现 | 浏览器内核（前端）\u002F Node V8底层封装（后端） | 强依赖Node.js内置的OpenSSL库 |\n| 执行上下文 | 必须在安全上下文（前端限制） | 服务端环境，无任何安全上下文限制 |\n\n**推荐使用\"globalThis.crypto\"的场景：** 正在编写纯前端项目、前后端全栈通用工具库（Isomorphic Lib），或者代码需要部署在 Cloudflare Workers、Vercel Edge 等现代边缘计算架构中。\n\n**推荐使用\"require('node:crypto')\"的场景：** 正在编写纯 Node.js 服务端项目（如大型后端服务、CLI 工具），且除了 Web Crypto 之外，还需要用到 Node.js 特有的高级安全特性（如流式加密大文件、硬件安全模块 HSM 交互等）。\n\n2. **使用细节建议**\n\nWeb Crypto API 是浏览器原生加密的黄金标准。它以零依赖、高性能、高安全性的优势，正在逐步取代各种第三方加密库。然而，正如其名 \"subtle\" 所警示的，加密是一个极其专业的领域，细微的错误就可能导致整个系统安全性完全失效。在使用 Web Crypto API 时：\n- 始终在 HTTPS 环境下使用\n- 选择正确的算法和参数（如 AES-GCM + 12 字节 IV）\n- 妥善管理密钥的生命周期\n\n## 10 加解密模板工具\n以下为您编写的这一套 AES-GCM 高级对称加密与解密工具函数。它做到了100% 零依赖、纯原生，通过 globalThis.crypto 实现完美同构。你不需要进行任何环境判断，同一段代码可以无缝运行在浏览器（安全上下文）、Node.js（19+）、Deno、Bun 以及边缘计算（如 Cloudflare Workers）中。\n\n为了解决数据传输与存储的问题，工具函数内部自动处理了 ArrayBuffer 与 Base64 字符串之间的相互转换。可以直接复制使用，代码如下：\n```ts [crypto.ts]\n\u002F**\n * 完美的同构 Web Crypto 安全加解密工具库 (TypeScript 箭头函数版本)\n * 适用环境：Browser (HTTPS), Node.js 19+, Deno, Bun, Cloudflare Workers\n *\u002F\n\n\u002F\u002F 1. 获取全局同构的 subtle 对象\nconst cryptoProvider = globalThis.crypto\nif (!cryptoProvider) {\n    throw new Error('当前运行环境不支持 Web Crypto API。请确保在 HTTPS、localhost 或现代 Node.js 19+ 环境下运行。')\n}\nconst subtle: SubtleCrypto = cryptoProvider.subtle\n\n\u002F**\n * 辅助函数：将 ArrayBuffer 转换为可传输的 Base64 字符串\n * 使用现代批处理写法apply，100% 消除严格模式下的 undefined 类型报错\n *\u002F\nconst bufferToBase64 = (buffer: ArrayBuffer): string => {\n    const bytes = new Uint8Array(buffer)\n    const binary = String.fromCharCode.apply(null, bytes as unknown as number[])\n    return btoa(binary)\n}\n\n\u002F**\n * 辅助函数：将 Base64 字符串还原为 ArrayBuffer\n * 使用 Array.from 映射，确保严格类型安全\n *\u002F\nconst base64ToBuffer = (base64: string): ArrayBuffer => {\n    const binaryString = atob(base64)\n    const bytes = Uint8Array.from(binaryString, (char) => char.charCodeAt(0))\n    return bytes.buffer\n}\n\n\u002F**\n * [同构] 生成 AES-GCM 256位加密密钥\n *\u002F\nexport const generateAESKey = async (): Promise\u003CCryptoKey> => {\n    return await subtle.generateKey(\n        { name: 'AES-GCM', length: 256 },\n        true, \u002F\u002F 允许导出\n        ['encrypt', 'decrypt']\n    )\n}\n\n\u002F**\n * [同构] 导出 CryptoKey 密钥为可传输的 Base64 字符串\n * @param cryptoKey - 浏览器或服务端生成的 CryptoKey 实体\n *\u002F\nexport const exportKeyToBase64 = async (cryptoKey: CryptoKey): Promise\u003Cstring> => {\n    const exported = await subtle.exportKey('raw', cryptoKey)\n    return bufferToBase64(exported)\n}\n\n\u002F**\n * [同构] 从 Base64 字符串导入还原为 CryptoKey 密钥对象\n * @param base64Key - Base64 格式的密钥字符串\n *\u002F\nexport const importKeyFromBase64 = async (base64Key: string): Promise\u003CCryptoKey> => {\n    const rawKeyBuffer = base64ToBuffer(base64Key)\n    return await subtle.importKey('raw', rawKeyBuffer, { name: 'AES-GCM' }, true, ['encrypt', 'decrypt'])\n}\n\n\u002F**\n * [同构] 使用 AES-GCM 算法加密字符串文本\n * @param text - 待加密的明文文本\n * @param key - CryptoKey 密钥对象\n * @returns 返回打包了 \"IV\" 和 \"密文\" 的统一 Base64 字符串\n *\u002F\nexport const encryptText = async (text: string, key: CryptoKey): Promise\u003Cstring> => {\n    const encoder = new TextEncoder()\n    const encodedText: Uint8Array\u003CArrayBuffer> = encoder.encode(text)\n    \u002F\u002F 生成 12 字节的密码学安全伪随机数作为 IV (AES-GCM 标准推荐)\n    const iv: Uint8Array\u003CArrayBuffer> = cryptoProvider.getRandomValues(new Uint8Array(12))\n    \u002F\u002F 执行加密，返回密文 ArrayBuffer\n    const cipherBuffer: ArrayBuffer = await subtle.encrypt({ name: 'AES-GCM', iv: iv }, key, encodedText)\n    \u002F\u002F 将 IV（12字节）和密文拼接，方便单字符串传输\n    const combined = new Uint8Array(iv.length + cipherBuffer.byteLength)\n    combined.set(iv, 0)\n    combined.set(new Uint8Array(cipherBuffer), iv.length)\n    return bufferToBase64(combined.buffer)\n}\n\n\u002F**\n * [同构] 使用 AES-GCM 算法解密文本\n * @param combinedBase64 - 由 encryptText 生成的统一加密 Base64 字符串（内部含 IV）\n * @param key - 对应的 CryptoKey 密钥对象\n *\u002F\nexport const decryptText = async (combinedBase64: string, key: CryptoKey): Promise\u003Cstring> => {\n    const combinedBuffer = base64ToBuffer(combinedBase64)\n    const combinedBytes = new Uint8Array(combinedBuffer)\n    \u002F\u002F 从头部切出前 12 字节作为 IV\n    const iv: Uint8Array\u003CArrayBuffer> = combinedBytes.slice(0, 12)\n    \u002F\u002F 剩下的部分作为真正的密文\n    const cipherText: Uint8Array\u003CArrayBuffer> = combinedBytes.slice(12)\n    \u002F\u002F 执行解密\n    const decryptedBuffer: ArrayBuffer = await subtle.decrypt({ name: 'AES-GCM', iv: iv }, key, cipherText.buffer)\n    const decoder = new TextDecoder()\n    return decoder.decode(decryptedBuffer)\n}\n```\nTS 测试脚本\n\n如果你在 Vite\u002FNuxt\u002FNext.js 项目或者使用了 ts-node \u002F bun \u002F deno 的后端环境中，可以直接引入并运行这段强类型的测试代码：\n\n```ts[test-crypto.ts]\nimport { decryptText, encryptText, exportKeyToBase64, generateAESKey, importKeyFromBase64 } from 'crypto'\n;(async () => {\n    try {\n        const rawData: string = '前后端全平台无缝传输的敏感数据 1234-abcd-TS-VERSION'\n        console.log('🔒 原始待加解密明文:', rawData)\n\n        \u002F\u002F ==========================================\n        \u002F\u002F 阶段一：在 A 端（例如 Node.js 后端）生成密钥并加密\n        \u002F\u002F ==========================================\n        const originalKey: CryptoKey = await generateAESKey()\n\n        \u002F\u002F 导出密钥为 Base64 字符串\n        const transportableKeyStr: string = await exportKeyToBase64(originalKey)\n        console.log('🔑 [传输中] 密钥已安全序列化为 Base64:', transportableKeyStr)\n\n        \u002F\u002F 对数据进行加密\n        const secureCipherText: string = await encryptText(rawData, originalKey)\n        console.log('📦 [传输中] 密文已安全打包（含IV）为 Base64:', secureCipherText)\n\n        \u002F\u002F ==========================================\n        \u002F\u002F 阶段二：在 B 端（例如现代 Web 浏览器前端）收到数据解密\n        \u002F\u002F ==========================================\n        console.log('\\n--- 数据已通过网络无缝抵达另一端 ---')\n\n        \u002F\u002F 1. 恢复强类型的 CryptoKey 实体\n        const receivedKey: CryptoKey = await importKeyFromBase64(transportableKeyStr)\n\n        \u002F\u002F 2. 还原数据内容\n        const decryptedOutput: string = await decryptText(secureCipherText, receivedKey)\n        console.log('🔓 [还原成功] 解密后的最终明文结果:', decryptedOutput)\n    } catch (error) {\n        console.error('❌ 密码学同构解密链路失败，错误原因: ', error)\n    }\n})()\n\n```",33.5,{"title":1033,"description":1044},{"loc":6707},"blog\u002F9.Web Crypto API浏览器原生加密的终极指南",[2096],[6715],{"name":6716,"symbol":6717,"icon":6718,"id":2096},"浏览器","web","mdi:web","2026-08-26 10:46:16",6031,"dFEAXKZPH39je0En-u1mE32EQFhpez4BM-ckLEv9l8w",{"id":6723,"title":6724,"articleId":6725,"articleThumb":6726,"body":6727,"categoryId":624,"categoryInfo":7494,"createDate":7498,"description":7499,"excerpt":7500,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":7505,"navigation":1003,"path":7506,"rawbody":7507,"readingTime":2185,"seo":7508,"sitemap":7509,"stem":7517,"tagIds":7518,"tagInfo":7519,"updateDate":7525,"wordCount":7526,"__hash__":7527},"blog\u002Fblog\u002F2.github仓库代码和gitee仓库代码双向自动同步方案.md","github仓库代码和gitee仓库代码双向自动同步方案","github-gitee-sync","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203348205.webp",{"type":10,"value":6728,"toc":7478},[6729,6732,6735,6738,6742,6751,6761,6766,6777,6783,6790,6794,6797,6806,6827,6837,6840,6844,6847,6856,6891,6894,6897,6900,6911,6919,6923,6929,6933,6939,6943,6949,6953,6956,6973,7136,7139,7143,7152,7162,7166,7169,7174,7183,7188,7195,7200,7210,7355,7362,7375,7378,7454,7457,7461,7464,7467,7471,7475],[13,6730,6731],{},"Github同步代码至Gitee或者是从Gitee更新代码，都需要借助Github Actions功能。GitHub Actions‌ 是 GitHub 提供的持续集成与持续交付（CI\u002FCD）平台，主要用于自动化软件开发流程中的构建、测试和部署任务。通过yml格式文件配置workflow实现自动化操作，可以实现一次提交，多仓库代码同步。目前Github Actions在实现本地代码提交Github仓库时，同步代码到Gitee，可以自动触发workflow执行，实现自动同步功能。反过来，当Gitee代码库存在更新，Github从Gitee同步更新时，借助Github Actions无法实现自动，只能借助定时任务，定时从Gitee同步代码。",[13,6733,6734],{},"相对于Github同步方案而言，Gitee同步代码至Github或者从Github更新代码非常简单。借助Gitee提供的强大的仓库镜像功能，只需要在Gitee的源仓库上进行简单配置就可以实现。",[13,6736,6737],{},"下面介绍Github和Gitee双向同步的具体实现步骤。",[17,6739,6741],{"id":6740},"_1-github自动同步gitee","1 Github自动同步Gitee",[13,6743,6744,6745,6750],{},"Github自动同步Gitee是指在本地提交代码至Github远程仓库时，同步将代码更新至Gitee仓库。目前通过Github Actions 实现Github仓库同步到gitee的Actions有很多，本文主要讲述如何使用【",[104,6746,6749],{"href":6747,"rel":6748,"target":28},"https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action",[108],"git-mirror-action","】镜像来实现同步操作。",[13,6752,6753,6755,6756,6760],{},[42,6754,6749],{"color":116}," 是一个用于自动同步 GitHub 和 Gitee（或其他 Git 平台）仓库的 GitHub Action，通过配置工作流（workflow）实现自动化部署。github仓库地址为：【",[104,6757,6759],{"href":6747,"rel":6758,"target":28},[108],"wearerequired\u002Fgit-mirror-action@master","】",[13,6762,6763],{},[71,6764,6765],{},"核心功能如下：",[128,6767,6768,6771,6774],{},[68,6769,6770],{},"双向同步：支持将 GitHub 仓库同步到 Gitee 或其他平台，也可实现反向同步。",[68,6772,6773],{},"‌灵活配置‌：通过 .yml 文件定义同步规则，支持源仓库与目标仓库的地址映射。",[68,6775,6776],{},"自动化部署‌：结合 GitHub Actions 工作流，可在代码更新时自动触发同步操作。",[13,6778,6779,6782],{},[71,6780,6781],{},"同步的原理","：利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中。",[13,6784,6785,6786],{},"详细配置参考：",[104,6787,6789],{"href":6747,"rel":6788},[108],"github源码仓库文档",[123,6791,6793],{"id":6792},"_11-创建gitee目标仓库","1.1 创建Gitee目标仓库",[13,6795,6796],{},"在实现github仓库同步到gitee仓库之前，首先需要在gitee初始化一个仓库，作为同步的目标仓库。可以直接创建一个空仓库，或者直接通过gitee自带的导入github仓库代码功能。具体导入github仓库步骤如下：",[13,6798,6799,6800,6805],{},"① 登陆[",[104,6801,6804],{"href":6802,"rel":6803,"target":28},"https:\u002F\u002Fgitee.com\u002Flogin",[108],"gitee","] -> 右上角加号 -> 从github\u002Fgitlab导入仓库。进入页面后，可直接通过url输入，也可以通过github授权后，批量选择导入的仓库。",[6807,6808,6810],"callout",{"color":1058,"icon":6809},"material-symbols:info-outline",[13,6811,6812,6813,6815,6816,6819,6820,6760,6824,6826],{},"温馨提示",[290,6814],{},"\n1 从url导入私有仓库时，需要填写仓库的账户和个人令牌。此处的令牌并非密码(github现在不建议直接账户密码认证)，而是GitHub 的「",[71,6817,6818],{},"Personal access token","」。点击前往设置【",[104,6821,6818],{"href":6822,"rel":6823,"target":28},"https:\u002F\u002Fgithub.com\u002Fsettings\u002Ftokens",[108],[290,6825],{},"\n2 从github导入仓库，需要github授权才行，授权后可以选择需要导入的仓库。",[13,6828,6829,6830,6834,6835,2028],{},"② 仓库导入成功后，进入仓库，仓库名称后面会显示一个 ",[6831,6832],"icon",{"name":6833},"material-symbols-light:refresh-rounded"," 符号，点击便可手动同步github仓库代码至gitee。私有仓库同步时，需要输入账号和个人令牌(github的",[71,6836,6818],{},[13,6838,6839],{},"至此，github仓库同步gitee仓库前期准备工作已准备完毕，下面开始介绍如何配置github自动同步代码至gitee。",[123,6841,6843],{"id":6842},"_12-创建ssh公私钥","1.2 创建SSH公私钥",[13,6845,6846],{},"SSH密钥对由公钥和私钥组成，公钥用于加密数据，私钥用于解密数据，通过非对称加密确保通信安全。使用 SSH 协议可以连接远程服务器和服务并向它们验证。 利用 SSH 密钥可以连接到 GitHub，而无需在每次访问时都提供用户名和 personal access token。GitHub通过公钥加密信息，私钥用于解密，从而确认用户身份。",[13,6848,6849,6850,6852,6853,6855],{},"①在本地机器上打开终端应用程序",[290,6851],{},"\n②生成SSH密钥对",[290,6854],{},"\n使用ssh-keygen命令来生成密钥对。您可以通过以下命令开始：",[679,6857,6861],{"className":6858,"code":6859,"language":6860,"meta":502,"style":502},"language-shell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ssh-keygen -t rsa  -b 4096 -C \"youremail@example.com\"\n","shell",[42,6862,6863],{"__ignoreMap":502},[688,6864,6865,6868,6871,6874,6877,6880,6883,6885,6888],{"class":690,"line":691},[688,6866,6867],{"class":694},"ssh-keygen",[688,6869,6870],{"class":697}," -t",[688,6872,6873],{"class":697}," rsa",[688,6875,6876],{"class":697},"  -b",[688,6878,6879],{"class":2220}," 4096",[688,6881,6882],{"class":697}," -C",[688,6884,3155],{"class":791},[688,6886,6887],{"class":697},"youremail@example.com",[688,6889,6890],{"class":791},"\"\n",[13,6892,6893],{},"这里，-t rsa指定了密钥的类型为RSA，-b 4096指定了密钥的位长度为4096位。RSA密钥的长度可以是1024位、2048位或4096位，推荐使用2048位或更高的安全性。-C（Comment）是 ssh-keygen 命令的一个选项，用于为生成的 SSH 密钥对添加注释。注释内容可以是任意文本，但通常推荐使用邮箱地址或密钥用途描述。注释仅保存在公钥文件中，私钥文件不包含此信息。",[13,6895,6896],{},"执行上述命令后，系统会询问您希望将密钥存储在哪个文件中，默认是~\u002F.ssh\u002Fid_rsa（私钥）和~\u002F.ssh\u002Fid_rsa.pub（公钥）。您可以按回车接受默认设置，或者输入其他路径来存储密钥文件。",[13,6898,6899],{},"接下来，系统会询问您是否要为密钥设置密码（passphrase）。强烈建议设置密码，因为即使私钥文件被保护，知道密码仍然可以访问您的服务器。如果您不想设置密码，可以按回车跳过此步骤。",[13,6901,6902,6903,6906,6907,6910],{},"如果连续三次回车，生成的秘钥对存储默认位置。",[42,6904,6905],{"color":116},"id_rsa"," 为私钥，",[42,6908,6909],{"color":116},"id_rsa.pub","为公钥。如果提示：already exists（已经存在），则可以到电脑位置：C:\\Users\\电脑账号名\\ .ssh 直接使用。",[13,6912,6913,6914,6760],{},"具体图文参考：【",[104,6915,6918],{"href":6916,"rel":6917,"target":28},"https:\u002F\u002Fgitee.com\u002Fhelp\u002Farticles\u002F4181#article-header0",[108],"生成\u002F添加SSH公钥",[123,6920,6922],{"id":6921},"_13-github配置ssh私钥","1.3 GitHub配置SSH私钥",[13,6924,6925,6926],{},"打开Github需要同步的项目，点击Settings->Secrets->Actions，设置私钥名称为：GITEE_RSA_PRIVATE_KEY，值为：上面生成SSH的私钥，即id_rsa 文件的内容\n",[419,6927],{"alt":502,"src":6928},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910125740784.webp",[123,6930,6932],{"id":6931},"_14-github配置ssh公钥","1.4 GitHub配置SSH公钥",[13,6934,6935,6936],{},"在Github点击右上角用户图像，点击Settings->SSH and GPG keys->New SSH key，名称为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n",[419,6937],{"alt":502,"src":6938},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910130224827.webp",[123,6940,6942],{"id":6941},"_15-gitee配置ssh公钥","1.5 Gitee配置SSH公钥",[13,6944,6945,6946],{},"在Gitee 设置->安全设置->SSH公钥，标题为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n",[419,6947],{"alt":502,"src":6948},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910130741176.webp",[123,6950,6952],{"id":6951},"_16-创建github-workflow","1.6 创建Github workflow",[13,6954,6955],{},"github创建workflow有2种方式，第一种直接在github项目中，点击actions创建新的workflow，第二种就是将项目clone本地，进行配置。二者大同小异，都是配置相应的设置。",[13,6957,6958,6959,6962,6965,6968,6969,6972],{},"①第一种：点击actions创建新的workflow\n",[419,6960],{"alt":502,"src":6961},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131433758.webp",[419,6963],{"alt":502,"src":6964},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131520866.webp",[419,6966],{"alt":502,"src":6967},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131747275.webp","\n②第二种：将项目clone到本地，用vscode打开，根目录下创建文件",[42,6970,6971],{"color":116},".github\\workflows\\sync-to-gitee.yml","，内容如下：",[679,6974,6979],{"className":6975,"code":6976,"filename":6977,"language":6978,"meta":502,"style":502},"language-yml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: Sync to Gitee\non:\n    push:\n        branches:\n            # 或者你想要同步的分支\n            - main\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Gitee\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 GitHub 源仓库地址\n                  source-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Gitee 目标仓库地址\n                  destination-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n","sync-to-gitee.yml","yml",[42,6980,6981,6991,6999,7006,7013,7018,7026,7033,7040,7050,7057,7067,7077,7084,7089,7099,7106,7111,7121,7126],{"__ignoreMap":502},[688,6982,6983,6986,6988],{"class":690,"line":691},[688,6984,6985],{"class":797},"name",[688,6987,801],{"class":791},[688,6989,6990],{"class":697}," Sync to Gitee\n",[688,6992,6993,6996],{"class":690,"line":506},[688,6994,6995],{"class":2442},"on",[688,6997,6998],{"class":791},":\n",[688,7000,7001,7004],{"class":690,"line":535},[688,7002,7003],{"class":797},"    push",[688,7005,6998],{"class":791},[688,7007,7008,7011],{"class":690,"line":609},[688,7009,7010],{"class":797},"        branches",[688,7012,6998],{"class":791},[688,7014,7015],{"class":690,"line":624},[688,7016,7017],{"class":859},"            # 或者你想要同步的分支\n",[688,7019,7020,7023],{"class":690,"line":856},[688,7021,7022],{"class":791},"            -",[688,7024,7025],{"class":697}," main\n",[688,7027,7028,7031],{"class":690,"line":863},[688,7029,7030],{"class":797},"jobs",[688,7032,6998],{"class":791},[688,7034,7035,7038],{"class":690,"line":874},[688,7036,7037],{"class":797},"    sync",[688,7039,6998],{"class":791},[688,7041,7042,7045,7047],{"class":690,"line":890},[688,7043,7044],{"class":797},"        runs-on",[688,7046,801],{"class":791},[688,7048,7049],{"class":697}," ubuntu-latest\n",[688,7051,7052,7055],{"class":690,"line":896},[688,7053,7054],{"class":797},"        steps",[688,7056,6998],{"class":791},[688,7058,7059,7061,7063,7065],{"class":690,"line":905},[688,7060,7022],{"class":791},[688,7062,3397],{"class":797},[688,7064,801],{"class":791},[688,7066,6990],{"class":697},[688,7068,7069,7072,7074],{"class":690,"line":2096},[688,7070,7071],{"class":797},"              uses",[688,7073,801],{"class":791},[688,7075,7076],{"class":697}," wearerequired\u002Fgit-mirror-action@master\n",[688,7078,7079,7082],{"class":690,"line":2138},[688,7080,7081],{"class":797},"              env",[688,7083,6998],{"class":791},[688,7085,7086],{"class":690,"line":2143},[688,7087,7088],{"class":859},"                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n",[688,7090,7091,7094,7096],{"class":690,"line":2149},[688,7092,7093],{"class":797},"                  SSH_PRIVATE_KEY",[688,7095,801],{"class":791},[688,7097,7098],{"class":697}," ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n",[688,7100,7101,7104],{"class":690,"line":2185},[688,7102,7103],{"class":797},"              with",[688,7105,6998],{"class":791},[688,7107,7108],{"class":690,"line":2261},[688,7109,7110],{"class":859},"                  # 注意替换为你的 GitHub 源仓库地址\n",[688,7112,7113,7116,7118],{"class":690,"line":2267},[688,7114,7115],{"class":797},"                  source-repo",[688,7117,801],{"class":791},[688,7119,7120],{"class":697}," git@github.com:AnyFork\u002Fanyfork-docs-client.git\n",[688,7122,7123],{"class":690,"line":2277},[688,7124,7125],{"class":859},"                  # 注意替换为你的 Gitee 目标仓库地址\n",[688,7127,7128,7131,7133],{"class":690,"line":2283},[688,7129,7130],{"class":797},"                  destination-repo",[688,7132,801],{"class":791},[688,7134,7135],{"class":697}," git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n",[13,7137,7138],{},"至此，github workflow配置完毕。以后提交代码至github仓库时，便会触发workflow自动执行，自动将github仓库代码同步至gitee仓库中。",[17,7140,7142],{"id":7141},"_2-github从gitee同步更新","2 Github从Gitee同步更新",[13,7144,7145,7146,7151],{},"Github仓库从Gitee仓库同步代码，也是借助Github Actions功能进行实现，能够实现此功能的Actions较多，本文还是采用\n【",[104,7147,7150],{"href":7148,"rel":7149,"target":28},"https:\u002F\u002Fgithub.com\u002FYikun\u002Fhub-mirror-action",[108],"Yikun\u002Fgitee-mirror-action","】进行实现。",[13,7153,7154,7155,648,7158,7161],{},"由于Github Actions在Gitee代码仓库更新时，无法自动感知gitee仓库发生更新，从而不能自动触发workflow的执行，因此形成了2种不同的同步方式：",[71,7156,7157],{},"webhooks实时同步方式",[71,7159,7160],{},"定时延迟同步方式","。下面分别介绍这2种同步方式的具体实现步骤。",[123,7163,7165],{"id":7164},"_21-定时延迟同步方式","2.1 定时延迟同步方式",[13,7167,7168],{},"定时延迟同步方式是最简单的一种方式，虽然存在延迟，但大部分情况下对代码同步的实时性要求并不高。可以根据实际需求，调整定时任务频率，增加同步次数。",[13,7170,7171],{},[71,7172,7173],{},"1 创建Github目标仓库",[13,7175,7176,7177,7182],{},"在实现从Gitee同步代码至目标仓库Github之前，需要在Github上创建一个空的仓库作为同步的目标仓库。登陆【",[104,7178,7181],{"href":7179,"rel":7180,"target":28},"https:\u002F\u002Fgithub.com\u002F",[108],"gihub","】->右上角加号->创建仓库，私有或者公有仓库均可。",[13,7184,7185],{},[71,7186,7187],{},"2 目标仓库配置SSH私钥",[13,7189,7190,7191,6760],{},"github目标仓库创建好后，需要配置仓库SSH私钥，具体步骤参考：【",[104,7192,7194],{"href":7193},"#_13-github%E9%85%8D%E7%BD%AEssh%E7%A7%81%E9%92%A5","1.3 github配置ssh私钥",[13,7196,7197],{},[71,7198,7199],{},"3 目标仓库创建Github workflow",[13,7201,7202,7203,7206,7207,6972],{},"在【",[104,7204,6952],{"href":7205},"#_16-%E5%88%9B%E5%BB%BAgithub-workflow","】已经讲述了如何创建Github workflow，此处不在赘述。下面采用第二种方式进行配置。将项目clone到本地，用vscode打开，根目录下创建文件",[42,7208,7209],{"color":116},".github\\workflows\\sync-to-github.yml",[679,7211,7214],{"className":6975,"code":7212,"filename":7213,"language":6978,"meta":502,"style":502},"name: Sync to Github\non:\n   schedule:\n    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n    - cron:  '10\u002F5 * * * *'\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Github\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 Gitee源仓库地址\n                  source-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Github 目标仓库地址\n                  destination-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n","sync-to-github.yml",[42,7215,7216,7225,7231,7238,7243,7261,7267,7273,7281,7287,7297,7305,7311,7315,7323,7329,7334,7342,7347],{"__ignoreMap":502},[688,7217,7218,7220,7222],{"class":690,"line":691},[688,7219,6985],{"class":797},[688,7221,801],{"class":791},[688,7223,7224],{"class":697}," Sync to Github\n",[688,7226,7227,7229],{"class":690,"line":506},[688,7228,6995],{"class":2442},[688,7230,6998],{"class":791},[688,7232,7233,7236],{"class":690,"line":535},[688,7234,7235],{"class":797},"   schedule",[688,7237,6998],{"class":791},[688,7239,7240],{"class":690,"line":609},[688,7241,7242],{"class":859},"    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n",[688,7244,7245,7248,7251,7253,7256,7259],{"class":690,"line":624},[688,7246,7247],{"class":791},"    -",[688,7249,7250],{"class":797}," cron",[688,7252,801],{"class":791},[688,7254,7255],{"class":791},"  '",[688,7257,7258],{"class":697},"10\u002F5 * * * *",[688,7260,6258],{"class":791},[688,7262,7263,7265],{"class":690,"line":856},[688,7264,7030],{"class":797},[688,7266,6998],{"class":791},[688,7268,7269,7271],{"class":690,"line":863},[688,7270,7037],{"class":797},[688,7272,6998],{"class":791},[688,7274,7275,7277,7279],{"class":690,"line":874},[688,7276,7044],{"class":797},[688,7278,801],{"class":791},[688,7280,7049],{"class":697},[688,7282,7283,7285],{"class":690,"line":890},[688,7284,7054],{"class":797},[688,7286,6998],{"class":791},[688,7288,7289,7291,7293,7295],{"class":690,"line":896},[688,7290,7022],{"class":791},[688,7292,3397],{"class":797},[688,7294,801],{"class":791},[688,7296,7224],{"class":697},[688,7298,7299,7301,7303],{"class":690,"line":905},[688,7300,7071],{"class":797},[688,7302,801],{"class":791},[688,7304,7076],{"class":697},[688,7306,7307,7309],{"class":690,"line":2096},[688,7308,7081],{"class":797},[688,7310,6998],{"class":791},[688,7312,7313],{"class":690,"line":2138},[688,7314,7088],{"class":859},[688,7316,7317,7319,7321],{"class":690,"line":2143},[688,7318,7093],{"class":797},[688,7320,801],{"class":791},[688,7322,7098],{"class":697},[688,7324,7325,7327],{"class":690,"line":2149},[688,7326,7103],{"class":797},[688,7328,6998],{"class":791},[688,7330,7331],{"class":690,"line":2185},[688,7332,7333],{"class":859},"                  # 注意替换为你的 Gitee源仓库地址\n",[688,7335,7336,7338,7340],{"class":690,"line":2261},[688,7337,7115],{"class":797},[688,7339,801],{"class":791},[688,7341,7135],{"class":697},[688,7343,7344],{"class":690,"line":2267},[688,7345,7346],{"class":859},"                  # 注意替换为你的 Github 目标仓库地址\n",[688,7348,7349,7351,7353],{"class":690,"line":2277},[688,7350,7130],{"class":797},[688,7352,801],{"class":791},[688,7354,7120],{"class":697},[13,7356,7357,7358,7361],{},"上面配置了",[42,7359,7360],{"color":116},"on:schedule:cron","定时任务，时间到了定时任务设置的时间，便会触发workflow执行。",[6807,7363,7364],{"color":1058,"icon":6809},[13,7365,6812,7366,7368,7369,7371,7372,7374],{},[290,7367],{},"\n1 设定的 schedule 是UCT时间，比如设置的08:00（也就是北京时间的16:00），但实际运行的时间为北京时间17:00 至 17：20 不等。",[290,7370],{},"\n2 Schedule在 GitHub 操作工作流运行的高负载期间，事件可能会延迟。高负载时间包括每小时开始。为了减少延迟的可能性，请安排您的工作流在不同的时间运行。实测延迟的时间为几十分钟，或者超过一个小时，甚至在某种极端情况下，将不会执行。",[290,7373],{},"\n3 Schedule 设置的 cron 时刻，仅仅是工作流进行计划排队的时刻，而不是准确的运行时刻。",[13,7376,7377],{},"GitHub Actions 默认使用 UTC 时间。如果你的工作流程应该在特定本地时间执行，你可以在 YAML 文件中指定时区：",[679,7379,7381],{"className":6975,"code":7380,"language":6978,"meta":502,"style":502},"jobs:\n  job1:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set Timezone\n      uses: szenius\u002Fset-timezone@v1.0\n      with:\n        timezoneLinux: \"Asia\u002FShanghai\"\n\n",[42,7382,7383,7389,7396,7405,7412,7423,7433,7440],{"__ignoreMap":502},[688,7384,7385,7387],{"class":690,"line":691},[688,7386,7030],{"class":797},[688,7388,6998],{"class":791},[688,7390,7391,7394],{"class":690,"line":506},[688,7392,7393],{"class":797},"  job1",[688,7395,6998],{"class":791},[688,7397,7398,7401,7403],{"class":690,"line":535},[688,7399,7400],{"class":797},"    runs-on",[688,7402,801],{"class":791},[688,7404,7049],{"class":697},[688,7406,7407,7410],{"class":690,"line":609},[688,7408,7409],{"class":797},"    steps",[688,7411,6998],{"class":791},[688,7413,7414,7416,7418,7420],{"class":690,"line":624},[688,7415,7247],{"class":791},[688,7417,3397],{"class":797},[688,7419,801],{"class":791},[688,7421,7422],{"class":697}," Set Timezone\n",[688,7424,7425,7428,7430],{"class":690,"line":856},[688,7426,7427],{"class":797},"      uses",[688,7429,801],{"class":791},[688,7431,7432],{"class":697}," szenius\u002Fset-timezone@v1.0\n",[688,7434,7435,7438],{"class":690,"line":863},[688,7436,7437],{"class":797},"      with",[688,7439,6998],{"class":791},[688,7441,7442,7445,7447,7449,7452],{"class":690,"line":874},[688,7443,7444],{"class":797},"        timezoneLinux",[688,7446,801],{"class":791},[688,7448,3155],{"class":791},[688,7450,7451],{"class":697},"Asia\u002FShanghai",[688,7453,6890],{"class":791},[13,7455,7456],{},"对于一些不需要实时进行同步的需求，可以采用定时延迟同步方案，方便配置也简单。",[123,7458,7460],{"id":7459},"_22-实时同步方式","2.2 实时同步方式",[13,7462,7463],{},"Webhook是一种事件驱动的通知机制，当发生特定事件（如代码推送、拉取请求创建等）时，会自动向指定的外部服务器发送HTTP POST请求（通常包含事件数据）。这种机制替代了轮询API的实时通知方式，允许开发者在事件发生时立即触发外部操作（如部署、测试或发送通知）。",[13,7465,7466],{},"Github和Gitee都支持Webhook功能，因此我们可以借助这一功能，在gitee代码发生提交时，触发gitee配置的自定义webhook，webhook通过调用github Api触发github actions自动执行，从而实现实时同步方式。",[17,7468,7470],{"id":7469},"_3-gitee自动同步github","3 Gitee自动同步Github",[17,7472,7474],{"id":7473},"_4-gitee从github同步更新","4 Gitee从Github同步更新",[968,7476,7477],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":502,"searchDepth":535,"depth":535,"links":7479},[7480,7488,7492,7493],{"id":6740,"depth":506,"text":6741,"children":7481},[7482,7483,7484,7485,7486,7487],{"id":6792,"depth":535,"text":6793},{"id":6842,"depth":535,"text":6843},{"id":6921,"depth":535,"text":6922},{"id":6931,"depth":535,"text":6932},{"id":6941,"depth":535,"text":6942},{"id":6951,"depth":535,"text":6952},{"id":7141,"depth":506,"text":7142,"children":7489},[7490,7491],{"id":7164,"depth":535,"text":7165},{"id":7459,"depth":535,"text":7460},{"id":7469,"depth":506,"text":7470},{"id":7473,"depth":506,"text":7474},{"name":7495,"symbol":7496,"icon":7497,"id":624},"仓库同步","repository","material-symbols-light:sync-desktop-outline","2025-09-09 21:55:35","‌日常工作中，可能会遇到github代码仓库需要自动同步代码至gitee仓库，或者gitee仓库代码同步至github仓库的应用场景，针对这个应用场景，下面便归纳一下github和gitee仓库实现双向自动同步方案和步骤。",{"type":10,"value":7501},[7502],[13,7503,7504],{},"到目前为止，想要实现在本地提交代码至Github仓库时，同时更新至Gitee仓库是可行的。相反，想要在本地提交代码至Gitee仓库时，同时更新至Github仓库也可以实现的。无论我们使用Github还是Gitee任意一个远程仓库，在代码提交时，头可以自动同步到另一个远程仓库，即所谓的双向自动同步(可推送至远端仓库，亦可从远端仓库同步更新)。当然，日常开发中，按照个人喜好，我们只需要选择一种即可。",{},"\u002Fblog\u002Fgithubgitee","---\ntitle: github仓库代码和gitee仓库代码双向自动同步方案\ndescription: ‌日常工作中，可能会遇到github代码仓库需要自动同步代码至gitee仓库，或者gitee仓库代码同步至github仓库的应用场景，针对这个应用场景，下面便归纳一下github和gitee仓库实现双向自动同步方案和步骤。\narticleId: github-gitee-sync\ncreateDate: \"2025-09-09 21:55:35\"\nupdateDate: \"2026-03-12 10:02:23\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203348205.webp\ntagIds: \n    - 2\n    - 3\ncategoryId: 5\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n\n到目前为止，想要实现在本地提交代码至Github仓库时，同时更新至Gitee仓库是可行的。相反，想要在本地提交代码至Gitee仓库时，同时更新至Github仓库也可以实现的。无论我们使用Github还是Gitee任意一个远程仓库，在代码提交时，头可以自动同步到另一个远程仓库，即所谓的双向自动同步(可推送至远端仓库，亦可从远端仓库同步更新)。当然，日常开发中，按照个人喜好，我们只需要选择一种即可。\n\u003C!--more-->\n\n\nGithub同步代码至Gitee或者是从Gitee更新代码，都需要借助Github Actions功能。GitHub Actions‌ 是 GitHub 提供的持续集成与持续交付（CI\u002FCD）平台，主要用于自动化软件开发流程中的构建、测试和部署任务。通过yml格式文件配置workflow实现自动化操作，可以实现一次提交，多仓库代码同步。目前Github Actions在实现本地代码提交Github仓库时，同步代码到Gitee，可以自动触发workflow执行，实现自动同步功能。反过来，当Gitee代码库存在更新，Github从Gitee同步更新时，借助Github Actions无法实现自动，只能借助定时任务，定时从Gitee同步代码。\n\n\n相对于Github同步方案而言，Gitee同步代码至Github或者从Github更新代码非常简单。借助Gitee提供的强大的仓库镜像功能，只需要在Gitee的源仓库上进行简单配置就可以实现。\n\n\n下面介绍Github和Gitee双向同步的具体实现步骤。\n\n\n## 1 Github自动同步Gitee\nGithub自动同步Gitee是指在本地提交代码至Github远程仓库时，同步将代码更新至Gitee仓库。目前通过Github Actions 实现Github仓库同步到gitee的Actions有很多，本文主要讲述如何使用【[git-mirror-action](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action){target=_blank}】镜像来实现同步操作。\n\n`git-mirror-action`{color=primary} 是一个用于自动同步 GitHub 和 Gitee（或其他 Git 平台）仓库的 GitHub Action，通过配置工作流（workflow）实现自动化部署。github仓库地址为：【[wearerequired\u002Fgit-mirror-action@master](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action){target=_blank}】\n \n**核心功能如下：**\n- 双向同步：支持将 GitHub 仓库同步到 Gitee 或其他平台，也可实现反向同步。\n- ‌灵活配置‌：通过 .yml 文件定义同步规则，支持源仓库与目标仓库的地址映射。\n- 自动化部署‌：结合 GitHub Actions 工作流，可在代码更新时自动触发同步操作。\n\n**同步的原理**：利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中。\n\n\n详细配置参考：[github源码仓库文档](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action)\n\n\n### 1.1 创建Gitee目标仓库\n在实现github仓库同步到gitee仓库之前，首先需要在gitee初始化一个仓库，作为同步的目标仓库。可以直接创建一个空仓库，或者直接通过gitee自带的导入github仓库代码功能。具体导入github仓库步骤如下：\n\n\n① 登陆[[gitee](https:\u002F\u002Fgitee.com\u002Flogin){target=_blank}] -> 右上角加号 -> 从github\u002Fgitlab导入仓库。进入页面后，可直接通过url输入，也可以通过github授权后，批量选择导入的仓库。\n::callout{icon=\"material-symbols:info-outline\" color=\"warning\"}\n温馨提示\u003C\u002Fbr>\n1 从url导入私有仓库时，需要填写仓库的账户和个人令牌。此处的令牌并非密码(github现在不建议直接账户密码认证)，而是GitHub 的「**Personal access token**」。点击前往设置【[Personal access token](https:\u002F\u002Fgithub.com\u002Fsettings\u002Ftokens){target=_blank}】\u003C\u002Fbr>\n2 从github导入仓库，需要github授权才行，授权后可以选择需要导入的仓库。\n::\n② 仓库导入成功后，进入仓库，仓库名称后面会显示一个 :icon{name=\"material-symbols-light:refresh-rounded\"} 符号，点击便可手动同步github仓库代码至gitee。私有仓库同步时，需要输入账号和个人令牌(github的**Personal access token**)\n\n\n至此，github仓库同步gitee仓库前期准备工作已准备完毕，下面开始介绍如何配置github自动同步代码至gitee。\n\n\n### 1.2 创建SSH公私钥\nSSH密钥对由公钥和私钥组成，公钥用于加密数据，私钥用于解密数据，通过非对称加密确保通信安全。使用 SSH 协议可以连接远程服务器和服务并向它们验证。 利用 SSH 密钥可以连接到 GitHub，而无需在每次访问时都提供用户名和 personal access token。GitHub通过公钥加密信息，私钥用于解密，从而确认用户身份。\n\n\n①在本地机器上打开终端应用程序  \n②生成SSH密钥对  \n使用ssh-keygen命令来生成密钥对。您可以通过以下命令开始：\n```shell\nssh-keygen -t rsa  -b 4096 -C \"youremail@example.com\"\n```\n这里，-t rsa指定了密钥的类型为RSA，-b 4096指定了密钥的位长度为4096位。RSA密钥的长度可以是1024位、2048位或4096位，推荐使用2048位或更高的安全性。-C（Comment）是 ssh-keygen 命令的一个选项，用于为生成的 SSH 密钥对添加注释。注释内容可以是任意文本，但通常推荐使用邮箱地址或密钥用途描述。注释仅保存在公钥文件中，私钥文件不包含此信息。\n\n\n执行上述命令后，系统会询问您希望将密钥存储在哪个文件中，默认是~\u002F.ssh\u002Fid_rsa（私钥）和~\u002F.ssh\u002Fid_rsa.pub（公钥）。您可以按回车接受默认设置，或者输入其他路径来存储密钥文件。\n\n接下来，系统会询问您是否要为密钥设置密码（passphrase）。强烈建议设置密码，因为即使私钥文件被保护，知道密码仍然可以访问您的服务器。如果您不想设置密码，可以按回车跳过此步骤。\n\n\n如果连续三次回车，生成的秘钥对存储默认位置。`id_rsa`{color=primary} 为私钥，`id_rsa.pub`{color=primary}为公钥。如果提示：already exists（已经存在），则可以到电脑位置：C:\\Users\\电脑账号名\\ .ssh 直接使用。\n\n\n具体图文参考：【[生成\u002F添加SSH公钥](https:\u002F\u002Fgitee.com\u002Fhelp\u002Farticles\u002F4181#article-header0){target=_blank}】\n\n\n### 1.3 GitHub配置SSH私钥\n打开Github需要同步的项目，点击Settings->Secrets->Actions，设置私钥名称为：GITEE_RSA_PRIVATE_KEY，值为：上面生成SSH的私钥，即id_rsa 文件的内容\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910125740784.webp)\n\n\n### 1.4 GitHub配置SSH公钥\n在Github点击右上角用户图像，点击Settings->SSH and GPG keys->New SSH key，名称为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910130224827.webp)\n\n\n### 1.5 Gitee配置SSH公钥\n在Gitee 设置->安全设置->SSH公钥，标题为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910130741176.webp)\n\n\n### 1.6 创建Github workflow\ngithub创建workflow有2种方式，第一种直接在github项目中，点击actions创建新的workflow，第二种就是将项目clone本地，进行配置。二者大同小异，都是配置相应的设置。\n\n\n①第一种：点击actions创建新的workflow\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131433758.webp)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131520866.webp)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250910131747275.webp)\n②第二种：将项目clone到本地，用vscode打开，根目录下创建文件`.github\\workflows\\sync-to-gitee.yml`{color=primary}，内容如下：\n```yml[sync-to-gitee.yml]\nname: Sync to Gitee\non:\n    push:\n        branches:\n            # 或者你想要同步的分支\n            - main\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Gitee\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 GitHub 源仓库地址\n                  source-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Gitee 目标仓库地址\n                  destination-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n```\n至此，github workflow配置完毕。以后提交代码至github仓库时，便会触发workflow自动执行，自动将github仓库代码同步至gitee仓库中。\n\n\n## 2 Github从Gitee同步更新\nGithub仓库从Gitee仓库同步代码，也是借助Github Actions功能进行实现，能够实现此功能的Actions较多，本文还是采用\n【[Yikun\u002Fgitee-mirror-action](https:\u002F\u002Fgithub.com\u002FYikun\u002Fhub-mirror-action){target=_blank}】进行实现。\n\n由于Github Actions在Gitee代码仓库更新时，无法自动感知gitee仓库发生更新，从而不能自动触发workflow的执行，因此形成了2种不同的同步方式：**webhooks实时同步方式**和**定时延迟同步方式**。下面分别介绍这2种同步方式的具体实现步骤。\n\n### 2.1 定时延迟同步方式\n定时延迟同步方式是最简单的一种方式，虽然存在延迟，但大部分情况下对代码同步的实时性要求并不高。可以根据实际需求，调整定时任务频率，增加同步次数。\n\n**1 创建Github目标仓库**\n\n 在实现从Gitee同步代码至目标仓库Github之前，需要在Github上创建一个空的仓库作为同步的目标仓库。登陆【[gihub](https:\u002F\u002Fgithub.com\u002F){target=_blank}】->右上角加号->创建仓库，私有或者公有仓库均可。\n\n\n**2 目标仓库配置SSH私钥**\n\n\ngithub目标仓库创建好后，需要配置仓库SSH私钥，具体步骤参考：【[1.3 github配置ssh私钥](#_13-github配置ssh私钥)】\n\n**3 目标仓库创建Github workflow**\n\n在【[1.6 创建Github workflow](#_16-创建github-workflow)】已经讲述了如何创建Github workflow，此处不在赘述。下面采用第二种方式进行配置。将项目clone到本地，用vscode打开，根目录下创建文件`.github\\workflows\\sync-to-github.yml`{color=primary}，内容如下：\n```yml[sync-to-github.yml]\nname: Sync to Github\non:\n   schedule:\n    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n    - cron:  '10\u002F5 * * * *'\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Github\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 Gitee源仓库地址\n                  source-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Github 目标仓库地址\n                  destination-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n```\n上面配置了`on:schedule:cron`{color=primary}定时任务，时间到了定时任务设置的时间，便会触发workflow执行。\n::callout{icon=\"material-symbols:info-outline\" color=\"warning\"}\n温馨提示\u003C\u002Fbr>\n1 设定的 schedule 是UCT时间，比如设置的08:00（也就是北京时间的16:00），但实际运行的时间为北京时间17:00 至 17：20 不等。\u003C\u002Fbr>\n2 Schedule在 GitHub 操作工作流运行的高负载期间，事件可能会延迟。高负载时间包括每小时开始。为了减少延迟的可能性，请安排您的工作流在不同的时间运行。实测延迟的时间为几十分钟，或者超过一个小时，甚至在某种极端情况下，将不会执行。\u003C\u002Fbr>\n3 Schedule 设置的 cron 时刻，仅仅是工作流进行计划排队的时刻，而不是准确的运行时刻。\n::\nGitHub Actions 默认使用 UTC 时间。如果你的工作流程应该在特定本地时间执行，你可以在 YAML 文件中指定时区：\n```yml\njobs:\n  job1:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set Timezone\n      uses: szenius\u002Fset-timezone@v1.0\n      with:\n        timezoneLinux: \"Asia\u002FShanghai\"\n\n```\n对于一些不需要实时进行同步的需求，可以采用定时延迟同步方案，方便配置也简单。\n\n\n### 2.2 实时同步方式\nWebhook是一种事件驱动的通知机制，当发生特定事件（如代码推送、拉取请求创建等）时，会自动向指定的外部服务器发送HTTP POST请求（通常包含事件数据）。这种机制替代了轮询API的实时通知方式，允许开发者在事件发生时立即触发外部操作（如部署、测试或发送通知）。\n\n\nGithub和Gitee都支持Webhook功能，因此我们可以借助这一功能，在gitee代码发生提交时，触发gitee配置的自定义webhook，webhook通过调用github Api触发github actions自动执行，从而实现实时同步方式。\n\n\n\n\n## 3 Gitee自动同步Github\n## 4 Gitee从Github同步更新\n",{"title":6724,"description":7499},{"loc":7506,"images":7510},[7511,7512,7513,7514,7515,7516],{"loc":6928},{"loc":6938},{"loc":6948},{"loc":6961},{"loc":6964},{"loc":6967},"blog\u002F2.github仓库代码和gitee仓库代码双向自动同步方案",[506,535],[7520,7522],{"name":6804,"icon":7521,"symbol":6804,"id":506},"simple-icons:gitee",{"name":7523,"symbol":7523,"icon":7524,"id":535},"github","ri:github-fill","2026-03-12 10:02:23",2880,"HXvbCFijzlprXNJ_6Ke-eAlsWps6lq7wkNS4-bskXuk",{"id":7529,"title":7530,"articleId":7531,"articleThumb":7532,"body":7533,"categoryId":609,"categoryInfo":8209,"createDate":8212,"description":8213,"excerpt":8214,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":8219,"navigation":1003,"path":8220,"rawbody":8221,"readingTime":8222,"seo":8223,"sitemap":8224,"stem":8227,"tagIds":8228,"tagInfo":8229,"updateDate":8233,"wordCount":8234,"__hash__":8235},"blog\u002Fblog\u002F3.网页字体设置：默认字体、font-family 和 @font-face 使用指南.md","网页字体设置：默认字体、font-family 和 @font-face 使用指南","fonts","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203742648.webp",{"type":10,"value":7534,"toc":8198},[7535,7539,7545,7551,7555,7558,7563,7566,7572,7578,7584,7590,7596,7602,7608,7614,7620,7626,7632,7638,7644,7650,7656,7660,7668,7679,7684,7695,7699,7702,7849,7852,7856,7859,7868,7919,7922,7962,7983,8026,8034,8037,8084,8086,8116,8120,8123,8130,8133,8141,8145,8148,8151,8154,8158,8188,8195],[17,7536,7538],{"id":7537},"_1-关于font-family属性","1 关于font-family属性",[13,7540,7541,7542,7544],{},"1.字体的 fallback 机制",[290,7543],{},"\n在 CSS 中，可以通过 font-family 引用多种系列、多种字体，并且可以对字体先后顺序进行设置。当用户打开一个网页的时候，浏览就会读取 font-family 第一个引用的字体，并去检索用户当前操作系统下的字体，如有就显示，如没有就检索下一个，以此类推。若浏览器找不到指定的字体，或者没有设置 font-family 则会 fallback 到浏览器的默认字体。",[13,7546,7547,7548,7550],{},"2.字体的先后顺序设置",[290,7549],{},"\n由于中文字体内都包含西文字体，如想优先显示效果较好的西文字体，需要将西文字体写在中文字体的前面。虽然用户群体中使用 Windows 系统较多，但 Mac 用户大部分会下载 Office，所以会存在许多 Windows 下常见的字体，比如微软雅黑。将 macOS 系统的字体写在 Windows 的前面，可以保证在对应平台显示更好的效果。",[17,7552,7554],{"id":7553},"_2-常见的网页字体","2 常见的网页字体",[13,7556,7557],{},"先了解 serif（衬线体）与 sans-serif（无衬线体），衬线体与无衬线体是两种最基础的字形分类，衬线体在笔画开始与末端的地方有像小三角的装饰。",[13,7559,7560],{},[419,7561],{"alt":502,"src":7562},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250731102434432.webp",[13,7564,7565],{},"衬线体更多使用在印刷品上，在纸张上有棱角的字体更容易被识别。而在屏幕显示中字体过多的装饰点缀容易造成视觉疲劳，所以在屏幕显示中更多使用无衬线体。下面是一些常见常用的字体：",[13,7567,7568,7571],{},[71,7569,7570],{},"system-ui："," 一种通用字体系列，它会选择当前操作系统的默认字体渲染。如在 macOS 与 iOS 系统里 system-ui 指向的中文字体为苹方，西文字体为 .SF NS。",[13,7573,7574,7577],{},[71,7575,7576],{},"-apple-system："," system-ui 的兼容写法，在 macOS 与 iOS 系统里调用苹果系统的默认字体。",[13,7579,7580,7583],{},[71,7581,7582],{},"BlinkMacSystemFont："," 为 macOS Chrome 里调用苹果系统的默认字体。",[13,7585,7586,7589],{},[71,7587,7588],{},"Arial："," 无衬线西文字体，经常与 Helvetica 一起出现，支持不同操作系统、不同浏览器，兼容性好，属于安全字体。",[13,7591,7592,7595],{},[71,7593,7594],{},"Tahoma："," 无衬线西文字体，经常出现，支持不同操作系统、不同浏览器，兼容性好，属于安全字体。",[13,7597,7598,7601],{},[71,7599,7600],{},"Helvetica \u002F Helvetica Neue："," 苹果生态中最常用的无衬线西文字体，Helvetica Neue 是 Helvetica 的升级版，加了不同粗细、不同宽度的字形。",[13,7603,7604,7607],{},[71,7605,7606],{},"Segoe UI："," 无衬线西文字体，Windows 系统的默认西文字体。",[13,7609,7610,7613],{},[71,7611,7612],{},"Roboto："," 无衬线西文字体，Android 系统的默认西文字体。",[13,7615,7616,7619],{},[71,7617,7618],{},"苹方："," 无衬线中文字体，苹果系统的默认中文字体，除了中文简体（PingFang SC），还有台湾繁体（PingFang TC）和香港繁体（PingFang HK）。",[13,7621,7622,7625],{},[71,7623,7624],{},"Hiragino Sans GB (冬青黑体）："," 无衬线中文字体，用于兼容不支持苹方的旧版苹果系统，作为苹方字体的 fallback。",[13,7627,7628,7631],{},[71,7629,7630],{},"Microsoft YaHei (微软雅黑)："," 无衬线中文字体，Windows 系统的默认中文字体，iOS 与 Android 系统不支持微软雅黑。",[13,7633,7634,7637],{},[71,7635,7636],{},"Noto Sans (思源黑体)："," 无衬线中文字体，Android 系统的默认中文字体，由 Google 与 Adobe 推出的开源字体。除了中文简体（Noto Sans CJK SC），还有中文繁体（ Sans CJK TC）。",[13,7639,7640,7643],{},[71,7641,7642],{},"WenQuanYi Micro Hei (文泉驿微米黑)："," 无衬线中文字体，Linux 系统的默认中文字体，用于兼容 Linux 系统。",[13,7645,7646,7649],{},[71,7647,7648],{},"Simsun (宋体)："," 衬线中文字体，风格明显，支持 Windows 与 macOS 系统。",[13,7651,7652,7655],{},[71,7653,7654],{},"sans-serif："," 一种无衬线字体系列，常见的兜底字体，在前面所有引用的字体都找不到时会生效，显示当前浏览器默认的无衬线字体。",[17,7657,7659],{"id":7658},"_3-使用自定义字体","3 使用自定义字体",[13,7661,7662,7663,7665],{},"使用自定义字体，常用的方式有2种，本地@font-face和外部样式表(如：Google Fonts Web API库），它们在使用和功能上有所不同。",[290,7664],{},[71,7666,7667],{},"@font-face：",[128,7669,7670,7673,7676],{},[68,7671,7672],{},"使用方法：通过CSS的@font-face规则定义字体，并在页面中使用该字体。",[68,7674,7675],{},"优点：允许使用自定义字体，不依赖外部服务器，可以更好地控制字体的加载和显示。",[68,7677,7678],{},"缺点：需要手动管理字体文件，可能会增加页面加载时间。",[13,7680,7681],{},[71,7682,7683],{},"外部样式表",[128,7685,7686,7689,7692],{},[68,7687,7688],{},"使用方法：通过向HTML文档添加一个特殊的样式表链接，然后以CSS样式引用该字体即可。",[68,7690,7691],{},"优点：无需进行任何编程，支持多种字体格式，包括WOFF、WOFF2和TTF等。",[68,7693,7694],{},"缺点：需要依赖外部服务器，可能会受到网络延迟或服务器故障的影响。",[123,7696,7698],{"id":7697},"_31-方法一","3.1 方法一",[13,7700,7701],{},"@font-face方式：将需要使用的字体文件下载后放在服务器上，用 @font-face 将字体文件作为一个资源应用到 CSS样式 文件。为了兼容不同浏览器需要准备多种字体格式文件，保证字体格式文件与浏览器的兼容情况。目前大部分浏览器都支持.woff2格式的字体文件，因此我们只需要引入.woff2这一种格式的字体文件即可。下面是详细使用方法：",[679,7703,7707],{"className":7704,"code":7705,"language":7706,"meta":502,"style":502},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@font-face {\n  font-family: 'warick';\n  src:local(\"warick\"),url(\".\u002Fwarick.257.woff2\")format(\"woff2\");\n  font-style:normal;\n  font-display:swap;\n  font-weight:400;\n}\nbody{\n    font-family: 'warick';\n}\n","css",[42,7708,7709,7716,7733,7783,7795,7807,7819,7823,7830,7845],{"__ignoreMap":502},[688,7710,7711,7714],{"class":690,"line":691},[688,7712,7713],{"class":776},"@font-face",[688,7715,871],{"class":791},[688,7717,7718,7722,7724,7726,7729,7731],{"class":690,"line":506},[688,7719,7721],{"class":7720},"sqsOY","  font-family",[688,7723,801],{"class":791},[688,7725,831],{"class":791},[688,7727,7728],{"class":697},"warick",[688,7730,807],{"class":791},[688,7732,2058],{"class":791},[688,7734,7735,7738,7740,7743,7745,7747,7749,7751,7754,7757,7759,7761,7764,7766,7768,7771,7773,7775,7778,7780],{"class":690,"line":535},[688,7736,7737],{"class":7720},"  src",[688,7739,801],{"class":791},[688,7741,7742],{"class":783},"local",[688,7744,788],{"class":791},[688,7746,2312],{"class":791},[688,7748,7728],{"class":697},[688,7750,2312],{"class":791},[688,7752,7753],{"class":791},"),",[688,7755,7756],{"class":783},"url",[688,7758,788],{"class":791},[688,7760,2312],{"class":791},[688,7762,7763],{"class":697},".\u002Fwarick.257.woff2",[688,7765,2312],{"class":791},[688,7767,2028],{"class":791},[688,7769,7770],{"class":783},"format",[688,7772,788],{"class":791},[688,7774,2312],{"class":791},[688,7776,7777],{"class":697},"woff2",[688,7779,2312],{"class":791},[688,7781,7782],{"class":791},");\n",[688,7784,7785,7788,7790,7793],{"class":690,"line":609},[688,7786,7787],{"class":7720},"  font-style",[688,7789,801],{"class":791},[688,7791,7792],{"class":787},"normal",[688,7794,2058],{"class":791},[688,7796,7797,7800,7802,7805],{"class":690,"line":624},[688,7798,7799],{"class":7720},"  font-display",[688,7801,801],{"class":791},[688,7803,7804],{"class":787},"swap",[688,7806,2058],{"class":791},[688,7808,7809,7812,7814,7817],{"class":690,"line":856},[688,7810,7811],{"class":7720},"  font-weight",[688,7813,801],{"class":791},[688,7815,7816],{"class":2220},"400",[688,7818,2058],{"class":791},[688,7820,7821],{"class":690,"line":863},[688,7822,2280],{"class":791},[688,7824,7825,7828],{"class":690,"line":874},[688,7826,7827],{"class":694},"body",[688,7829,792],{"class":791},[688,7831,7832,7835,7837,7839,7841,7843],{"class":690,"line":890},[688,7833,7834],{"class":7720},"    font-family",[688,7836,801],{"class":791},[688,7838,831],{"class":791},[688,7840,7728],{"class":697},[688,7842,807],{"class":791},[688,7844,2058],{"class":791},[688,7846,7847],{"class":690,"line":896},[688,7848,2280],{"class":791},[13,7850,7851],{},"项目中可以通过配置多个@font-face设置多种字体文件，需要使用那种字体，便可通过CSS属性 font-family: '字体名称';进行实际应用。",[123,7853,7855],{"id":7854},"_32-方法二","3.2 方法二",[13,7857,7858],{},"外部样式表：无需下载字体文件，项目中只需要引入对应的CSS外部样式表即可，然后通过CSS属性 font-family: '字体名称'引用需要的字体。下面以Google Fonts和jsDelivr cdn加速github仓库静态资源2种方式，讲讲如何使用。",[13,7860,7861,7862,7867],{},"Google Fonts站点，不仅支持字体文件下载，本地引入字体文件的方式，同时也支持Google Fonts Web API方式进行引入，比如：",[104,7863,7866],{"href":7864,"rel":7865,"target":28},"https:\u002F\u002Ffonts.google.com\u002Fnoto\u002Fspecimen\u002FNoto+Sans?selected=Material+Symbols+Outlined:home:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%231f1f1f",[108],"Noto Sans","字体，我们在web项目中可以直接采用以下方式进行引入：",[679,7869,7871],{"className":7704,"code":7870,"language":7706,"meta":502,"style":502},"\u003Clink href=\"https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap\" rel=\"stylesheet\">\n",[42,7872,7873],{"__ignoreMap":502},[688,7874,7875,7877,7880,7883,7885,7888,7891,7894,7897,7899,7902,7904,7907,7909,7912,7914,7917],{"class":690,"line":691},[688,7876,935],{"class":787},[688,7878,7879],{"class":694},"link",[688,7881,7882],{"class":787}," href=\"https:\u002F\u002Ffonts",[688,7884,2072],{"class":791},[688,7886,7887],{"class":694},"googleapis",[688,7889,7890],{"class":787},".com\u002Fcss2?family=Noto",[688,7892,7893],{"class":791},"+",[688,7895,7896],{"class":787},"Sans:ital",[688,7898,2129],{"class":791},[688,7900,7901],{"class":787},"wght@0,100.",[688,7903,2072],{"class":791},[688,7905,7906],{"class":787},"900;1",[688,7908,2129],{"class":791},[688,7910,7911],{"class":787},"100.",[688,7913,2072],{"class":791},[688,7915,7916],{"class":787},"900&display=swap\" rel=\"stylesheet\"",[688,7918,941],{"class":791},[13,7920,7921],{},"然后项目中直接使用字体：",[679,7923,7925],{"className":7704,"code":7924,"language":7706,"meta":502,"style":502},"body, html {\n   font-family: \"Noto Sans\", sans-serif;\n}\n",[42,7926,7927,7938,7958],{"__ignoreMap":502},[688,7928,7929,7931,7933,7936],{"class":690,"line":691},[688,7930,7827],{"class":694},[688,7932,2129],{"class":791},[688,7934,7935],{"class":694}," html",[688,7937,871],{"class":791},[688,7939,7940,7943,7945,7947,7949,7951,7953,7956],{"class":690,"line":506},[688,7941,7942],{"class":7720},"   font-family",[688,7944,801],{"class":791},[688,7946,3155],{"class":791},[688,7948,7866],{"class":697},[688,7950,2312],{"class":791},[688,7952,2129],{"class":791},[688,7954,7955],{"class":787}," sans-serif",[688,7957,2058],{"class":791},[688,7959,7960],{"class":690,"line":535},[688,7961,2280],{"class":791},[13,7963,7964,7965,7968,7969,7974,7975,7978,7979,7982],{},"因为",[42,7966,7967],{},"fonts.googleapis.com","在国外，加载过程会很慢，因此可以采用",[104,7970,7973],{"href":7971,"rel":7972},"http:\u002F\u002Fgooglefonts.cn\u002F",[108],"Google字体中国站","，但是引用地址不是",[42,7976,7977],{},"googlefonts.cn","，所以很容易错把网站地址当作引用地址而出现错误。其引用地址是",[42,7980,7981],{},"https:\u002F\u002Ffonts.font.im","。上面的引入地址可以调整为：",[679,7984,7986],{"className":7704,"code":7985,"language":7706,"meta":502,"style":502},"\u003Clink href=\"https:\u002F\u002Ffonts.font.im\u002Fcss2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap\" rel=\"stylesheet\">\n",[42,7987,7988],{"__ignoreMap":502},[688,7989,7990,7992,7994,7996,7998,8001,8004,8006,8008,8010,8012,8014,8016,8018,8020,8022,8024],{"class":690,"line":691},[688,7991,935],{"class":787},[688,7993,7879],{"class":694},[688,7995,7882],{"class":787},[688,7997,2072],{"class":791},[688,7999,8000],{"class":694},"font",[688,8002,8003],{"class":787},".im\u002Fcss2?family=Noto",[688,8005,7893],{"class":791},[688,8007,7896],{"class":787},[688,8009,2129],{"class":791},[688,8011,7901],{"class":787},[688,8013,2072],{"class":791},[688,8015,7906],{"class":787},[688,8017,2129],{"class":791},[688,8019,7911],{"class":787},[688,8021,2072],{"class":791},[688,8023,7916],{"class":787},[688,8025,941],{"class":791},[13,8027,8028,8029,8033],{},"当然也可以将自己的字体文件和字体样式文件存放在github仓库，作为静态资源通过jsDelivr进行加速访问。详情查看",[104,8030,8032],{"href":8031,"target":28},"\u002Farticle\u002Fdetail\u002F20250730101107","使用jsDelivr+Github 实现静态资源免费CDN加速","教程，本博客中的字体就是采用此方法进行引入加载。下面是详细使用方式：",[13,8035,8036],{},"引入字体样式文件，此文件通过@font-face定义了需要的字体和字体文件引用源",[679,8038,8040],{"className":6858,"code":8039,"language":6860,"meta":502,"style":502},"\u003Clink rel=\"stylesheet\" type=\"text\u002Fcss\" href=\"https:\u002F\u002Fcdn.anyfork.top\u002Ffonts\u002Fdivision\u002FWarick\u002Fwarick.css\">\n",[42,8041,8042],{"__ignoreMap":502},[688,8043,8044,8046,8049,8051,8053,8056,8058,8061,8063,8065,8068,8070,8073,8075,8077,8080,8082],{"class":690,"line":691},[688,8045,935],{"class":791},[688,8047,8048],{"class":787},"link rel",[688,8050,2303],{"class":791},[688,8052,2312],{"class":791},[688,8054,8055],{"class":697},"stylesheet",[688,8057,2312],{"class":791},[688,8059,8060],{"class":787}," type",[688,8062,2303],{"class":791},[688,8064,2312],{"class":791},[688,8066,8067],{"class":697},"text\u002Fcss",[688,8069,2312],{"class":791},[688,8071,8072],{"class":787}," href",[688,8074,2303],{"class":791},[688,8076,2312],{"class":791},[688,8078,8079],{"class":697},"https:\u002F\u002Fcdn.anyfork.top\u002Ffonts\u002Fdivision\u002FWarick\u002Fwarick.css",[688,8081,2312],{"class":791},[688,8083,941],{"class":791},[13,8085,7921],{},[679,8087,8089],{"className":7704,"code":8088,"language":7706,"meta":502,"style":502},"body, html {\n    font-family: warick;\n}\n",[42,8090,8091,8101,8112],{"__ignoreMap":502},[688,8092,8093,8095,8097,8099],{"class":690,"line":691},[688,8094,7827],{"class":694},[688,8096,2129],{"class":791},[688,8098,7935],{"class":694},[688,8100,871],{"class":791},[688,8102,8103,8105,8107,8110],{"class":690,"line":506},[688,8104,7834],{"class":7720},[688,8106,801],{"class":791},[688,8108,8109],{"class":787}," warick",[688,8111,2058],{"class":791},[688,8113,8114],{"class":690,"line":535},[688,8115,2280],{"class":791},[17,8117,8119],{"id":8118},"_4-字体文件优化","4 字体文件优化",[13,8121,8122],{},"在使用自定义字体时，有时候字体文件比较大，导致网页加载字体文件需要很长时间，影响站点体验，下面便讲讲如何优化。",[13,8124,8125,8126,8129],{},"unicode-range 是 CSS @font-face 规则中的一个属性，用于指定字体文件需要包含的 Unicode 字符范围，以优化字体加载效率。unicode-range 通过指定 Unicode 编码范围来控制字体加载，可显著减少字体文件体积和加载时间，使用这个特性可以优化字体文件加载，实现类似",[42,8127,8128],{"color":116},"按需加载","的效果。",[13,8131,8132],{},"当我们加载网站页面时，页面上展示的文字类型和文字数量都是有限的，比如：对于我的博客而言，主要涉及简体中文和西文，不涉及其他复杂的语种，而且页面上展示的汉字或者西文并非全部的Unicode 字符范围，因此我们只需要加载页面上包含的Unicode字符即可，不需要将整个字体文件加载进来，这样就可以将大的字体文件转变为小的字体文件进行加载。",[13,8134,8135,8140],{},[104,8136,8139],{"href":8137,"rel":8138},"https:\u002F\u002Fchinese-font.netlify.app\u002Fzh-cn\u002Fonline-split\u002F",[108],"中文网字计划","站点提供了一个在线分包的工具，核心功能是将大的字体文件中包含的不同语种字体的 Unicode 字符，进行智能地分包，将不同语种字体按照 Unicode 字符范围进行拆分为多个小的字体文件。页面加载时，根据unicode-range自动加载所需的字体文件。这样可以明显提示字体加载速度，本站便是采用这种方法。",[17,8142,8144],{"id":8143},"_5-字体侵权问题","5 字体侵权问题",[13,8146,8147],{},"对于允许商用的字体，网站上可以任意使用，不存在字体侵权问题。",[13,8149,8150],{},"使用 font-family 的属性引用不可商用的字体，并且网页中也能显示这种字体，不会构成侵权问题，也不需要进行额外的授权许可。因为能够用 font-family 引用成功的字体是用户系统内本身就存在的字体。比如常见的苹方字体，只要我们系统中为引入苹方字体文件，只是应用苹方字体名，不存在侵权。",[13,8152,8153],{},"使用 @font-face 需要将字体文件下载后上传项目或服务器引用，使页面显示字体不再依赖用户系统自带字体，这时如要使用到不可商用的字体，需要购买字体版权，否则就属于侵权。",[17,8155,8157],{"id":8156},"_6-字体网站推荐","6 字体网站推荐",[22,8159,8160,8168,8174,8181],{},[25,8161,8165],{"icon":8162,"target":28,"title":8163,"to":8164},"bi:fonts","Google Fonts","https:\u002F\u002Fwww.googlefonts.cn\u002F",[13,8166,8167],{},"Google字体中文官方站点，提供谷歌字体在线预览，提供Google字体调试工具，Google字体CDN,Google字体镜像，谷歌字体下载功能。",[25,8169,8171],{"icon":8162,"target":28,"title":8139,"to":8170},"https:\u002F\u002Fchinese-font.netlify.app\u002Fzh-cn\u002Fcdn\u002F",[13,8172,8173],{},"字图 CDN, 一个免费的中文字体公益 CDN 服务, 致力于为国内外全球 CJK 开发者提供高质量网络字体服务，让中文字体在互联网世界起飞",[25,8175,8178],{"icon":8162,"target":28,"title":8176,"to":8177},"字体天下","https:\u002F\u002Fwww.fonts.net.cn\u002F",[13,8179,8180],{},"字体天下提供中文字体、手写字体、英文字体、图形字体等各种字体的高速免费下载和在线预览服务.",[25,8182,8185],{"icon":8162,"target":28,"title":8183,"to":8184},"China Webmaster站长字体","https:\u002F\u002Ffont.chinaz.com\u002F",[13,8186,8187],{},"字体库提供,中文字体下载,英文字体下载,书法字体下载,繁体字体下载,艺术字体下载,广告字体下载,方正字体下载,草书字体下载,等字体免费下载",[13,8189,8190,8191],{},"更多字体站点，",[104,8192,8194],{"href":8193,"target":28},"\u002Flinks#74","点击前往",[968,8196,8197],{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":502,"searchDepth":535,"depth":535,"links":8199},[8200,8201,8202,8206,8207,8208],{"id":7537,"depth":506,"text":7538},{"id":7553,"depth":506,"text":7554},{"id":7658,"depth":506,"text":7659,"children":8203},[8204,8205],{"id":7697,"depth":535,"text":7698},{"id":7854,"depth":535,"text":7855},{"id":8118,"depth":506,"text":8119},{"id":8143,"depth":506,"text":8144},{"id":8156,"depth":506,"text":8157},{"name":8210,"symbol":7706,"icon":8211,"id":609},"CSS","material-symbols:css","2025-07-31 10:13:34","一个漂亮的网站，不仅仅依靠基础的版面布局设计，一款漂亮的字体也是至关重要。本文通过网站字体基础知识的讲解，让大家熟练掌握，网站中如何修改自己心仪的字体以及如何优化字体文件过大导致的加载过慢的问题。",{"type":10,"value":8215},[8216],[13,8217,8218],{},"不同操作系统、不同浏览器下的默认字体是不同的，在网页项目中，我们可以通过 CSS 的 font-family 和 @font-face 来让页面渲染出自己心仪的字体。在使用之前，我们需要了解一下，网页中关于字体设定方面的基础知识。",{},"\u002Fblog\u002Ffont-family-@font-face","---\ntitle: 网页字体设置：默认字体、font-family 和 @font-face 使用指南\ndescription: 一个漂亮的网站，不仅仅依靠基础的版面布局设计，一款漂亮的字体也是至关重要。本文通过网站字体基础知识的讲解，让大家熟练掌握，网站中如何修改自己心仪的字体以及如何优化字体文件过大导致的加载过慢的问题。\narticleId: fonts\ncreateDate: \"2025-07-31 10:13:34\"\nupdateDate: \"2026-03-12 10:32:11\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203742648.webp\ntagIds: \n    - 7\ncategoryId: 4\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n不同操作系统、不同浏览器下的默认字体是不同的，在网页项目中，我们可以通过 CSS 的 font-family 和 @font-face 来让页面渲染出自己心仪的字体。在使用之前，我们需要了解一下，网页中关于字体设定方面的基础知识。\n\u003C!--more-->\n## 1 关于font-family属性\n1.字体的 fallback 机制  \n在 CSS 中，可以通过 font-family 引用多种系列、多种字体，并且可以对字体先后顺序进行设置。当用户打开一个网页的时候，浏览就会读取 font-family 第一个引用的字体，并去检索用户当前操作系统下的字体，如有就显示，如没有就检索下一个，以此类推。若浏览器找不到指定的字体，或者没有设置 font-family 则会 fallback 到浏览器的默认字体。 \n \n2.字体的先后顺序设置  \n由于中文字体内都包含西文字体，如想优先显示效果较好的西文字体，需要将西文字体写在中文字体的前面。虽然用户群体中使用 Windows 系统较多，但 Mac 用户大部分会下载 Office，所以会存在许多 Windows 下常见的字体，比如微软雅黑。将 macOS 系统的字体写在 Windows 的前面，可以保证在对应平台显示更好的效果。\n## 2 常见的网页字体\n先了解 serif（衬线体）与 sans-serif（无衬线体），衬线体与无衬线体是两种最基础的字形分类，衬线体在笔画开始与末端的地方有像小三角的装饰。\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250731102434432.webp)\n\n衬线体更多使用在印刷品上，在纸张上有棱角的字体更容易被识别。而在屏幕显示中字体过多的装饰点缀容易造成视觉疲劳，所以在屏幕显示中更多使用无衬线体。下面是一些常见常用的字体：\n \n**system-ui：** 一种通用字体系列，它会选择当前操作系统的默认字体渲染。如在 macOS 与 iOS 系统里 system-ui 指向的中文字体为苹方，西文字体为 .SF NS。\n  \n**-apple-system：** system-ui 的兼容写法，在 macOS 与 iOS 系统里调用苹果系统的默认字体。\n  \n**BlinkMacSystemFont：** 为 macOS Chrome 里调用苹果系统的默认字体。  \n\n**Arial：** 无衬线西文字体，经常与 Helvetica 一起出现，支持不同操作系统、不同浏览器，兼容性好，属于安全字体。\n  \n**Tahoma：** 无衬线西文字体，经常出现，支持不同操作系统、不同浏览器，兼容性好，属于安全字体。 \n \n**Helvetica \u002F Helvetica Neue：** 苹果生态中最常用的无衬线西文字体，Helvetica Neue 是 Helvetica 的升级版，加了不同粗细、不同宽度的字形。  \n\n**Segoe UI：** 无衬线西文字体，Windows 系统的默认西文字体。  \n\n**Roboto：** 无衬线西文字体，Android 系统的默认西文字体。\n  \n**苹方：** 无衬线中文字体，苹果系统的默认中文字体，除了中文简体（PingFang SC），还有台湾繁体（PingFang TC）和香港繁体（PingFang HK）。  \n\n**Hiragino Sans GB (冬青黑体）：** 无衬线中文字体，用于兼容不支持苹方的旧版苹果系统，作为苹方字体的 fallback。\n \n**Microsoft YaHei (微软雅黑)：** 无衬线中文字体，Windows 系统的默认中文字体，iOS 与 Android 系统不支持微软雅黑。  \n\n**Noto Sans (思源黑体)：** 无衬线中文字体，Android 系统的默认中文字体，由 Google 与 Adobe 推出的开源字体。除了中文简体（Noto Sans CJK SC），还有中文繁体（ Sans CJK TC）。  \n\n**WenQuanYi Micro Hei (文泉驿微米黑)：** 无衬线中文字体，Linux 系统的默认中文字体，用于兼容 Linux 系统。 \n \n**Simsun (宋体)：** 衬线中文字体，风格明显，支持 Windows 与 macOS 系统。  \n\n**sans-serif：** 一种无衬线字体系列，常见的兜底字体，在前面所有引用的字体都找不到时会生效，显示当前浏览器默认的无衬线字体。 \n\n## 3 使用自定义字体\n使用自定义字体，常用的方式有2种，本地@font-face和外部样式表(如：Google Fonts Web API库），它们在使用和功能上有所不同。  \n**@font-face：**\n- 使用方法：通过CSS的@font-face规则定义字体，并在页面中使用该字体。\n- 优点：允许使用自定义字体，不依赖外部服务器，可以更好地控制字体的加载和显示。\n- 缺点：需要手动管理字体文件，可能会增加页面加载时间。\n\n**外部样式表**\n- 使用方法：通过向HTML文档添加一个特殊的样式表链接，然后以CSS样式引用该字体即可。\n- 优点：无需进行任何编程，支持多种字体格式，包括WOFF、WOFF2和TTF等。\n- 缺点：需要依赖外部服务器，可能会受到网络延迟或服务器故障的影响。\n### 3.1 方法一\n@font-face方式：将需要使用的字体文件下载后放在服务器上，用 @font-face 将字体文件作为一个资源应用到 CSS样式 文件。为了兼容不同浏览器需要准备多种字体格式文件，保证字体格式文件与浏览器的兼容情况。目前大部分浏览器都支持.woff2格式的字体文件，因此我们只需要引入.woff2这一种格式的字体文件即可。下面是详细使用方法：\n```css\n@font-face {\n  font-family: 'warick';\n  src:local(\"warick\"),url(\".\u002Fwarick.257.woff2\")format(\"woff2\");\n  font-style:normal;\n  font-display:swap;\n  font-weight:400;\n}\nbody{\n    font-family: 'warick';\n}\n```\n项目中可以通过配置多个@font-face设置多种字体文件，需要使用那种字体，便可通过CSS属性 font-family: '字体名称';进行实际应用。\n### 3.2 方法二\n外部样式表：无需下载字体文件，项目中只需要引入对应的CSS外部样式表即可，然后通过CSS属性 font-family: '字体名称'引用需要的字体。下面以Google Fonts和jsDelivr cdn加速github仓库静态资源2种方式，讲讲如何使用。\n\nGoogle Fonts站点，不仅支持字体文件下载，本地引入字体文件的方式，同时也支持Google Fonts Web API方式进行引入，比如：[Noto Sans](https:\u002F\u002Ffonts.google.com\u002Fnoto\u002Fspecimen\u002FNoto+Sans?selected=Material+Symbols+Outlined:home:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%231f1f1f){target='_blank'}字体，我们在web项目中可以直接采用以下方式进行引入：\n```css\n\u003Clink href=\"https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap\" rel=\"stylesheet\">\n```\n然后项目中直接使用字体：\n```css\nbody, html {\n   font-family: \"Noto Sans\", sans-serif;\n}\n```\n因为`fonts.googleapis.com`在国外，加载过程会很慢，因此可以采用[Google字体中国站](http:\u002F\u002Fgooglefonts.cn\u002F)，但是引用地址不是`googlefonts.cn`，所以很容易错把网站地址当作引用地址而出现错误。其引用地址是`https:\u002F\u002Ffonts.font.im`。上面的引入地址可以调整为：\n```css\n\u003Clink href=\"https:\u002F\u002Ffonts.font.im\u002Fcss2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap\" rel=\"stylesheet\">\n```\n当然也可以将自己的字体文件和字体样式文件存放在github仓库，作为静态资源通过jsDelivr进行加速访问。详情查看[使用jsDelivr+Github 实现静态资源免费CDN加速](\u002Farticle\u002Fdetail\u002F20250730101107){target='_blank'}教程，本博客中的字体就是采用此方法进行引入加载。下面是详细使用方式：  \n\n引入字体样式文件，此文件通过@font-face定义了需要的字体和字体文件引用源\n```shell\n\u003Clink rel=\"stylesheet\" type=\"text\u002Fcss\" href=\"https:\u002F\u002Fcdn.anyfork.top\u002Ffonts\u002Fdivision\u002FWarick\u002Fwarick.css\">\n```\n然后项目中直接使用字体：\n```css\nbody, html {\n    font-family: warick;\n}\n```\n## 4 字体文件优化\n在使用自定义字体时，有时候字体文件比较大，导致网页加载字体文件需要很长时间，影响站点体验，下面便讲讲如何优化。\n\n\nunicode-range 是 CSS @font-face 规则中的一个属性，用于指定字体文件需要包含的 Unicode 字符范围，以优化字体加载效率。unicode-range 通过指定 Unicode 编码范围来控制字体加载，可显著减少字体文件体积和加载时间，使用这个特性可以优化字体文件加载，实现类似`按需加载`{color='primary'}的效果。\n\n\n当我们加载网站页面时，页面上展示的文字类型和文字数量都是有限的，比如：对于我的博客而言，主要涉及简体中文和西文，不涉及其他复杂的语种，而且页面上展示的汉字或者西文并非全部的Unicode 字符范围，因此我们只需要加载页面上包含的Unicode字符即可，不需要将整个字体文件加载进来，这样就可以将大的字体文件转变为小的字体文件进行加载。\n\n\n[中文网字计划](https:\u002F\u002Fchinese-font.netlify.app\u002Fzh-cn\u002Fonline-split\u002F)站点提供了一个在线分包的工具，核心功能是将大的字体文件中包含的不同语种字体的 Unicode 字符，进行智能地分包，将不同语种字体按照 Unicode 字符范围进行拆分为多个小的字体文件。页面加载时，根据unicode-range自动加载所需的字体文件。这样可以明显提示字体加载速度，本站便是采用这种方法。\n## 5 字体侵权问题\n对于允许商用的字体，网站上可以任意使用，不存在字体侵权问题。\n\n使用 font-family 的属性引用不可商用的字体，并且网页中也能显示这种字体，不会构成侵权问题，也不需要进行额外的授权许可。因为能够用 font-family 引用成功的字体是用户系统内本身就存在的字体。比如常见的苹方字体，只要我们系统中为引入苹方字体文件，只是应用苹方字体名，不存在侵权。\n\n使用 @font-face 需要将字体文件下载后上传项目或服务器引用，使页面显示字体不再依赖用户系统自带字体，这时如要使用到不可商用的字体，需要购买字体版权，否则就属于侵权。\n## 6 字体网站推荐\n::card-group\n\n::card\n---\ntitle: Google Fonts\nicon: bi:fonts\nto: https:\u002F\u002Fwww.googlefonts.cn\u002F\ntarget: _blank\n---\nGoogle字体中文官方站点，提供谷歌字体在线预览，提供Google字体调试工具，Google字体CDN,Google字体镜像，谷歌字体下载功能。\n::\n\n::card\n---\ntitle: 中文网字计划\nicon: bi:fonts\nto: https:\u002F\u002Fchinese-font.netlify.app\u002Fzh-cn\u002Fcdn\u002F\ntarget: _blank\n---\n字图 CDN, 一个免费的中文字体公益 CDN 服务, 致力于为国内外全球 CJK 开发者提供高质量网络字体服务，让中文字体在互联网世界起飞\n::\n\n::card\n---\ntitle: 字体天下\nicon: bi:fonts\nto: https:\u002F\u002Fwww.fonts.net.cn\u002F\ntarget: _blank\n---\n字体天下提供中文字体、手写字体、英文字体、图形字体等各种字体的高速免费下载和在线预览服务.\n::\n\n\n::card\n---\ntitle: China Webmaster站长字体\nicon: bi:fonts\nto: https:\u002F\u002Ffont.chinaz.com\u002F\ntarget: _blank\n---\n字体库提供,中文字体下载,英文字体下载,书法字体下载,繁体字体下载,艺术字体下载,广告字体下载,方正字体下载,草书字体下载,等字体免费下载\n::\n\n::\n\n更多字体站点，[点击前往](\u002Flinks#74){target='_blank'}\n",16.1,{"title":7530,"description":8213},{"loc":8220,"images":8225},[8226],{"loc":7562},"blog\u002F3.网页字体设置：默认字体、font-family 和 @font-face 使用指南",[863],[8230],{"name":8231,"symbol":8000,"icon":8232,"id":863},"font-family","radix-icons:font-family","2026-03-12 10:32:11",2898,"0-WhXQ8Nb0pYF_GtV13yyeO8TN6sO9764cm5yEtzTms",{"id":8237,"title":8032,"articleId":8238,"articleThumb":8239,"body":8240,"categoryId":863,"categoryInfo":8701,"createDate":8705,"description":8706,"excerpt":8707,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":8712,"navigation":1003,"path":8713,"rawbody":8714,"readingTime":8715,"seo":8716,"sitemap":8717,"stem":8720,"tagIds":8721,"tagInfo":8722,"updateDate":8727,"wordCount":8728,"__hash__":8729},"blog\u002Fblog\u002F4.使用jsDelivr+Github 实现静态资源免费CDN加速.md","jsDelivr-github-cdn","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203950175.webp",{"type":10,"value":8241,"toc":8696},[8242,8246,8276,8329,8339,8359,8363,8386,8559,8562,8566,8579,8680,8683,8693],[17,8243,8245],{"id":8244},"_1-使用流程","1 使用流程",[13,8247,8248,8249,8252,8254,8255,8260,8261,8263,8264,8266,8267,8269,8270,8272,8273,2072],{},"1.登陆github账号，官方地址 ",[104,8250,7179],{"href":7179,"rel":8251,"target":28},[108],[290,8253],{},"\n2.创建公开项目，如我创建了",[104,8256,8259],{"href":8257,"rel":8258,"target":28},"https:\u002F\u002Fgithub.com\u002FAnyFork\u002FResource",[108],"Resource","项目.",[290,8262],{},"\n3.在仓库",[42,8265,8259],{"color":116},"中，创建静态资源目录，比如：js，css，images等目录。",[290,8268],{},"\n4.上传静态资源到对应目录下面。",[290,8271],{},"\n5.jsdelivr cdn访问的格式是：",[42,8274,8275],{"color":116},"https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fuser\u002Frepo@version\u002Ffile",[679,8277,8279],{"className":6858,"code":8278,"language":6860,"meta":502,"style":502},"user: 其中user代表用户名，我的是anyfork\nrepo: 代表项目仓库名称，就是刚才创建项目名：Resource\nversion: 代表的是版本号或者分支号，不想发布版本，亦可不要\nfile: 代表的是文件路径，包含相对于项目的文件目录+文件名+文件格式后缀\n最终组成带版本: https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource@1.0.0\u002Fjquery.min.js\n或者不区分版本: https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource\u002Fjquery.min.js\n",[42,8280,8281,8289,8297,8305,8313,8321],{"__ignoreMap":502},[688,8282,8283,8286],{"class":690,"line":691},[688,8284,8285],{"class":694},"user:",[688,8287,8288],{"class":697}," 其中user代表用户名，我的是anyfork\n",[688,8290,8291,8294],{"class":690,"line":506},[688,8292,8293],{"class":694},"repo:",[688,8295,8296],{"class":697}," 代表项目仓库名称，就是刚才创建项目名：Resource\n",[688,8298,8299,8302],{"class":690,"line":535},[688,8300,8301],{"class":694},"version:",[688,8303,8304],{"class":697}," 代表的是版本号或者分支号，不想发布版本，亦可不要\n",[688,8306,8307,8310],{"class":690,"line":609},[688,8308,8309],{"class":694},"file:",[688,8311,8312],{"class":697}," 代表的是文件路径，包含相对于项目的文件目录+文件名+文件格式后缀\n",[688,8314,8315,8318],{"class":690,"line":624},[688,8316,8317],{"class":694},"最终组成带版本:",[688,8319,8320],{"class":697}," https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource@1.0.0\u002Fjquery.min.js\n",[688,8322,8323,8326],{"class":690,"line":856},[688,8324,8325],{"class":694},"或者不区分版本:",[688,8327,8328],{"class":697}," https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource\u002Fjquery.min.js\n",[13,8330,8331,8332,8335,8336],{},"例如：",[42,8333,8334],{"color":116},"https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp","，效果如下：\n",[419,8337],{"alt":502,"src":8338},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250730095907687.webp",[3056,8340,8341,8353],{},[13,8342,8343,8344,8346,8347,8349,8350,8352],{},"温馨提示：",[290,8345],{},"\nGithub 是最受欢迎的、免费的、开源项目托管平台，对我们来说最大的优点就是代码仓库的创建数量不受限制，但是对于免费账户而言，github有容量的限制。",[290,8348],{},"\n1.公共仓库：无明确总容量限制，但建议单个仓库不超过1GB以确保性能。若仓库过大（如超过5GB），可能会收到GitHub的优化提示邮件。单个文件最大100MB，超过100MB的文件会被直接拦截。若通过浏览器上传，文件最大为25MB通过git客户端上传文件超过50M时，就会给出警告。",[290,8351],{},"\n2.私有仓库：每个私有仓库最大500MB；每个私有仓库最多支持3名协作者；仓库未明确指明容量限制，但一般遵循500M容量限制。",[8354,8355,8358],"div",{"className":8356},[8357],"text-warning-600","jsDelivr CDN只能对小于50M的文件进行加速，超过50M，将不提供加速服务。",[17,8360,8362],{"id":8361},"_2-刷新缓存","2 刷新缓存",[13,8364,8365,8366,8370,8371,8375,8376,8378,8379,8381,8382,8385],{},"有时候更改文件没有及时生效，对于 jsDelivr，缓存刷新的方式也很简单，只需将想刷新的链接的开头的cdn 更改为 purge。",[104,8367,8368],{"href":8368,"rel":8369,"target":28},"https:\u002F\u002Fcdn.jsdelivr.net\u002F",[108],"切换为",[104,8372,8373],{"href":8373,"rel":8374,"target":28},"https:\u002F\u002Fpurge.jsdelivr.net\u002F",[108],"，即可实时刷新。",[290,8377],{},"\n例如我们需要刷新",[42,8380,8334],{},"，只需要在浏览器地址栏输入",[42,8383,8384],{},"https:\u002F\u002Fpurge.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp","回车进行刷新，浏览器会返回缓存刷新成功的信息，如下：",[679,8387,8391],{"className":8388,"code":8389,"language":8390,"meta":502,"style":502},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"id\": \"l80qBHp1o7SRq3hL\",\n  \"status\": \"finished\",\n  \"timestamp\": \"2025-07-30T04:03:50.621Z\",\n  \"paths\": {\n    \"\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp\": {\n      \"throttled\": false,\n      \"providers\": {\n        \"CF\": true,\n        \"FY\": true\n      }\n    }\n  }\n}\n","json",[42,8392,8393,8397,8418,8438,8458,8471,8485,8500,8513,8527,8541,8546,8550,8555],{"__ignoreMap":502},[688,8394,8395],{"class":690,"line":691},[688,8396,792],{"class":791},[688,8398,8399,8402,8405,8407,8409,8411,8414,8416],{"class":690,"line":506},[688,8400,8401],{"class":791},"  \"",[688,8403,8404],{"class":2013},"id",[688,8406,2312],{"class":791},[688,8408,801],{"class":791},[688,8410,3155],{"class":791},[688,8412,8413],{"class":697},"l80qBHp1o7SRq3hL",[688,8415,2312],{"class":791},[688,8417,838],{"class":791},[688,8419,8420,8422,8425,8427,8429,8431,8434,8436],{"class":690,"line":535},[688,8421,8401],{"class":791},[688,8423,8424],{"class":2013},"status",[688,8426,2312],{"class":791},[688,8428,801],{"class":791},[688,8430,3155],{"class":791},[688,8432,8433],{"class":697},"finished",[688,8435,2312],{"class":791},[688,8437,838],{"class":791},[688,8439,8440,8442,8445,8447,8449,8451,8454,8456],{"class":690,"line":609},[688,8441,8401],{"class":791},[688,8443,8444],{"class":2013},"timestamp",[688,8446,2312],{"class":791},[688,8448,801],{"class":791},[688,8450,3155],{"class":791},[688,8452,8453],{"class":697},"2025-07-30T04:03:50.621Z",[688,8455,2312],{"class":791},[688,8457,838],{"class":791},[688,8459,8460,8462,8465,8467,8469],{"class":690,"line":624},[688,8461,8401],{"class":791},[688,8463,8464],{"class":2013},"paths",[688,8466,2312],{"class":791},[688,8468,801],{"class":791},[688,8470,871],{"class":791},[688,8472,8473,8476,8479,8481,8483],{"class":690,"line":856},[688,8474,8475],{"class":791},"    \"",[688,8477,8478],{"class":694},"\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp",[688,8480,2312],{"class":791},[688,8482,801],{"class":791},[688,8484,871],{"class":791},[688,8486,8487,8490,8493,8495,8497],{"class":690,"line":863},[688,8488,8489],{"class":791},"      \"",[688,8491,8492],{"class":2220},"throttled",[688,8494,2312],{"class":791},[688,8496,801],{"class":791},[688,8498,8499],{"class":791}," false,\n",[688,8501,8502,8504,8507,8509,8511],{"class":690,"line":874},[688,8503,8489],{"class":791},[688,8505,8506],{"class":2220},"providers",[688,8508,2312],{"class":791},[688,8510,801],{"class":791},[688,8512,871],{"class":791},[688,8514,8515,8517,8520,8522,8524],{"class":690,"line":890},[688,8516,4327],{"class":791},[688,8518,8519],{"class":797},"CF",[688,8521,2312],{"class":791},[688,8523,801],{"class":791},[688,8525,8526],{"class":791}," true,\n",[688,8528,8529,8531,8534,8536,8538],{"class":690,"line":896},[688,8530,4327],{"class":791},[688,8532,8533],{"class":797},"FY",[688,8535,2312],{"class":791},[688,8537,801],{"class":791},[688,8539,8540],{"class":791}," true\n",[688,8542,8543],{"class":690,"line":905},[688,8544,8545],{"class":791},"      }\n",[688,8547,8548],{"class":690,"line":2096},[688,8549,893],{"class":791},[688,8551,8552],{"class":690,"line":2138},[688,8553,8554],{"class":791},"  }\n",[688,8556,8557],{"class":690,"line":2143},[688,8558,2280],{"class":791},[13,8560,8561],{},"返回status: finished，就代表完成了。",[17,8563,8565],{"id":8564},"_3-域名替代","3 域名替代",[13,8567,8568,8569,8572,8573,8575,8576,8578],{},"Jsdelivr国内的CDN服务",[42,8570,8571],{"color":116},"cdn.jsdelivr.net","经常会被DNS污染了，被指向了Google、Twitter 和 Facebook 的 IP 地址，导致使用CDN服务加速的链接访问失败。这时候我们需要寻找一些未被污染的域名进行加速访问，等官方修复回去后再替换回去就行了。",[290,8574],{},"\n下面罗列jsDelivr针对github国内加速节点，当",[42,8577,8571],{"color":116},"被污染无法稳定访问时，可以用下面的域名进行平替使用。",[260,8580,8581,8594],{},[263,8582,8583],{},[266,8584,8585,8588,8591],{},[269,8586,8587],{},"节点名称",[269,8589,8590],{},"描述",[269,8592,8593],{},"可用性",[278,8595,8596,8608,8621,8633,8646,8658,8669],{},[266,8597,8598,8602,8605],{},[283,8599,8600],{},[42,8601,8571],{},[283,8603,8604],{},"通用节点",[283,8606,8607],{},"低",[266,8609,8610,8615,8618],{},[283,8611,8612],{},[42,8613,8614],{},"gcore.jsdelivr.net",[283,8616,8617],{},"Gcore 节点",[283,8619,8620],{},"高",[266,8622,8623,8628,8631],{},[283,8624,8625],{},[42,8626,8627],{},"testingcf.jsdelivr.net",[283,8629,8630],{},"Cloudflare 节点",[283,8632,8620],{},[266,8634,8635,8640,8643],{},[283,8636,8637],{},[42,8638,8639],{},"quantil.jsdelivr.net",[283,8641,8642],{},"Quantil 节点",[283,8644,8645],{},"尚可",[266,8647,8648,8653,8656],{},[283,8649,8650],{},[42,8651,8652],{},"fastly.jsdelivr.net",[283,8654,8655],{},"Fastly 节点",[283,8657,8645],{},[266,8659,8660,8665,8667],{},[283,8661,8662],{},[42,8663,8664],{},"originfastly.jsdelivr.net",[283,8666,8655],{},[283,8668,8607],{},[266,8670,8671,8676,8678],{},[283,8672,8673],{},[42,8674,8675],{},"test1.jsdelivr.net",[283,8677,8630],{},[283,8679,8607],{},[13,8681,8682],{},"优先推荐使用如下可用性高的平替域名：",[128,8684,8685,8687,8689,8691],{},[68,8686,8614],{},[68,8688,8652],{},[68,8690,8627],{},[68,8692,8675],{},[968,8694,8695],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":502,"searchDepth":535,"depth":535,"links":8697},[8698,8699,8700],{"id":8244,"depth":506,"text":8245},{"id":8361,"depth":506,"text":8362},{"id":8564,"depth":506,"text":8565},{"name":8702,"symbol":8703,"icon":8704,"id":863},"jsDelivr","jsdelivr","logos:jsdelivr","2025-07-30 10:11:07","jsDelivr 是一套免费的 CDN （Content Delivery Network，内容分发网络）服务提供商，可以为你的网站或应用提供静态资源的加速服务。利用 jsDelivr，你可以将静态资源（如图片、CSS、JS 文件）缓存到 Github 仓库中，从而提高静态资源的加载速度和访问速度。",{"type":10,"value":8708},[8709],[13,8710,8711],{},"jsDelivr是唯一具有中国政府颁发的具有有效ICP许可证的公共CDN，为其他一些有特殊要求的项目提供了npm，github，wordpress插件和自定义端点的镜像，全球750个节点，访问速度测试都是蛮快的，并且是完全免费的，你可以加速你网站的静态资源，也可以搭建自己的图库，这里我们仅用github来做下面的教程。",{},"\u002Fblog\u002Fjsdelivr+github-cdn","---\ntitle: 使用jsDelivr+Github 实现静态资源免费CDN加速\ndescription: jsDelivr 是一套免费的 CDN （Content Delivery Network，内容分发网络）服务提供商，可以为你的网站或应用提供静态资源的加速服务。利用 jsDelivr，你可以将静态资源（如图片、CSS、JS 文件）缓存到 Github 仓库中，从而提高静态资源的加载速度和访问速度。\narticleId: jsDelivr-github-cdn\ncreateDate: \"2025-07-30 10:11:07\"\nupdateDate: \"2026-03-12 10:35:12\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327203950175.webp\ntagIds: \n    - 6\ncategoryId: 7\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n\njsDelivr是唯一具有中国政府颁发的具有有效ICP许可证的公共CDN，为其他一些有特殊要求的项目提供了npm，github，wordpress插件和自定义端点的镜像，全球750个节点，访问速度测试都是蛮快的，并且是完全免费的，你可以加速你网站的静态资源，也可以搭建自己的图库，这里我们仅用github来做下面的教程。\n\u003C!--more-->\n\n\n## 1 使用流程\n1.登陆github账号，官方地址 [https:\u002F\u002Fgithub.com\u002F](https:\u002F\u002Fgithub.com\u002F){target=\"_blank\"}  \n2.创建公开项目，如我创建了[Resource](https:\u002F\u002Fgithub.com\u002FAnyFork\u002FResource){target=\"_blank\"}项目.  \n3.在仓库`Resource`{color='primary'}中，创建静态资源目录，比如：js，css，images等目录。  \n4.上传静态资源到对应目录下面。   \n5.jsdelivr cdn访问的格式是：`https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fuser\u002Frepo@version\u002Ffile`{color='primary'}.\n```shell\nuser: 其中user代表用户名，我的是anyfork\nrepo: 代表项目仓库名称，就是刚才创建项目名：Resource\nversion: 代表的是版本号或者分支号，不想发布版本，亦可不要\nfile: 代表的是文件路径，包含相对于项目的文件目录+文件名+文件格式后缀\n最终组成带版本: https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource@1.0.0\u002Fjquery.min.js\n或者不区分版本: https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fanyfork\u002FResource\u002Fjquery.min.js\n```\n例如：`https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp`{color='primary'}，效果如下：\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250730095907687.webp)\n::tip\n温馨提示：\u003C\u002Fbr>\nGithub 是最受欢迎的、免费的、开源项目托管平台，对我们来说最大的优点就是代码仓库的创建数量不受限制，但是对于免费账户而言，github有容量的限制。\u003C\u002Fbr>\n1.公共仓库：无明确总容量限制，但建议单个仓库不超过1GB以确保性能。若仓库过大（如超过5GB），可能会收到GitHub的优化提示邮件。单个文件最大100MB，超过100MB的文件会被直接拦截。若通过浏览器上传，文件最大为25MB通过git客户端上传文件超过50M时，就会给出警告。\u003C\u002Fbr>\n2.私有仓库：每个私有仓库最大500MB；每个私有仓库最多支持3名协作者；仓库未明确指明容量限制，但一般遵循500M容量限制。\n\u003Cdiv class=\"text-warning-600\">jsDelivr CDN只能对小于50M的文件进行加速，超过50M，将不提供加速服务。\u003C\u002Fdiv>\n::\n## 2 刷新缓存\n有时候更改文件没有及时生效，对于 jsDelivr，缓存刷新的方式也很简单，只需将想刷新的链接的开头的cdn 更改为 purge。[https:\u002F\u002Fcdn.jsdelivr.net\u002F](https:\u002F\u002Fcdn.jsdelivr.net\u002F){target='_blank'}切换为[https:\u002F\u002Fpurge.jsdelivr.net\u002F](https:\u002F\u002Fpurge.jsdelivr.net\u002F){target='_blank'}，即可实时刷新。  \n例如我们需要刷新`https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp`，只需要在浏览器地址栏输入`https:\u002F\u002Fpurge.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp`回车进行刷新，浏览器会返回缓存刷新成功的信息，如下：\n```json\n{\n  \"id\": \"l80qBHp1o7SRq3hL\",\n  \"status\": \"finished\",\n  \"timestamp\": \"2025-07-30T04:03:50.621Z\",\n  \"paths\": {\n    \"\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250730095907687.webp\": {\n      \"throttled\": false,\n      \"providers\": {\n        \"CF\": true,\n        \"FY\": true\n      }\n    }\n  }\n}\n```\n返回status: finished，就代表完成了。\n## 3 域名替代\nJsdelivr国内的CDN服务`cdn.jsdelivr.net`{color='primary'}经常会被DNS污染了，被指向了Google、Twitter 和 Facebook 的 IP 地址，导致使用CDN服务加速的链接访问失败。这时候我们需要寻找一些未被污染的域名进行加速访问，等官方修复回去后再替换回去就行了。  \n下面罗列jsDelivr针对github国内加速节点，当`cdn.jsdelivr.net`{color='primary'}被污染无法稳定访问时，可以用下面的域名进行平替使用。\n| 节点名称    | 描述   | 可用性                     |\n|---------|-----------|-------------------- |\n| `cdn.jsdelivr.net`  |     通用节点      | 低 |\n| `gcore.jsdelivr.net`  |   Gcore 节点    | 高 |\n| `testingcf.jsdelivr.net` | Cloudflare 节点 | 高 |\n| `quantil.jsdelivr.net`   | Quantil 节点     | 尚可 |\n| `fastly.jsdelivr.net` | Fastly 节点 | 尚可 |\n| `originfastly.jsdelivr.net` |Fastly 节点  | 低 |\n| `test1.jsdelivr.net` | Cloudflare 节点 | 低 |\n\n\n优先推荐使用如下可用性高的平替域名：\n- gcore.jsdelivr.net\n- fastly.jsdelivr.net\n- testingcf.jsdelivr.net\n- test1.jsdelivr.net",5.2,{"title":8032,"description":8706},{"loc":8713,"images":8718},[8719],{"loc":8338},"blog\u002F4.使用jsDelivr+Github 实现静态资源免费CDN加速",[856],[8723],{"name":8724,"symbol":8725,"icon":8726,"id":856},"CDN","cdn","fa-brands:keycdn","2026-03-12 10:35:12",932,"HZP2pKW8B0_3_l0aMbiByFREEfILbmI9LnYSy-5HJ1k",{"id":8731,"title":8732,"articleId":8733,"articleThumb":8734,"body":8735,"categoryId":535,"categoryInfo":9009,"createDate":9013,"description":9014,"excerpt":9015,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":9020,"navigation":1003,"path":9021,"rawbody":9022,"readingTime":863,"seo":9023,"sitemap":9024,"stem":9044,"tagIds":9045,"tagInfo":9046,"updateDate":9051,"wordCount":9052,"__hash__":9053},"blog\u002Fblog\u002F5.VMware WorkStation 17 Pro虚拟机安装和配置教程.md","VMware WorkStation 17 Pro虚拟机安装和配置教程","vmware-workstation","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204303632.webp",{"type":10,"value":8736,"toc":9000},[8737,8741,8744,8748,8751,8755,8758,8762,8765,8768,8777,8782,8791,8796,8805,8810,8813,8818,8821,8826,8829,8833,8843,8848,8854,8859,8872,8877,8880,8885,8892,8897,8908,8913,8916,8921,8924,8929,8932,8937,8941,8944,8949,8963,8968,8987,8992,8997],[17,8738,8740],{"id":8739},"_1-前期准备","1 前期准备",[13,8742,8743],{},"在VMware虚拟机安装之前，我们需要提前准备好下面两方面的工作：创建目录和下载VMware安装程序",[123,8745,8747],{"id":8746},"_11-创建安装目录","1.1 创建安装目录",[13,8749,8750],{},"VMware默认安装路径为C盘，一般不建议放在C盘安装，我们可以自定义安装路径，在安装之前，我们可以在磁盘容量比较大的磁盘创建VMware安装目录，比如：F:\u002Fvmware。在安装时，我们可以将自定义安装路径设为F:\u002Fvmware。",[123,8752,8754],{"id":8753},"_12-虚拟机存放目录","1.2 虚拟机存放目录",[13,8756,8757],{},"虚拟机存放目录，一般需要的磁盘空间比较大，用于存放新创建的虚拟机工作空间和系统文件目录，随着虚拟机增多，此目录会越来越大，所以我们需要在容量较大的磁盘上创建目录，比如：F:\u002FvmwareData。在后面虚拟机安装成功后，配置虚拟机存放目录。",[123,8759,8761],{"id":8760},"_13-下载vmware安装包","1.3 下载VMware安装包",[13,8763,8764],{},"VMware Workstation从‌2024年11月11日‌起对所有用户(商业、教育及个人)免费使用，并覆盖所有付费功能特性。包括VMware Workstation Pro和Fusion Pro的所有付费功能，适用于Windows、Linux及Mac系统。从VMware Workstation Pro 17版本开始，个人可以免费使用，并且不需要对软件进行激活操作，推荐安装最新版本的VMware虚拟机进行体验。",[13,8766,8767],{},"相对于以前版本的安装，VMware Workstation Pro 17版本比较麻烦，具体步骤如下：",[13,8769,8770,8771,8776],{},"1 登陆",[104,8772,8775],{"href":8773,"rel":8774,"target":28},"https:\u002F\u002Faccess.broadcom.com\u002Fdefault\u002Fui\u002Fv1\u002Fsignin\u002F",[108],"Broadcom","，没有账号需要自己注册一个。",[13,8778,8779],{},[419,8780],{"alt":502,"src":8781},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721113333586.png",[13,8783,8784,8785,8790],{},"2 登陆成功后，点击",[104,8786,8789],{"href":8787,"rel":8788,"target":28},"https:\u002F\u002Fsupport.broadcom.com\u002Fgroup\u002Fecx\u002Ffree-downloads",[108],"Free Downloads","，进入下载列表页面。",[13,8792,8793],{},[419,8794],{"alt":502,"src":8795},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721113840017.png",[13,8797,8798,8799,8804],{},"3 页面列表下拉，找到",[104,8800,8803],{"href":8801,"rel":8802,"target":28},"https:\u002F\u002Fsupport.broadcom.com\u002Fgroup\u002Fecx\u002Fproductdownloads?subfamily=VMware%20Workstation%20Pro&freeDownloads=true",[108],"VMware Workstation Pro","，点击进入。",[13,8806,8807],{},[419,8808],{"alt":502,"src":8809},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114129290.png",[13,8811,8812],{},"4 选择对应的系统版本，展开下载项，点击对应的版本，进行下载。",[13,8814,8815],{},[419,8816],{"alt":502,"src":8817},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114604129.png",[13,8819,8820],{},"5 点击下载图标，进行下载。",[13,8822,8823],{},[419,8824],{"alt":502,"src":8825},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114614137.png",[13,8827,8828],{},"下载可能很慢，等待下载完毕，便可进行安装。",[17,8830,8832],{"id":8831},"_2-安装vmware虚拟机","2 安装VMware虚拟机",[13,8834,8835,8836,8839,8840,8842],{},"1 找到刚刚下载的VMware的安装程序，在安装程序上鼠标右键点击，选择以管理员身份运行，此时会弹出一个安装确认弹框，点击",[42,8837,8838],{"color":116},"是","，点完",[42,8841,8838],{"color":116},"以后这里需要稍微等待一会，才会显示安装界面：",[13,8844,8845],{},[419,8846],{"alt":502,"src":8847},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115045491.png",[13,8849,8850,8851],{},"2 同意安装协议，然后",[42,8852,8853],{"color":116},"下一步",[13,8855,8856],{},[419,8857],{"alt":502,"src":8858},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115232581.png",[13,8860,8861,8862,8864,8865,8868,8869,8871],{},"3 点完 ",[42,8863,8853],{"color":116},"以后可能会出现下面这个界面，也可能不会出现，因人而异。如果出现了就勾选自动安装 ",[42,8866,8867],{"color":116},"Windows Hypervisor Platform (WHP)","，然后",[42,8870,8853],{"color":116}," 即可。如果没有出现就跳过这一步。",[13,8873,8874],{},[419,8875],{"alt":502,"src":8876},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115417180.png",[13,8878,8879],{},"4 更改VMware安装目录，比如指定我们上面创建好的目录：F:\u002Fvmware",[13,8881,8882],{},[419,8883],{"alt":502,"src":8884},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115559582.png",[13,8886,8887,8888,8891],{},"5 选择我们刚刚创建的VMware的安装目录，然后点击确定，下一步，如果出现这个弹窗直接点",[42,8889,8890],{"color":116},"确定","，如果没有出现直接跳过这一步。",[13,8893,8894],{},[419,8895],{"alt":502,"src":8896},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115744675.png",[13,8898,8899,8900,8903,8904,8907],{},"6 将",[42,8901,8902],{"color":116},"启动时检查产品更新"," 和",[42,8905,8906],{"color":116}," 加入 VMware 客户体验提升计划","取消勾选，然后点击下一步。",[13,8909,8910],{},[419,8911],{"alt":502,"src":8912},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115905277.png",[13,8914,8915],{},"7 勾选创建桌面快捷方式",[13,8917,8918],{},[419,8919],{"alt":502,"src":8920},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115953920.png",[13,8922,8923],{},"8 点击安装。",[13,8925,8926],{},[419,8927],{"alt":502,"src":8928},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120049904.png",[13,8930,8931],{},"9 然后等待安装进度条结束后，安装成功。",[13,8933,8934],{},[419,8935],{"alt":502,"src":8936},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120156931.png",[17,8938,8940],{"id":8939},"_3-设置虚拟机安装路径","3 设置虚拟机安装路径",[13,8942,8943],{},"这一步也很重要。后期创建虚拟机的时候会让你选择虚拟机存放位置，如果这一步没有做的话，那你每次创建虚拟机的时候都要手动的去选择存放位置。虚拟机安装成功后，打开虚拟机",[13,8945,8946],{},[419,8947],{"alt":502,"src":8948},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120307536.png",[13,8950,8951,8952,567,8955,8958,8959,8962],{},"首先在",[42,8953,8954],{"color":116},"VMware工具栏",[42,8956,8957],{"color":116},"编辑","，然后点击",[42,8960,8961],{"color":116},"首选项","：",[13,8964,8965],{},[419,8966],{"alt":502,"src":8967},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120632353.png",[13,8969,8970,8971,8974,8975,8978,8979,8982,8983,8986],{},"在左侧侧边栏，点击",[42,8972,8973],{"color":116},"工作区","，然后就能看到",[42,8976,8977],{"color":116},"虚拟机的默认位置(D)"," 的选项了，我们点击",[42,8980,8981],{"color":116}," 浏览","，将默认位置改为我们刚刚创建的",[42,8984,8985],{"color":116},"vmwareData","目录。",[13,8988,8989],{},[419,8990],{"alt":502,"src":8991},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120831956.png",[13,8993,8994],{},[419,8995],{"alt":502,"src":8996},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721121025337.png",[13,8998,8999],{},"这样的话，我们在创建虚拟机的时候，就会默认存放在我们设置的目录中了，到此VMware安装和配置变结束了。",{"title":502,"searchDepth":535,"depth":535,"links":9001},[9002,9007,9008],{"id":8739,"depth":506,"text":8740,"children":9003},[9004,9005,9006],{"id":8746,"depth":535,"text":8747},{"id":8753,"depth":535,"text":8754},{"id":8760,"depth":535,"text":8761},{"id":8831,"depth":506,"text":8832},{"id":8939,"depth":506,"text":8940},{"name":9010,"symbol":9011,"icon":9012,"id":535},"软件安装","software","carbon:software-resource-cluster","2025-07-21 11:09:31","本文记录了VMware WorkStation 17 Pro虚拟机在windows 10系统上完整的安装配置教程，包含安装程序下载流程，自定义VMware默认安装目录，自定义新建虚拟机默认存放位置等配置步骤。",{"type":10,"value":9016},[9017],[13,9018,9019],{},"VMware Workstation是一款由VMware公司开发的桌面虚拟化软件，允许在单台物理计算机上同时运行多个独立的操作系统(如Windows、Linux等)，实现多系统并行操作而无需重启；提供硬件虚拟化支持，模拟CPU、内存、硬盘等硬件资源，创建接近物理机的运行环境；支持3D图形加速、网络模拟（桥接\u002FNAT）、共享文件夹及加密安全功能；提供快照与克隆功能，便于保存虚拟机状态或快速复制实例；为IT专业人员提供隔离的虚拟环境，提升工作效率和安全性。",{},"\u002Fblog\u002Fvmware-workstation-17-pro","---\ntitle: VMware WorkStation 17 Pro虚拟机安装和配置教程\ndescription: 本文记录了VMware WorkStation 17 Pro虚拟机在windows 10系统上完整的安装配置教程，包含安装程序下载流程，自定义VMware默认安装目录，自定义新建虚拟机默认存放位置等配置步骤。\narticleId: vmware-workstation\ncreateDate: \"2025-07-21 11:09:31\"\nupdateDate: \"2026-03-12 10:38:12\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204303632.webp\ntagIds: \n    - 5\ncategoryId: 3\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\nVMware Workstation是一款由VMware公司开发的桌面虚拟化软件，允许在单台物理计算机上同时运行多个独立的操作系统(如Windows、Linux等)，实现多系统并行操作而无需重启；提供硬件虚拟化支持，模拟CPU、内存、硬盘等硬件资源，创建接近物理机的运行环境；支持3D图形加速、网络模拟（桥接\u002FNAT）、共享文件夹及加密安全功能；提供快照与克隆功能，便于保存虚拟机状态或快速复制实例；为IT专业人员提供隔离的虚拟环境，提升工作效率和安全性。\n\u003C!--more-->\n## 1 前期准备\n在VMware虚拟机安装之前，我们需要提前准备好下面两方面的工作：创建目录和下载VMware安装程序\n### 1.1 创建安装目录\nVMware默认安装路径为C盘，一般不建议放在C盘安装，我们可以自定义安装路径，在安装之前，我们可以在磁盘容量比较大的磁盘创建VMware安装目录，比如：F:\u002Fvmware。在安装时，我们可以将自定义安装路径设为F:\u002Fvmware。\n### 1.2 虚拟机存放目录\n虚拟机存放目录，一般需要的磁盘空间比较大，用于存放新创建的虚拟机工作空间和系统文件目录，随着虚拟机增多，此目录会越来越大，所以我们需要在容量较大的磁盘上创建目录，比如：F:\u002FvmwareData。在后面虚拟机安装成功后，配置虚拟机存放目录。\n### 1.3 下载VMware安装包\nVMware Workstation从‌2024年11月11日‌起对所有用户(商业、教育及个人)免费使用，并覆盖所有付费功能特性。包括VMware Workstation Pro和Fusion Pro的所有付费功能，适用于Windows、Linux及Mac系统。从VMware Workstation Pro 17版本开始，个人可以免费使用，并且不需要对软件进行激活操作，推荐安装最新版本的VMware虚拟机进行体验。\n\n\n相对于以前版本的安装，VMware Workstation Pro 17版本比较麻烦，具体步骤如下：\n\n\n1 登陆[Broadcom](https:\u002F\u002Faccess.broadcom.com\u002Fdefault\u002Fui\u002Fv1\u002Fsignin\u002F){target=\"_blank\"}，没有账号需要自己注册一个。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721113333586.png)\n\n\n2 登陆成功后，点击[Free Downloads](https:\u002F\u002Fsupport.broadcom.com\u002Fgroup\u002Fecx\u002Ffree-downloads){target=\"_blank\"}，进入下载列表页面。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721113840017.png)\n\n\n3 页面列表下拉，找到[VMware Workstation Pro](https:\u002F\u002Fsupport.broadcom.com\u002Fgroup\u002Fecx\u002Fproductdownloads?subfamily=VMware%20Workstation%20Pro&freeDownloads=true){target=\"_blank\"}，点击进入。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114129290.png)\n\n\n4 选择对应的系统版本，展开下载项，点击对应的版本，进行下载。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114604129.png)\n\n\n5 点击下载图标，进行下载。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721114614137.png)\n\n\n下载可能很慢，等待下载完毕，便可进行安装。\n\n\n## 2 安装VMware虚拟机\n1 找到刚刚下载的VMware的安装程序，在安装程序上鼠标右键点击，选择以管理员身份运行，此时会弹出一个安装确认弹框，点击`是`{color=\"primary\"}，点完`是`{color=\"primary\"}以后这里需要稍微等待一会，才会显示安装界面：\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115045491.png)\n\n\n2 同意安装协议，然后`下一步`{color=\"primary\"}\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115232581.png)\n\n\n3 点完 `下一步`{color=\"primary\"}以后可能会出现下面这个界面，也可能不会出现，因人而异。如果出现了就勾选自动安装 `Windows Hypervisor Platform (WHP)`{color=\"primary\"}，然后`下一步`{color=\"primary\"} 即可。如果没有出现就跳过这一步。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115417180.png)\n\n\n4 更改VMware安装目录，比如指定我们上面创建好的目录：F:\u002Fvmware\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115559582.png)\n\n\n5 选择我们刚刚创建的VMware的安装目录，然后点击确定，下一步，如果出现这个弹窗直接点`确定`{color=\"primary\"}，如果没有出现直接跳过这一步。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115744675.png)\n\n\n6 将`启动时检查产品更新`{color=\"primary\"} 和` 加入 VMware 客户体验提升计划`{color=\"primary\"}取消勾选，然后点击下一步。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115905277.png)\n\n\n7 勾选创建桌面快捷方式\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721115953920.png)\n\n\n8 点击安装。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120049904.png)\n\n\n9 然后等待安装进度条结束后，安装成功。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120156931.png)\n\n\n\n\n## 3 设置虚拟机安装路径\n这一步也很重要。后期创建虚拟机的时候会让你选择虚拟机存放位置，如果这一步没有做的话，那你每次创建虚拟机的时候都要手动的去选择存放位置。虚拟机安装成功后，打开虚拟机\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120307536.png)\n\n\n首先在`VMware工具栏`{color=\"primary\"}点击`编辑`{color=\"primary\"}，然后点击`首选项`{color=\"primary\"}：\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120632353.png)\n\n\n在左侧侧边栏，点击`工作区`{color=\"primary\"}，然后就能看到`虚拟机的默认位置(D)`{color=\"primary\"} 的选项了，我们点击` 浏览`{color=\"primary\"}，将默认位置改为我们刚刚创建的`vmwareData`{color=\"primary\"}目录。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721120831956.png)\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721121025337.png)\n\n\n这样的话，我们在创建虚拟机的时候，就会默认存放在我们设置的目录中了，到此VMware安装和配置变结束了。\n",{"title":8732,"description":9014},{"loc":9021,"images":9025},[9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043],{"loc":8781},{"loc":8795},{"loc":8809},{"loc":8817},{"loc":8825},{"loc":8847},{"loc":8858},{"loc":8876},{"loc":8884},{"loc":8896},{"loc":8912},{"loc":8920},{"loc":8928},{"loc":8936},{"loc":8948},{"loc":8967},{"loc":8991},{"loc":8996},"blog\u002F5.VMware WorkStation 17 Pro虚拟机安装和配置教程",[624],[9047],{"name":9048,"symbol":9049,"icon":9050,"id":624},"VMware","vmware","lineicons:vmware","2026-03-12 10:38:12",1260,"4Y-CEd3g-FR5rQn0d31H8-iaT0bY6QcF1SFn96-GcyM",{"id":9055,"title":9056,"articleId":9057,"articleThumb":9058,"body":9059,"categoryId":506,"categoryInfo":9860,"createDate":9864,"description":9865,"excerpt":9866,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":9871,"navigation":1003,"path":9872,"rawbody":9873,"readingTime":9874,"seo":9875,"sitemap":9876,"stem":9931,"tagIds":9932,"tagInfo":9933,"updateDate":9935,"wordCount":9936,"__hash__":9937},"blog\u002Fblog\u002F8.VMware 17虚拟机安装原版MacOS Sequoia15.5苹果系统教程.md","VMware 17虚拟机安装原版MacOS Sequoia15.5苹果系统教程","vmware-macOS","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204553579.webp",{"type":10,"value":9060,"toc":9843},[9061,9064,9066,9069,9078,9081,9085,9088,9094,9098,9107,9116,9121,9126,9131,9143,9163,9167,9177,9193,9204,9208,9212,9215,9220,9223,9228,9231,9236,9246,9250,9253,9258,9261,9266,9269,9274,9277,9282,9285,9290,9293,9298,9301,9306,9309,9314,9317,9322,9325,9330,9334,9337,9355,9358,9368,9372,9378,9383,9386,9391,9394,9399,9402,9413,9416,9421,9424,9429,9432,9437,9440,9445,9448,9453,9456,9461,9464,9469,9472,9477,9480,9485,9488,9493,9496,9501,9504,9509,9512,9517,9520,9525,9528,9533,9536,9541,9544,9549,9552,9557,9560,9565,9568,9573,9577,9580,9632,9635,9638,9644,9649,9652,9663,9666,9671,9674,9679,9682,9687,9690,9695,9698,9701,9705,9708,9712,9733,9736,9739,9743,9746,9752,9758,9769,9772,9807,9837,9840],[13,9062,9063],{},"本技术文档系统性地记录了在Windows 10操作系统作为宿主机环境下，利用VMware虚拟化平台安装macOS操作系统的完整技术方案，文档包含从环境准备到系统优化的全流程技术细节。",[17,9065,8740],{"id":8739},[13,9067,9068],{},"在安装之前，我们先看看下面的视频教程，有个初步的操作体验，然后根据后面文本，逐步执行安装过程。",[9070,9071],"iframe",{"src":9072,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114120250689097&bvid=BV1Bz9yYYEtF&cid=28738064038&p=1&autoplay=0","no",0,"true","100%","450px",[13,9079,9080],{},"在VMware Workstation Pro 17安装Sequoia15.5黑苹果系统之前，我们需要提前准备好安装需要的软件和镜像。",[123,9082,9084],{"id":9083},"_11-安装vmware虚拟机","1.1 安装VMware虚拟机",[13,9086,9087],{},"VMware Workstation从‌2024年11月11日‌起对所有用户(商业、教育及个人)免费使用，并覆盖所有付费功能特性。包括VMware Workstation Pro和Fusion Pro的所有付费功能，适用于Windows、Linux及Mac系统。从VMware Workstation Pro 17版本开始，个人可以免费使用，并且不需要对软件进行激活操作，推荐安装最新版本的VMware虚拟机进行体验。本文采用的是VMware Workstation Pro 17.1.10版本的虚拟机。",[13,9089,9090,9091],{},"VMware虚拟机详细安装教程参考文章：",[104,9092,8732],{"href":9093,"target":28},"\u002Farticle\u002Fdetail\u002F20250721110931",[123,9095,9097],{"id":9096},"_12-下载unlocker工具","1.2 下载Unlocker工具",[13,9099,9100,9101,9106],{},"VMware Workstation Pro虚拟机默认不支持MacOS系统安装，需要借助第三方工具",[104,9102,9105],{"href":9103,"target":28,"rel":9104},"https:\u002F\u002Fgithub.com\u002FDrDonk\u002Funlocker",[108],"MacOS Unlocker","进行解锁后，才能安装MacOS系统。",[13,9108,9109,9112],{},[71,9110,9111],{},"1. 下载unlocker427：",[104,9113,9114],{"href":9114,"target":28,"rel":9115},"https:\u002F\u002Fgithub.com\u002FDrDonk\u002Funlocker\u002Freleases\u002Ftag\u002Fv4.2.7",[108],[13,9117,9118],{},[419,9119],{"alt":502,"src":9120},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716204503922.png",[13,9122,9123],{},[71,9124,9125],{},"2. 解压缩到任意目录",[13,9127,9128],{},[419,9129],{"alt":502,"src":9130},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716210808722.png",[13,9132,9133,9136,9138,9139,9142],{},[71,9134,9135],{},"3. 运行unlock.exe",[290,9137],{},"\n关闭VMware虚拟机，任务管理器杀掉VMware相关的进程，然后进入打开解压出来的【Unlocker427文件夹】-【Windows】-双击【Unlock.exe】\n",[419,9140],{"alt":502,"src":9141},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716205618470.png","\n执行完毕后，点击任意按键退出。",[13,9144,9145,9148,9150,9151,9154,9155,9158,9159,9162],{},[71,9146,9147],{},"4. 验证解锁",[290,9149],{},"\n打开VMware软件，点击【文件】-【新建虚拟机】- 【创建虚拟机向导】\n",[419,9152],{"alt":502,"src":9153},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212602755.png","\n如果出现",[42,9156,9157],{},"MacOS选项","，表示解锁成功，如果没有，则需要完全退出VMware软件，然后重新执行一下",[42,9160,9161],{},"Unlock.exe","的安装。",[123,9164,9166],{"id":9165},"_13-下载苹果iso镜像","1.3 下载苹果ISO镜像",[13,9168,9169,9170,9173,9174,9176],{},"苹果官网提供的原始镜像无法直接用于VMware虚拟机，需要将原始镜像制作成VMware通用的",[42,9171,9172],{"color":116},".iso","格式镜像文件。我们可以用工具自己制作，也可以从第三方网站下载",[42,9175,9172],{"color":116},"镜像。推荐从下面几个站点下载镜像：",[65,9178,9179,9186],{},[68,9180,9181,9182],{},"苹果系统之家：",[104,9183,9184],{"href":9184,"target":28,"rel":9185},"https:\u002F\u002Fmacoshome.com\u002Fmacos",[108],[68,9187,9188,9189],{},"黑苹果屋：",[104,9190,9191],{"href":9191,"target":28,"rel":9192},"https:\u002F\u002Fimacos.top\u002Fcategory\u002Fhpgw\u002Fxtgx\u002Fiso\u002F",[108],[13,9194,9195,9196,9199,9200],{},"本文安装的",[42,9197,9198],{},"MacOS Sequoia15.5.iso","镜像下载地址：",[104,9201,9202],{"href":9202,"target":28,"rel":9203},"https:\u002F\u002Fmacoshome.com\u002Fmacos\u002F57355.html",[108],[17,9205,9207],{"id":9206},"_2-开始安装","2 开始安装",[123,9209,9211],{"id":9210},"_21-创建虚拟机","2.1 创建虚拟机",[13,9213,9214],{},"1 新建虚拟机向导，选择自定义",[13,9216,9217],{},[419,9218],{"alt":502,"src":9219},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212534185.png",[13,9221,9222],{},"2 选择虚拟机硬件兼容性，默认下一步",[13,9224,9225],{},[419,9226],{"alt":502,"src":9227},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212540211.png",[13,9229,9230],{},"3 安装客户机操作系统，稍后安装操作系统",[13,9232,9233],{},[419,9234],{"alt":502,"src":9235},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212545672.png",[13,9237,9238,9239,9242,9243],{},"4 选择客户机操作系统，选择",[42,9240,9241],{},"Apple macOS(M)","，版本选择",[42,9244,9245],{},"macOS 15",[13,9247,9248],{},[419,9249],{"alt":502,"src":9153},[13,9251,9252],{},"5 命名虚拟机，选择虚拟机存储位置",[13,9254,9255],{},[419,9256],{"alt":502,"src":9257},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213703927.png",[13,9259,9260],{},"6 处理器数量，处理器核数，根据系统情况调整",[13,9262,9263],{},[419,9264],{"alt":502,"src":9265},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213710361.png",[13,9267,9268],{},"7 设置虚拟机内存，至少4G",[13,9270,9271],{},[419,9272],{"alt":502,"src":9273},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213720396.png",[13,9275,9276],{},"8 选择网络类型，使用网络地址转换NAT",[13,9278,9279],{},[419,9280],{"alt":502,"src":9281},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214011459.png",[13,9283,9284],{},"9 选择I\u002FO控制器类型，默认推荐",[13,9286,9287],{},[419,9288],{"alt":502,"src":9289},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214020532.png",[13,9291,9292],{},"10 选择磁盘类型，默认推荐",[13,9294,9295],{},[419,9296],{"alt":502,"src":9297},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214105918.png",[13,9299,9300],{},"11 创建新磁盘",[13,9302,9303],{},[419,9304],{"alt":502,"src":9305},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214111961.png",[13,9307,9308],{},"12 创建磁盘容量，建议至少80G，磁盘拆分多个文件",[13,9310,9311],{},[419,9312],{"alt":502,"src":9313},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214115108.png",[13,9315,9316],{},"13 指定磁盘文件名称和文件路径，默认即可",[13,9318,9319],{},[419,9320],{"alt":502,"src":9321},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214130493.png",[13,9323,9324],{},"14 点击完成，完成虚拟机创建",[13,9326,9327],{},[419,9328],{"alt":502,"src":9329},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214136750.png",[123,9331,9333],{"id":9332},"_22-修改虚拟机","2.2 修改虚拟机",[13,9335,9336],{},"找到我们刚刚创建的虚拟机保存位置，然后找到后缀名位 .vmx 的文件，用编辑器打开，在最后一行加入以下代码：",[679,9338,9340],{"className":6858,"code":9339,"language":6860,"meta":502,"style":502},"smc.version = \"0\"\n",[42,9341,9342],{"__ignoreMap":502},[688,9343,9344,9347,9349,9351,9353],{"class":690,"line":691},[688,9345,9346],{"class":694},"smc.version",[688,9348,2046],{"class":697},[688,9350,3155],{"class":791},[688,9352,2240],{"class":697},[688,9354,6890],{"class":791},[13,9356,9357],{},"smc.version = \"0\" 是解决 VMware 虚拟机运行 macOS 时出现的兼容性问题关键配置项，主要用于绕过 VMware 对 macOS 系统的版本限制。在 VMware 中安装 macOS 时，若硬件兼容性设置为 Workstation 11 或更高版本，可能导致虚拟机无法启动。通过添加 smc.version = \"0\" 到虚拟机配置文件（.vmx 文件），可强制虚拟机以较低版本兼容模式运行，避免因系统版本不匹配导致的崩溃。",[13,9359,9360,9361,9364,9365],{},"修改虚拟机，配置",[42,9362,9363],{},"macOS","镜像文件\n",[419,9366],{"alt":502,"src":9367},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221015437.png",[123,9369,9371],{"id":9370},"_23-安装macos系统","2.3 安装MacOS系统",[13,9373,9374,9375,9377],{},"1 打开虚拟机，进行安装",[42,9376,9363],{},"系统",[13,9379,9380],{},[419,9381],{"alt":502,"src":9382},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221456354.png",[13,9384,9385],{},"2 选择简体中文，下一步",[13,9387,9388],{},[419,9389],{"alt":502,"src":9390},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221555854.png",[13,9392,9393],{},"3 选择磁盘工具，初始化磁盘",[13,9395,9396],{},[419,9397],{"alt":502,"src":9398},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221641339.png",[13,9400,9401],{},"4 点击磁盘，进行抹除",[13,9403,9404,9407,9410],{},[419,9405],{"alt":502,"src":9406},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221743149.png",[419,9408],{"alt":502,"src":9409},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221903192.png",[419,9411],{"alt":502,"src":9412},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221942479.png",[13,9414,9415],{},"5 选择安装macOS Sequoia，点击继续",[13,9417,9418],{},[419,9419],{"alt":502,"src":9420},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222030643.png",[13,9422,9423],{},"6 同意安装协议",[13,9425,9426],{},[419,9427],{"alt":502,"src":9428},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222201251.png",[13,9430,9431],{},"7 选择安装磁盘",[13,9433,9434],{},[419,9435],{"alt":502,"src":9436},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222209652.png",[13,9438,9439],{},"8 等待安装，等待大约半个小时，自动重启",[13,9441,9442],{},[419,9443],{"alt":502,"src":9444},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222219950.png",[13,9446,9447],{},"9 选择国家和地区",[13,9449,9450],{},[419,9451],{"alt":502,"src":9452},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222353260.png",[13,9454,9455],{},"10 设为新机",[13,9457,9458],{},[419,9459],{"alt":502,"src":9460},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222400147.png",[13,9462,9463],{},"11 设置输入法",[13,9465,9466],{},[419,9467],{"alt":502,"src":9468},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222403888.png",[13,9470,9471],{},"12 设置辅助功能，点击以后",[13,9473,9474],{},[419,9475],{"alt":502,"src":9476},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222415947.png",[13,9478,9479],{},"13 数据与隐私，继续",[13,9481,9482],{},[419,9483],{"alt":502,"src":9484},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222418924.png",[13,9486,9487],{},"14 自动更新系统，继续",[13,9489,9490],{},[419,9491],{"alt":502,"src":9492},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222830204.png",[13,9494,9495],{},"15 appId账号登陆，接点击左下角的“稍后设置”按钮，再点击“跳过”按钮",[13,9497,9498],{},[419,9499],{"alt":502,"src":9500},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224005862.png",[13,9502,9503],{},"16 条款与条件，只能同意啦",[13,9505,9506],{},[419,9507],{"alt":502,"src":9508},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224239343.png",[13,9510,9511],{},"17 因为我们前面没有登录Apple账户，所以这里需要创建一个本地账户，建议用户名使用纯英文字符",[13,9513,9514],{},[419,9515],{"alt":502,"src":9516},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224244290.png",[13,9518,9519],{},"18 服务定位，建议先不开启，避免占用资源，所以点击“继续”和“不使用”按钮",[13,9521,9522],{},[419,9523],{"alt":502,"src":9524},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224311838.png",[13,9526,9527],{},"19 选择时区，你可以用鼠标点击那个地图，比如我这里点击了上海，时区会影响时间的显示，所以得选对了（当然后面我也会讲如何修改时区）",[13,9529,9530],{},[419,9531],{"alt":502,"src":9532},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224317014.png",[13,9534,9535],{},"20 分析功能，建议取消勾选“与Apple共享Mac分析”选项，然后点击“继续”按钮",[13,9537,9538],{},[419,9539],{"alt":502,"src":9540},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224321051.png",[13,9542,9543],{},"21 屏幕使用时间，为了节省性能资源，建议先不要开启，直接点击“稍后设置”按钮",[13,9545,9546],{},[419,9547],{"alt":502,"src":9548},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224325700.png",[13,9550,9551],{},"22 外观，看你心情随便选择一个吧",[13,9553,9554],{},[419,9555],{"alt":502,"src":9556},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224330741.png",[13,9558,9559],{},"23 大功告成！现在终于进入到macOS 15的桌面了，但是你需要等一下，因为现在可能有点卡",[13,9561,9562],{},[419,9563],{"alt":502,"src":9564},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716225210885.png",[13,9566,9567],{},"等了一段时间之后，你可以试着动动鼠标，发现已经可以正常使用了，但是壁纸一直加载不出来，你也不用继续等了，因为显存过小，所以它默认的动态壁纸是永远也加载不出来的。为了不至于显示这么丑的白屏，我们可以打开设置选项，找一张图片壁纸给它换上。",[13,9569,9570],{},[419,9571],{"alt":502,"src":9572},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716225946874.png",[123,9574,9576],{"id":9575},"_24-安装vmtools","2.4 安装VMtools",[13,9578,9579],{},"VMtools（VMware Tools）是 VMware 为虚拟机提供的一套增强工具套件，主要功能包括优化性能、提升用户体验及实现主机与虚拟机间的协同操作。核心功能如下：",[65,9581,9582,9593,9607,9618],{},[68,9583,9584,9585],{},"优化硬件性能\n",[128,9586,9587,9590],{},[68,9588,9589],{},"提升图形处理性能，支持高分辨率显示及 SVGA模式 ，通过虚拟显卡驱动增强显示效果；",[68,9591,9592],{},"优化内存管理，在宿主机内存不足时自动回收虚拟机空闲内存。",[68,9594,9595,9596],{},"增强用户体验\n",[128,9597,9598,9601,9604],{},[68,9599,9600],{},"实现鼠标在宿主机与虚拟机间的无缝切换（无需按Ctrl+Alt组合键）；",[68,9602,9603],{},"支持全屏模式，提升视觉体验；",[68,9605,9606],{},"同步虚拟机与宿主机时间，确保时间一致性。",[68,9608,9609,9610],{},"文件操作优化\n",[128,9611,9612,9615],{},[68,9613,9614],{},"支持通过拖拽方式实现文件跨主机传输；",[68,9616,9617],{},"允许直接复制\u002F粘贴操作，简化文件管理流程。",[68,9619,9620,9621],{},"其他功能\n",[128,9622,9623,9626,9629],{},[68,9624,9625],{},"提供虚拟磁盘压缩功能，优化存储空间利用率；",[68,9627,9628],{},"支持软关机命令，安全关闭虚拟机；",[68,9630,9631],{},"集成 API接口 ，供开发者实现高级自动化功能。",[13,9633,9634],{},"虽然壁纸显示正常了，但是电脑依然是那么卡，默认安装的显存只有3M，不卡才怪。所以我们需要安装一下VMtools工具，让它能识别更大的显存，客户机自动适应桌面分辨率，还可以在宿主机之间随便拖拽传输文件，实现文件目录共享。",[13,9636,9637],{},"安装VMtools的详细步骤如下：",[13,9639,9640,9641,9643],{},"1 关键重启客户机，点击左上角苹果图标，点击关机。",[290,9642],{},"\n2 完全关机之后点击“编辑虚拟机设置”按钮，又回到自定义硬件的界面了，还是点击“CD\u002FDVD （SATA）”选项，这次要把ISO镜像改为“darwin12.0.5.iso”这个文件了（可以参考我的截图），别忘了点击“确定”按钮。",[13,9645,9646],{},[419,9647],{"alt":502,"src":9648},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104137398.jpeg",[13,9650,9651],{},"3 现在再次启动虚拟机，进入macOS之后，发现桌面右上角已经加载了“VMware Tools”了，双击打开它，再双击“安装VMware Tools”按钮就可以启动安装向导了，第一个界面就点击“继续”按钮。",[13,9653,9654,9657,9660],{},[419,9655],{"alt":502,"src":9656},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222835507.png",[419,9658],{"alt":502,"src":9659},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222839842.png",[419,9661],{"alt":502,"src":9662},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222845215.png",[13,9664,9665],{},"4 选择“为这台电脑上的所有用户安装”，再点击“继续”按钮。",[13,9667,9668],{},[419,9669],{"alt":502,"src":9670},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222851133.png",[13,9672,9673],{},"5 如果安装过程出现各种提示，肯定都是选择“允许”。还有就是，可能会提示“系统扩展已被阻止”，那就点击“打开系统设置”按钮。",[13,9675,9676],{},[419,9677],{"alt":502,"src":9678},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104745284.png",[13,9680,9681],{},"6 在系统的隐私与安全性这边可以看到“来自开发者XXX已被阻止载入”（可以参考一下我的截图），那我们要点击“允许”按钮。",[13,9683,9684],{},[419,9685],{"alt":502,"src":9686},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104751187.png",[13,9688,9689],{},"7 然后它会再次让你输入你的账户密码。",[13,9691,9692],{},[419,9693],{"alt":502,"src":9694},"https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721105008842.png",[13,9696,9697],{},"8 重新启动客户机，重启后你会发现，屏幕尺寸会自适应，显存也由原来3M变为128M，亦可以拖拽文件到客户机桌面上。",[13,9699,9700],{},"VMtools安装成功后，重启客户机系统后，我们发现客户机可以调整屏幕和分辨率大小，可以拖拽复制文件到客户机桌面，到此VMware虚拟机成功安装MacOS Sequoia 15.5版本的苹果系统。",[17,9702,9704],{"id":9703},"_3-常见问题","3 常见问题",[13,9706,9707],{},"VMware17虚拟机成功安装MacOS15.5系统后，可能会出现以下几个问题，下面罗列可能出现的问题以及解决方案。",[123,9709,9711],{"id":9710},"_31-关于本机无法打开","3.1 关于本机无法打开",[13,9713,9714,9715,9717,9720,9721,9723,9726,9727,9729,9732],{},"MacOS15安装完成后，打开系统设置->通用->关于本机，可能会出现无法打开问题，导致这个问题的原因是系统兼容性问题，需要通过OC引导修改Mac三码。这三个代码共同构成设备的核心身份验证信息，常用于激活验证、保修服务等场景。\nMac三码通常指设备的三个核心序列号\u002F识别码，包括：",[290,9716],{},[71,9718,9719],{},"1‌. 主板序列号（Board Serial Number\u002FMLB）‌："," 标识设备硬件主板的唯一性",[290,9722],{},[71,9724,9725],{},"2‌. 系统ID（CustomUUID\u002FSystem-id）‌："," 用于区分不同设备的唯一标识",[290,9728],{},[71,9730,9731],{},"3‌. 设备序列号（Serial Number）‌："," 通常位于设备包装或机身标签上 ‌",[13,9734,9735],{},"具体如何配置oc引导，参考下面视频教程：",[9070,9737],{"src":9738,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114130870602635&bvid=BV1HXRbYaELm&cid=28774172609&p=1&autoplay=0",[123,9740,9742],{"id":9741},"_32-apple-id登陆认证失败","3.2 Apple ID登陆认证失败",[13,9744,9745],{},"当我们安装完成后，登陆Apple ID账号，发现Apple ID 账号登陆认证失败。主要与以下几个技术原因相关：",[13,9747,9748,9751],{},[71,9749,9750],{},"1. 硬件仿真不完整："," 虚拟机环境无法完全模拟真实的Mac硬件（如缺失SMBIOS设备信息），导致苹果服务器无法验证设备合法性‌。",[13,9753,9754,9757],{},[71,9755,9756],{},"2.系统签名验证异常：","  macOS的安全机制（如系统完整性保护SIP）会检测系统运行环境，虚拟机特有的硬件特征可能触发安全拦截‌。部分情况下需要手动修改内核扩展签名设置才能通过验证‌。",[13,9759,9760,9761,9764,9765,9768],{},"针对上面问题，可以通过",[42,9762,9763],{"color":116},"OpenCore Configurator(occ)","工具给",[42,9766,9767],{"color":116},"OpenCore(oc)","引导文件打个内核补丁，就可以解决Apple ID登陆认证失败问题。详细处理过程参考下面视频：",[9070,9770],{"src":9771,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114183114851562&bvid=BV1orXLYyEPR&cid=28932572816&p=1&autoplay=0",[13,9773,9774,9775,9777,9778,9783,9785,9786,9790,9792,9793,9795,9796,9800,9802,9803],{},"核心资源下载:",[290,9776],{},"\n1 VMware OC1.0.2：",[104,9779,9782],{"href":9780,"target":28,"rel":9781},"https:\u002F\u002Fpan.baidu.com\u002Fs\u002F1SLKDAMCsrUuZyluhs9i5kw?pwd=htww",[108],"百度网盘",[290,9784],{},"\n2 OpenCore Configurator 2.77.0.0：",[104,9787,9782],{"href":9788,"target":28,"rel":9789},"https:\u002F\u002Fpan.baidu.com\u002Fs\u002F1TdwtM4sizJhkdbMTNyqSnQ?pwd=8q59",[108],[290,9791],{},"\n亦可从下面站点进行下载：",[290,9794],{},"\n3【免费版】OpenCore Configurator 2.77.0.0 OC配置器中文版 - 苹果系统之家：",[104,9797,9798],{"href":9798,"target":28,"rel":9799},"https:\u002F\u002Fmacoshome.com\u002Fhackintosh\u002Fhtools\u002F2100.html",[108],[290,9801],{},"\n4【收费版】OpenCore Configurator–版本2.78.0.2(支持1.0.4正式版及1.0.5开发版) - 黑苹果屋:\n",[104,9804,9805],{"href":9805,"target":28,"rel":9806},"https:\u002F\u002Fimacos.top\u002F2025\u002F06\u002F11\u002Fopencore-configurator-2-78-0-2\u002F",[108],[3056,9808,9809,9812],{},[13,9810,9811],{},"注意事项：",[65,9813,9814,9817,9828,9834],{},[68,9815,9816],{},"occ压缩包直接拖拽复制到客户机MacOS系统桌面上，点击自动解压缩安装。",[68,9818,9819,9820,9823,9824,9827],{},"occ选择加载的oc目录下面的",[42,9821,9822],{},"config.plist","文件，导入",[42,9825,9826],{},"config","文件后，软件可能只显示SSD-ET.aml和DSDT.aml，与视频中不一致，不影响，只要打开自己安装的客户机oc目录下面的文件即可。",[68,9829,9830,9831,9833],{},"kernel内核设置完毕后，点击自动保存，需要将修改后的文件替换掉oc目录下面的",[42,9832,9826],{},"配置文件，名称不能变。",[68,9835,9836],{},"occ的版本必须支持oc版本才行，否则无法编辑或者编辑失败，编辑完成后，重启客户机。",[13,9838,9839],{},"客户机重启后，登陆Apple ID账号，登陆成功！",[968,9841,9842],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":502,"searchDepth":535,"depth":535,"links":9844},[9845,9850,9856],{"id":8739,"depth":506,"text":8740,"children":9846},[9847,9848,9849],{"id":9083,"depth":535,"text":9084},{"id":9096,"depth":535,"text":9097},{"id":9165,"depth":535,"text":9166},{"id":9206,"depth":506,"text":9207,"children":9851},[9852,9853,9854,9855],{"id":9210,"depth":535,"text":9211},{"id":9332,"depth":535,"text":9333},{"id":9370,"depth":535,"text":9371},{"id":9575,"depth":535,"text":9576},{"id":9703,"depth":506,"text":9704,"children":9857},[9858,9859],{"id":9710,"depth":535,"text":9711},{"id":9741,"depth":535,"text":9742},{"name":9861,"symbol":9862,"icon":9863,"id":506},"黑苹果","apple","ic:baseline-apple","2025-07-16 15:59:25","在Windows 10操作系统环境下，我们可以通过VMware Workstation Pro 17.1.10虚拟机软件尝试安装macOS Sequoia 15.5系统，从而在非苹果硬件平台上体验苹果操作系统。",{"type":10,"value":9867},[9868],[13,9869,9870],{},"自从苹果采用Intel的处理器，OS X被黑客破解后可以安装在Intel CPU与部分AMD CPU的机器上。从而出现了一大批非苹果设备而使用苹果操作系统的机器，被称为黑苹果(Hackintosh)；在Mac苹果机上面安装原版Mac系统的被称为白苹果(Macintosh)，与黑苹果相对。黑苹果可以不依赖虚拟机直接安装，常见的安装方式有2种，第一种传统安装方式，第二种\n虚拟机安装方式，两种方式的核心区别在于：传统安装需修改硬件启动模式，而虚拟机安装依赖软件层模拟Mac环境。",{},"\u002Fblog\u002Fvmware-17macos-sequoia15.5","---\ntitle: VMware 17虚拟机安装原版MacOS Sequoia15.5苹果系统教程\ndescription: 在Windows 10操作系统环境下，我们可以通过VMware Workstation Pro 17.1.10虚拟机软件尝试安装macOS Sequoia 15.5系统，从而在非苹果硬件平台上体验苹果操作系统。\narticleId: vmware-macOS\ncreateDate: \"2025-07-16 15:59:25\"\nupdateDate: \"2026-03-12 10:46:16\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204553579.webp\ntagIds: \n      - 5\ncategoryId: 2\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n自从苹果采用Intel的处理器，OS X被黑客破解后可以安装在Intel CPU与部分AMD CPU的机器上。从而出现了一大批非苹果设备而使用苹果操作系统的机器，被称为黑苹果(Hackintosh)；在Mac苹果机上面安装原版Mac系统的被称为白苹果(Macintosh)，与黑苹果相对。黑苹果可以不依赖虚拟机直接安装，常见的安装方式有2种，第一种传统安装方式，第二种\n虚拟机安装方式，两种方式的核心区别在于：传统安装需修改硬件启动模式，而虚拟机安装依赖软件层模拟Mac环境。\n\u003C!--more-->\n\n\n本技术文档系统性地记录了在Windows 10操作系统作为宿主机环境下，利用VMware虚拟化平台安装macOS操作系统的完整技术方案，文档包含从环境准备到系统优化的全流程技术细节。\n\n\n## 1 前期准备\n在安装之前，我们先看看下面的视频教程，有个初步的操作体验，然后根据后面文本，逐步执行安装过程。\n\u003Ciframe src=\"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114120250689097&bvid=BV1Bz9yYYEtF&cid=28738064038&p=1&autoplay=0\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"450px\">\u003C\u002Fiframe>\n\n在VMware Workstation Pro 17安装Sequoia15.5黑苹果系统之前，我们需要提前准备好安装需要的软件和镜像。\n\n\n### 1.1 安装VMware虚拟机\nVMware Workstation从‌2024年11月11日‌起对所有用户(商业、教育及个人)免费使用，并覆盖所有付费功能特性。包括VMware Workstation Pro和Fusion Pro的所有付费功能，适用于Windows、Linux及Mac系统。从VMware Workstation Pro 17版本开始，个人可以免费使用，并且不需要对软件进行激活操作，推荐安装最新版本的VMware虚拟机进行体验。本文采用的是VMware Workstation Pro 17.1.10版本的虚拟机。\n\n\nVMware虚拟机详细安装教程参考文章：[VMware WorkStation 17 Pro虚拟机安装和配置教程](\u002Farticle\u002Fdetail\u002F20250721110931){target=\"_blank\"}\n\n### 1.2 下载Unlocker工具  \nVMware Workstation Pro虚拟机默认不支持MacOS系统安装，需要借助第三方工具[MacOS Unlocker](https:\u002F\u002Fgithub.com\u002FDrDonk\u002Funlocker){target=\"_blank\"}进行解锁后，才能安装MacOS系统。\n\n**1. 下载unlocker427：**[https:\u002F\u002Fgithub.com\u002FDrDonk\u002Funlocker\u002Freleases\u002Ftag\u002Fv4.2.7](https:\u002F\u002Fgithub.com\u002FDrDonk\u002Funlocker\u002Freleases\u002Ftag\u002Fv4.2.7){target=\"_blank\"}\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716204503922.png)\n\n**2. 解压缩到任意目录** \n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716210808722.png)\n\n\n**3. 运行unlock.exe**  \n关闭VMware虚拟机，任务管理器杀掉VMware相关的进程，然后进入打开解压出来的【Unlocker427文件夹】-【Windows】-双击【Unlock.exe】\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716205618470.png)\n执行完毕后，点击任意按键退出。\n\n**4. 验证解锁**  \n打开VMware软件，点击【文件】-【新建虚拟机】- 【创建虚拟机向导】\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212602755.png)\n如果出现`MacOS选项`，表示解锁成功，如果没有，则需要完全退出VMware软件，然后重新执行一下`Unlock.exe`的安装。\n\n### 1.3 下载苹果ISO镜像\n苹果官网提供的原始镜像无法直接用于VMware虚拟机，需要将原始镜像制作成VMware通用的`.iso`{color=primary}格式镜像文件。我们可以用工具自己制作，也可以从第三方网站下载`.iso`{color=primary}镜像。推荐从下面几个站点下载镜像：\n\n\n1. 苹果系统之家：[https:\u002F\u002Fmacoshome.com\u002Fmacos](https:\u002F\u002Fmacoshome.com\u002Fmacos){target=\"_blank\"}\n2. 黑苹果屋：[https:\u002F\u002Fimacos.top\u002Fcategory\u002Fhpgw\u002Fxtgx\u002Fiso\u002F](https:\u002F\u002Fimacos.top\u002Fcategory\u002Fhpgw\u002Fxtgx\u002Fiso\u002F){target=\"_blank\"}\n\n\n本文安装的`MacOS Sequoia15.5.iso`镜像下载地址：[https:\u002F\u002Fmacoshome.com\u002Fmacos\u002F57355.html](https:\u002F\u002Fmacoshome.com\u002Fmacos\u002F57355.html){target=\"_blank\"}\n\n## 2 开始安装\n### 2.1 创建虚拟机\n1 新建虚拟机向导，选择自定义\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212534185.png)\n\n\n2 选择虚拟机硬件兼容性，默认下一步\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212540211.png)\n\n3 安装客户机操作系统，稍后安装操作系统\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212545672.png)\n\n\n4 选择客户机操作系统，选择`Apple macOS(M)`，版本选择`macOS 15`\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716212602755.png)\n\n\n5 命名虚拟机，选择虚拟机存储位置\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213703927.png)\n\n\n6 处理器数量，处理器核数，根据系统情况调整\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213710361.png)\n\n\n7 设置虚拟机内存，至少4G\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716213720396.png)\n\n\n8 选择网络类型，使用网络地址转换NAT\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214011459.png)\n\n\n9 选择I\u002FO控制器类型，默认推荐\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214020532.png)\n\n\n10 选择磁盘类型，默认推荐\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214105918.png)\n\n\n11 创建新磁盘\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214111961.png)\n\n\n12 创建磁盘容量，建议至少80G，磁盘拆分多个文件\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214115108.png)\n\n\n13 指定磁盘文件名称和文件路径，默认即可\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214130493.png)\n\n\n14 点击完成，完成虚拟机创建\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716214136750.png)\n\n\n### 2.2 修改虚拟机\n找到我们刚刚创建的虚拟机保存位置，然后找到后缀名位 .vmx 的文件，用编辑器打开，在最后一行加入以下代码：\n```shell\nsmc.version = \"0\"\n```\nsmc.version = \"0\" 是解决 VMware 虚拟机运行 macOS 时出现的兼容性问题关键配置项，主要用于绕过 VMware 对 macOS 系统的版本限制。在 VMware 中安装 macOS 时，若硬件兼容性设置为 Workstation 11 或更高版本，可能导致虚拟机无法启动。通过添加 smc.version = \"0\" 到虚拟机配置文件（.vmx 文件），可强制虚拟机以较低版本兼容模式运行，避免因系统版本不匹配导致的崩溃。\n\n\n修改虚拟机，配置`macOS`镜像文件\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221015437.png)\n### 2.3 安装MacOS系统\n1 打开虚拟机，进行安装`macOS`系统\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221456354.png)\n\n\n2 选择简体中文，下一步\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221555854.png)\n\n\n3 选择磁盘工具，初始化磁盘\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221641339.png)\n\n\n4 点击磁盘，进行抹除\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221743149.png)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221903192.png)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716221942479.png)\n\n\n5 选择安装macOS Sequoia，点击继续\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222030643.png)\n\n\n6 同意安装协议\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222201251.png)\n\n\n7 选择安装磁盘\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222209652.png)\n\n\n8 等待安装，等待大约半个小时，自动重启\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222219950.png)\n\n\n9 选择国家和地区\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222353260.png)\n\n\n10 设为新机\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222400147.png)\n\n\n11 设置输入法\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222403888.png)\n\n\n12 设置辅助功能，点击以后\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222415947.png)\n\n\n13 数据与隐私，继续\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222418924.png)\n\n\n14 自动更新系统，继续\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222830204.png)\n\n\n15 appId账号登陆，接点击左下角的“稍后设置”按钮，再点击“跳过”按钮\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224005862.png)\n\n\n16 条款与条件，只能同意啦\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224239343.png)\n\n\n17 因为我们前面没有登录Apple账户，所以这里需要创建一个本地账户，建议用户名使用纯英文字符\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224244290.png)\n\n\n18 服务定位，建议先不开启，避免占用资源，所以点击“继续”和“不使用”按钮\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224311838.png)\n\n\n19 选择时区，你可以用鼠标点击那个地图，比如我这里点击了上海，时区会影响时间的显示，所以得选对了（当然后面我也会讲如何修改时区）\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224317014.png)\n\n\n20 分析功能，建议取消勾选“与Apple共享Mac分析”选项，然后点击“继续”按钮\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224321051.png)\n\n\n21 屏幕使用时间，为了节省性能资源，建议先不要开启，直接点击“稍后设置”按钮\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224325700.png)\n\n\n22 外观，看你心情随便选择一个吧\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716224330741.png)\n\n\n23 大功告成！现在终于进入到macOS 15的桌面了，但是你需要等一下，因为现在可能有点卡\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716225210885.png)\n\n\n等了一段时间之后，你可以试着动动鼠标，发现已经可以正常使用了，但是壁纸一直加载不出来，你也不用继续等了，因为显存过小，所以它默认的动态壁纸是永远也加载不出来的。为了不至于显示这么丑的白屏，我们可以打开设置选项，找一张图片壁纸给它换上。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716225946874.png)\n\n\n### 2.4 安装VMtools\nVMtools（VMware Tools）是 VMware 为虚拟机提供的一套增强工具套件，主要功能包括优化性能、提升用户体验及实现主机与虚拟机间的协同操作。核心功能如下：\n1. 优化硬件性能   \n   - 提升图形处理性能，支持高分辨率显示及 SVGA模式 ，通过虚拟显卡驱动增强显示效果；\n   - 优化内存管理，在宿主机内存不足时自动回收虚拟机空闲内存。\n2. 增强用户体验\n   - 实现鼠标在宿主机与虚拟机间的无缝切换（无需按Ctrl+Alt组合键）；\n   - 支持全屏模式，提升视觉体验；\n   - 同步虚拟机与宿主机时间，确保时间一致性。\n3. 文件操作优化\n   - 支持通过拖拽方式实现文件跨主机传输；\n   - 允许直接复制\u002F粘贴操作，简化文件管理流程。\n4. 其他功能\n   - 提供虚拟磁盘压缩功能，优化存储空间利用率；\n   - 支持软关机命令，安全关闭虚拟机；\n   - 集成 API接口 ，供开发者实现高级自动化功能。\n\n\n虽然壁纸显示正常了，但是电脑依然是那么卡，默认安装的显存只有3M，不卡才怪。所以我们需要安装一下VMtools工具，让它能识别更大的显存，客户机自动适应桌面分辨率，还可以在宿主机之间随便拖拽传输文件，实现文件目录共享。\n\n\n安装VMtools的详细步骤如下：\n\n\n1 关键重启客户机，点击左上角苹果图标，点击关机。  \n2 完全关机之后点击“编辑虚拟机设置”按钮，又回到自定义硬件的界面了，还是点击“CD\u002FDVD （SATA）”选项，这次要把ISO镜像改为“darwin12.0.5.iso”这个文件了（可以参考我的截图），别忘了点击“确定”按钮。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104137398.jpeg)\n\n\n3 现在再次启动虚拟机，进入macOS之后，发现桌面右上角已经加载了“VMware Tools”了，双击打开它，再双击“安装VMware Tools”按钮就可以启动安装向导了，第一个界面就点击“继续”按钮。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222835507.png)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222839842.png)\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222845215.png)\n\n\n4 选择“为这台电脑上的所有用户安装”，再点击“继续”按钮。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250716222851133.png)\n\n\n5 如果安装过程出现各种提示，肯定都是选择“允许”。还有就是，可能会提示“系统扩展已被阻止”，那就点击“打开系统设置”按钮。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104745284.png)\n\n\n6 在系统的隐私与安全性这边可以看到“来自开发者XXX已被阻止载入”（可以参考一下我的截图），那我们要点击“允许”按钮。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721104751187.png)\n\n\n7 然后它会再次让你输入你的账户密码。\n\n\n![](https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20250721105008842.png)\n\n\n8 重新启动客户机，重启后你会发现，屏幕尺寸会自适应，显存也由原来3M变为128M，亦可以拖拽文件到客户机桌面上。\n\n\nVMtools安装成功后，重启客户机系统后，我们发现客户机可以调整屏幕和分辨率大小，可以拖拽复制文件到客户机桌面，到此VMware虚拟机成功安装MacOS Sequoia 15.5版本的苹果系统。\n\n\n## 3 常见问题\nVMware17虚拟机成功安装MacOS15.5系统后，可能会出现以下几个问题，下面罗列可能出现的问题以及解决方案。\n\n### 3.1 关于本机无法打开\n\nMacOS15安装完成后，打开系统设置->通用->关于本机，可能会出现无法打开问题，导致这个问题的原因是系统兼容性问题，需要通过OC引导修改Mac三码。这三个代码共同构成设备的核心身份验证信息，常用于激活验证、保修服务等场景。\nMac三码通常指设备的三个核心序列号\u002F识别码，包括：  \n**1‌. 主板序列号（Board Serial Number\u002FMLB）‌：** 标识设备硬件主板的唯一性  \n**2‌. 系统ID（CustomUUID\u002FSystem-id）‌：** 用于区分不同设备的唯一标识  \n**3‌. 设备序列号（Serial Number）‌：** 通常位于设备包装或机身标签上 ‌  \n\n\n具体如何配置oc引导，参考下面视频教程：\n\n\n\u003Ciframe src=\"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114130870602635&bvid=BV1HXRbYaELm&cid=28774172609&p=1&autoplay=0\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"450px\">\u003C\u002Fiframe>\n\n\n### 3.2 Apple ID登陆认证失败\n\n\n当我们安装完成后，登陆Apple ID账号，发现Apple ID 账号登陆认证失败。主要与以下几个技术原因相关：\n\n\n**1. 硬件仿真不完整：** 虚拟机环境无法完全模拟真实的Mac硬件（如缺失SMBIOS设备信息），导致苹果服务器无法验证设备合法性‌。\n\n\n**2.系统签名验证异常：**  macOS的安全机制（如系统完整性保护SIP）会检测系统运行环境，虚拟机特有的硬件特征可能触发安全拦截‌。部分情况下需要手动修改内核扩展签名设置才能通过验证‌。\n\n\n针对上面问题，可以通过`OpenCore Configurator(occ)`{color=\"primary\"}工具给`OpenCore(oc)`{color=\"primary\"}引导文件打个内核补丁，就可以解决Apple ID登陆认证失败问题。详细处理过程参考下面视频：\n\u003Ciframe src=\"\u002F\u002Fplayer.bilibili.com\u002Fplayer.html?isOutside=true&aid=114183114851562&bvid=BV1orXLYyEPR&cid=28932572816&p=1&autoplay=0\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"450px\">\u003C\u002Fiframe>  \n\n核心资源下载:  \n1 VMware OC1.0.2：[百度网盘]( https:\u002F\u002Fpan.baidu.com\u002Fs\u002F1SLKDAMCsrUuZyluhs9i5kw?pwd=htww){target=\"_blank\"}   \n2 OpenCore Configurator 2.77.0.0：[百度网盘](https:\u002F\u002Fpan.baidu.com\u002Fs\u002F1TdwtM4sizJhkdbMTNyqSnQ?pwd=8q59){target=\"_blank\"}  \n亦可从下面站点进行下载：  \n3【免费版】OpenCore Configurator 2.77.0.0 OC配置器中文版 - 苹果系统之家：[https:\u002F\u002Fmacoshome.com\u002Fhackintosh\u002Fhtools\u002F2100.html](https:\u002F\u002Fmacoshome.com\u002Fhackintosh\u002Fhtools\u002F2100.html){target=\"_blank\"}  \n4【收费版】OpenCore Configurator–版本2.78.0.2(支持1.0.4正式版及1.0.5开发版) - 黑苹果屋: \n[https:\u002F\u002Fimacos.top\u002F2025\u002F06\u002F11\u002Fopencore-configurator-2-78-0-2\u002F](https:\u002F\u002Fimacos.top\u002F2025\u002F06\u002F11\u002Fopencore-configurator-2-78-0-2\u002F){target=\"_blank\"}\n\n::tip\n注意事项：\n1. occ压缩包直接拖拽复制到客户机MacOS系统桌面上，点击自动解压缩安装。\n2. occ选择加载的oc目录下面的`config.plist`文件，导入`config`文件后，软件可能只显示SSD-ET.aml和DSDT.aml，与视频中不一致，不影响，只要打开自己安装的客户机oc目录下面的文件即可。\n3. kernel内核设置完毕后，点击自动保存，需要将修改后的文件替换掉oc目录下面的`config`配置文件，名称不能变。\n4. occ的版本必须支持oc版本才行，否则无法编辑或者编辑失败，编辑完成后，重启客户机。\n::\n客户机重启后，登陆Apple ID账号，登陆成功！\n",19.8,{"title":9056,"description":9865},{"loc":9872,"images":9877},[9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930],{"loc":9120},{"loc":9130},{"loc":9141},{"loc":9153},{"loc":9219},{"loc":9227},{"loc":9235},{"loc":9153},{"loc":9257},{"loc":9265},{"loc":9273},{"loc":9281},{"loc":9289},{"loc":9297},{"loc":9305},{"loc":9313},{"loc":9321},{"loc":9329},{"loc":9367},{"loc":9382},{"loc":9390},{"loc":9398},{"loc":9406},{"loc":9409},{"loc":9412},{"loc":9420},{"loc":9428},{"loc":9436},{"loc":9444},{"loc":9452},{"loc":9460},{"loc":9468},{"loc":9476},{"loc":9484},{"loc":9492},{"loc":9500},{"loc":9508},{"loc":9516},{"loc":9524},{"loc":9532},{"loc":9540},{"loc":9548},{"loc":9556},{"loc":9564},{"loc":9572},{"loc":9648},{"loc":9656},{"loc":9659},{"loc":9662},{"loc":9670},{"loc":9678},{"loc":9686},{"loc":9694},"blog\u002F8.VMware 17虚拟机安装原版MacOS Sequoia15.5苹果系统教程",[624],[9934],{"name":9048,"symbol":9049,"icon":9050,"id":624},"2026-03-12 10:46:16",3566,"2DxRxdSveKBfRYv-Zcba580WargdF89VJTLTAQLwFTg",{"id":9939,"title":9940,"articleId":9941,"articleThumb":9942,"body":9943,"categoryId":905,"categoryInfo":10818,"createDate":10821,"description":10822,"excerpt":10823,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":10828,"navigation":1003,"path":10829,"rawbody":10830,"readingTime":10831,"seo":10832,"sitemap":10833,"stem":10839,"tagIds":10840,"tagInfo":10841,"updateDate":10845,"wordCount":10846,"__hash__":10847},"blog\u002Fblog\u002F6.GitHub克隆拉取和推送代码时443超时问题解决方法.md","GitHub克隆拉取和推送代码时443超时问题解决方法","github-timeout","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204841213.webp",{"type":10,"value":9944,"toc":10807},[9945,9949,9952,9955,9959,9962,9977,9982,9985,9997,10002,10006,10017,10024,10037,10056,10062,10075,10082,10088,10104,10107,10121,10127,10383,10387,10397,10400,10450,10453,10479,10483,10486,10490,10500,10504,10509,10512,10558,10567,10606,10611,10614,10639,10647,10652,10655,10687,10690,10715,10720,10723,10765,10767,10801,10804],[17,9946,9948],{"id":9947},"_1-修改hosts文件","1 修改hosts文件",[13,9950,9951],{},"Hosts文件是系统中用于将网址域名与IP地址进行快速映射的数据库，在用户访问网站时优先被查询。这个没有扩展名的系统文件，虽然不起眼，却扮演着至关重要的角色。它类似于一个关联“数据库”，将众多常用的网址域名与对应的IP地址紧密相连。每当用户在浏览器中输入一个网址并尝试登录时，系统会首先自动在Hosts文件中寻找相应的IP地址。一旦找到，系统会迅速打开对应的网页；若未找到，则会自动将网址提交至DNS域名解析服务器进行IP地址的深入解析。",[13,9953,9954],{},"在解决 GitHub 在提交代码时出现 443 错误的问题时，修改 hosts 文件是一个可能的解决方案。这通常发生在 GitHub 的 IP 地址被错误地解析或者 DNS 解析出现问题的情况下，导致连接超时问题。通过修改hosts文件后，你可以绕过国内的访问限制，当尝试访问github及其相关域名时，系统将优先使用这些映射，从而可能解决网络连通性问题。以下是具体步骤：",[123,9956,9958],{"id":9957},"_11-查找github的ip地址","1.1 查找GitHub的IP地址",[13,9960,9961],{},"首先，你需要找到 GitHub 的 IP 地址。可以通过运行以下命令来获取 GitHub 的 IP 地址：",[679,9963,9967],{"className":9964,"code":9965,"language":9966,"meta":502,"style":502},"language-Bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ping github.com\n","Bash",[42,9968,9969],{"__ignoreMap":502},[688,9970,9971,9974],{"class":690,"line":691},[688,9972,9973],{"class":694},"ping",[688,9975,9976],{"class":697}," github.com\n",[13,9978,9979],{},[419,9980],{"alt":502,"src":9981},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250629165553736.webp",[13,9983,9984],{},"或者，你可以使用以下命令获取更多 IP 地址：",[679,9986,9988],{"className":9964,"code":9987,"language":9966,"meta":502,"style":502},"nslookup github.com\n",[42,9989,9990],{"__ignoreMap":502},[688,9991,9992,9995],{"class":690,"line":691},[688,9993,9994],{"class":694},"nslookup",[688,9996,9976],{"class":697},[13,9998,9999],{},[419,10000],{"alt":502,"src":10001},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250629165553775.webp",[123,10003,10005],{"id":10004},"_12-手动编辑hosts文件","1.2 手动编辑hosts文件",[13,10007,10008,10009,10012,10013,10016],{},"在不同操作系统中，Hosts文件的位置各有不同，便于管理和编辑。例如，在Windows系统中，它通常位于",[42,10010,10011],{"color":116},"C:\\Windows\\System32\\drivers\\etc\\hosts","路径下；而在Android和iOS系统中，它则分别位于",[42,10014,10015],{"color":116},"\u002Fetc\u002Fhosts和\u002Fprivate\u002Fetc\u002Fhosts","等路径。对于Mac OS X系统，其位置则可能因版本不同而有所差异。",[128,10018,10019],{},[68,10020,10021],{},[71,10022,10023],{},"对于Windows系统",[13,10025,10026,10027,10030,10031,10033,10034,10036],{},"1、",[71,10028,10029],{},"以管理员权限身份","，通过记事本打开",[42,10032,10011],{"color":116},"文件。",[290,10035],{},"\n2、在文件末尾添加以下行（替换 \u003Cgithub_ip> 为你从 ping 或 nslookup 命令中获取的 IP 地址）:",[679,10038,10040],{"className":681,"code":10039,"language":684,"meta":502,"style":502}," \u003Cgithub_ip> github.com\n",[42,10041,10042],{"__ignoreMap":502},[688,10043,10044,10047,10050,10053],{"class":690,"line":691},[688,10045,10046],{"class":791}," \u003C",[688,10048,10049],{"class":694},"github_ip",[688,10051,10052],{"class":787},"> ",[688,10054,10055],{"class":697},"github.com\n",[13,10057,10058,10059,10061],{},"3、保存修改后的配置文件，并关闭文件。",[290,10060],{},"\n4、为了确保更改生效，你可以清空 DNS 缓存，在终端刷新本地DNS缓存：",[679,10063,10065],{"className":681,"code":10064,"language":684,"meta":502,"style":502},"ipconfig \u002Fflushdns\n",[42,10066,10067],{"__ignoreMap":502},[688,10068,10069,10072],{"class":690,"line":691},[688,10070,10071],{"class":694},"ipconfig",[688,10073,10074],{"class":697}," \u002Fflushdns\n",[128,10076,10077],{},[68,10078,10079],{},[71,10080,10081],{},"对于 macOS 或 Linux",[13,10083,10084,10085,10087],{},"1、打开终端。",[290,10086],{},"\n2、使用文本编辑器打开 \u002Fetc\u002Fhosts 文件，例如使用命令：",[679,10089,10091],{"className":681,"code":10090,"language":684,"meta":502,"style":502}," sudo vi \u002Fetc\u002Fhosts\n",[42,10092,10093],{"__ignoreMap":502},[688,10094,10095,10098,10101],{"class":690,"line":691},[688,10096,10097],{"class":694}," sudo",[688,10099,10100],{"class":697}," vi",[688,10102,10103],{"class":697}," \u002Fetc\u002Fhosts\n",[13,10105,10106],{},"3、在文件末尾添加以下行（同样替换 \u003Cgithub_ip>）：",[679,10108,10109],{"className":681,"code":10039,"language":684,"meta":502,"style":502},[42,10110,10111],{"__ignoreMap":502},[688,10112,10113,10115,10117,10119],{"class":690,"line":691},[688,10114,10046],{"class":791},[688,10116,10049],{"class":694},[688,10118,10052],{"class":787},[688,10120,10055],{"class":697},[13,10122,10123,10124,10126],{},"4、保存修改后的配置文件，并关闭文件。",[290,10125],{},"\n5、在 macOS 或 Linux 上，通常不需要手动清空 DNS 缓存，因为系统会自动处理。但如果你怀疑有缓存问题，可以尝试重启你的计算机。",[6807,10128,10130,10146,10380],{"color":116,"icon":10129},"circum:warning",[13,10131,6812,10132,10134,10135,10137,10138,10141,10142,10145],{},[290,10133],{},"\n1 修改hosts方法可能不太稳定，但至少在一定程度上能够解决问题。如果过一段时间后，发现修改hosts也无法连接，需要重新修改hosts文件中ip和github映射关系。",[290,10136],{},"\n2 如果",[42,10139,10140],{},"hosts","文件中加入",[42,10143,10144],{},"\u003Cgithub ip> github.com","后发现还是连接不通，可以尝试加入以下IP地址和域名映射关系：",[679,10147,10149],{"className":681,"code":10148,"language":684,"meta":502,"style":502},"185.199.108.154   github.githubassets.com\n140.82.113.22     central.github.com\n185.199.108.133   desktop.githubusercontent.com\n185.199.109.153   assets-cdn.github.com\n185.199.110.133   camo.githubusercontent.com\n185.199.108.133   github.map.fastly.net\n151.101.201.194   github.global.ssl.fastly.net\n140.82.116.3      gist.github.com\n185.199.108.153   github.io\n140.82.116.3      github.com\n140.82.116.6      api.github.com\n185.199.111.133   raw.githubusercontent.com\n185.199.108.133   user-images.githubusercontent.com\n185.199.108.133   favicons.githubusercontent.com\n185.199.110.133   avatars5.githubusercontent.com\n185.199.108.133   avatars4.githubusercontent.com\n185.199.108.133   avatars3.githubusercontent.com\n185.199.109.133   avatars2.githubusercontent.com\n185.199.108.133   avatars1.githubusercontent.com\n185.199.108.133   avatars0.githubusercontent.com\n185.199.109.133   avatars.githubusercontent.com\n140.82.116.9      codeload.github.com\n52.217.135.153    github-cloud.s3.amazonaws.com\n3.5.21.109        github-com.s3.amazonaws.com\n3.5.29.177        github-production-release-asset-2e65be.s3.amazonaws.com\n52.216.63.25      github-production-user-asset-6210df.s3.amazonaws.com\n52.217.223.1      github-production-repository-file-5c1aeb.s3.amazonaws.com\n185.199.110.153   githubstatus.com\n140.82.112.17     github.community\n185.199.108.133   media.githubusercontent.com\n",[42,10150,10151,10159,10167,10175,10183,10191,10198,10206,10214,10222,10229,10237,10245,10252,10259,10266,10273,10280,10288,10295,10302,10309,10317,10325,10333,10341,10349,10357,10365,10373],{"__ignoreMap":502},[688,10152,10153,10156],{"class":690,"line":691},[688,10154,10155],{"class":694},"185.199.108.154",[688,10157,10158],{"class":697},"   github.githubassets.com\n",[688,10160,10161,10164],{"class":690,"line":506},[688,10162,10163],{"class":694},"140.82.113.22",[688,10165,10166],{"class":697},"     central.github.com\n",[688,10168,10169,10172],{"class":690,"line":535},[688,10170,10171],{"class":694},"185.199.108.133",[688,10173,10174],{"class":697},"   desktop.githubusercontent.com\n",[688,10176,10177,10180],{"class":690,"line":609},[688,10178,10179],{"class":694},"185.199.109.153",[688,10181,10182],{"class":697},"   assets-cdn.github.com\n",[688,10184,10185,10188],{"class":690,"line":624},[688,10186,10187],{"class":694},"185.199.110.133",[688,10189,10190],{"class":697},"   camo.githubusercontent.com\n",[688,10192,10193,10195],{"class":690,"line":856},[688,10194,10171],{"class":694},[688,10196,10197],{"class":697},"   github.map.fastly.net\n",[688,10199,10200,10203],{"class":690,"line":863},[688,10201,10202],{"class":694},"151.101.201.194",[688,10204,10205],{"class":697},"   github.global.ssl.fastly.net\n",[688,10207,10208,10211],{"class":690,"line":874},[688,10209,10210],{"class":694},"140.82.116.3",[688,10212,10213],{"class":697},"      gist.github.com\n",[688,10215,10216,10219],{"class":690,"line":890},[688,10217,10218],{"class":694},"185.199.108.153",[688,10220,10221],{"class":697},"   github.io\n",[688,10223,10224,10226],{"class":690,"line":896},[688,10225,10210],{"class":694},[688,10227,10228],{"class":697},"      github.com\n",[688,10230,10231,10234],{"class":690,"line":905},[688,10232,10233],{"class":694},"140.82.116.6",[688,10235,10236],{"class":697},"      api.github.com\n",[688,10238,10239,10242],{"class":690,"line":2096},[688,10240,10241],{"class":694},"185.199.111.133",[688,10243,10244],{"class":697},"   raw.githubusercontent.com\n",[688,10246,10247,10249],{"class":690,"line":2138},[688,10248,10171],{"class":694},[688,10250,10251],{"class":697},"   user-images.githubusercontent.com\n",[688,10253,10254,10256],{"class":690,"line":2143},[688,10255,10171],{"class":694},[688,10257,10258],{"class":697},"   favicons.githubusercontent.com\n",[688,10260,10261,10263],{"class":690,"line":2149},[688,10262,10187],{"class":694},[688,10264,10265],{"class":697},"   avatars5.githubusercontent.com\n",[688,10267,10268,10270],{"class":690,"line":2185},[688,10269,10171],{"class":694},[688,10271,10272],{"class":697},"   avatars4.githubusercontent.com\n",[688,10274,10275,10277],{"class":690,"line":2261},[688,10276,10171],{"class":694},[688,10278,10279],{"class":697},"   avatars3.githubusercontent.com\n",[688,10281,10282,10285],{"class":690,"line":2267},[688,10283,10284],{"class":694},"185.199.109.133",[688,10286,10287],{"class":697},"   avatars2.githubusercontent.com\n",[688,10289,10290,10292],{"class":690,"line":2277},[688,10291,10171],{"class":694},[688,10293,10294],{"class":697},"   avatars1.githubusercontent.com\n",[688,10296,10297,10299],{"class":690,"line":2283},[688,10298,10171],{"class":694},[688,10300,10301],{"class":697},"   avatars0.githubusercontent.com\n",[688,10303,10304,10306],{"class":690,"line":2288},[688,10305,10284],{"class":694},[688,10307,10308],{"class":697},"   avatars.githubusercontent.com\n",[688,10310,10311,10314],{"class":690,"line":2294},[688,10312,10313],{"class":694},"140.82.116.9",[688,10315,10316],{"class":697},"      codeload.github.com\n",[688,10318,10319,10322],{"class":690,"line":2761},[688,10320,10321],{"class":694},"52.217.135.153",[688,10323,10324],{"class":697},"    github-cloud.s3.amazonaws.com\n",[688,10326,10327,10330],{"class":690,"line":2768},[688,10328,10329],{"class":694},"3.5.21.109",[688,10331,10332],{"class":697},"        github-com.s3.amazonaws.com\n",[688,10334,10335,10338],{"class":690,"line":2773},[688,10336,10337],{"class":694},"3.5.29.177",[688,10339,10340],{"class":697},"        github-production-release-asset-2e65be.s3.amazonaws.com\n",[688,10342,10343,10346],{"class":690,"line":2779},[688,10344,10345],{"class":694},"52.216.63.25",[688,10347,10348],{"class":697},"      github-production-user-asset-6210df.s3.amazonaws.com\n",[688,10350,10351,10354],{"class":690,"line":2795},[688,10352,10353],{"class":694},"52.217.223.1",[688,10355,10356],{"class":697},"      github-production-repository-file-5c1aeb.s3.amazonaws.com\n",[688,10358,10359,10362],{"class":690,"line":5013},[688,10360,10361],{"class":694},"185.199.110.153",[688,10363,10364],{"class":697},"   githubstatus.com\n",[688,10366,10367,10370],{"class":690,"line":5032},[688,10368,10369],{"class":694},"140.82.112.17",[688,10371,10372],{"class":697},"     github.community\n",[688,10374,10375,10377],{"class":690,"line":5078},[688,10376,10171],{"class":694},[688,10378,10379],{"class":697},"   media.githubusercontent.com\n",[13,10381,10382],{},"上面具体域名对应的映射ip，可以通过命令行ping的方式获取。",[123,10384,10386],{"id":10385},"_13-工具编辑hosts文件","1.3 工具编辑hosts文件",[13,10388,10389,10390,10393,10394,10396],{},"对于windows系统可以借助第三方工具",[42,10391,10392],{},"WinHostsManager","进行修改",[42,10395,10140],{},"文件。‌ WinHostsManager 是一款功能强大的hosts文件管理工具，主要用于管理和修改hosts文件。‌",[13,10398,10399],{},"WinHostsManager的主要功能包括：",[65,10401,10402,10408,10414,10420,10426,10432,10438,10444],{},[68,10403,10404,10407],{},[71,10405,10406],{},"添加新的host项目‌："," 用户可以轻松添加新的IP地址和域名映射。",[68,10409,10410,10413],{},[71,10411,10412],{},"保存修改‌："," 将新的IP地址和域名直接加载到hosts文件中并保存",[68,10415,10416,10419],{},[71,10417,10418],{},"显示最高映射方案‌："," 提供当前最高的映射方案，方便用户选择。",[68,10421,10422,10425],{},[71,10423,10424],{},"获取最快的主机IP编辑方式‌："," 优化编辑过程，提高编辑效率。",[68,10427,10428,10431],{},[71,10429,10430],{},"支持重启主机‌："," 编辑完成后，支持重启主机以应用更改",[68,10433,132,10434,10437],{},[71,10435,10436],{},"查看端口项目‌："," 在列表上查看打开的端口项目。",[68,10439,132,10440,10443],{},[71,10441,10442],{},"建立过滤‌："," 提供过滤功能，方便管理hosts文件‌。",[68,10445,10446,10449],{},[71,10447,10448],{},"支持禁用ip：","  提供启用和禁用ip和域名映射关系功能。",[13,10451,10452],{},"此外，WinHostsManager还具有以下特点：",[128,10454,10455,10461,10467,10473],{},[68,10456,10457,10460],{},[71,10458,10459],{},"操作简单‌："," 用户无需知道hosts文件的保存位置，即可进行修改。",[68,10462,10463,10466],{},[71,10464,10465],{},"节省时间‌："," 软件会自动将内容写入hosts文件，节省了在C盘上查找hosts文件地址的时间。",[68,10468,10469,10472],{},[71,10470,10471],{},"支持特殊地址访问‌："," 帮助用户访问一些特殊地址。",[68,10474,10475,10478],{},[71,10476,10477],{},"备份和恢复功能‌："," 支持hosts文件的备份和恢复，确保数据安全‌。",[17,10480,10482],{"id":10481},"_2-配置git代理","2 配置GIT代理",[13,10484,10485],{},"通常我们访问GitHub站点都需要本地打开VPN工具才能访问，但即使打开VPN工具，打开了全局代理模式，git拉取或者提交代码依然报443连接错误。在Git中配置代理服务器是为了帮助你通过一个HTTP或HTTPS代理连接到GitHub外部网络资源，根据你的网络环境，你可能需要设置代理来绕过某些限制或提高访问速度，才能让git客户端通过VPN代理渠道访问github，否则git客户端不走VPN代理就会出现连接错误。",[123,10487,10489],{"id":10488},"_21-vpn代理ip和端口","2.1 VPN代理IP和端口",[13,10491,10492,10493,10496,10497],{},"打开本地VPN工具，查看设置页面http(s)代理IP和端口。以海豚湾为例，查看方法如下图：\n",[419,10494],{"alt":502,"src":10495},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250701092746871.webp","\n或者查看电脑本地代理端口，查看方法如下图：\n",[419,10498],{"alt":502,"src":10499},"https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250701092752202.webp",[123,10501,10503],{"id":10502},"_22-git本地代理配置","2.2 GIT本地代理配置",[13,10505,10506],{},[71,10507,10508],{},"1. 全局代理配置",[13,10510,10511],{},"如果你希望对所有Git操作使用同一个代理服务器，你可以通过以下命令格式配置全局代理：",[679,10513,10515],{"className":681,"code":10514,"language":684,"meta":502,"style":502},"# 配置http代理\ngit config --global http.proxy http:\u002F\u002Fproxy_address:port\n# 配置https代理\ngit config --global https.proxy https:\u002F\u002Fproxy_address:port\n",[42,10516,10517,10522,10539,10544],{"__ignoreMap":502},[688,10518,10519],{"class":690,"line":691},[688,10520,10521],{"class":859},"# 配置http代理\n",[688,10523,10524,10527,10530,10533,10536],{"class":690,"line":506},[688,10525,10526],{"class":694},"git",[688,10528,10529],{"class":697}," config",[688,10531,10532],{"class":697}," --global",[688,10534,10535],{"class":697}," http.proxy",[688,10537,10538],{"class":697}," http:\u002F\u002Fproxy_address:port\n",[688,10540,10541],{"class":690,"line":535},[688,10542,10543],{"class":859},"# 配置https代理\n",[688,10545,10546,10548,10550,10552,10555],{"class":690,"line":609},[688,10547,10526],{"class":694},[688,10549,10529],{"class":697},[688,10551,10532],{"class":697},[688,10553,10554],{"class":697}," https.proxy",[688,10556,10557],{"class":697}," https:\u002F\u002Fproxy_address:port\n",[13,10559,744,10560,648,10563,10566],{},[42,10561,10562],{},"proxy_address",[42,10564,10565],{},"port","替换为你的代理服务器的地址和端口。例如：您正在使用127.0.0.1的代理服务器和4780的端口，那么您需要输入以下命令：",[679,10568,10570],{"className":681,"code":10569,"language":684,"meta":502,"style":502},"# 配置http代理\ngit config --global http.proxy http:\u002F\u002F127.0.0.1:4780\n# 配置https代理\ngit config --global https.proxy https:\u002F\u002F127.0.0.1:4780\n",[42,10571,10572,10576,10589,10593],{"__ignoreMap":502},[688,10573,10574],{"class":690,"line":691},[688,10575,10521],{"class":859},[688,10577,10578,10580,10582,10584,10586],{"class":690,"line":506},[688,10579,10526],{"class":694},[688,10581,10529],{"class":697},[688,10583,10532],{"class":697},[688,10585,10535],{"class":697},[688,10587,10588],{"class":697}," http:\u002F\u002F127.0.0.1:4780\n",[688,10590,10591],{"class":690,"line":535},[688,10592,10543],{"class":859},[688,10594,10595,10597,10599,10601,10603],{"class":690,"line":609},[688,10596,10526],{"class":694},[688,10598,10529],{"class":697},[688,10600,10532],{"class":697},[688,10602,10554],{"class":697},[688,10604,10605],{"class":697}," https:\u002F\u002F127.0.0.1:4780\n",[13,10607,10608],{},[71,10609,10610],{},"2. 单个仓库代理配置",[13,10612,10613],{},"如果你只想为特定的Git仓库设置代理，而不是全局，你需要进入到本地具体代码仓库目录下，使用以下命令：",[679,10615,10617],{"className":681,"code":10616,"language":684,"meta":502,"style":502},"git config http.proxy http:\u002F\u002Fproxy_address:port\ngit config https.proxy https:\u002F\u002Fproxy_address:port\n",[42,10618,10619,10629],{"__ignoreMap":502},[688,10620,10621,10623,10625,10627],{"class":690,"line":691},[688,10622,10526],{"class":694},[688,10624,10529],{"class":697},[688,10626,10535],{"class":697},[688,10628,10538],{"class":697},[688,10630,10631,10633,10635,10637],{"class":690,"line":506},[688,10632,10526],{"class":694},[688,10634,10529],{"class":697},[688,10636,10554],{"class":697},[688,10638,10557],{"class":697},[13,10640,10641,10642,648,10644,10646],{},"同样地，替换",[42,10643,10562],{},[42,10645,10565],{},"为你的代理服务器信息。",[13,10648,10649],{},[71,10650,10651],{},"3. 取消代理配置",[13,10653,10654],{},"如果你需要取消之前设置的代理配置，可以使用以下命令：",[679,10656,10658],{"className":681,"code":10657,"language":684,"meta":502,"style":502},"git config --global --unset http.proxy\ngit config --global --unset https.proxy\n",[42,10659,10660,10674],{"__ignoreMap":502},[688,10661,10662,10664,10666,10668,10671],{"class":690,"line":691},[688,10663,10526],{"class":694},[688,10665,10529],{"class":697},[688,10667,10532],{"class":697},[688,10669,10670],{"class":697}," --unset",[688,10672,10673],{"class":697}," http.proxy\n",[688,10675,10676,10678,10680,10682,10684],{"class":690,"line":506},[688,10677,10526],{"class":694},[688,10679,10529],{"class":697},[688,10681,10532],{"class":697},[688,10683,10670],{"class":697},[688,10685,10686],{"class":697}," https.proxy\n",[13,10688,10689],{},"或者针对单个仓库：",[679,10691,10693],{"className":681,"code":10692,"language":684,"meta":502,"style":502},"git config --unset http.proxy\ngit config --unset https.proxy\n",[42,10694,10695,10705],{"__ignoreMap":502},[688,10696,10697,10699,10701,10703],{"class":690,"line":691},[688,10698,10526],{"class":694},[688,10700,10529],{"class":697},[688,10702,10670],{"class":697},[688,10704,10673],{"class":697},[688,10706,10707,10709,10711,10713],{"class":690,"line":506},[688,10708,10526],{"class":694},[688,10710,10529],{"class":697},[688,10712,10670],{"class":697},[688,10714,10686],{"class":697},[13,10716,10717],{},[71,10718,10719],{},"4. 查看代理配置",[13,10721,10722],{},"如果你需要查询当前代理配置，可以使用以下命令：",[679,10724,10726],{"className":681,"code":10725,"language":684,"meta":502,"style":502},"# 查看http代理\ngit config --global --get  http.proxy\n# 查看https代理\ngit config --global --get  https.proxy\n",[42,10727,10728,10733,10747,10752],{"__ignoreMap":502},[688,10729,10730],{"class":690,"line":691},[688,10731,10732],{"class":859},"# 查看http代理\n",[688,10734,10735,10737,10739,10741,10744],{"class":690,"line":506},[688,10736,10526],{"class":694},[688,10738,10529],{"class":697},[688,10740,10532],{"class":697},[688,10742,10743],{"class":697}," --get",[688,10745,10746],{"class":697},"  http.proxy\n",[688,10748,10749],{"class":690,"line":535},[688,10750,10751],{"class":859},"# 查看https代理\n",[688,10753,10754,10756,10758,10760,10762],{"class":690,"line":609},[688,10755,10526],{"class":694},[688,10757,10529],{"class":697},[688,10759,10532],{"class":697},[688,10761,10743],{"class":697},[688,10763,10764],{"class":697},"  https.proxy\n",[13,10766,10689],{},[679,10768,10770],{"className":681,"code":10769,"language":684,"meta":502,"style":502},"# 查看http代理\ngit config  --get  http.proxy\n# 查看https代理\ngit config  --get  https.proxy\n",[42,10771,10772,10776,10787,10791],{"__ignoreMap":502},[688,10773,10774],{"class":690,"line":691},[688,10775,10732],{"class":859},[688,10777,10778,10780,10782,10785],{"class":690,"line":506},[688,10779,10526],{"class":694},[688,10781,10529],{"class":697},[688,10783,10784],{"class":697},"  --get",[688,10786,10746],{"class":697},[688,10788,10789],{"class":690,"line":535},[688,10790,10751],{"class":859},[688,10792,10793,10795,10797,10799],{"class":690,"line":609},[688,10794,10526],{"class":694},[688,10796,10529],{"class":697},[688,10798,10784],{"class":697},[688,10800,10764],{"class":697},[13,10802,10803],{},"如果VPN代理IP和端口发生改变，需要重新配置git代码地址。",[968,10805,10806],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":502,"searchDepth":535,"depth":535,"links":10808},[10809,10814],{"id":9947,"depth":506,"text":9948,"children":10810},[10811,10812,10813],{"id":9957,"depth":535,"text":9958},{"id":10004,"depth":535,"text":10005},{"id":10385,"depth":535,"text":10386},{"id":10481,"depth":506,"text":10482,"children":10815},[10816,10817],{"id":10488,"depth":535,"text":10489},{"id":10502,"depth":535,"text":10503},{"name":10819,"symbol":7523,"icon":10820,"id":905},"GitHub","mdi:github","2025-06-29 15:36:09","GitHub对中国大陆IP的访问进行了限制，国内想访问GitHub站点，需要科学上网，才能访问Github站点。有时候就算通过梯子，使用git命令克隆、推送、拉取GitHub仓库的代码也会报443连接超时错误.",{"type":10,"value":10824},[10825],[13,10826,10827],{},"在国内由于网络原因，在命令窗口能够Ping通github.com域名，但通过git命令操作github仓库代码时，无论是克隆，拉取、推送还是提交，经常会出现fatal: unable to access 'xxx': Failed to connect to github.com port 443: Timed out 禁止访问连接或者github连接超时异常，有时候即使开了梯子也没用，把VPN工具改成全局路由模式也不行。下面记录几种常见解决方法，彻底解决git命令连接github连接超时问题。",{},"\u002Fblog\u002Fgithub443","---\ntitle: GitHub克隆拉取和推送代码时443超时问题解决方法\ndescription: GitHub对中国大陆IP的访问进行了限制，国内想访问GitHub站点，需要科学上网，才能访问Github站点。有时候就算通过梯子，使用git命令克隆、推送、拉取GitHub仓库的代码也会报443连接超时错误.\narticleId: github-timeout\ncreateDate: \"2025-06-29 15:36:09\"\nupdateDate: \"2026-03-12 10:40:16\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327204841213.webp\ntagIds: \n    - 11\ncategoryId: 11\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n\n在国内由于网络原因，在命令窗口能够Ping通github.com域名，但通过git命令操作github仓库代码时，无论是克隆，拉取、推送还是提交，经常会出现fatal: unable to access 'xxx': Failed to connect to github.com port 443: Timed out 禁止访问连接或者github连接超时异常，有时候即使开了梯子也没用，把VPN工具改成全局路由模式也不行。下面记录几种常见解决方法，彻底解决git命令连接github连接超时问题。\n\u003C!--more-->\n\n## 1 修改hosts文件\nHosts文件是系统中用于将网址域名与IP地址进行快速映射的数据库，在用户访问网站时优先被查询。这个没有扩展名的系统文件，虽然不起眼，却扮演着至关重要的角色。它类似于一个关联“数据库”，将众多常用的网址域名与对应的IP地址紧密相连。每当用户在浏览器中输入一个网址并尝试登录时，系统会首先自动在Hosts文件中寻找相应的IP地址。一旦找到，系统会迅速打开对应的网页；若未找到，则会自动将网址提交至DNS域名解析服务器进行IP地址的深入解析。\n\n在解决 GitHub 在提交代码时出现 443 错误的问题时，修改 hosts 文件是一个可能的解决方案。这通常发生在 GitHub 的 IP 地址被错误地解析或者 DNS 解析出现问题的情况下，导致连接超时问题。通过修改hosts文件后，你可以绕过国内的访问限制，当尝试访问github及其相关域名时，系统将优先使用这些映射，从而可能解决网络连通性问题。以下是具体步骤：\n\n### 1.1 查找GitHub的IP地址\n首先，你需要找到 GitHub 的 IP 地址。可以通过运行以下命令来获取 GitHub 的 IP 地址：\n```Bash\nping github.com\n```\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250629165553736.webp)\n\n或者，你可以使用以下命令获取更多 IP 地址：\n```Bash\nnslookup github.com\n```\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F06\u002F20250629165553775.webp)\n\n### 1.2 手动编辑hosts文件\n在不同操作系统中，Hosts文件的位置各有不同，便于管理和编辑。例如，在Windows系统中，它通常位于`C:\\Windows\\System32\\drivers\\etc\\hosts`{color=primary}路径下；而在Android和iOS系统中，它则分别位于`\u002Fetc\u002Fhosts和\u002Fprivate\u002Fetc\u002Fhosts`{color=primary}等路径。对于Mac OS X系统，其位置则可能因版本不同而有所差异。\n\n- **对于Windows系统** \n\n1、**以管理员权限身份**，通过记事本打开`C:\\Windows\\System32\\drivers\\etc\\hosts`{color=primary}文件。  \n2、在文件末尾添加以下行（替换 \u003Cgithub_ip> 为你从 ping 或 nslookup 命令中获取的 IP 地址）:\n ```bash\n  \u003Cgithub_ip> github.com\n ``` \n3、保存修改后的配置文件，并关闭文件。  \n4、为了确保更改生效，你可以清空 DNS 缓存，在终端刷新本地DNS缓存：\n ```bash\nipconfig \u002Fflushdns\n ``` \n- **对于 macOS 或 Linux**\n\n1、打开终端。  \n2、使用文本编辑器打开 \u002Fetc\u002Fhosts 文件，例如使用命令：\n```bash\n sudo vi \u002Fetc\u002Fhosts\n```\n3、在文件末尾添加以下行（同样替换 \u003Cgithub_ip>）：\n```bash\n \u003Cgithub_ip> github.com\n```\n4、保存修改后的配置文件，并关闭文件。  \n5、在 macOS 或 Linux 上，通常不需要手动清空 DNS 缓存，因为系统会自动处理。但如果你怀疑有缓存问题，可以尝试重启你的计算机。\n::callout{icon=\"circum:warning\" color=\"primary\"}\n温馨提示\u003C\u002Fbr>\n1 修改hosts方法可能不太稳定，但至少在一定程度上能够解决问题。如果过一段时间后，发现修改hosts也无法连接，需要重新修改hosts文件中ip和github映射关系。\u003C\u002Fbr>\n2 如果`hosts`文件中加入`\u003Cgithub ip> github.com`后发现还是连接不通，可以尝试加入以下IP地址和域名映射关系：\n```bash\n185.199.108.154   github.githubassets.com\n140.82.113.22     central.github.com\n185.199.108.133   desktop.githubusercontent.com\n185.199.109.153   assets-cdn.github.com\n185.199.110.133   camo.githubusercontent.com\n185.199.108.133   github.map.fastly.net\n151.101.201.194   github.global.ssl.fastly.net\n140.82.116.3      gist.github.com\n185.199.108.153   github.io\n140.82.116.3      github.com\n140.82.116.6      api.github.com\n185.199.111.133   raw.githubusercontent.com\n185.199.108.133   user-images.githubusercontent.com\n185.199.108.133   favicons.githubusercontent.com\n185.199.110.133   avatars5.githubusercontent.com\n185.199.108.133   avatars4.githubusercontent.com\n185.199.108.133   avatars3.githubusercontent.com\n185.199.109.133   avatars2.githubusercontent.com\n185.199.108.133   avatars1.githubusercontent.com\n185.199.108.133   avatars0.githubusercontent.com\n185.199.109.133   avatars.githubusercontent.com\n140.82.116.9      codeload.github.com\n52.217.135.153    github-cloud.s3.amazonaws.com\n3.5.21.109        github-com.s3.amazonaws.com\n3.5.29.177        github-production-release-asset-2e65be.s3.amazonaws.com\n52.216.63.25      github-production-user-asset-6210df.s3.amazonaws.com\n52.217.223.1      github-production-repository-file-5c1aeb.s3.amazonaws.com\n185.199.110.153   githubstatus.com\n140.82.112.17     github.community\n185.199.108.133   media.githubusercontent.com\n```\n上面具体域名对应的映射ip，可以通过命令行ping的方式获取。\n::\n\n### 1.3 工具编辑hosts文件\n\n\n对于windows系统可以借助第三方工具`WinHostsManager`进行修改`hosts`文件。‌ WinHostsManager 是一款功能强大的hosts文件管理工具，主要用于管理和修改hosts文件。‌\n\n\nWinHostsManager的主要功能包括：\n\n\n1. **添加新的host项目‌：** 用户可以轻松添加新的IP地址和域名映射。\n2. **保存修改‌：** 将新的IP地址和域名直接加载到hosts文件中并保存\n3. **显示最高映射方案‌：** 提供当前最高的映射方案，方便用户选择。\n4. **获取最快的主机IP编辑方式‌：** 优化编辑过程，提高编辑效率。\n5. **支持重启主机‌：** 编辑完成后，支持重启主机以应用更改\n6. ‌**查看端口项目‌：** 在列表上查看打开的端口项目。\n7. ‌**建立过滤‌：** 提供过滤功能，方便管理hosts文件‌。\n8. **支持禁用ip：**  提供启用和禁用ip和域名映射关系功能。\n\n\n此外，WinHostsManager还具有以下特点：\n\n\n- **操作简单‌：** 用户无需知道hosts文件的保存位置，即可进行修改。\n- **节省时间‌：** 软件会自动将内容写入hosts文件，节省了在C盘上查找hosts文件地址的时间。\n- **支持特殊地址访问‌：** 帮助用户访问一些特殊地址。\n- **备份和恢复功能‌：** 支持hosts文件的备份和恢复，确保数据安全‌。\n\n## 2 配置GIT代理\n\n\n通常我们访问GitHub站点都需要本地打开VPN工具才能访问，但即使打开VPN工具，打开了全局代理模式，git拉取或者提交代码依然报443连接错误。在Git中配置代理服务器是为了帮助你通过一个HTTP或HTTPS代理连接到GitHub外部网络资源，根据你的网络环境，你可能需要设置代理来绕过某些限制或提高访问速度，才能让git客户端通过VPN代理渠道访问github，否则git客户端不走VPN代理就会出现连接错误。\n\n\n### 2.1 VPN代理IP和端口\n\n\n打开本地VPN工具，查看设置页面http(s)代理IP和端口。以海豚湾为例，查看方法如下图：\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250701092746871.webp)\n或者查看电脑本地代理端口，查看方法如下图：\n![](https:\u002F\u002Fimage.anyfork.top\u002F2025\u002F07\u002F20250701092752202.webp)\n\n\n### 2.2 GIT本地代理配置\n**1. 全局代理配置**\n\n\n如果你希望对所有Git操作使用同一个代理服务器，你可以通过以下命令格式配置全局代理：\n```bash\n# 配置http代理\ngit config --global http.proxy http:\u002F\u002Fproxy_address:port\n# 配置https代理\ngit config --global https.proxy https:\u002F\u002Fproxy_address:port\n```\n将`proxy_address`和`port`替换为你的代理服务器的地址和端口。例如：您正在使用127.0.0.1的代理服务器和4780的端口，那么您需要输入以下命令：\n```bash\n# 配置http代理\ngit config --global http.proxy http:\u002F\u002F127.0.0.1:4780\n# 配置https代理\ngit config --global https.proxy https:\u002F\u002F127.0.0.1:4780\n```\n**2. 单个仓库代理配置**\n\n\n如果你只想为特定的Git仓库设置代理，而不是全局，你需要进入到本地具体代码仓库目录下，使用以下命令：\n```bash\ngit config http.proxy http:\u002F\u002Fproxy_address:port\ngit config https.proxy https:\u002F\u002Fproxy_address:port\n```\n同样地，替换`proxy_address`和`port`为你的代理服务器信息。\n\n\n**3. 取消代理配置**\n\n\n如果你需要取消之前设置的代理配置，可以使用以下命令：\n```bash\ngit config --global --unset http.proxy\ngit config --global --unset https.proxy\n```\n或者针对单个仓库：\n```bash\ngit config --unset http.proxy\ngit config --unset https.proxy\n```\n**4. 查看代理配置**\n\n\n如果你需要查询当前代理配置，可以使用以下命令：\n```bash\n# 查看http代理\ngit config --global --get  http.proxy\n# 查看https代理\ngit config --global --get  https.proxy\n```\n或者针对单个仓库：\n```bash\n# 查看http代理\ngit config  --get  http.proxy\n# 查看https代理\ngit config  --get  https.proxy\n```\n如果VPN代理IP和端口发生改变，需要重新配置git代码地址。\n\n\n\n\n\n\n\n",10.9,{"title":9940,"description":10822},{"loc":10829,"images":10834},[10835,10836,10837,10838],{"loc":9981},{"loc":10001},{"loc":10495},{"loc":10499},"blog\u002F6.GitHub克隆拉取和推送代码时443超时问题解决方法",[905],[10842],{"name":10843,"symbol":10526,"icon":10844,"id":905},"Git","material-icon-theme:git","2026-03-12 10:40:16",1961,"M9DyDR2XFJKH2Q6wgeTWRfcunplG33vJn14-PamKb2E",{"id":10849,"title":10850,"articleId":10851,"articleThumb":10852,"body":10853,"categoryId":896,"categoryInfo":11877,"createDate":11878,"description":11879,"excerpt":11880,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1002,"meta":11885,"navigation":1003,"path":11886,"rawbody":11887,"readingTime":11888,"seo":11889,"sitemap":11890,"stem":11891,"tagIds":11892,"tagInfo":11893,"updateDate":11897,"wordCount":11898,"__hash__":11899},"blog\u002Fblog\u002F7.Windows和Linux系统上NVM安装多个版本的Node.js.md","Windows和Linux系统上NVM安装多个版本的Node.js","nvm-node","https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327205225806.webp",{"type":10,"value":10854,"toc":11863},[10855,10868,10872,10887,10935,10939,10961,10966,10973,10981,10984,10992,10997,11017,11022,11025,11037,11040,11044,11058,11063,11068,11094,11099,11122,11127,11130,11220,11229,11234,11250,11255,11269,11272,11276,11285,11289,11294,11386,11391,11400,11403,11441,11447,11452,11491,11496,11512,11516,11521,11537,11546,11551,11566,11571,11671,11676,11689,11692,11696,11701,11712,11717,11725,11729,11734,11742,11756,11761,11770,11828,11847,11860],[6807,10856,10858],{"color":116,"icon":6809,"target":28,"to":10857},"https:\u002F\u002Fgithub.com\u002Fnvm-sh\u002Fnvm\u002Fblob\u002Fmaster\u002FREADME.md",[13,10859,10860,10861,10864,10865,10867],{},"点击访问",[42,10862,10863],{},"nvm","官网，阅读",[42,10866,10863],{},"使用文档",[17,10869,10871],{"id":10870},"_1-安装nvm软件","1. 安装NVM软件",[13,10873,10874,10875,10880,10881,10883,10884,10886],{},"访问",[104,10876,10879],{"href":10877,"rel":10878},"https:\u002F\u002Fgithub.com\u002Fnvm-sh\u002Fnvm",[108],"NVM","的源码仓库，可以查看最新版本的",[42,10882,10863],{},"包，在不同的系统上安装",[42,10885,10863],{},"方式存在差异，但基本都可以通过源代码包和第三方快捷方式进行安装。",[1058,10888,10889,10897],{},[13,10890,10891,10894,10895],{},[71,10892,10893],{},"注意："," ",[290,10896],{},[65,10898,10899,10908],{},[68,10900,10901,10902,10904,10905,10907],{},"无论什么系统，通过",[42,10903,10863],{},"安装node.js之前，都需要卸载现已安装好的",[42,10906,6694],{},"，避免发生安装冲突和错误问题。",[68,10909,10910,10911,10914,10915,10917,10918,10921,10922,10924,10925,10927,10928,10931,10932,10934],{},"对于",[42,10912,10913],{},"Linux","系统，不同版本的",[42,10916,6694],{},"对",[42,10919,10920],{},"gcc","版本有要求，安装",[42,10923,6694],{},"对应的",[42,10926,10920],{},"版本，Node.js才能安装成功。建议使用最新版本的",[42,10929,10930],{},"linux","镜像系统(gcc版本比较高，满足高版本Node.js安装需求)，否则需要手动升级系统",[42,10933,10920],{},"版本，非常麻烦。",[123,10936,10938],{"id":10937},"_11-windows安装nvm","1.1 Windows安装NVM",[13,10940,10941,10942,10945,10946,10949,10950,10953,10954,10956,10957,10960],{},"windows系统可以通过",[42,10943,10944],{},"nvm-windows​","进行安装，",[42,10947,10948],{},"nvm-windows","是一个",[42,10951,10952],{},".exe","的安装包，在",[42,10955,10863],{},"源码包的基础上编译成了可执行文件，便于在",[42,10958,10959],{},"Windows","环境下安装。",[13,10962,10963],{},[71,10964,10965],{},"1. 下载nvm-windows",[13,10967,10874,10968,10972],{},[104,10969,10948],{"href":10970,"rel":10971},"https:\u002F\u002Fgithub.com\u002Fcoreybutler\u002Fnvm-windows\u002Freleases",[108],"官方仓库，下载最新版本的安装包。",[128,10974,10975,10978],{},[68,10976,10977],{},"稳定版：nvm-setup.exe",[68,10979,10980],{},"便携版：nvm-noinstall.zip",[13,10982,10983],{},"稳定版是可执行文件，可以直接点击安装，推荐使用稳定版安装。便携版为免安装的文件包，之间解压到磁盘上即可。",[3056,10985,10986],{},[13,10987,10988,10989,10991],{},"二者区别：稳定版安装后，会自动添加环境变量，软件安装完毕就可以直接使用",[42,10990,10863],{},",便携版需要手动配置环境变量，才能使用。",[13,10993,10994],{},[71,10995,10996],{},"2. 运行安装程序",[65,10998,10999,11002,11008,11014],{},[68,11000,11001],{},"点击运行稳定版，勾选许可协议，下一步.",[68,11003,11004,11005,11007],{},"设置",[42,11006,10863],{},"安装路径，可自定义安装路径 .",[68,11009,11010,11011,11013],{},"设置 ",[42,11012,6694],{}," 的安装路径.",[68,11015,11016],{},"安装完成.",[13,11018,11019],{},[71,11020,11021],{},"3.验证安装",[13,11023,11024],{},"打开新的命令提示符（CMD）或 PowerShell，运行：",[679,11026,11028],{"className":6858,"code":11027,"language":6860,"meta":502,"style":502},"nvm -v\n",[42,11029,11030],{"__ignoreMap":502},[688,11031,11032,11034],{"class":690,"line":691},[688,11033,10863],{"class":694},[688,11035,11036],{"class":697}," -v\n",[13,11038,11039],{},"如果显示版本号（如 1.1.9），说明安装成功。",[123,11041,11043],{"id":11042},"_12-linux安装nvm","1.2 Linux安装NVM",[13,11045,11046,11047,11049,11050,11053,11054,11057],{},"Linux系统上安装",[42,11048,10863],{},"，可以通过",[42,11051,11052],{},"nvm-sh","脚本和",[42,11055,11056],{},"源码包","2种方式进行安装。",[13,11059,11060],{},[71,11061,11062],{},"1. 使用脚本安装",[128,11064,11065],{},[68,11066,11067],{},"打开终端，运行以下命令：",[679,11069,11071],{"className":766,"code":11070,"language":769,"meta":502,"style":502},"curl -o- https:\u002F\u002Fraw.githubusercontent.com\u002Fnvm-sh\u002Fnvm\u002Fv0.40.3\u002Finstall.sh | bash\n",[42,11072,11073],{"__ignoreMap":502},[688,11074,11075,11078,11081,11084,11086,11089,11091],{"class":690,"line":691},[688,11076,11077],{"class":787},"curl ",[688,11079,11080],{"class":791},"-",[688,11082,11083],{"class":787},"o",[688,11085,11080],{"class":791},[688,11087,11088],{"class":694}," https",[688,11090,801],{"class":791},[688,11092,11093],{"class":859},"\u002F\u002Fraw.githubusercontent.com\u002Fnvm-sh\u002Fnvm\u002Fv0.40.3\u002Finstall.sh | bash\n",[128,11095,11096],{},[68,11097,11098],{},"或者使用 wget：",[679,11100,11102],{"className":766,"code":11101,"language":769,"meta":502,"style":502},"wget -qO- https:\u002F\u002Fraw.githubusercontent.com\u002Fnvm-sh\u002Fnvm\u002Fv0.40.3\u002Finstall.sh | bash\n",[42,11103,11104],{"__ignoreMap":502},[688,11105,11106,11109,11111,11114,11116,11118,11120],{"class":690,"line":691},[688,11107,11108],{"class":787},"wget ",[688,11110,11080],{"class":791},[688,11112,11113],{"class":787},"qO",[688,11115,11080],{"class":791},[688,11117,11088],{"class":694},[688,11119,801],{"class":791},[688,11121,11093],{"class":859},[13,11123,11124],{},[71,11125,11126],{},"2. 配置环境变量",[13,11128,11129],{},"安装完成后，将以下内容添加到你的 shell 配置文件（ ~\u002F.bashrc、 ~\u002F.zshrc 或 ~\u002F.profile）：",[679,11131,11133],{"className":766,"code":11132,"language":769,"meta":502,"style":502},"export NVM_DIR=\"$HOME\u002F.nvm\"\n[ -s \"$NVM_DIR\u002Fnvm.sh\" ] && \\. \"$NVM_DIR\u002Fnvm.sh\"  # 加载 nvm\n[ -s \"$NVM_DIR\u002Fbash_completion\" ] && \\. \"$NVM_DIR\u002Fbash_completion\"  # 加载自动补全\n",[42,11134,11135,11151,11188],{"__ignoreMap":502},[688,11136,11137,11139,11142,11144,11146,11149],{"class":690,"line":691},[688,11138,777],{"class":2013},[688,11140,11141],{"class":787}," NVM_DIR",[688,11143,2303],{"class":791},[688,11145,2312],{"class":791},[688,11147,11148],{"class":697},"$HOME\u002F.nvm",[688,11150,6890],{"class":791},[688,11152,11153,11156,11158,11161,11163,11166,11168,11171,11174,11177,11179,11181,11183,11185],{"class":690,"line":506},[688,11154,11155],{"class":787},"[ ",[688,11157,11080],{"class":791},[688,11159,11160],{"class":787},"s ",[688,11162,2312],{"class":791},[688,11164,11165],{"class":697},"$NVM_DIR\u002Fnvm.sh",[688,11167,2312],{"class":791},[688,11169,11170],{"class":787}," ] ",[688,11172,11173],{"class":791},"&&",[688,11175,11176],{"class":787}," \\",[688,11178,2072],{"class":791},[688,11180,3155],{"class":791},[688,11182,11165],{"class":697},[688,11184,2312],{"class":791},[688,11186,11187],{"class":787},"  # 加载 nvm\n",[688,11189,11190,11192,11194,11196,11198,11201,11203,11205,11207,11209,11211,11213,11215,11217],{"class":690,"line":535},[688,11191,11155],{"class":787},[688,11193,11080],{"class":791},[688,11195,11160],{"class":787},[688,11197,2312],{"class":791},[688,11199,11200],{"class":697},"$NVM_DIR\u002Fbash_completion",[688,11202,2312],{"class":791},[688,11204,11170],{"class":787},[688,11206,11173],{"class":791},[688,11208,11176],{"class":787},[688,11210,2072],{"class":791},[688,11212,3155],{"class":791},[688,11214,11200],{"class":697},[688,11216,2312],{"class":791},[688,11218,11219],{"class":787},"  # 加载自动补全\n",[223,11221,11222],{},[13,11223,11224,11225,11228],{},"注意: 通过脚本安装，脚本执行完，默认在",[42,11226,11227],{},"~\u002F.bashrc","中加入了上面的环境变量配置，只需要重新加载环境变量文件即可。",[13,11230,11231],{},[71,11232,11233],{},"3. 重新加载环境变量",[679,11235,11237],{"className":766,"code":11236,"language":769,"meta":502,"style":502},"source ~\u002F.bashrc\n",[42,11238,11239],{"__ignoreMap":502},[688,11240,11241,11244,11247],{"class":690,"line":691},[688,11242,11243],{"class":787},"source ",[688,11245,11246],{"class":791},"~\u002F.",[688,11248,11249],{"class":787},"bashrc\n",[13,11251,11252],{},[71,11253,11254],{},"4. 验证安装",[679,11256,11257],{"className":766,"code":11027,"language":769,"meta":502,"style":502},[42,11258,11259],{"__ignoreMap":502},[688,11260,11261,11264,11266],{"class":690,"line":691},[688,11262,11263],{"class":787},"nvm ",[688,11265,11080],{"class":791},[688,11267,11268],{"class":787},"v\n",[13,11270,11271],{},"如果显示版本号（如：0.40.3)，说明安装成功。",[17,11273,11275],{"id":11274},"_2-nvm管理nodejs","2. Nvm管理Node.js",[13,11277,11278,11279,11281,11282,11284],{},"无论Window系统，还是Linux系统，",[42,11280,10863],{},"安装成功后，安装和管理",[42,11283,6694],{},"的命令基本一致。",[123,11286,11288],{"id":11287},"_21-基本命令","2.1  基本命令",[13,11290,11291],{},[71,11292,11293],{},"1. 安装 Node.js 版本",[679,11295,11297],{"className":766,"code":11296,"language":769,"meta":502,"style":502},"# 安装最新版本的node，\"node\" 是最新版本的别名\nnvm install node \n# 安装最新的 LTS 版本\nnvm install --lts \n# 安装最新 18.x 版本\nnvm install 18 \n# 安装指定版本     \nnvm install 16.14.0  \n# 设置别名为my_alias，别名不能包含空格或者斜杠\nnvm alias my_alias v14.4.0\n",[42,11298,11299,11313,11318,11323,11334,11344,11353,11358,11371,11376],{"__ignoreMap":502},[688,11300,11301,11304,11306,11308,11310],{"class":690,"line":691},[688,11302,11303],{"class":787},"# 安装最新版本的node，",[688,11305,2312],{"class":791},[688,11307,6695],{"class":697},[688,11309,2312],{"class":791},[688,11311,11312],{"class":787}," 是最新版本的别名\n",[688,11314,11315],{"class":690,"line":506},[688,11316,11317],{"class":787},"nvm install node \n",[688,11319,11320],{"class":690,"line":535},[688,11321,11322],{"class":787},"# 安装最新的 LTS 版本\n",[688,11324,11325,11328,11331],{"class":690,"line":609},[688,11326,11327],{"class":787},"nvm install ",[688,11329,11330],{"class":791},"--",[688,11332,11333],{"class":787},"lts \n",[688,11335,11336,11339,11341],{"class":690,"line":624},[688,11337,11338],{"class":787},"# 安装最新 18",[688,11340,2072],{"class":791},[688,11342,11343],{"class":787},"x 版本\n",[688,11345,11346,11348,11351],{"class":690,"line":856},[688,11347,11327],{"class":787},[688,11349,11350],{"class":2220},"18",[688,11352,4149],{"class":787},[688,11354,11355],{"class":690,"line":863},[688,11356,11357],{"class":787},"# 安装指定版本     \n",[688,11359,11360,11362,11365,11367,11369],{"class":690,"line":874},[688,11361,11327],{"class":787},[688,11363,11364],{"class":2220},"16.14",[688,11366,2072],{"class":791},[688,11368,2240],{"class":2220},[688,11370,902],{"class":787},[688,11372,11373],{"class":690,"line":890},[688,11374,11375],{"class":787},"# 设置别名为my_alias，别名不能包含空格或者斜杠\n",[688,11377,11378,11381,11383],{"class":690,"line":896},[688,11379,11380],{"class":787},"nvm alias my_alias v14",[688,11382,2072],{"class":791},[688,11384,11385],{"class":2220},"4.0\n",[13,11387,11388],{},[71,11389,11390],{},"2. 查看已安装版本",[679,11392,11394],{"className":766,"code":11393,"language":769,"meta":502,"style":502},"nvm ls\n",[42,11395,11396],{"__ignoreMap":502},[688,11397,11398],{"class":690,"line":691},[688,11399,11393],{"class":787},[13,11401,11402],{},"显示结果为：",[679,11404,11406],{"className":766,"code":11405,"language":769,"meta":502,"style":502},"    v16.14.0\n    v18.12.1\n->  v20.7.0\n",[42,11407,11408,11418,11428],{"__ignoreMap":502},[688,11409,11410,11413,11415],{"class":690,"line":691},[688,11411,11412],{"class":787},"    v16",[688,11414,2072],{"class":791},[688,11416,11417],{"class":2220},"14.0\n",[688,11419,11420,11423,11425],{"class":690,"line":506},[688,11421,11422],{"class":787},"    v18",[688,11424,2072],{"class":791},[688,11426,11427],{"class":2220},"12.1\n",[688,11429,11430,11433,11436,11438],{"class":690,"line":535},[688,11431,11432],{"class":791},"->",[688,11434,11435],{"class":787},"  v20",[688,11437,2072],{"class":791},[688,11439,11440],{"class":2220},"7.0\n",[13,11442,11443,11444,11446],{},"箭头指向为当前使用的",[42,11445,6694],{},"版本",[13,11448,11449],{},[71,11450,11451],{},"3. 切换Node.js版本",[679,11453,11455],{"className":766,"code":11454,"language":769,"meta":502,"style":502},"# 切换到 18.x\nnvm use 18\n# 切换到指定版本      \nnvm use 16.14.0  \n",[42,11456,11457,11467,11475,11480],{"__ignoreMap":502},[688,11458,11459,11462,11464],{"class":690,"line":691},[688,11460,11461],{"class":787},"# 切换到 18",[688,11463,2072],{"class":791},[688,11465,11466],{"class":787},"x\n",[688,11468,11469,11472],{"class":690,"line":506},[688,11470,11471],{"class":787},"nvm use ",[688,11473,11474],{"class":2220},"18\n",[688,11476,11477],{"class":690,"line":535},[688,11478,11479],{"class":787},"# 切换到指定版本      \n",[688,11481,11482,11484,11486,11488],{"class":690,"line":609},[688,11483,11471],{"class":787},[688,11485,11364],{"class":2220},[688,11487,2072],{"class":791},[688,11489,11490],{"class":2220},"0\n",[13,11492,11493],{},[71,11494,11495],{},"4. 卸载Node.js版本",[679,11497,11499],{"className":766,"code":11498,"language":769,"meta":502,"style":502},"nvm uninstall 16.14.0\n",[42,11500,11501],{"__ignoreMap":502},[688,11502,11503,11506,11508,11510],{"class":690,"line":691},[688,11504,11505],{"class":787},"nvm uninstall ",[688,11507,11364],{"class":2220},[688,11509,2072],{"class":791},[688,11511,11490],{"class":2220},[123,11513,11515],{"id":11514},"_22-高阶用法","2.2 高阶用法",[13,11517,11518],{},[71,11519,11520],{},"1. 设置默认版本",[679,11522,11524],{"className":766,"code":11523,"language":769,"meta":502,"style":502},"nvm alias default 18\n",[42,11525,11526],{"__ignoreMap":502},[688,11527,11528,11531,11534],{"class":690,"line":691},[688,11529,11530],{"class":787},"nvm alias ",[688,11532,11533],{"class":776},"default",[688,11535,11536],{"class":2220}," 18\n",[13,11538,11539,11540,11542,11543,11545],{},"第一个安装的版本会被自动设置为默认版本，新打开的终端",[42,11541,6860],{},"都会使用默认的",[42,11544,6694],{},"版本。",[13,11547,11548],{},[71,11549,11550],{},"2. 查看远程可用版本",[679,11552,11554],{"className":766,"code":11553,"language":769,"meta":502,"style":502},"nvm ls-remote\n",[42,11555,11556],{"__ignoreMap":502},[688,11557,11558,11561,11563],{"class":690,"line":691},[688,11559,11560],{"class":787},"nvm ls",[688,11562,11080],{"class":791},[688,11564,11565],{"class":787},"remote\n",[13,11567,11568],{},[71,11569,11570],{},"3. 临时选择版本，并输出版本号，该命令不会永久切换版本，仅临时运行一次",[679,11572,11574],{"className":766,"code":11573,"language":769,"meta":502,"style":502},"# 临时选择最新node版本，并输出版本号\nnvm run node --version\n# 临时切换到 Node.js 18.12.1 版本，并输出该版本的 Node.js 号\nnvm run 18.12.1 node --version\n# 临时切换到 Node.js 18.12.1 版本，并输出该版本的 Node.js 号\nnvm exec 18.12.1 node --version\n",[42,11575,11576,11581,11591,11616,11634,11654],{"__ignoreMap":502},[688,11577,11578],{"class":690,"line":691},[688,11579,11580],{"class":787},"# 临时选择最新node版本，并输出版本号\n",[688,11582,11583,11586,11588],{"class":690,"line":506},[688,11584,11585],{"class":787},"nvm run node ",[688,11587,11330],{"class":791},[688,11589,11590],{"class":787},"version\n",[688,11592,11593,11596,11598,11601,11604,11606,11608,11611,11613],{"class":690,"line":535},[688,11594,11595],{"class":787},"# 临时切换到 Node",[688,11597,2072],{"class":791},[688,11599,11600],{"class":787},"js ",[688,11602,11603],{"class":2220},"18.12",[688,11605,2072],{"class":791},[688,11607,3194],{"class":2220},[688,11609,11610],{"class":787}," 版本，并输出该版本的 Node",[688,11612,2072],{"class":791},[688,11614,11615],{"class":787},"js 号\n",[688,11617,11618,11621,11623,11625,11627,11630,11632],{"class":690,"line":609},[688,11619,11620],{"class":787},"nvm run ",[688,11622,11603],{"class":2220},[688,11624,2072],{"class":791},[688,11626,3194],{"class":2220},[688,11628,11629],{"class":787}," node ",[688,11631,11330],{"class":791},[688,11633,11590],{"class":787},[688,11635,11636,11638,11640,11642,11644,11646,11648,11650,11652],{"class":690,"line":624},[688,11637,11595],{"class":787},[688,11639,2072],{"class":791},[688,11641,11600],{"class":787},[688,11643,11603],{"class":2220},[688,11645,2072],{"class":791},[688,11647,3194],{"class":2220},[688,11649,11610],{"class":787},[688,11651,2072],{"class":791},[688,11653,11615],{"class":787},[688,11655,11656,11659,11661,11663,11665,11667,11669],{"class":690,"line":856},[688,11657,11658],{"class":787},"nvm exec ",[688,11660,11603],{"class":2220},[688,11662,2072],{"class":791},[688,11664,3194],{"class":2220},[688,11666,11629],{"class":787},[688,11668,11330],{"class":791},[688,11670,11590],{"class":787},[13,11672,11673],{},[71,11674,11675],{},"4. 查看已安装Node.js的安装路径",[679,11677,11679],{"className":766,"code":11678,"language":769,"meta":502,"style":502},"nvm which 12.22\n",[42,11680,11681],{"__ignoreMap":502},[688,11682,11683,11686],{"class":690,"line":691},[688,11684,11685],{"class":787},"nvm which ",[688,11687,11688],{"class":2220},"12.22\n",[17,11690,11691],{"id":9703},"3. 常见问题",[123,11693,11695],{"id":11694},"_31-windows-常见问题","3.1. Windows 常见问题",[13,11697,11698],{},[71,11699,11700],{},"1. nvm 命令无效​",[128,11702,11703,11706,11709],{},[68,11704,11705],{},"确保以管理员身份运行命令提示符。",[68,11707,11708],{},"检查环境变量是否设置正确。",[68,11710,11711],{},"关闭终端重新打开或者重启电脑。",[13,11713,11714],{},[71,11715,11716],{},"2. 安装失败",[128,11718,11719,11722],{},[68,11720,11721],{},"安装路径不能有中文和空格。",[68,11723,11724],{},"关闭杀毒软件。",[123,11726,11728],{"id":11727},"_32-linux-常见问题","3.2. Linux 常见问题",[13,11730,11731],{},[71,11732,11733],{},"1. nvm命令找不到",[128,11735,11736,11739],{},[68,11737,11738],{},"nvm环境变量是否配置成功。",[68,11740,11741],{},"环境变量是否重新加载。",[13,11743,11744,11745,11748,11749,11752,11753],{},"运行",[42,11746,11747],{"color":116}," source ~\u002F.bashrc"," 或",[42,11750,11751],{"color":116}," source ~\u002F.zshrc","  或者",[42,11754,11755],{"color":116},"source ~\u002F.profile",[13,11757,11758],{},[71,11759,11760],{},"2. Node.js安装速度慢",[13,11762,11763,11764,11766,11767,11769],{},"在",[42,11765,10913],{},"系统环境变量中配置",[42,11768,6694],{},"阿里云镜像地址",[679,11771,11773],{"className":681,"code":11772,"language":684,"meta":502,"style":502},"# 编辑环境变量文件\nvi ~\u002F.bashrc\n# 最后一行输入\nexport NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n# 保存退出\n:wq!\n# 重新加载环境变量\nsource  ~\u002F.bashrc\n",[42,11774,11775,11780,11788,11793,11805,11810,11815,11820],{"__ignoreMap":502},[688,11776,11777],{"class":690,"line":691},[688,11778,11779],{"class":859},"# 编辑环境变量文件\n",[688,11781,11782,11785],{"class":690,"line":506},[688,11783,11784],{"class":694},"vi",[688,11786,11787],{"class":697}," ~\u002F.bashrc\n",[688,11789,11790],{"class":690,"line":535},[688,11791,11792],{"class":859},"# 最后一行输入\n",[688,11794,11795,11797,11800,11802],{"class":690,"line":609},[688,11796,777],{"class":2013},[688,11798,11799],{"class":787}," NVM_NODEJS_ORG_MIRROR",[688,11801,2303],{"class":791},[688,11803,11804],{"class":787},"https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n",[688,11806,11807],{"class":690,"line":624},[688,11808,11809],{"class":859},"# 保存退出\n",[688,11811,11812],{"class":690,"line":856},[688,11813,11814],{"class":694},":wq!\n",[688,11816,11817],{"class":690,"line":863},[688,11818,11819],{"class":859},"# 重新加载环境变量\n",[688,11821,11822,11825],{"class":690,"line":874},[688,11823,11824],{"class":783},"source",[688,11826,11827],{"class":697},"  ~\u002F.bashrc\n",[13,11829,11763,11830,11833,11834,11836,11837,11839,11840,11842,11843,11846],{},[42,11831,11832],{},"windows","系统中配置",[42,11835,10879],{},"下载",[42,11838,6694],{},"使用的阿里云镜像地址，在",[42,11841,10863],{},"安装目录下的",[42,11844,11845],{},"settings.txt","文件中添加以下内容：",[679,11848,11850],{"className":681,"code":11849,"language":684,"meta":502,"style":502},"node_mirror: https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n\n",[42,11851,11852],{"__ignoreMap":502},[688,11853,11854,11857],{"class":690,"line":691},[688,11855,11856],{"class":694},"node_mirror:",[688,11858,11859],{"class":697}," https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n",[968,11861,11862],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":502,"searchDepth":535,"depth":535,"links":11864},[11865,11869,11873],{"id":10870,"depth":506,"text":10871,"children":11866},[11867,11868],{"id":10937,"depth":535,"text":10938},{"id":11042,"depth":535,"text":11043},{"id":11274,"depth":506,"text":11275,"children":11870},[11871,11872],{"id":11287,"depth":535,"text":11288},{"id":11514,"depth":535,"text":11515},{"id":9703,"depth":506,"text":11691,"children":11874},[11875,11876],{"id":11694,"depth":535,"text":11695},{"id":11727,"depth":535,"text":11728},{"name":6694,"symbol":6695,"icon":6696,"id":896},"2025-06-16 21:33:26","在Windows和Linux系统上，通过NVM版本管理器安装和管理不同版本的Node.js，易于快速实现不同版本的Nose.js安装和切换，满足不同应用场景的需求，同时也降低运维成本。",{"type":10,"value":11881},[11882],[13,11883,11884],{},"NVM（Node Version Manager）是专为Node.js设计的版本管理工具，用于安装和管理多个不同版本的Node.js，允许在同一台机器上安装、切换和使用多个不同版本的Node.js，适用于开发者处理多个项目需要不同Node版本的需求。本文从Windows和Linux2个不同的操作系统入手，简单记录NVM安装不同Node.js的使用步骤。",{},"\u002Fblog\u002Fwindowslinuxnvmnode.js","---\ntitle: Windows和Linux系统上NVM安装多个版本的Node.js\ndescription: 在Windows和Linux系统上，通过NVM版本管理器安装和管理不同版本的Node.js，易于快速实现不同版本的Nose.js安装和切换，满足不同应用场景的需求，同时也降低运维成本。\narticleId: nvm-node\ncreateDate: \"2025-06-16 21:33:26\"\nupdateDate: \"2026-03-12 10:44:16\"\narticleThumb: https:\u002F\u002Fcdn.anyfork.top\u002Fimages\u002F20260327205225806.webp\ntagIds: \n    - 10\ncategoryId: 10\nisTop: false\nisRecommend: true\nisHot: true\nisHidden: false\nnavigation: true\n---\nNVM（Node Version Manager）是专为Node.js设计的版本管理工具，用于安装和管理多个不同版本的Node.js，允许在同一台机器上安装、切换和使用多个不同版本的Node.js，适用于开发者处理多个项目需要不同Node版本的需求。本文从Windows和Linux2个不同的操作系统入手，简单记录NVM安装不同Node.js的使用步骤。\n\u003C!--more-->\n\n::callout{icon=\"material-symbols:info-outline\" color=\"primary\" to=\"https:\u002F\u002Fgithub.com\u002Fnvm-sh\u002Fnvm\u002Fblob\u002Fmaster\u002FREADME.md\" target=\"_blank\"}\n点击访问`nvm`官网，阅读`nvm`使用文档\n::\n\n## 1. 安装NVM软件\n访问[NVM](https:\u002F\u002Fgithub.com\u002Fnvm-sh\u002Fnvm)的源码仓库，可以查看最新版本的`nvm`包，在不同的系统上安装`nvm`方式存在差异，但基本都可以通过源代码包和第三方快捷方式进行安装。\n::warning\n**注意：** \u003C\u002Fbr>\n1. 无论什么系统，通过`nvm`安装node.js之前，都需要卸载现已安装好的`Node.js`，避免发生安装冲突和错误问题。\n2. 对于`Linux`系统，不同版本的`Node.js`对`gcc`版本有要求，安装`Node.js`对应的`gcc`版本，Node.js才能安装成功。建议使用最新版本的`linux`镜像系统(gcc版本比较高，满足高版本Node.js安装需求)，否则需要手动升级系统`gcc`版本，非常麻烦。\n::\n\n### 1.1 Windows安装NVM\nwindows系统可以通过`nvm-windows​`进行安装，`nvm-windows`是一个`.exe`的安装包，在`nvm`源码包的基础上编译成了可执行文件，便于在`Windows`环境下安装。\n\n**1. 下载nvm-windows**\n\n访问[nvm-windows](https:\u002F\u002Fgithub.com\u002Fcoreybutler\u002Fnvm-windows\u002Freleases)官方仓库，下载最新版本的安装包。\n- 稳定版：nvm-setup.exe\n- 便携版：nvm-noinstall.zip\n\n稳定版是可执行文件，可以直接点击安装，推荐使用稳定版安装。便携版为免安装的文件包，之间解压到磁盘上即可。\n::tip\n二者区别：稳定版安装后，会自动添加环境变量，软件安装完毕就可以直接使用`nvm`,便携版需要手动配置环境变量，才能使用。\n::\n**2. 运行安装程序**\n1. 点击运行稳定版，勾选许可协议，下一步.\n2. 设置`nvm`安装路径，可自定义安装路径 .\n3. 设置 `Node.js` 的安装路径.\n4. 安装完成.\n\n**3.验证安装**\n\n打开新的命令提示符（CMD）或 PowerShell，运行：\n```shell\nnvm -v\n```\n如果显示版本号（如 1.1.9），说明安装成功。\n### 1.2 Linux安装NVM\nLinux系统上安装`nvm`，可以通过`nvm-sh`脚本和`源码包`2种方式进行安装。\n\n**1. 使用脚本安装**\n- 打开终端，运行以下命令：\n```ts\ncurl -o- https:\u002F\u002Fraw.githubusercontent.com\u002Fnvm-sh\u002Fnvm\u002Fv0.40.3\u002Finstall.sh | bash\n```\n- 或者使用 wget：\n```ts\nwget -qO- https:\u002F\u002Fraw.githubusercontent.com\u002Fnvm-sh\u002Fnvm\u002Fv0.40.3\u002Finstall.sh | bash\n```\n**2. 配置环境变量**\n\n安装完成后，将以下内容添加到你的 shell 配置文件（ ~\u002F.bashrc、 ~\u002F.zshrc 或 ~\u002F.profile）：\n```ts\nexport NVM_DIR=\"$HOME\u002F.nvm\"\n[ -s \"$NVM_DIR\u002Fnvm.sh\" ] && \\. \"$NVM_DIR\u002Fnvm.sh\"  # 加载 nvm\n[ -s \"$NVM_DIR\u002Fbash_completion\" ] && \\. \"$NVM_DIR\u002Fbash_completion\"  # 加载自动补全\n```\n::note\n注意: 通过脚本安装，脚本执行完，默认在`~\u002F.bashrc`中加入了上面的环境变量配置，只需要重新加载环境变量文件即可。\n::\n**3. 重新加载环境变量**\n```ts\nsource ~\u002F.bashrc\n```\n**4. 验证安装**\n```ts\nnvm -v\n```\n如果显示版本号（如：0.40.3)，说明安装成功。\n## 2. Nvm管理Node.js\n无论Window系统，还是Linux系统，`nvm`安装成功后，安装和管理`Node.js`的命令基本一致。\n### 2.1  基本命令\n**1. 安装 Node.js 版本**\n```ts\n# 安装最新版本的node，\"node\" 是最新版本的别名\nnvm install node \n# 安装最新的 LTS 版本\nnvm install --lts \n# 安装最新 18.x 版本\nnvm install 18 \n# 安装指定版本     \nnvm install 16.14.0  \n# 设置别名为my_alias，别名不能包含空格或者斜杠\nnvm alias my_alias v14.4.0\n```\n**2. 查看已安装版本**\n```ts\nnvm ls\n```\n显示结果为：\n```ts\n    v16.14.0\n    v18.12.1\n->  v20.7.0\n```\n箭头指向为当前使用的`Node.js`版本\n\n**3. 切换Node.js版本**\n```ts\n# 切换到 18.x\nnvm use 18\n# 切换到指定版本      \nnvm use 16.14.0  \n```\n**4. 卸载Node.js版本**\n```ts\nnvm uninstall 16.14.0\n```\n### 2.2 高阶用法\n\n**1. 设置默认版本**\n```ts\nnvm alias default 18\n```\n第一个安装的版本会被自动设置为默认版本，新打开的终端`shell`都会使用默认的`Node.js`版本。\n\n**2. 查看远程可用版本**\n```ts\nnvm ls-remote\n```\n**3. 临时选择版本，并输出版本号，该命令不会永久切换版本，仅临时运行一次**\n```ts\n# 临时选择最新node版本，并输出版本号\nnvm run node --version\n# 临时切换到 Node.js 18.12.1 版本，并输出该版本的 Node.js 号\nnvm run 18.12.1 node --version\n# 临时切换到 Node.js 18.12.1 版本，并输出该版本的 Node.js 号\nnvm exec 18.12.1 node --version\n```\n**4. 查看已安装Node.js的安装路径**\n```ts\nnvm which 12.22\n```\n## 3. 常见问题\n### 3.1. Windows 常见问题\n**1. nvm 命令无效​**\n- 确保以管理员身份运行命令提示符。\n- 检查环境变量是否设置正确。\n- 关闭终端重新打开或者重启电脑。\n\n\n**2. 安装失败**\n- 安装路径不能有中文和空格。\n- 关闭杀毒软件。\n\n\n### 3.2. Linux 常见问题\n**1. nvm命令找不到**\n- nvm环境变量是否配置成功。\n- 环境变量是否重新加载。\n\n运行` source ~\u002F.bashrc`{color=primary} 或` source ~\u002F.zshrc`{color=primary}  或者`source ~\u002F.profile`{color=primary} \n\n\n**2. Node.js安装速度慢**\n\n\n在`Linux`系统环境变量中配置`Node.js`阿里云镜像地址\n```bash\n# 编辑环境变量文件\nvi ~\u002F.bashrc\n# 最后一行输入\nexport NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n# 保存退出\n:wq!\n# 重新加载环境变量\nsource  ~\u002F.bashrc\n```\n在`windows`系统中配置`NVM`下载`Node.js`使用的阿里云镜像地址，在`nvm`安装目录下的`settings.txt`文件中添加以下内容：\n```bash\nnode_mirror: https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n\n```",6.9,{"title":10850,"description":11879},{"loc":11886},"blog\u002F7.Windows和Linux系统上NVM安装多个版本的Node.js",[896],[11894],{"name":11895,"icon":11896,"symbol":10863,"id":896},"Nvm","arcticons:nvm","2026-03-12 10:44:16",1249,"9iHIa12iRIYm9H-TvvIow1Llgd04AkZq0PGYBX-u5WE",[11901,12566,17444,18044,18572,18950,19165,19797,20495],{"id":5,"title":6,"articleId":7,"articleThumb":8,"body":11902,"categoryId":691,"categoryInfo":12543,"createDate":994,"description":995,"excerpt":12544,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1003,"meta":12548,"navigation":1003,"path":1005,"rawbody":1006,"readingTime":1007,"seo":12549,"sitemap":12550,"stem":1022,"tagIds":12563,"tagInfo":12564,"updateDate":1028,"wordCount":1029,"__hash__":1030},{"type":10,"value":11903,"toc":12523},[11904,11906,11908,11928,11930,11950,11952,11957,11963,11965,12003,12005,12023,12025,12027,12033,12035,12037,12047,12049,12051,12143,12145,12147,12156,12160,12172,12176,12178,12189,12204,12208,12212,12222,12226,12230,12236,12240,12242,12248,12252,12256,12262,12272,12274,12280,12284,12290,12302,12304,12313,12315,12359,12361,12375,12483,12485,12489,12517,12521],[13,11905,15],{},[17,11907,20],{"id":19},[22,11909,11910,11914,11920,11924],{},[25,11911,11912],{"icon":27,"target":28,"title":29,"to":30},[13,11913,33],{},[25,11915,11916],{"icon":27,"target":28,"title":36,"to":37},[13,11917,40,11918,45],{},[42,11919,44],{},[25,11921,11922],{"icon":27,"target":28,"title":48,"to":49},[13,11923,52],{},[25,11925,11926],{"icon":27,"target":28,"title":55,"to":56},[13,11927,59],{},[17,11929,63],{"id":62},[65,11931,11932,11936,11940,11944],{},[68,11933,11934,74],{},[71,11935,73],{},[68,11937,11938,80],{},[71,11939,79],{},[68,11941,11942,86],{},[71,11943,85],{},[68,11945,11946,92,11948,96],{},[71,11947,91],{},[42,11949,95],{},[17,11951,100],{"id":99},[13,11953,11954,110],{},[104,11955,109],{"href":106,"rel":11956,"target":28},[108],[13,11958,113,11959,117,11961,121],{},[42,11960,109],{"color":116},[42,11962,120],{"color":116},[123,11964,126],{"id":125},[128,11966,11967,11971,11975,11979,11983,11987,11991,11995,11999],{},[68,11968,132,11969,136],{},[71,11970,135],{},[68,11972,132,11973,142],{},[71,11974,141],{},[68,11976,132,11977,148],{},[71,11978,147],{},[68,11980,132,11981,154],{},[71,11982,153],{},[68,11984,11985,160],{},[71,11986,159],{},[68,11988,11989,166],{},[71,11990,165],{},[68,11992,11993,172],{},[71,11994,171],{},[68,11996,11997,178],{},[71,11998,177],{},[68,12000,12001,184],{},[71,12002,183],{},[123,12004,188],{"id":187},[128,12006,12007,12011,12015,12019],{},[68,12008,12009,196],{},[71,12010,195],{},[68,12012,12013,202],{},[71,12014,201],{},[68,12016,12017,208],{},[71,12018,207],{},[68,12020,12021,214],{},[71,12022,213],{},[123,12024,218],{"id":217},[13,12026,221],{},[223,12028,12029],{},[13,12030,227,12031,230],{},[42,12032,109],{},[123,12034,234],{"id":233},[13,12036,237],{},[65,12038,12039,12041,12043,12045],{},[68,12040,242],{},[68,12042,245],{},[68,12044,248],{},[68,12046,251],{},[17,12048,255],{"id":254},[13,12050,258],{},[260,12052,12053,12063],{},[263,12054,12055],{},[266,12056,12057,12059,12061],{},[269,12058,271],{},[269,12060,274],{},[269,12062,95],{},[278,12064,12065,12085,12097,12109,12131],{},[266,12066,12067,12069,12077],{},[283,12068,285],{},[283,12070,288,12071,292,12073,295,12075,298],{},[290,12072],{},[290,12074],{},[290,12076],{},[283,12078,301,12079,304,12081,307,12083,310],{},[290,12080],{},[290,12082],{},[290,12084],{},[266,12086,12087,12089,12093],{},[283,12088,315],{},[283,12090,318,12091,321],{},[290,12092],{},[283,12094,324,12095,327],{},[290,12096],{},[266,12098,12099,12101,12105],{},[283,12100,332],{},[283,12102,335,12103,338],{},[290,12104],{},[283,12106,341,12107,344],{},[290,12108],{},[266,12110,12111,12113,12123],{},[283,12112,349],{},[283,12114,352,12115,355,12117,358,12119,361,12121,364],{},[290,12116],{},[290,12118],{},[290,12120],{},[290,12122],{},[283,12124,367,12125,370,12127,373,12129,376],{},[290,12126],{},[290,12128],{},[290,12130],{},[266,12132,12133,12135,12137],{},[283,12134,381],{},[283,12136,384],{},[283,12138,387,12139,390,12141,393],{},[290,12140],{},[290,12142],{},[17,12144,397],{"id":396},[123,12146,401],{"id":400},[13,12148,404,12149,407,12151,410,12153,415],{},[42,12150,274],{},[42,12152,95],{},[104,12154,109],{"href":413,"rel":12155,"target":28},[108],[13,12157,12158],{},[419,12159],{"alt":421,"src":422},[13,12161,425,12162,428,12164,431,12166,435,12168,439,12170,443],{},[42,12163,274],{},[42,12165,95],{},[42,12167,434],{},[42,12169,438],{},[42,12171,442],{},[13,12173,12174],{},[419,12175],{"alt":448,"src":449},[123,12177,453],{"id":452},[13,12179,456,12180,459,12182,464,12185,468,12187,471],{},[42,12181,109],{},[104,12183,274],{"href":462,"rel":12184,"target":28},[108],[42,12186,467],{},[42,12188,109],{},[65,12190,12191],{},[68,12192,476,12193,482,12196,486,12198,489,12200,493,12202,497],{},[104,12194,481],{"href":479,"rel":12195},[108],[42,12197,485],{},[42,12199,95],{},[42,12201,492],{},[42,12203,496],{},[13,12205,12206],{},[419,12207],{"alt":502,"src":503},[65,12209,12210],{"start":506},[68,12211,509],{},[13,12213,512,12214,516,12216,519,12218,523,12220,527],{},[42,12215,515],{},[42,12217,442],{},[42,12219,522],{},[42,12221,526],{},[13,12223,12224],{},[419,12225],{"alt":502,"src":532},[65,12227,12228],{"start":535},[68,12229,538],{},[13,12231,541,12232,544,12234,548],{},[42,12233,496],{},[42,12235,547],{},[13,12237,12238],{},[419,12239],{"alt":502,"src":553},[13,12241,556],{},[13,12243,12244,12246],{},[419,12245],{"alt":502,"src":561},[419,12247],{"alt":502,"src":564},[13,12249,567,12250,497],{},[42,12251,570],{},[13,12253,12254],{},[419,12255],{"alt":502,"src":575},[13,12257,578,12258,582,12260,585],{},[42,12259,581],{},[42,12261,526],{},[13,12263,588,12264,592,12266,595,12268,599,12270,603],{},[42,12265,591],{},[42,12267,591],{},[42,12269,598],{},[42,12271,602],{},[13,12273,606],{},[65,12275,12276],{"start":609},[68,12277,612,12278,616],{},[42,12279,615],{},[13,12281,12282],{},[419,12283],{"alt":502,"src":621},[65,12285,12286],{"start":624},[68,12287,627,12288,631],{},[42,12289,630],{},[13,12291,12292,637,12294,641,12296,644,12298,648,12300,651],{},[419,12293],{"alt":502,"src":636},[42,12295,640],{},[42,12297,438],{},[42,12299,647],{},[42,12301,442],{},[17,12303,655],{"id":654},[13,12305,12306,663,12309,667,12311,670],{},[104,12307,662],{"href":660,"rel":12308,"target":28},[108],[42,12310,666],{},[42,12312,95],{},[123,12314,674],{"id":673},[676,12316,12317,12331,12345],{},[679,12318,12319],{"className":681,"code":682,"filename":683,"language":684,"meta":502,"style":502},[42,12320,12321],{"__ignoreMap":502},[688,12322,12323,12325,12327,12329],{"class":690,"line":691},[688,12324,683],{"class":694},[688,12326,698],{"class":697},[688,12328,701],{"class":697},[688,12330,704],{"class":697},[679,12332,12333],{"className":681,"code":707,"filename":708,"language":684,"meta":502,"style":502},[42,12334,12335],{"__ignoreMap":502},[688,12336,12337,12339,12341,12343],{"class":690,"line":691},[688,12338,708],{"class":694},[688,12340,698],{"class":697},[688,12342,701],{"class":697},[688,12344,704],{"class":697},[679,12346,12347],{"className":681,"code":723,"filename":724,"language":684,"meta":502,"style":502},[42,12348,12349],{"__ignoreMap":502},[688,12350,12351,12353,12355,12357],{"class":690,"line":691},[688,12352,724],{"class":694},[688,12354,733],{"class":697},[688,12356,701],{"class":697},[688,12358,704],{"class":697},[123,12360,741],{"id":740},[13,12362,744,12363,748,12365,752,12367,755,12369,644,12371,648,12373,763],{},[42,12364,747],{"color":116},[42,12366,751],{},[42,12368,95],{},[42,12370,758],{},[42,12372,434],{},[42,12374,442],{},[679,12376,12377],{"className":766,"code":767,"filename":768,"language":769,"meta":502,"style":502},[42,12378,12379,12391,12407,12413,12427,12441,12445,12453,12467,12471,12477],{"__ignoreMap":502},[688,12380,12381,12383,12385,12387,12389],{"class":690,"line":691},[688,12382,777],{"class":776},[688,12384,780],{"class":776},[688,12386,784],{"class":783},[688,12388,788],{"class":787},[688,12390,792],{"class":791},[688,12392,12393,12395,12397,12399,12401,12403,12405],{"class":690,"line":506},[688,12394,798],{"class":797},[688,12396,801],{"class":791},[688,12398,804],{"class":787},[688,12400,807],{"class":791},[688,12402,747],{"class":697},[688,12404,807],{"class":791},[688,12406,814],{"class":787},[688,12408,12409,12411],{"class":690,"line":535},[688,12410,819],{"class":787},[688,12412,792],{"class":791},[688,12414,12415,12417,12419,12421,12423,12425],{"class":690,"line":609},[688,12416,826],{"class":797},[688,12418,801],{"class":791},[688,12420,831],{"class":791},[688,12422,438],{"class":697},[688,12424,807],{"class":791},[688,12426,838],{"class":791},[688,12428,12429,12431,12433,12435,12437,12439],{"class":690,"line":624},[688,12430,843],{"class":797},[688,12432,801],{"class":791},[688,12434,831],{"class":791},[688,12436,647],{"class":697},[688,12438,807],{"class":791},[688,12440,838],{"class":791},[688,12442,12443],{"class":690,"line":856},[688,12444,860],{"class":859},[688,12446,12447,12449,12451],{"class":690,"line":863},[688,12448,866],{"class":797},[688,12450,801],{"class":791},[688,12452,871],{"class":791},[688,12454,12455,12457,12459,12461,12463,12465],{"class":690,"line":874},[688,12456,877],{"class":797},[688,12458,801],{"class":791},[688,12460,831],{"class":791},[688,12462,442],{"class":697},[688,12464,807],{"class":791},[688,12466,838],{"class":791},[688,12468,12469],{"class":690,"line":890},[688,12470,893],{"class":791},[688,12472,12473,12475],{"class":690,"line":896},[688,12474,899],{"class":791},[688,12476,902],{"class":787},[688,12478,12479,12481],{"class":690,"line":905},[688,12480,908],{"class":791},[688,12482,911],{"class":787},[123,12484,915],{"id":914},[13,12486,918,12487,922],{},[42,12488,921],{},[679,12490,12491],{"className":925,"code":926,"filename":927,"language":928,"meta":502,"style":502},[42,12492,12493,12501,12509],{"__ignoreMap":502},[688,12494,12495,12497,12499],{"class":690,"line":691},[688,12496,935],{"class":791},[688,12498,938],{"class":797},[688,12500,941],{"class":791},[688,12502,12503,12505,12507],{"class":690,"line":506},[688,12504,946],{"class":791},[688,12506,949],{"class":797},[688,12508,952],{"class":791},[688,12510,12511,12513,12515],{"class":690,"line":535},[688,12512,957],{"class":791},[688,12514,938],{"class":797},[688,12516,941],{"class":791},[13,12518,12519],{},[419,12520],{"alt":502,"src":966},[968,12522,970],{},{"title":502,"searchDepth":535,"depth":535,"links":12524},[12525,12526,12527,12533,12534,12538],{"id":19,"depth":506,"text":20},{"id":62,"depth":506,"text":63},{"id":99,"depth":506,"text":100,"children":12528},[12529,12530,12531,12532],{"id":125,"depth":535,"text":126},{"id":187,"depth":535,"text":188},{"id":217,"depth":535,"text":218},{"id":233,"depth":535,"text":234},{"id":254,"depth":506,"text":255},{"id":396,"depth":506,"text":397,"children":12535},[12536,12537],{"id":400,"depth":535,"text":401},{"id":452,"depth":535,"text":453},{"id":654,"depth":506,"text":655,"children":12539},[12540,12541,12542],{"id":673,"depth":535,"text":674},{"id":740,"depth":535,"text":741},{"id":914,"depth":535,"text":915},{"name":992,"symbol":492,"icon":993,"id":691},{"type":10,"value":12545},[12546],[13,12547,1000],{},{},{"title":6,"description":995},{"loc":1005,"images":12551},[12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562],{"loc":422},{"loc":449},{"loc":503},{"loc":532},{"loc":553},{"loc":561},{"loc":564},{"loc":575},{"loc":621},{"loc":636},{"loc":966},[691],[12565],{"name":274,"icon":1026,"symbol":1027,"id":691},{"id":1032,"title":1033,"articleId":1034,"articleThumb":1035,"body":12567,"categoryId":896,"categoryInfo":17431,"createDate":6697,"description":1044,"excerpt":17432,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":17438,"navigation":1003,"path":6707,"rawbody":6708,"readingTime":6709,"seo":17439,"sitemap":17440,"stem":6712,"tagIds":17441,"tagInfo":17442,"updateDate":6719,"wordCount":6720,"__hash__":6721},{"type":10,"value":12568,"toc":17407},[12569,12571,12573,12575,12577,12579,12581,12585,12587,12589,12595,12605,12611,12621,12627,12637,12643,12653,12659,12669,12671,12673,12683,12685,12687,12689,12691,12715,12717,12719,12759,12761,12763,12793,12795,12797,12817,12819,12821,12845,12847,12905,12907,12913,12959,12967,12973,12999,13001,13007,13063,13071,13077,13123,13125,13131,13177,13185,13187,13225,13227,13229,13231,13233,13235,13241,13539,13545,13679,13685,13959,13965,14195,14199,14201,14203,14209,14389,14395,14531,14537,14669,14671,14673,14679,14835,14841,14993,14999,15165,15167,15169,15171,15177,15279,15285,15441,15443,15449,15469,15475,15501,15507,15515,15517,15523,15525,15603,15605,15659,15663,15667,15673,15675,15683,15685,15687,15689,16993,16995,16997,17405],[17,12570,1041],{"id":1040},[13,12572,1044],{},[13,12574,1047],{},[13,12576,1050],{},[13,12578,1053],{},[13,12580,1056],{},[1058,12582,12583],{},[13,12584,1062],{},[17,12586,1066],{"id":1065},[13,12588,1069],{},[65,12590,12591],{},[68,12592,12593,1077],{},[71,12594,1076],{},[128,12596,12597,12601],{},[68,12598,12599,1085],{},[71,12600,1084],{},[68,12602,12603,1091],{},[71,12604,1090],{},[65,12606,12607],{"start":506},[68,12608,12609],{},[71,12610,1098],{},[128,12612,12613,12617],{},[68,12614,12615,1106],{},[71,12616,1105],{},[68,12618,12619,1112],{},[71,12620,1111],{},[65,12622,12623],{"start":535},[68,12624,12625,1120],{},[71,12626,1119],{},[128,12628,12629,12633],{},[68,12630,12631,1128],{},[71,12632,1127],{},[68,12634,12635,1134],{},[71,12636,1133],{},[65,12638,12639],{"start":609},[68,12640,12641],{},[71,12642,1141],{},[128,12644,12645,12649],{},[68,12646,12647,1148],{},[71,12648,1084],{},[68,12650,12651,1154],{},[71,12652,1153],{},[65,12654,12655],{"start":624},[68,12656,12657],{},[71,12658,1161],{},[128,12660,12661,12665],{},[68,12662,12663,1169],{},[71,12664,1168],{},[68,12666,12667,1175],{},[71,12668,1174],{},[17,12670,1179],{"id":1178},[13,12672,1182],{},[128,12674,12675,12679],{},[68,12676,12677,1190],{},[71,12678,1189],{},[68,12680,12681,1196],{},[71,12682,1195],{},[17,12684,1200],{"id":1199},[13,12686,1203],{},[123,12688,1207],{"id":1206},[13,12690,1210],{},[128,12692,12693,12697],{},[68,12694,12695,1218],{},[71,12696,1217],{},[68,12698,12699,12701],{},[71,12700,1223],{},[128,12702,12703,12707,12711],{},[68,12704,12705,1231],{},[71,12706,1230],{},[68,12708,12709,1237],{},[71,12710,1236],{},[68,12712,12713,1243],{},[71,12714,1242],{},[123,12716,1247],{"id":1246},[13,12718,1250],{},[128,12720,12721,12725],{},[68,12722,12723,1257],{},[71,12724,1217],{},[68,12726,12727,12729],{},[71,12728,1262],{},[128,12730,12731,12735,12739,12743,12747,12751,12755],{},[68,12732,12733,1270],{},[71,12734,1269],{},[68,12736,12737,1276],{},[71,12738,1275],{},[68,12740,12741,1282],{},[71,12742,1281],{},[68,12744,12745,1288],{},[71,12746,1287],{},[68,12748,12749,1294],{},[71,12750,1293],{},[68,12752,12753,1300],{},[71,12754,1299],{},[68,12756,12757,1306],{},[71,12758,1305],{},[123,12760,1310],{"id":1309},[13,12762,1313],{},[128,12764,12765,12769],{},[68,12766,12767,1320],{},[71,12768,1217],{},[68,12770,12771,12773],{},[71,12772,1325],{},[128,12774,12775,12779,12783,12787],{},[68,12776,12777,1333],{},[71,12778,1332],{},[68,12780,12781,1339],{},[71,12782,1338],{},[68,12784,12785,1345],{},[71,12786,1344],{},[68,12788,12789,1351,12791,1355],{},[71,12790,1350],{},[688,12792,1354],{},[123,12794,1359],{"id":1358},[13,12796,1362],{},[128,12798,12799,12803],{},[68,12800,12801,1369],{},[71,12802,1217],{},[68,12804,12805,12807],{},[71,12806,1374],{},[128,12808,12809,12813],{},[68,12810,12811,1382],{},[71,12812,1381],{},[68,12814,12815,1388],{},[71,12816,1387],{},[123,12818,1392],{"id":1391},[13,12820,1395],{},[128,12822,12823,12827],{},[68,12824,12825,1402],{},[71,12826,1217],{},[68,12828,12829,12831],{},[71,12830,1407],{},[128,12832,12833,12837,12841],{},[68,12834,12835,1415],{},[71,12836,1414],{},[68,12838,12839,1421],{},[71,12840,1420],{},[68,12842,12843,1427],{},[71,12844,1426],{},[123,12846,1431],{"id":1430},[260,12848,12849,12861],{},[263,12850,12851],{},[266,12852,12853,12855,12857,12859],{},[269,12854,1440],{},[269,12856,1443],{},[269,12858,1446],{},[269,12860,1449],{},[278,12862,12863,12873,12885,12895],{},[266,12864,12865,12867,12869,12871],{},[283,12866,1456],{},[283,12868,1459],{},[283,12870,1462],{},[283,12872,1465],{},[266,12874,12875,12877,12879,12881],{},[283,12876,1470],{},[283,12878,1473],{},[283,12880,1476],{},[283,12882,1479,12883,1483],{},[42,12884,1482],{},[266,12886,12887,12889,12891,12893],{},[283,12888,1488],{},[283,12890,1491],{},[283,12892,1494],{},[283,12894,1497],{},[266,12896,12897,12899,12901,12903],{},[283,12898,1502],{},[283,12900,1505],{},[283,12902,1494],{},[283,12904,1510],{},[17,12906,1514],{"id":1513},[65,12908,12909],{},[68,12910,12911],{},[71,12912,1521],{},[260,12914,12915,12927],{},[263,12916,12917],{},[266,12918,12919,12921,12923,12925],{},[269,12920,1530],{},[269,12922,1533],{},[269,12924,1536],{},[269,12926,1539],{},[278,12928,12929,12939,12949],{},[266,12930,12931,12933,12935,12937],{},[283,12932,1546],{},[283,12934,1549],{},[283,12936,1552],{},[283,12938,1555],{},[266,12940,12941,12943,12945,12947],{},[283,12942,1560],{},[283,12944,1549],{},[283,12946,1565],{},[283,12948,1568],{},[266,12950,12951,12953,12955,12957],{},[283,12952,1573],{},[283,12954,1549],{},[283,12956,1578],{},[283,12958,1581],{},[128,12960,12961,12963,12965],{},[68,12962,1586],{},[68,12964,1589],{},[68,12966,1592],{},[65,12968,12969],{"start":506},[68,12970,12971],{},[71,12972,1599],{},[260,12974,12975,12987],{},[263,12976,12977],{},[266,12978,12979,12981,12983,12985],{},[269,12980,1530],{},[269,12982,1533],{},[269,12984,1536],{},[269,12986,1539],{},[278,12988,12989],{},[266,12990,12991,12993,12995,12997],{},[283,12992,1620],{},[283,12994,1623],{},[283,12996,1626],{},[283,12998,1629],{},[13,13000,1632],{},[65,13002,13003],{"start":535},[68,13004,13005],{},[71,13006,1639],{},[260,13008,13009,13021],{},[263,13010,13011],{},[266,13012,13013,13015,13017,13019],{},[269,13014,1648],{},[269,13016,1533],{},[269,13018,1536],{},[269,13020,1539],{},[278,13022,13023,13033,13043,13053],{},[266,13024,13025,13027,13029,13031],{},[283,13026,1661],{},[283,13028,1664],{},[283,13030,1667],{},[283,13032,1670],{},[266,13034,13035,13037,13039,13041],{},[283,13036,1675],{},[283,13038,1664],{},[283,13040,1680],{},[283,13042,1683],{},[266,13044,13045,13047,13049,13051],{},[283,13046,1688],{},[283,13048,1664],{},[283,13050,1693],{},[283,13052,1696],{},[266,13054,13055,13057,13059,13061],{},[283,13056,1701],{},[283,13058,1664],{},[283,13060,1706],{},[283,13062,1709],{},[128,13064,13065,13067,13069],{},[68,13066,1714],{},[68,13068,1717],{},[68,13070,1720],{},[65,13072,13073],{"start":609},[68,13074,13075],{},[71,13076,1727],{},[260,13078,13079,13091],{},[263,13080,13081],{},[266,13082,13083,13085,13087,13089],{},[269,13084,1648],{},[269,13086,1533],{},[269,13088,1536],{},[269,13090,1539],{},[278,13092,13093,13103,13113],{},[266,13094,13095,13097,13099,13101],{},[283,13096,1748],{},[283,13098,1751],{},[283,13100,1754],{},[283,13102,1757],{},[266,13104,13105,13107,13109,13111],{},[283,13106,1762],{},[283,13108,1751],{},[283,13110,1767],{},[283,13112,1770],{},[266,13114,13115,13117,13119,13121],{},[283,13116,1775],{},[283,13118,1751],{},[283,13120,1780],{},[283,13122,1783],{},[13,13124,1786],{},[65,13126,13127],{"start":624},[68,13128,13129],{},[71,13130,1793],{},[260,13132,13133,13145],{},[263,13134,13135],{},[266,13136,13137,13139,13141,13143],{},[269,13138,1648],{},[269,13140,1533],{},[269,13142,1536],{},[269,13144,1539],{},[278,13146,13147,13157,13167],{},[266,13148,13149,13151,13153,13155],{},[283,13150,1814],{},[283,13152,1817],{},[283,13154,1820],{},[283,13156,1823],{},[266,13158,13159,13161,13163,13165],{},[283,13160,1828],{},[283,13162,1831],{},[283,13164,1834],{},[283,13166,1837],{},[266,13168,13169,13171,13173,13175],{},[283,13170,1842],{},[283,13172,1831],{},[283,13174,1847],{},[283,13176,1850],{},[128,13178,13179,13181,13183],{},[68,13180,1855],{},[68,13182,1858],{},[68,13184,1861],{},[17,13186,1865],{"id":1864},[260,13188,13189,13199],{},[263,13190,13191],{},[266,13192,13193,13195,13197],{},[269,13194,1648],{},[269,13196,1876],{},[269,13198,1879],{},[278,13200,13201,13209,13217],{},[266,13202,13203,13205,13207],{},[283,13204,1886],{},[283,13206,1889],{},[283,13208,1892],{},[266,13210,13211,13213,13215],{},[283,13212,1897],{},[283,13214,1900],{},[283,13216,1903],{},[266,13218,13219,13221,13223],{},[283,13220,1908],{},[283,13222,1911],{},[283,13224,1914],{},[17,13226,1918],{"id":1917},[13,13228,1921],{},[123,13230,1925],{"id":1924},[13,13232,1928],{},[13,13234,1931],{},[65,13236,13237],{},[68,13238,13239,1939],{},[71,13240,1938],{},[679,13242,13243],{"className":1942,"code":1943,"language":1944,"meta":502,"style":502},[42,13244,13245,13249,13253,13271,13287,13291,13307,13311,13327,13349,13353,13357,13393,13397,13401,13429,13491,13495,13503,13507,13511,13515],{"__ignoreMap":502},[688,13246,13247],{"class":690,"line":691},[688,13248,1951],{"class":859},[688,13250,13251],{"class":690,"line":506},[688,13252,1956],{"class":859},[688,13254,13255,13257,13259,13261,13263,13265,13267,13269],{"class":690,"line":535},[688,13256,1961],{"class":859},[688,13258,1964],{"class":776},[688,13260,1968],{"class":1967},[688,13262,1971],{"class":776},[688,13264,1975],{"class":1974},[688,13266,908],{"class":776},[688,13268,1981],{"class":1980},[688,13270,1984],{"class":859},[688,13272,13273,13275,13277,13279,13281,13283,13285],{"class":690,"line":609},[688,13274,1961],{"class":859},[688,13276,1964],{"class":776},[688,13278,1993],{"class":1967},[688,13280,1971],{"class":776},[688,13282,1998],{"class":1974},[688,13284,908],{"class":776},[688,13286,2003],{"class":859},[688,13288,13289],{"class":690,"line":624},[688,13290,2008],{"class":859},[688,13292,13293,13295,13297,13299,13301,13303,13305],{"class":690,"line":856},[688,13294,2014],{"class":2013},[688,13296,2017],{"class":2013},[688,13298,2020],{"class":783},[688,13300,788],{"class":791},[688,13302,2025],{"class":1980},[688,13304,2028],{"class":791},[688,13306,871],{"class":791},[688,13308,13309],{"class":690,"line":863},[688,13310,2035],{"class":859},[688,13312,13313,13315,13317,13319,13321,13323,13325],{"class":690,"line":874},[688,13314,2040],{"class":2013},[688,13316,2043],{"class":787},[688,13318,2046],{"class":791},[688,13320,2049],{"class":791},[688,13322,2052],{"class":783},[688,13324,2055],{"class":797},[688,13326,2058],{"class":791},[688,13328,13329,13331,13333,13335,13337,13339,13341,13343,13345,13347],{"class":690,"line":890},[688,13330,2040],{"class":2013},[688,13332,2065],{"class":787},[688,13334,2046],{"class":791},[688,13336,2043],{"class":787},[688,13338,2072],{"class":791},[688,13340,2075],{"class":783},[688,13342,788],{"class":797},[688,13344,2025],{"class":787},[688,13346,2028],{"class":797},[688,13348,2058],{"class":791},[688,13350,13351],{"class":690,"line":896},[688,13352,2088],{"emptyLinePlaceholder":1003},[688,13354,13355],{"class":690,"line":905},[688,13356,2093],{"class":859},[688,13358,13359,13361,13363,13365,13367,13369,13371,13373,13375,13377,13379,13381,13383,13385,13387,13389,13391],{"class":690,"line":2096},[688,13360,2040],{"class":2013},[688,13362,2101],{"class":787},[688,13364,2046],{"class":791},[688,13366,2106],{"class":776},[688,13368,2109],{"class":787},[688,13370,2072],{"class":791},[688,13372,2114],{"class":787},[688,13374,2072],{"class":791},[688,13376,1751],{"class":783},[688,13378,788],{"class":797},[688,13380,807],{"class":791},[688,13382,1748],{"class":697},[688,13384,807],{"class":791},[688,13386,2129],{"class":791},[688,13388,2065],{"class":787},[688,13390,2028],{"class":797},[688,13392,2058],{"class":791},[688,13394,13395],{"class":690,"line":2138},[688,13396,2088],{"emptyLinePlaceholder":1003},[688,13398,13399],{"class":690,"line":2143},[688,13400,2146],{"class":859},[688,13402,13403,13405,13407,13409,13411,13413,13415,13417,13419,13421,13423,13425,13427],{"class":690,"line":2149},[688,13404,2040],{"class":2013},[688,13406,2154],{"class":787},[688,13408,2046],{"class":791},[688,13410,2159],{"class":787},[688,13412,2072],{"class":791},[688,13414,2164],{"class":783},[688,13416,788],{"class":797},[688,13418,2169],{"class":791},[688,13420,2172],{"class":783},[688,13422,788],{"class":797},[688,13424,2177],{"class":787},[688,13426,2180],{"class":797},[688,13428,2058],{"class":791},[688,13430,13431,13433,13435,13437,13439,13441,13443,13445,13447,13449,13451,13453,13455,13457,13459,13461,13463,13465,13467,13469,13471,13473,13475,13477,13479,13481,13483,13485,13487,13489],{"class":690,"line":2185},[688,13432,2040],{"class":2013},[688,13434,2190],{"class":787},[688,13436,2046],{"class":791},[688,13438,2154],{"class":787},[688,13440,2072],{"class":791},[688,13442,2199],{"class":783},[688,13444,788],{"class":797},[688,13446,2204],{"class":1980},[688,13448,2207],{"class":2013},[688,13450,2210],{"class":787},[688,13452,2072],{"class":791},[688,13454,2215],{"class":783},[688,13456,788],{"class":797},[688,13458,2221],{"class":2220},[688,13460,2028],{"class":797},[688,13462,2072],{"class":791},[688,13464,2228],{"class":783},[688,13466,788],{"class":797},[688,13468,2233],{"class":2220},[688,13470,2129],{"class":791},[688,13472,831],{"class":791},[688,13474,2240],{"class":697},[688,13476,807],{"class":791},[688,13478,2180],{"class":797},[688,13480,2072],{"class":791},[688,13482,2249],{"class":783},[688,13484,788],{"class":797},[688,13486,2254],{"class":791},[688,13488,2028],{"class":797},[688,13490,2058],{"class":791},[688,13492,13493],{"class":690,"line":2261},[688,13494,2264],{"class":797},[688,13496,13497,13499,13501],{"class":690,"line":2267},[688,13498,2270],{"class":776},[688,13500,2190],{"class":787},[688,13502,2058],{"class":791},[688,13504,13505],{"class":690,"line":2277},[688,13506,2280],{"class":791},[688,13508,13509],{"class":690,"line":2283},[688,13510,2088],{"emptyLinePlaceholder":1003},[688,13512,13513],{"class":690,"line":2288},[688,13514,2291],{"class":859},[688,13516,13517,13519,13521,13523,13525,13527,13529,13531,13533,13535,13537],{"class":690,"line":2294},[688,13518,2297],{"class":2013},[688,13520,2300],{"class":787},[688,13522,2303],{"class":791},[688,13524,2106],{"class":776},[688,13526,2020],{"class":783},[688,13528,788],{"class":787},[688,13530,2312],{"class":791},[688,13532,2315],{"class":697},[688,13534,2312],{"class":791},[688,13536,2028],{"class":787},[688,13538,2058],{"class":791},[65,13540,13541],{"start":506},[68,13542,13543,2329],{},[71,13544,2328],{},[679,13546,13547],{"className":1942,"code":2332,"language":1944,"meta":502,"style":502},[42,13548,13549,13553,13557,13573,13577,13589,13607,13611,13625,13635,13639,13647,13669,13675],{"__ignoreMap":502},[688,13550,13551],{"class":690,"line":691},[688,13552,1951],{"class":859},[688,13554,13555],{"class":690,"line":506},[688,13556,2343],{"class":859},[688,13558,13559,13561,13563,13565,13567,13569,13571],{"class":690,"line":535},[688,13560,1961],{"class":859},[688,13562,1964],{"class":776},[688,13564,1993],{"class":1967},[688,13566,1971],{"class":776},[688,13568,2356],{"class":1974},[688,13570,908],{"class":776},[688,13572,2361],{"class":859},[688,13574,13575],{"class":690,"line":609},[688,13576,2008],{"class":859},[688,13578,13579,13581,13583,13585,13587],{"class":690,"line":624},[688,13580,2014],{"class":2013},[688,13582,2017],{"class":2013},[688,13584,2374],{"class":783},[688,13586,2055],{"class":791},[688,13588,871],{"class":791},[688,13590,13591,13593,13595,13597,13599,13601,13603,13605],{"class":690,"line":856},[688,13592,2270],{"class":776},[688,13594,2106],{"class":776},[688,13596,2109],{"class":787},[688,13598,2072],{"class":791},[688,13600,2114],{"class":787},[688,13602,2072],{"class":791},[688,13604,2395],{"class":783},[688,13606,2398],{"class":797},[688,13608,13609],{"class":690,"line":863},[688,13610,2403],{"class":791},[688,13612,13613,13615,13617,13619,13621,13623],{"class":690,"line":874},[688,13614,2408],{"class":797},[688,13616,801],{"class":791},[688,13618,831],{"class":791},[688,13620,2415],{"class":697},[688,13622,807],{"class":791},[688,13624,838],{"class":791},[688,13626,13627,13629,13631,13633],{"class":690,"line":890},[688,13628,2424],{"class":797},[688,13630,801],{"class":791},[688,13632,2429],{"class":2220},[688,13634,2432],{"class":859},[688,13636,13637],{"class":690,"line":896},[688,13638,2437],{"class":791},[688,13640,13641,13643,13645],{"class":690,"line":905},[688,13642,2443],{"class":2442},[688,13644,2129],{"class":791},[688,13646,2448],{"class":859},[688,13648,13649,13651,13653,13655,13657,13659,13661,13663,13665,13667],{"class":690,"line":2096},[688,13650,2453],{"class":797},[688,13652,807],{"class":791},[688,13654,2458],{"class":697},[688,13656,807],{"class":791},[688,13658,2129],{"class":791},[688,13660,831],{"class":791},[688,13662,2467],{"class":697},[688,13664,807],{"class":791},[688,13666,2472],{"class":797},[688,13668,2475],{"class":859},[688,13670,13671,13673],{"class":690,"line":2138},[688,13672,2480],{"class":797},[688,13674,2058],{"class":791},[688,13676,13677],{"class":690,"line":2143},[688,13678,2280],{"class":791},[65,13680,13681],{"start":535},[68,13682,13683,2494],{},[71,13684,2493],{},[679,13686,13687],{"className":1942,"code":2497,"language":1944,"meta":502,"style":502},[42,13688,13689,13693,13697,13715,13733,13749,13753,13773,13789,13811,13815,13819,13823,13851,13855,13859,13881,13885,13899,13909,13913,13921,13927,13933,13937,13941,13955],{"__ignoreMap":502},[688,13690,13691],{"class":690,"line":691},[688,13692,1951],{"class":859},[688,13694,13695],{"class":690,"line":506},[688,13696,2508],{"class":859},[688,13698,13699,13701,13703,13705,13707,13709,13711,13713],{"class":690,"line":535},[688,13700,1961],{"class":859},[688,13702,1964],{"class":776},[688,13704,1968],{"class":1967},[688,13706,1971],{"class":776},[688,13708,1975],{"class":1974},[688,13710,908],{"class":776},[688,13712,1981],{"class":1980},[688,13714,2527],{"class":859},[688,13716,13717,13719,13721,13723,13725,13727,13729,13731],{"class":690,"line":609},[688,13718,1961],{"class":859},[688,13720,1964],{"class":776},[688,13722,1968],{"class":1967},[688,13724,1971],{"class":776},[688,13726,1488],{"class":1974},[688,13728,908],{"class":776},[688,13730,2544],{"class":1980},[688,13732,2547],{"class":859},[688,13734,13735,13737,13739,13741,13743,13745,13747],{"class":690,"line":624},[688,13736,1961],{"class":859},[688,13738,1964],{"class":776},[688,13740,1993],{"class":1967},[688,13742,1971],{"class":776},[688,13744,2560],{"class":1974},[688,13746,908],{"class":776},[688,13748,2565],{"class":859},[688,13750,13751],{"class":690,"line":856},[688,13752,2008],{"class":859},[688,13754,13755,13757,13759,13761,13763,13765,13767,13769,13771],{"class":690,"line":863},[688,13756,2014],{"class":2013},[688,13758,2017],{"class":2013},[688,13760,2578],{"class":783},[688,13762,788],{"class":791},[688,13764,2025],{"class":1980},[688,13766,2129],{"class":791},[688,13768,2544],{"class":1980},[688,13770,2028],{"class":791},[688,13772,871],{"class":791},[688,13774,13775,13777,13779,13781,13783,13785,13787],{"class":690,"line":874},[688,13776,2040],{"class":2013},[688,13778,2043],{"class":787},[688,13780,2046],{"class":791},[688,13782,2049],{"class":791},[688,13784,2052],{"class":783},[688,13786,2055],{"class":797},[688,13788,2058],{"class":791},[688,13790,13791,13793,13795,13797,13799,13801,13803,13805,13807,13809],{"class":690,"line":890},[688,13792,2040],{"class":2013},[688,13794,2613],{"class":787},[688,13796,2046],{"class":791},[688,13798,2043],{"class":787},[688,13800,2072],{"class":791},[688,13802,2075],{"class":783},[688,13804,788],{"class":797},[688,13806,2025],{"class":787},[688,13808,2028],{"class":797},[688,13810,2058],{"class":791},[688,13812,13813],{"class":690,"line":896},[688,13814,2088],{"emptyLinePlaceholder":1003},[688,13816,13817],{"class":690,"line":905},[688,13818,2638],{"class":859},[688,13820,13821],{"class":690,"line":2096},[688,13822,2643],{"class":859},[688,13824,13825,13827,13829,13831,13833,13835,13837,13839,13841,13843,13845,13847,13849],{"class":690,"line":2138},[688,13826,2040],{"class":2013},[688,13828,2650],{"class":787},[688,13830,2046],{"class":791},[688,13832,2109],{"class":787},[688,13834,2072],{"class":791},[688,13836,2659],{"class":783},[688,13838,788],{"class":797},[688,13840,2169],{"class":791},[688,13842,2172],{"class":783},[688,13844,788],{"class":797},[688,13846,2670],{"class":2220},[688,13848,2180],{"class":797},[688,13850,2058],{"class":791},[688,13852,13853],{"class":690,"line":2143},[688,13854,2088],{"emptyLinePlaceholder":1003},[688,13856,13857],{"class":690,"line":2149},[688,13858,2683],{"class":859},[688,13860,13861,13863,13865,13867,13869,13871,13873,13875,13877,13879],{"class":690,"line":2185},[688,13862,2040],{"class":2013},[688,13864,2690],{"class":787},[688,13866,2046],{"class":791},[688,13868,2106],{"class":776},[688,13870,2109],{"class":787},[688,13872,2072],{"class":791},[688,13874,2114],{"class":787},[688,13876,2072],{"class":791},[688,13878,2458],{"class":783},[688,13880,2398],{"class":797},[688,13882,13883],{"class":690,"line":2261},[688,13884,2403],{"class":791},[688,13886,13887,13889,13891,13893,13895,13897],{"class":690,"line":2267},[688,13888,2408],{"class":797},[688,13890,801],{"class":791},[688,13892,831],{"class":791},[688,13894,2415],{"class":697},[688,13896,807],{"class":791},[688,13898,838],{"class":791},[688,13900,13901,13903,13905,13907],{"class":690,"line":2277},[688,13902,2729],{"class":797},[688,13904,801],{"class":791},[688,13906,2650],{"class":787},[688,13908,2736],{"class":859},[688,13910,13911],{"class":690,"line":2283},[688,13912,2437],{"class":791},[688,13914,13915,13917,13919],{"class":690,"line":2288},[688,13916,2745],{"class":787},[688,13918,2129],{"class":791},[688,13920,2750],{"class":859},[688,13922,13923,13925],{"class":690,"line":2294},[688,13924,2755],{"class":787},[688,13926,2758],{"class":859},[688,13928,13929,13931],{"class":690,"line":2761},[688,13930,2480],{"class":797},[688,13932,2058],{"class":791},[688,13934,13935],{"class":690,"line":2768},[688,13936,2088],{"emptyLinePlaceholder":1003},[688,13938,13939],{"class":690,"line":2773},[688,13940,2776],{"class":859},[688,13942,13943,13945,13947,13949,13951,13953],{"class":690,"line":2779},[688,13944,2270],{"class":776},[688,13946,1971],{"class":791},[688,13948,2690],{"class":787},[688,13950,2129],{"class":791},[688,13952,2650],{"class":787},[688,13954,2792],{"class":791},[688,13956,13957],{"class":690,"line":2795},[688,13958,2280],{"class":791},[65,13960,13961],{"start":609},[68,13962,13963,2805],{},[71,13964,2804],{},[679,13966,13967],{"className":1942,"code":2808,"language":1944,"meta":502,"style":502},[42,13968,13969,13973,13977,13995,14013,14031,14047,14051,14075,14079,14101,14105,14119,14129,14133,14139,14143,14149,14153,14157,14173,14191],{"__ignoreMap":502},[688,13970,13971],{"class":690,"line":691},[688,13972,1951],{"class":859},[688,13974,13975],{"class":690,"line":506},[688,13976,2819],{"class":859},[688,13978,13979,13981,13983,13985,13987,13989,13991,13993],{"class":690,"line":535},[688,13980,1961],{"class":859},[688,13982,1964],{"class":776},[688,13984,1968],{"class":1967},[688,13986,1971],{"class":776},[688,13988,2832],{"class":1974},[688,13990,908],{"class":776},[688,13992,2690],{"class":1980},[688,13994,2839],{"class":859},[688,13996,13997,13999,14001,14003,14005,14007,14009,14011],{"class":690,"line":609},[688,13998,1961],{"class":859},[688,14000,1964],{"class":776},[688,14002,1968],{"class":1967},[688,14004,1971],{"class":776},[688,14006,1488],{"class":1974},[688,14008,908],{"class":776},[688,14010,2544],{"class":1980},[688,14012,2858],{"class":859},[688,14014,14015,14017,14019,14021,14023,14025,14027,14029],{"class":690,"line":624},[688,14016,1961],{"class":859},[688,14018,1964],{"class":776},[688,14020,1968],{"class":1967},[688,14022,1971],{"class":776},[688,14024,2871],{"class":1974},[688,14026,908],{"class":776},[688,14028,2650],{"class":1980},[688,14030,2878],{"class":859},[688,14032,14033,14035,14037,14039,14041,14043,14045],{"class":690,"line":856},[688,14034,1961],{"class":859},[688,14036,1964],{"class":776},[688,14038,1993],{"class":1967},[688,14040,1971],{"class":776},[688,14042,1998],{"class":1974},[688,14044,908],{"class":776},[688,14046,2895],{"class":859},[688,14048,14049],{"class":690,"line":863},[688,14050,2008],{"class":859},[688,14052,14053,14055,14057,14059,14061,14063,14065,14067,14069,14071,14073],{"class":690,"line":874},[688,14054,2014],{"class":2013},[688,14056,2017],{"class":2013},[688,14058,2908],{"class":783},[688,14060,788],{"class":791},[688,14062,2913],{"class":1980},[688,14064,2129],{"class":791},[688,14066,2544],{"class":1980},[688,14068,2129],{"class":791},[688,14070,2650],{"class":1980},[688,14072,2028],{"class":791},[688,14074,871],{"class":791},[688,14076,14077],{"class":690,"line":890},[688,14078,2930],{"class":859},[688,14080,14081,14083,14085,14087,14089,14091,14093,14095,14097,14099],{"class":690,"line":896},[688,14082,2040],{"class":2013},[688,14084,2937],{"class":787},[688,14086,2046],{"class":791},[688,14088,2106],{"class":776},[688,14090,2109],{"class":787},[688,14092,2072],{"class":791},[688,14094,2114],{"class":787},[688,14096,2072],{"class":791},[688,14098,2467],{"class":783},[688,14100,2398],{"class":797},[688,14102,14103],{"class":690,"line":905},[688,14104,2403],{"class":791},[688,14106,14107,14109,14111,14113,14115,14117],{"class":690,"line":2096},[688,14108,2408],{"class":797},[688,14110,801],{"class":791},[688,14112,831],{"class":791},[688,14114,2415],{"class":697},[688,14116,807],{"class":791},[688,14118,838],{"class":791},[688,14120,14121,14123,14125,14127],{"class":690,"line":2138},[688,14122,2729],{"class":797},[688,14124,801],{"class":791},[688,14126,2650],{"class":787},[688,14128,2982],{"class":859},[688,14130,14131],{"class":690,"line":2143},[688,14132,2437],{"class":791},[688,14134,14135,14137],{"class":690,"line":2149},[688,14136,2745],{"class":787},[688,14138,838],{"class":791},[688,14140,14141],{"class":690,"line":2185},[688,14142,2997],{"class":787},[688,14144,14145,14147],{"class":690,"line":2261},[688,14146,2480],{"class":797},[688,14148,2058],{"class":791},[688,14150,14151],{"class":690,"line":2267},[688,14152,2088],{"emptyLinePlaceholder":1003},[688,14154,14155],{"class":690,"line":2277},[688,14156,3012],{"class":859},[688,14158,14159,14161,14163,14165,14167,14169,14171],{"class":690,"line":2283},[688,14160,2040],{"class":2013},[688,14162,3019],{"class":787},[688,14164,2046],{"class":791},[688,14166,2049],{"class":791},[688,14168,3026],{"class":783},[688,14170,2055],{"class":797},[688,14172,2058],{"class":791},[688,14174,14175,14177,14179,14181,14183,14185,14187,14189],{"class":690,"line":2288},[688,14176,2270],{"class":776},[688,14178,3019],{"class":787},[688,14180,2072],{"class":791},[688,14182,3041],{"class":783},[688,14184,788],{"class":797},[688,14186,3046],{"class":787},[688,14188,2028],{"class":797},[688,14190,2058],{"class":791},[688,14192,14193],{"class":690,"line":2294},[688,14194,2280],{"class":791},[3056,14196,14197],{},[13,14198,3060],{},[123,14200,3064],{"id":3063},[13,14202,3067],{},[65,14204,14205],{},[68,14206,14207],{},[71,14208,3074],{},[679,14210,14211],{"className":1942,"code":3077,"language":1944,"meta":502,"style":502},[42,14212,14213,14217,14221,14237,14241,14253,14271,14275,14289,14301,14329,14345,14349,14357,14379,14385],{"__ignoreMap":502},[688,14214,14215],{"class":690,"line":691},[688,14216,1951],{"class":859},[688,14218,14219],{"class":690,"line":506},[688,14220,3088],{"class":859},[688,14222,14223,14225,14227,14229,14231,14233,14235],{"class":690,"line":535},[688,14224,1961],{"class":859},[688,14226,1964],{"class":776},[688,14228,1993],{"class":1967},[688,14230,1971],{"class":776},[688,14232,3101],{"class":1974},[688,14234,908],{"class":776},[688,14236,3106],{"class":859},[688,14238,14239],{"class":690,"line":609},[688,14240,2008],{"class":859},[688,14242,14243,14245,14247,14249,14251],{"class":690,"line":624},[688,14244,2014],{"class":2013},[688,14246,2017],{"class":2013},[688,14248,3119],{"class":783},[688,14250,2055],{"class":791},[688,14252,871],{"class":791},[688,14254,14255,14257,14259,14261,14263,14265,14267,14269],{"class":690,"line":856},[688,14256,2270],{"class":776},[688,14258,2106],{"class":776},[688,14260,2109],{"class":787},[688,14262,2072],{"class":791},[688,14264,2114],{"class":787},[688,14266,2072],{"class":791},[688,14268,2395],{"class":783},[688,14270,2398],{"class":797},[688,14272,14273],{"class":690,"line":863},[688,14274,2403],{"class":791},[688,14276,14277,14279,14281,14283,14285,14287],{"class":690,"line":874},[688,14278,3150],{"class":797},[688,14280,801],{"class":791},[688,14282,3155],{"class":791},[688,14284,3158],{"class":697},[688,14286,2312],{"class":791},[688,14288,838],{"class":791},[688,14290,14291,14293,14295,14297,14299],{"class":690,"line":890},[688,14292,3167],{"class":797},[688,14294,801],{"class":791},[688,14296,3172],{"class":2220},[688,14298,2129],{"class":791},[688,14300,3177],{"class":859},[688,14302,14303,14305,14307,14309,14311,14313,14315,14317,14319,14321,14323,14325,14327],{"class":690,"line":896},[688,14304,3182],{"class":797},[688,14306,801],{"class":791},[688,14308,2049],{"class":791},[688,14310,2172],{"class":783},[688,14312,3191],{"class":797},[688,14314,3194],{"class":2220},[688,14316,2129],{"class":791},[688,14318,3199],{"class":2220},[688,14320,2129],{"class":791},[688,14322,3204],{"class":2220},[688,14324,3207],{"class":797},[688,14326,2129],{"class":791},[688,14328,3212],{"class":859},[688,14330,14331,14333,14335,14337,14339,14341,14343],{"class":690,"line":905},[688,14332,3217],{"class":797},[688,14334,801],{"class":791},[688,14336,3155],{"class":791},[688,14338,1748],{"class":697},[688,14340,2312],{"class":791},[688,14342,2129],{"class":791},[688,14344,3230],{"class":859},[688,14346,14347],{"class":690,"line":2096},[688,14348,2437],{"class":791},[688,14350,14351,14353,14355],{"class":690,"line":2138},[688,14352,3239],{"class":2442},[688,14354,2129],{"class":791},[688,14356,3244],{"class":859},[688,14358,14359,14361,14363,14365,14367,14369,14371,14373,14375,14377],{"class":690,"line":2143},[688,14360,2453],{"class":797},[688,14362,2312],{"class":791},[688,14364,2458],{"class":697},[688,14366,2312],{"class":791},[688,14368,2129],{"class":791},[688,14370,3155],{"class":791},[688,14372,2467],{"class":697},[688,14374,2312],{"class":791},[688,14376,2472],{"class":797},[688,14378,3267],{"class":859},[688,14380,14381,14383],{"class":690,"line":2149},[688,14382,2480],{"class":797},[688,14384,2058],{"class":791},[688,14386,14387],{"class":690,"line":2185},[688,14388,2280],{"class":791},[65,14390,14391],{"start":506},[68,14392,14393],{},[71,14394,3284],{},[679,14396,14397],{"className":1942,"code":3287,"language":1944,"meta":502,"style":502},[42,14398,14399,14403,14407,14411,14431,14447,14469,14473,14477,14495,14511,14517,14521,14527],{"__ignoreMap":502},[688,14400,14401],{"class":690,"line":691},[688,14402,1951],{"class":859},[688,14404,14405],{"class":690,"line":506},[688,14406,3298],{"class":859},[688,14408,14409],{"class":690,"line":535},[688,14410,2008],{"class":859},[688,14412,14413,14415,14417,14419,14421,14423,14425,14427,14429],{"class":690,"line":609},[688,14414,2014],{"class":2013},[688,14416,2017],{"class":2013},[688,14418,3311],{"class":783},[688,14420,788],{"class":791},[688,14422,2025],{"class":1980},[688,14424,2129],{"class":791},[688,14426,3320],{"class":1980},[688,14428,2028],{"class":791},[688,14430,871],{"class":791},[688,14432,14433,14435,14437,14439,14441,14443,14445],{"class":690,"line":624},[688,14434,2040],{"class":2013},[688,14436,2043],{"class":787},[688,14438,2046],{"class":791},[688,14440,2049],{"class":791},[688,14442,2052],{"class":783},[688,14444,2055],{"class":797},[688,14446,2058],{"class":791},[688,14448,14449,14451,14453,14455,14457,14459,14461,14463,14465,14467],{"class":690,"line":856},[688,14450,2040],{"class":2013},[688,14452,2065],{"class":787},[688,14454,2046],{"class":791},[688,14456,2043],{"class":787},[688,14458,2072],{"class":791},[688,14460,2075],{"class":783},[688,14462,788],{"class":797},[688,14464,2025],{"class":787},[688,14466,2028],{"class":797},[688,14468,2058],{"class":791},[688,14470,14471],{"class":690,"line":863},[688,14472,2088],{"emptyLinePlaceholder":1003},[688,14474,14475],{"class":690,"line":874},[688,14476,3371],{"class":859},[688,14478,14479,14481,14483,14485,14487,14489,14491,14493],{"class":690,"line":890},[688,14480,2270],{"class":776},[688,14482,2106],{"class":776},[688,14484,2109],{"class":787},[688,14486,2072],{"class":791},[688,14488,2114],{"class":787},[688,14490,2072],{"class":791},[688,14492,2458],{"class":783},[688,14494,2398],{"class":797},[688,14496,14497,14499,14501,14503,14505,14507,14509],{"class":690,"line":896},[688,14498,3394],{"class":791},[688,14500,3397],{"class":797},[688,14502,801],{"class":791},[688,14504,3155],{"class":791},[688,14506,3158],{"class":697},[688,14508,2312],{"class":791},[688,14510,3408],{"class":791},[688,14512,14513,14515],{"class":690,"line":905},[688,14514,3413],{"class":787},[688,14516,838],{"class":791},[688,14518,14519],{"class":690,"line":2096},[688,14520,3420],{"class":787},[688,14522,14523,14525],{"class":690,"line":2138},[688,14524,2480],{"class":797},[688,14526,2058],{"class":791},[688,14528,14529],{"class":690,"line":2143},[688,14530,2280],{"class":791},[65,14532,14533],{"start":535},[68,14534,14535],{},[71,14536,3437],{},[679,14538,14539],{"className":1942,"code":3440,"language":1944,"meta":502,"style":502},[42,14540,14541,14545,14549,14553,14573,14595,14611,14617,14621,14627,14631,14647,14665],{"__ignoreMap":502},[688,14542,14543],{"class":690,"line":691},[688,14544,1951],{"class":859},[688,14546,14547],{"class":690,"line":506},[688,14548,3451],{"class":859},[688,14550,14551],{"class":690,"line":535},[688,14552,2008],{"class":859},[688,14554,14555,14557,14559,14561,14563,14565,14567,14569,14571],{"class":690,"line":609},[688,14556,2014],{"class":2013},[688,14558,2017],{"class":2013},[688,14560,3464],{"class":783},[688,14562,788],{"class":791},[688,14564,2913],{"class":1980},[688,14566,2129],{"class":791},[688,14568,3473],{"class":1980},[688,14570,2028],{"class":791},[688,14572,871],{"class":791},[688,14574,14575,14577,14579,14581,14583,14585,14587,14589,14591,14593],{"class":690,"line":624},[688,14576,2040],{"class":2013},[688,14578,2937],{"class":787},[688,14580,2046],{"class":791},[688,14582,2106],{"class":776},[688,14584,2109],{"class":787},[688,14586,2072],{"class":791},[688,14588,2114],{"class":787},[688,14590,2072],{"class":791},[688,14592,2467],{"class":783},[688,14594,2398],{"class":797},[688,14596,14597,14599,14601,14603,14605,14607,14609],{"class":690,"line":856},[688,14598,3394],{"class":791},[688,14600,3397],{"class":797},[688,14602,801],{"class":791},[688,14604,3155],{"class":791},[688,14606,3158],{"class":697},[688,14608,2312],{"class":791},[688,14610,3408],{"class":791},[688,14612,14613,14615],{"class":690,"line":863},[688,14614,3520],{"class":787},[688,14616,838],{"class":791},[688,14618,14619],{"class":690,"line":874},[688,14620,2997],{"class":787},[688,14622,14623,14625],{"class":690,"line":890},[688,14624,2480],{"class":797},[688,14626,2058],{"class":791},[688,14628,14629],{"class":690,"line":896},[688,14630,2088],{"emptyLinePlaceholder":1003},[688,14632,14633,14635,14637,14639,14641,14643,14645],{"class":690,"line":905},[688,14634,2040],{"class":2013},[688,14636,3019],{"class":787},[688,14638,2046],{"class":791},[688,14640,2049],{"class":791},[688,14642,3026],{"class":783},[688,14644,2055],{"class":797},[688,14646,2058],{"class":791},[688,14648,14649,14651,14653,14655,14657,14659,14661,14663],{"class":690,"line":2096},[688,14650,2270],{"class":776},[688,14652,3019],{"class":787},[688,14654,2072],{"class":791},[688,14656,3041],{"class":783},[688,14658,788],{"class":797},[688,14660,3046],{"class":787},[688,14662,2028],{"class":797},[688,14664,2058],{"class":791},[688,14666,14667],{"class":690,"line":2138},[688,14668,2280],{"class":791},[123,14670,3578],{"id":3577},[13,14672,3581],{},[65,14674,14675],{},[68,14676,14677],{},[71,14678,3588],{},[679,14680,14681],{"className":1942,"code":3591,"language":1944,"meta":502,"style":502},[42,14682,14683,14687,14691,14695,14707,14725,14729,14743,14753,14779,14793,14797,14803,14825,14831],{"__ignoreMap":502},[688,14684,14685],{"class":690,"line":691},[688,14686,1951],{"class":859},[688,14688,14689],{"class":690,"line":506},[688,14690,3602],{"class":859},[688,14692,14693],{"class":690,"line":535},[688,14694,2008],{"class":859},[688,14696,14697,14699,14701,14703,14705],{"class":690,"line":609},[688,14698,2014],{"class":2013},[688,14700,2017],{"class":2013},[688,14702,3615],{"class":783},[688,14704,2055],{"class":791},[688,14706,871],{"class":791},[688,14708,14709,14711,14713,14715,14717,14719,14721,14723],{"class":690,"line":624},[688,14710,2270],{"class":776},[688,14712,2106],{"class":776},[688,14714,2109],{"class":787},[688,14716,2072],{"class":791},[688,14718,2114],{"class":787},[688,14720,2072],{"class":791},[688,14722,2395],{"class":783},[688,14724,2398],{"class":797},[688,14726,14727],{"class":690,"line":856},[688,14728,2403],{"class":791},[688,14730,14731,14733,14735,14737,14739,14741],{"class":690,"line":863},[688,14732,2408],{"class":797},[688,14734,801],{"class":791},[688,14736,3155],{"class":791},[688,14738,1675],{"class":697},[688,14740,2312],{"class":791},[688,14742,838],{"class":791},[688,14744,14745,14747,14749,14751],{"class":690,"line":874},[688,14746,3660],{"class":797},[688,14748,801],{"class":791},[688,14750,3172],{"class":2220},[688,14752,838],{"class":791},[688,14754,14755,14757,14759,14761,14763,14765,14767,14769,14771,14773,14775,14777],{"class":690,"line":890},[688,14756,3671],{"class":797},[688,14758,801],{"class":791},[688,14760,2049],{"class":791},[688,14762,2172],{"class":783},[688,14764,3191],{"class":797},[688,14766,3194],{"class":2220},[688,14768,2129],{"class":791},[688,14770,3199],{"class":2220},[688,14772,2129],{"class":791},[688,14774,3204],{"class":2220},[688,14776,3207],{"class":797},[688,14778,838],{"class":791},[688,14780,14781,14783,14785,14787,14789,14791],{"class":690,"line":896},[688,14782,3698],{"class":797},[688,14784,801],{"class":791},[688,14786,3155],{"class":791},[688,14788,1748],{"class":697},[688,14790,2312],{"class":791},[688,14792,838],{"class":791},[688,14794,14795],{"class":690,"line":905},[688,14796,2437],{"class":791},[688,14798,14799,14801],{"class":690,"line":2096},[688,14800,3239],{"class":2442},[688,14802,838],{"class":791},[688,14804,14805,14807,14809,14811,14813,14815,14817,14819,14821,14823],{"class":690,"line":2138},[688,14806,2453],{"class":797},[688,14808,2312],{"class":791},[688,14810,3727],{"class":697},[688,14812,2312],{"class":791},[688,14814,2129],{"class":791},[688,14816,3155],{"class":791},[688,14818,3736],{"class":697},[688,14820,2312],{"class":791},[688,14822,2472],{"class":797},[688,14824,3743],{"class":859},[688,14826,14827,14829],{"class":690,"line":2143},[688,14828,2480],{"class":797},[688,14830,2058],{"class":791},[688,14832,14833],{"class":690,"line":2149},[688,14834,2280],{"class":791},[65,14836,14837],{"start":506},[68,14838,14839],{},[71,14840,3760],{},[679,14842,14843],{"className":1942,"code":3763,"language":1944,"meta":502,"style":502},[42,14844,14845,14849,14853,14857,14873,14877,14897,14913,14935,14939,14957,14973,14979,14983,14989],{"__ignoreMap":502},[688,14846,14847],{"class":690,"line":691},[688,14848,2088],{"emptyLinePlaceholder":1003},[688,14850,14851],{"class":690,"line":506},[688,14852,1951],{"class":859},[688,14854,14855],{"class":690,"line":535},[688,14856,3778],{"class":859},[688,14858,14859,14861,14863,14865,14867,14869,14871],{"class":690,"line":609},[688,14860,1961],{"class":859},[688,14862,1964],{"class":776},[688,14864,1993],{"class":1967},[688,14866,1971],{"class":776},[688,14868,1482],{"class":1974},[688,14870,908],{"class":776},[688,14872,3795],{"class":859},[688,14874,14875],{"class":690,"line":624},[688,14876,2008],{"class":859},[688,14878,14879,14881,14883,14885,14887,14889,14891,14893,14895],{"class":690,"line":856},[688,14880,2014],{"class":2013},[688,14882,2017],{"class":2013},[688,14884,3808],{"class":783},[688,14886,788],{"class":791},[688,14888,2025],{"class":1980},[688,14890,2129],{"class":791},[688,14892,3473],{"class":1980},[688,14894,2028],{"class":791},[688,14896,871],{"class":791},[688,14898,14899,14901,14903,14905,14907,14909,14911],{"class":690,"line":863},[688,14900,2040],{"class":2013},[688,14902,2043],{"class":787},[688,14904,2046],{"class":791},[688,14906,2049],{"class":791},[688,14908,2052],{"class":783},[688,14910,2055],{"class":797},[688,14912,2058],{"class":791},[688,14914,14915,14917,14919,14921,14923,14925,14927,14929,14931,14933],{"class":690,"line":874},[688,14916,2040],{"class":2013},[688,14918,2065],{"class":787},[688,14920,2046],{"class":791},[688,14922,2043],{"class":787},[688,14924,2072],{"class":791},[688,14926,2075],{"class":783},[688,14928,788],{"class":797},[688,14930,2025],{"class":787},[688,14932,2028],{"class":797},[688,14934,2058],{"class":791},[688,14936,14937],{"class":690,"line":890},[688,14938,2088],{"emptyLinePlaceholder":1003},[688,14940,14941,14943,14945,14947,14949,14951,14953,14955],{"class":690,"line":896},[688,14942,2270],{"class":776},[688,14944,2106],{"class":776},[688,14946,2109],{"class":787},[688,14948,2072],{"class":791},[688,14950,2114],{"class":787},[688,14952,2072],{"class":791},[688,14954,3727],{"class":783},[688,14956,2398],{"class":797},[688,14958,14959,14961,14963,14965,14967,14969,14971],{"class":690,"line":905},[688,14960,3394],{"class":791},[688,14962,3397],{"class":797},[688,14964,801],{"class":791},[688,14966,3155],{"class":791},[688,14968,1675],{"class":697},[688,14970,2312],{"class":791},[688,14972,3408],{"class":791},[688,14974,14975,14977],{"class":690,"line":2096},[688,14976,3520],{"class":787},[688,14978,838],{"class":791},[688,14980,14981],{"class":690,"line":2138},[688,14982,3420],{"class":787},[688,14984,14985,14987],{"class":690,"line":2143},[688,14986,2480],{"class":797},[688,14988,2058],{"class":791},[688,14990,14991],{"class":690,"line":2149},[688,14992,2280],{"class":791},[65,14994,14995],{"start":535},[68,14996,14997],{},[71,14998,3923],{},[679,15000,15001],{"className":1942,"code":3926,"language":1944,"meta":502,"style":502},[42,15002,15003,15007,15011,15015,15031,15035,15059,15075,15097,15101,15119,15135,15141,15149,15155,15161],{"__ignoreMap":502},[688,15004,15005],{"class":690,"line":691},[688,15006,2088],{"emptyLinePlaceholder":1003},[688,15008,15009],{"class":690,"line":506},[688,15010,1951],{"class":859},[688,15012,15013],{"class":690,"line":535},[688,15014,3941],{"class":859},[688,15016,15017,15019,15021,15023,15025,15027,15029],{"class":690,"line":609},[688,15018,1961],{"class":859},[688,15020,1964],{"class":776},[688,15022,1993],{"class":1967},[688,15024,1971],{"class":776},[688,15026,3954],{"class":1974},[688,15028,908],{"class":776},[688,15030,3959],{"class":859},[688,15032,15033],{"class":690,"line":624},[688,15034,2008],{"class":859},[688,15036,15037,15039,15041,15043,15045,15047,15049,15051,15053,15055,15057],{"class":690,"line":856},[688,15038,2014],{"class":2013},[688,15040,2017],{"class":2013},[688,15042,3972],{"class":783},[688,15044,788],{"class":791},[688,15046,2025],{"class":1980},[688,15048,2129],{"class":791},[688,15050,3981],{"class":1980},[688,15052,2129],{"class":791},[688,15054,3320],{"class":1980},[688,15056,2028],{"class":791},[688,15058,871],{"class":791},[688,15060,15061,15063,15065,15067,15069,15071,15073],{"class":690,"line":863},[688,15062,2040],{"class":2013},[688,15064,2043],{"class":787},[688,15066,2046],{"class":791},[688,15068,2049],{"class":791},[688,15070,2052],{"class":783},[688,15072,2055],{"class":797},[688,15074,2058],{"class":791},[688,15076,15077,15079,15081,15083,15085,15087,15089,15091,15093,15095],{"class":690,"line":874},[688,15078,2040],{"class":2013},[688,15080,2065],{"class":787},[688,15082,2046],{"class":791},[688,15084,2043],{"class":787},[688,15086,2072],{"class":791},[688,15088,2075],{"class":783},[688,15090,788],{"class":797},[688,15092,2025],{"class":787},[688,15094,2028],{"class":797},[688,15096,2058],{"class":791},[688,15098,15099],{"class":690,"line":890},[688,15100,2088],{"emptyLinePlaceholder":1003},[688,15102,15103,15105,15107,15109,15111,15113,15115,15117],{"class":690,"line":896},[688,15104,2270],{"class":776},[688,15106,2106],{"class":776},[688,15108,2109],{"class":787},[688,15110,2072],{"class":791},[688,15112,2114],{"class":787},[688,15114,2072],{"class":791},[688,15116,3736],{"class":783},[688,15118,2398],{"class":797},[688,15120,15121,15123,15125,15127,15129,15131,15133],{"class":690,"line":905},[688,15122,3394],{"class":791},[688,15124,3397],{"class":797},[688,15126,801],{"class":791},[688,15128,3155],{"class":791},[688,15130,1675],{"class":697},[688,15132,2312],{"class":791},[688,15134,3408],{"class":791},[688,15136,15137,15139],{"class":690,"line":2096},[688,15138,3413],{"class":787},[688,15140,838],{"class":791},[688,15142,15143,15145,15147],{"class":690,"line":2138},[688,15144,4076],{"class":787},[688,15146,2129],{"class":791},[688,15148,4081],{"class":859},[688,15150,15151,15153],{"class":690,"line":2143},[688,15152,4086],{"class":787},[688,15154,4089],{"class":859},[688,15156,15157,15159],{"class":690,"line":2149},[688,15158,2480],{"class":797},[688,15160,2058],{"class":791},[688,15162,15163],{"class":690,"line":2185},[688,15164,2280],{"class":791},[123,15166,4103],{"id":4102},[13,15168,4106],{},[13,15170,4109],{},[65,15172,15173],{},[68,15174,15175],{},[71,15176,4116],{},[679,15178,15179],{"className":1942,"code":4119,"language":1944,"meta":502,"style":502},[42,15180,15181,15185,15189,15207,15223,15227,15243,15275],{"__ignoreMap":502},[688,15182,15183],{"class":690,"line":691},[688,15184,1951],{"class":859},[688,15186,15187],{"class":690,"line":506},[688,15188,4130],{"class":859},[688,15190,15191,15193,15195,15197,15199,15201,15203,15205],{"class":690,"line":535},[688,15192,1961],{"class":859},[688,15194,1964],{"class":776},[688,15196,1968],{"class":1967},[688,15198,1971],{"class":776},[688,15200,1488],{"class":1974},[688,15202,908],{"class":776},[688,15204,2544],{"class":1980},[688,15206,4149],{"class":859},[688,15208,15209,15211,15213,15215,15217,15219,15221],{"class":690,"line":609},[688,15210,1961],{"class":859},[688,15212,1964],{"class":776},[688,15214,1993],{"class":1967},[688,15216,1971],{"class":776},[688,15218,4162],{"class":1974},[688,15220,908],{"class":776},[688,15222,4167],{"class":859},[688,15224,15225],{"class":690,"line":624},[688,15226,2008],{"class":859},[688,15228,15229,15231,15233,15235,15237,15239,15241],{"class":690,"line":856},[688,15230,2014],{"class":2013},[688,15232,2017],{"class":2013},[688,15234,4180],{"class":783},[688,15236,788],{"class":791},[688,15238,467],{"class":1980},[688,15240,2028],{"class":791},[688,15242,871],{"class":791},[688,15244,15245,15247,15249,15251,15253,15255,15257,15259,15261,15263,15265,15267,15269,15271,15273],{"class":690,"line":863},[688,15246,2270],{"class":776},[688,15248,2106],{"class":776},[688,15250,2109],{"class":787},[688,15252,2072],{"class":791},[688,15254,2114],{"class":787},[688,15256,2072],{"class":791},[688,15258,4205],{"class":783},[688,15260,788],{"class":797},[688,15262,2312],{"class":791},[688,15264,4212],{"class":697},[688,15266,2312],{"class":791},[688,15268,2129],{"class":791},[688,15270,2544],{"class":787},[688,15272,2028],{"class":797},[688,15274,2058],{"class":791},[688,15276,15277],{"class":690,"line":874},[688,15278,2280],{"class":791},[65,15280,15281],{"start":506},[68,15282,15283],{},[71,15284,4233],{},[679,15286,15287],{"className":1942,"code":4236,"language":1944,"meta":502,"style":502},[42,15288,15289,15293,15297,15315,15329,15333,15349,15367,15377,15383,15401,15409,15431,15437],{"__ignoreMap":502},[688,15290,15291],{"class":690,"line":691},[688,15292,1951],{"class":859},[688,15294,15295],{"class":690,"line":506},[688,15296,4247],{"class":859},[688,15298,15299,15301,15303,15305,15307,15309,15311,15313],{"class":690,"line":535},[688,15300,1961],{"class":859},[688,15302,1964],{"class":776},[688,15304,1968],{"class":1967},[688,15306,1971],{"class":776},[688,15308,4260],{"class":1974},[688,15310,908],{"class":776},[688,15312,4265],{"class":1980},[688,15314,4149],{"class":859},[688,15316,15317,15319,15321,15323,15325,15327],{"class":690,"line":609},[688,15318,1961],{"class":859},[688,15320,1964],{"class":776},[688,15322,1993],{"class":1967},[688,15324,1971],{"class":776},[688,15326,2356],{"class":1974},[688,15328,2280],{"class":776},[688,15330,15331],{"class":690,"line":624},[688,15332,2008],{"class":859},[688,15334,15335,15337,15339,15341,15343,15345,15347],{"class":690,"line":856},[688,15336,2014],{"class":2013},[688,15338,2017],{"class":2013},[688,15340,4294],{"class":783},[688,15342,788],{"class":791},[688,15344,4299],{"class":1980},[688,15346,2028],{"class":791},[688,15348,871],{"class":791},[688,15350,15351,15353,15355,15357,15359,15361,15363,15365],{"class":690,"line":863},[688,15352,2270],{"class":776},[688,15354,2106],{"class":776},[688,15356,2109],{"class":787},[688,15358,2072],{"class":791},[688,15360,2114],{"class":787},[688,15362,2072],{"class":791},[688,15364,4320],{"class":783},[688,15366,2398],{"class":797},[688,15368,15369,15371,15373,15375],{"class":690,"line":874},[688,15370,4327],{"class":791},[688,15372,4212],{"class":697},[688,15374,2312],{"class":791},[688,15376,838],{"class":791},[688,15378,15379,15381],{"class":690,"line":890},[688,15380,4338],{"class":787},[688,15382,838],{"class":791},[688,15384,15385,15387,15389,15391,15393,15395,15397,15399],{"class":690,"line":896},[688,15386,3394],{"class":791},[688,15388,3397],{"class":797},[688,15390,801],{"class":791},[688,15392,3155],{"class":791},[688,15394,2415],{"class":697},[688,15396,2312],{"class":791},[688,15398,4357],{"class":791},[688,15400,4360],{"class":859},[688,15402,15403,15405,15407],{"class":690,"line":905},[688,15404,3239],{"class":2442},[688,15406,2129],{"class":791},[688,15408,4369],{"class":859},[688,15410,15411,15413,15415,15417,15419,15421,15423,15425,15427,15429],{"class":690,"line":2096},[688,15412,2453],{"class":797},[688,15414,2312],{"class":791},[688,15416,2458],{"class":697},[688,15418,2312],{"class":791},[688,15420,2129],{"class":791},[688,15422,3155],{"class":791},[688,15424,2467],{"class":697},[688,15426,2312],{"class":791},[688,15428,2472],{"class":797},[688,15430,4392],{"class":859},[688,15432,15433,15435],{"class":690,"line":2138},[688,15434,2480],{"class":797},[688,15436,2058],{"class":791},[688,15438,15439],{"class":690,"line":2143},[688,15440,2280],{"class":791},[17,15442,4406],{"id":4405},[65,15444,15445],{},[68,15446,15447],{},[71,15448,4413],{},[128,15450,15451,15455],{},[68,15452,15453,4421],{},[71,15454,4420],{},[68,15456,15457,15459],{},[71,15458,4426],{},[128,15460,15461,15463,15465,15467],{},[68,15462,4431],{},[68,15464,4434],{},[68,15466,4437],{},[68,15468,4440],{},[65,15470,15471],{"start":506},[68,15472,15473],{},[71,15474,4447],{},[128,15476,15477,15489],{},[68,15478,15479,15481],{},[71,15480,4454],{},[128,15482,15483,15485,15487],{},[68,15484,4459],{},[68,15486,4462],{},[68,15488,4465],{},[68,15490,15491,15493],{},[71,15492,4470],{},[128,15494,15495,15497,15499],{},[68,15496,4475],{},[68,15498,4478],{},[68,15500,4481],{},[65,15502,15503],{"start":535},[68,15504,15505],{},[71,15506,4488],{},[128,15508,15509,15511,15513],{},[68,15510,4493],{},[68,15512,4496],{},[68,15514,4499],{},[17,15516,4503],{"id":4502},[65,15518,15519],{},[68,15520,15521],{},[71,15522,4510],{},[13,15524,4513],{},[679,15526,15527],{"className":1942,"code":4516,"language":1944,"meta":502,"style":502},[42,15528,15529,15533,15553,15557,15561,15587],{"__ignoreMap":502},[688,15530,15531],{"class":690,"line":691},[688,15532,4523],{"class":859},[688,15534,15535,15537,15539,15541,15543,15545,15547,15549,15551],{"class":690,"line":506},[688,15536,2297],{"class":2013},[688,15538,1971],{"class":791},[688,15540,4532],{"class":787},[688,15542,908],{"class":791},[688,15544,2046],{"class":791},[688,15546,4539],{"class":787},[688,15548,2072],{"class":791},[688,15550,4544],{"class":787},[688,15552,2058],{"class":791},[688,15554,15555],{"class":690,"line":535},[688,15556,2088],{"emptyLinePlaceholder":1003},[688,15558,15559],{"class":690,"line":609},[688,15560,4555],{"class":859},[688,15562,15563,15565,15567,15569,15571,15573,15575,15577,15579,15581,15583,15585],{"class":690,"line":624},[688,15564,2297],{"class":2013},[688,15566,1971],{"class":791},[688,15568,4564],{"class":787},[688,15570,908],{"class":791},[688,15572,2046],{"class":791},[688,15574,4571],{"class":783},[688,15576,788],{"class":787},[688,15578,807],{"class":791},[688,15580,4578],{"class":697},[688,15582,807],{"class":791},[688,15584,2028],{"class":787},[688,15586,2058],{"class":791},[688,15588,15589,15591,15593,15595,15597,15599,15601],{"class":690,"line":856},[688,15590,2297],{"class":2013},[688,15592,1971],{"class":791},[688,15594,4532],{"class":787},[688,15596,908],{"class":791},[688,15598,2046],{"class":791},[688,15600,4599],{"class":787},[688,15602,2058],{"class":791},[13,15604,4604],{},[260,15606,15607,15617],{},[263,15608,15609],{},[266,15610,15611,15613,15615],{},[269,15612,4613],{},[269,15614,4616],{},[269,15616,4619],{},[278,15618,15619,15627,15635,15643,15651],{},[266,15620,15621,15623,15625],{},[283,15622,4626],{},[283,15624,4629],{},[283,15626,4632],{},[266,15628,15629,15631,15633],{},[283,15630,4637],{},[283,15632,4640],{},[283,15634,4643],{},[266,15636,15637,15639,15641],{},[283,15638,4648],{},[283,15640,4651],{},[283,15642,4654],{},[266,15644,15645,15647,15649],{},[283,15646,4659],{},[283,15648,4662],{},[283,15650,4665],{},[266,15652,15653,15655,15657],{},[283,15654,4670],{},[283,15656,4673],{},[283,15658,4676],{},[13,15660,15661,4682],{},[71,15662,4681],{},[13,15664,15665,4688],{},[71,15666,4687],{},[65,15668,15669],{"start":506},[68,15670,15671],{},[71,15672,4695],{},[13,15674,4698],{},[128,15676,15677,15679,15681],{},[68,15678,4703],{},[68,15680,4706],{},[68,15682,4709],{},[17,15684,4713],{"id":4712},[13,15686,4716],{},[13,15688,4719],{},[679,15690,15691],{"className":766,"code":4722,"filename":4723,"language":769,"meta":502,"style":502},[42,15692,15693,15697,15701,15705,15709,15713,15717,15731,15743,15761,15765,15783,15787,15791,15795,15799,15803,15827,15845,15879,15891,15895,15899,15903,15907,15911,15915,15939,15955,15995,16005,16009,16013,16017,16021,16025,16051,16065,16089,16097,16117,16121,16125,16129,16133,16137,16149,16153,16187,16217,16229,16233,16237,16241,16245,16257,16261,16295,16311,16373,16377,16381,16385,16389,16401,16413,16423,16427,16469,16483,16513,16517,16553,16557,16609,16613,16643,16661,16691,16707,16711,16715,16719,16723,16735,16747,16751,16793,16809,16827,16831,16865,16869,16899,16903,16959,16973,16989],{"__ignoreMap":502},[688,15694,15695],{"class":690,"line":691},[688,15696,1951],{"class":859},[688,15698,15699],{"class":690,"line":506},[688,15700,4734],{"class":859},[688,15702,15703],{"class":690,"line":535},[688,15704,4739],{"class":859},[688,15706,15707],{"class":690,"line":609},[688,15708,2008],{"class":859},[688,15710,15711],{"class":690,"line":624},[688,15712,2088],{"emptyLinePlaceholder":1003},[688,15714,15715],{"class":690,"line":856},[688,15716,4752],{"class":859},[688,15718,15719,15721,15723,15725,15727,15729],{"class":690,"line":863},[688,15720,2297],{"class":2013},[688,15722,4759],{"class":787},[688,15724,2303],{"class":791},[688,15726,4539],{"class":787},[688,15728,2072],{"class":791},[688,15730,4768],{"class":787},[688,15732,15733,15735,15737,15739,15741],{"class":690,"line":874},[688,15734,4773],{"class":776},[688,15736,4776],{"class":787},[688,15738,4779],{"class":791},[688,15740,4782],{"class":787},[688,15742,792],{"class":791},[688,15744,15745,15747,15749,15751,15753,15755,15757,15759],{"class":690,"line":890},[688,15746,4789],{"class":776},[688,15748,2049],{"class":791},[688,15750,4794],{"class":783},[688,15752,788],{"class":797},[688,15754,807],{"class":791},[688,15756,4801],{"class":697},[688,15758,807],{"class":791},[688,15760,911],{"class":797},[688,15762,15763],{"class":690,"line":896},[688,15764,2280],{"class":791},[688,15766,15767,15769,15771,15773,15775,15777,15779,15781],{"class":690,"line":905},[688,15768,2297],{"class":2013},[688,15770,4816],{"class":787},[688,15772,801],{"class":791},[688,15774,4821],{"class":694},[688,15776,2046],{"class":791},[688,15778,4826],{"class":787},[688,15780,2072],{"class":791},[688,15782,4831],{"class":787},[688,15784,15785],{"class":690,"line":2096},[688,15786,2088],{"emptyLinePlaceholder":1003},[688,15788,15789],{"class":690,"line":2138},[688,15790,1951],{"class":859},[688,15792,15793],{"class":690,"line":2143},[688,15794,4844],{"class":859},[688,15796,15797],{"class":690,"line":2149},[688,15798,4849],{"class":859},[688,15800,15801],{"class":690,"line":2185},[688,15802,2008],{"class":859},[688,15804,15805,15807,15809,15811,15813,15815,15817,15819,15821,15823,15825],{"class":690,"line":2261},[688,15806,2297],{"class":2013},[688,15808,4860],{"class":787},[688,15810,2303],{"class":791},[688,15812,4776],{"class":791},[688,15814,4867],{"class":1980},[688,15816,801],{"class":791},[688,15818,4872],{"class":694},[688,15820,4875],{"class":791},[688,15822,4878],{"class":694},[688,15824,2207],{"class":2013},[688,15826,871],{"class":791},[688,15828,15829,15831,15833,15835,15837,15839,15841,15843],{"class":690,"line":2267},[688,15830,2040],{"class":2013},[688,15832,4889],{"class":787},[688,15834,2046],{"class":791},[688,15836,2049],{"class":791},[688,15838,2172],{"class":783},[688,15840,788],{"class":797},[688,15842,4867],{"class":787},[688,15844,911],{"class":797},[688,15846,15847,15849,15851,15853,15855,15857,15859,15861,15863,15865,15867,15869,15871,15873,15875,15877],{"class":690,"line":2277},[688,15848,2040],{"class":2013},[688,15850,4908],{"class":787},[688,15852,2046],{"class":791},[688,15854,4913],{"class":787},[688,15856,2072],{"class":791},[688,15858,4918],{"class":787},[688,15860,2072],{"class":791},[688,15862,4923],{"class":783},[688,15864,788],{"class":797},[688,15866,4928],{"class":791},[688,15868,4889],{"class":787},[688,15870,4933],{"class":776},[688,15872,4936],{"class":694},[688,15874,4933],{"class":776},[688,15876,4941],{"class":694},[688,15878,4944],{"class":797},[688,15880,15881,15883,15885,15887,15889],{"class":690,"line":2283},[688,15882,2270],{"class":776},[688,15884,4951],{"class":783},[688,15886,788],{"class":797},[688,15888,4956],{"class":787},[688,15890,911],{"class":797},[688,15892,15893],{"class":690,"line":2288},[688,15894,2280],{"class":791},[688,15896,15897],{"class":690,"line":2294},[688,15898,2088],{"emptyLinePlaceholder":1003},[688,15900,15901],{"class":690,"line":2761},[688,15902,1951],{"class":859},[688,15904,15905],{"class":690,"line":2768},[688,15906,4975],{"class":859},[688,15908,15909],{"class":690,"line":2773},[688,15910,4980],{"class":859},[688,15912,15913],{"class":690,"line":2779},[688,15914,2008],{"class":859},[688,15916,15917,15919,15921,15923,15925,15927,15929,15931,15933,15935,15937],{"class":690,"line":2795},[688,15918,2297],{"class":2013},[688,15920,4991],{"class":787},[688,15922,2303],{"class":791},[688,15924,4776],{"class":791},[688,15926,4998],{"class":1980},[688,15928,801],{"class":791},[688,15930,4878],{"class":694},[688,15932,4875],{"class":791},[688,15934,4872],{"class":694},[688,15936,2207],{"class":2013},[688,15938,871],{"class":791},[688,15940,15941,15943,15945,15947,15949,15951,15953],{"class":690,"line":5013},[688,15942,2040],{"class":2013},[688,15944,5018],{"class":787},[688,15946,2046],{"class":791},[688,15948,5023],{"class":783},[688,15950,788],{"class":797},[688,15952,4998],{"class":787},[688,15954,911],{"class":797},[688,15956,15957,15959,15961,15963,15965,15967,15969,15971,15973,15975,15977,15979,15981,15983,15985,15987,15989,15991,15993],{"class":690,"line":5032},[688,15958,2040],{"class":2013},[688,15960,4889],{"class":787},[688,15962,2046],{"class":791},[688,15964,2172],{"class":787},[688,15966,2072],{"class":791},[688,15968,2164],{"class":783},[688,15970,788],{"class":797},[688,15972,5049],{"class":787},[688,15974,2129],{"class":791},[688,15976,4776],{"class":791},[688,15978,5056],{"class":1980},[688,15980,2028],{"class":791},[688,15982,2207],{"class":2013},[688,15984,5063],{"class":787},[688,15986,2072],{"class":791},[688,15988,5068],{"class":783},[688,15990,788],{"class":797},[688,15992,2240],{"class":2220},[688,15994,5075],{"class":797},[688,15996,15997,15999,16001,16003],{"class":690,"line":5078},[688,15998,2270],{"class":776},[688,16000,4889],{"class":787},[688,16002,2072],{"class":791},[688,16004,5087],{"class":787},[688,16006,16007],{"class":690,"line":5090},[688,16008,2280],{"class":791},[688,16010,16011],{"class":690,"line":5095},[688,16012,2088],{"emptyLinePlaceholder":1003},[688,16014,16015],{"class":690,"line":5100},[688,16016,1951],{"class":859},[688,16018,16019],{"class":690,"line":5105},[688,16020,5108],{"class":859},[688,16022,16023],{"class":690,"line":5111},[688,16024,2008],{"class":859},[688,16026,16027,16029,16031,16033,16035,16037,16039,16041,16043,16045,16047,16049],{"class":690,"line":5116},[688,16028,777],{"class":776},[688,16030,5121],{"class":2013},[688,16032,5124],{"class":787},[688,16034,2303],{"class":791},[688,16036,5129],{"class":2013},[688,16038,5132],{"class":791},[688,16040,5135],{"class":694},[688,16042,935],{"class":791},[688,16044,1488],{"class":694},[688,16046,5142],{"class":791},[688,16048,2207],{"class":2013},[688,16050,871],{"class":791},[688,16052,16053,16055,16057,16059,16061,16063],{"class":690,"line":5149},[688,16054,2270],{"class":776},[688,16056,2106],{"class":776},[688,16058,4816],{"class":787},[688,16060,2072],{"class":791},[688,16062,2395],{"class":783},[688,16064,2398],{"class":797},[688,16066,16067,16069,16071,16073,16075,16077,16079,16081,16083,16085,16087],{"class":690,"line":5164},[688,16068,3394],{"class":791},[688,16070,3397],{"class":797},[688,16072,801],{"class":791},[688,16074,831],{"class":791},[688,16076,2415],{"class":697},[688,16078,807],{"class":791},[688,16080,2129],{"class":791},[688,16082,5181],{"class":797},[688,16084,801],{"class":791},[688,16086,2429],{"class":2220},[688,16088,3408],{"class":791},[688,16090,16091,16093,16095],{"class":690,"line":5190},[688,16092,3239],{"class":2442},[688,16094,2129],{"class":791},[688,16096,5197],{"class":859},[688,16098,16099,16101,16103,16105,16107,16109,16111,16113,16115],{"class":690,"line":5200},[688,16100,2453],{"class":797},[688,16102,807],{"class":791},[688,16104,2458],{"class":697},[688,16106,807],{"class":791},[688,16108,2129],{"class":791},[688,16110,831],{"class":791},[688,16112,2467],{"class":697},[688,16114,807],{"class":791},[688,16116,814],{"class":797},[688,16118,16119],{"class":690,"line":5221},[688,16120,5224],{"class":797},[688,16122,16123],{"class":690,"line":5227},[688,16124,2280],{"class":791},[688,16126,16127],{"class":690,"line":5232},[688,16128,2088],{"emptyLinePlaceholder":1003},[688,16130,16131],{"class":690,"line":5237},[688,16132,1951],{"class":859},[688,16134,16135],{"class":690,"line":5242},[688,16136,5245],{"class":859},[688,16138,16139,16141,16143,16145,16147],{"class":690,"line":5248},[688,16140,1961],{"class":859},[688,16142,1964],{"class":776},[688,16144,1968],{"class":1967},[688,16146,5257],{"class":1980},[688,16148,5260],{"class":859},[688,16150,16151],{"class":690,"line":5263},[688,16152,2008],{"class":859},[688,16154,16155,16157,16159,16161,16163,16165,16167,16169,16171,16173,16175,16177,16179,16181,16183,16185],{"class":690,"line":5268},[688,16156,777],{"class":776},[688,16158,5121],{"class":2013},[688,16160,5275],{"class":787},[688,16162,2303],{"class":791},[688,16164,5129],{"class":2013},[688,16166,4776],{"class":791},[688,16168,5284],{"class":1980},[688,16170,801],{"class":791},[688,16172,5289],{"class":694},[688,16174,4875],{"class":791},[688,16176,5135],{"class":694},[688,16178,935],{"class":791},[688,16180,1975],{"class":694},[688,16182,5142],{"class":791},[688,16184,2207],{"class":2013},[688,16186,871],{"class":791},[688,16188,16189,16191,16193,16195,16197,16199,16201,16203,16205,16207,16209,16211,16213,16215],{"class":690,"line":5306},[688,16190,2040],{"class":2013},[688,16192,5311],{"class":787},[688,16194,2046],{"class":791},[688,16196,2106],{"class":776},[688,16198,4816],{"class":787},[688,16200,2072],{"class":791},[688,16202,4205],{"class":783},[688,16204,788],{"class":797},[688,16206,807],{"class":791},[688,16208,5328],{"class":697},[688,16210,807],{"class":791},[688,16212,2129],{"class":791},[688,16214,5257],{"class":787},[688,16216,911],{"class":797},[688,16218,16219,16221,16223,16225,16227],{"class":690,"line":5339},[688,16220,2270],{"class":776},[688,16222,5344],{"class":783},[688,16224,788],{"class":797},[688,16226,5349],{"class":787},[688,16228,911],{"class":797},[688,16230,16231],{"class":690,"line":5354},[688,16232,2280],{"class":791},[688,16234,16235],{"class":690,"line":5359},[688,16236,2088],{"emptyLinePlaceholder":1003},[688,16238,16239],{"class":690,"line":5364},[688,16240,1951],{"class":859},[688,16242,16243],{"class":690,"line":5369},[688,16244,5372],{"class":859},[688,16246,16247,16249,16251,16253,16255],{"class":690,"line":5375},[688,16248,1961],{"class":859},[688,16250,1964],{"class":776},[688,16252,1968],{"class":1967},[688,16254,5384],{"class":1980},[688,16256,5387],{"class":859},[688,16258,16259],{"class":690,"line":5390},[688,16260,2008],{"class":859},[688,16262,16263,16265,16267,16269,16271,16273,16275,16277,16279,16281,16283,16285,16287,16289,16291,16293],{"class":690,"line":5395},[688,16264,777],{"class":776},[688,16266,5121],{"class":2013},[688,16268,5402],{"class":787},[688,16270,2303],{"class":791},[688,16272,5129],{"class":2013},[688,16274,4776],{"class":791},[688,16276,5411],{"class":1980},[688,16278,801],{"class":791},[688,16280,4878],{"class":694},[688,16282,4875],{"class":791},[688,16284,5135],{"class":694},[688,16286,935],{"class":791},[688,16288,1488],{"class":694},[688,16290,5142],{"class":791},[688,16292,2207],{"class":2013},[688,16294,871],{"class":791},[688,16296,16297,16299,16301,16303,16305,16307,16309],{"class":690,"line":5432},[688,16298,2040],{"class":2013},[688,16300,5437],{"class":787},[688,16302,2046],{"class":791},[688,16304,5442],{"class":783},[688,16306,788],{"class":797},[688,16308,5411],{"class":787},[688,16310,911],{"class":797},[688,16312,16313,16315,16317,16319,16321,16323,16325,16327,16329,16331,16333,16335,16337,16339,16341,16343,16345,16347,16349,16351,16353,16355,16357,16359,16361,16363,16365,16367,16369,16371],{"class":690,"line":5451},[688,16314,2270],{"class":776},[688,16316,2106],{"class":776},[688,16318,4816],{"class":787},[688,16320,2072],{"class":791},[688,16322,4320],{"class":783},[688,16324,788],{"class":797},[688,16326,807],{"class":791},[688,16328,5328],{"class":697},[688,16330,807],{"class":791},[688,16332,2129],{"class":791},[688,16334,5437],{"class":787},[688,16336,2129],{"class":791},[688,16338,1971],{"class":791},[688,16340,3397],{"class":797},[688,16342,801],{"class":791},[688,16344,831],{"class":791},[688,16346,2415],{"class":697},[688,16348,807],{"class":791},[688,16350,4357],{"class":791},[688,16352,5492],{"class":2442},[688,16354,2129],{"class":791},[688,16356,5497],{"class":797},[688,16358,807],{"class":791},[688,16360,2458],{"class":697},[688,16362,807],{"class":791},[688,16364,2129],{"class":791},[688,16366,831],{"class":791},[688,16368,2467],{"class":697},[688,16370,807],{"class":791},[688,16372,5514],{"class":797},[688,16374,16375],{"class":690,"line":5517},[688,16376,2280],{"class":791},[688,16378,16379],{"class":690,"line":5522},[688,16380,2088],{"emptyLinePlaceholder":1003},[688,16382,16383],{"class":690,"line":5527},[688,16384,1951],{"class":859},[688,16386,16387],{"class":690,"line":5532},[688,16388,5535],{"class":859},[688,16390,16391,16393,16395,16397,16399],{"class":690,"line":5538},[688,16392,1961],{"class":859},[688,16394,1964],{"class":776},[688,16396,1968],{"class":1967},[688,16398,1981],{"class":1980},[688,16400,5549],{"class":859},[688,16402,16403,16405,16407,16409,16411],{"class":690,"line":5552},[688,16404,1961],{"class":859},[688,16406,1964],{"class":776},[688,16408,1968],{"class":1967},[688,16410,2544],{"class":1980},[688,16412,5563],{"class":859},[688,16414,16415,16417,16419,16421],{"class":690,"line":5566},[688,16416,1961],{"class":859},[688,16418,1964],{"class":776},[688,16420,1993],{"class":1967},[688,16422,5575],{"class":859},[688,16424,16425],{"class":690,"line":5578},[688,16426,2008],{"class":859},[688,16428,16429,16431,16433,16435,16437,16439,16441,16443,16445,16447,16449,16451,16453,16455,16457,16459,16461,16463,16465,16467],{"class":690,"line":5583},[688,16430,777],{"class":776},[688,16432,5121],{"class":2013},[688,16434,5590],{"class":787},[688,16436,2303],{"class":791},[688,16438,5129],{"class":2013},[688,16440,4776],{"class":791},[688,16442,2025],{"class":1980},[688,16444,801],{"class":791},[688,16446,4878],{"class":694},[688,16448,2129],{"class":791},[688,16450,2544],{"class":1980},[688,16452,801],{"class":791},[688,16454,5289],{"class":694},[688,16456,4875],{"class":791},[688,16458,5135],{"class":694},[688,16460,935],{"class":791},[688,16462,1975],{"class":694},[688,16464,5142],{"class":791},[688,16466,2207],{"class":2013},[688,16468,871],{"class":791},[688,16470,16471,16473,16475,16477,16479,16481],{"class":690,"line":5627},[688,16472,2040],{"class":2013},[688,16474,2043],{"class":787},[688,16476,2046],{"class":791},[688,16478,2049],{"class":791},[688,16480,2052],{"class":783},[688,16482,5640],{"class":797},[688,16484,16485,16487,16489,16491,16493,16495,16497,16499,16501,16503,16505,16507,16509,16511],{"class":690,"line":5643},[688,16486,2040],{"class":2013},[688,16488,2613],{"class":787},[688,16490,801],{"class":791},[688,16492,2172],{"class":694},[688,16494,935],{"class":791},[688,16496,2832],{"class":694},[688,16498,5142],{"class":791},[688,16500,2046],{"class":791},[688,16502,2043],{"class":787},[688,16504,2072],{"class":791},[688,16506,2075],{"class":783},[688,16508,788],{"class":797},[688,16510,2025],{"class":787},[688,16512,911],{"class":797},[688,16514,16515],{"class":690,"line":5674},[688,16516,5677],{"class":859},[688,16518,16519,16521,16523,16525,16527,16529,16531,16533,16535,16537,16539,16541,16543,16545,16547,16549,16551],{"class":690,"line":5680},[688,16520,2040],{"class":2013},[688,16522,2650],{"class":787},[688,16524,801],{"class":791},[688,16526,2172],{"class":694},[688,16528,935],{"class":791},[688,16530,2832],{"class":694},[688,16532,5142],{"class":791},[688,16534,2046],{"class":791},[688,16536,4826],{"class":787},[688,16538,2072],{"class":791},[688,16540,2659],{"class":783},[688,16542,788],{"class":797},[688,16544,2169],{"class":791},[688,16546,2172],{"class":783},[688,16548,788],{"class":797},[688,16550,2670],{"class":2220},[688,16552,5075],{"class":797},[688,16554,16555],{"class":690,"line":5717},[688,16556,5720],{"class":859},[688,16558,16559,16561,16563,16565,16567,16569,16571,16573,16575,16577,16579,16581,16583,16585,16587,16589,16591,16593,16595,16597,16599,16601,16603,16605,16607],{"class":690,"line":5723},[688,16560,2040],{"class":2013},[688,16562,5728],{"class":787},[688,16564,801],{"class":791},[688,16566,4872],{"class":694},[688,16568,2046],{"class":791},[688,16570,2106],{"class":776},[688,16572,4816],{"class":787},[688,16574,2072],{"class":791},[688,16576,2458],{"class":783},[688,16578,788],{"class":797},[688,16580,5747],{"class":791},[688,16582,3397],{"class":797},[688,16584,801],{"class":791},[688,16586,831],{"class":791},[688,16588,2415],{"class":697},[688,16590,807],{"class":791},[688,16592,2129],{"class":791},[688,16594,2650],{"class":797},[688,16596,801],{"class":791},[688,16598,2650],{"class":787},[688,16600,4357],{"class":791},[688,16602,2544],{"class":787},[688,16604,2129],{"class":791},[688,16606,2613],{"class":787},[688,16608,911],{"class":797},[688,16610,16611],{"class":690,"line":5778},[688,16612,5781],{"class":859},[688,16614,16615,16617,16619,16621,16623,16625,16627,16629,16631,16633,16635,16637,16639,16641],{"class":690,"line":5784},[688,16616,2040],{"class":2013},[688,16618,5789],{"class":787},[688,16620,2046],{"class":791},[688,16622,2049],{"class":791},[688,16624,2172],{"class":783},[688,16626,788],{"class":797},[688,16628,5800],{"class":787},[688,16630,2072],{"class":791},[688,16632,5805],{"class":787},[688,16634,5808],{"class":791},[688,16636,5728],{"class":787},[688,16638,2072],{"class":791},[688,16640,5815],{"class":787},[688,16642,911],{"class":797},[688,16644,16645,16647,16649,16651,16653,16655,16657,16659],{"class":690,"line":5820},[688,16646,5823],{"class":787},[688,16648,2072],{"class":791},[688,16650,5828],{"class":783},[688,16652,788],{"class":797},[688,16654,5800],{"class":787},[688,16656,2129],{"class":791},[688,16658,3199],{"class":2220},[688,16660,911],{"class":797},[688,16662,16663,16665,16667,16669,16671,16673,16675,16677,16679,16681,16683,16685,16687,16689],{"class":690,"line":5841},[688,16664,5823],{"class":787},[688,16666,2072],{"class":791},[688,16668,5828],{"class":783},[688,16670,788],{"class":797},[688,16672,2169],{"class":791},[688,16674,2172],{"class":783},[688,16676,788],{"class":797},[688,16678,5858],{"class":787},[688,16680,2028],{"class":797},[688,16682,2129],{"class":791},[688,16684,2650],{"class":787},[688,16686,2072],{"class":791},[688,16688,5805],{"class":787},[688,16690,911],{"class":797},[688,16692,16693,16695,16697,16699,16701,16703,16705],{"class":690,"line":5873},[688,16694,2270],{"class":776},[688,16696,5344],{"class":783},[688,16698,788],{"class":797},[688,16700,5882],{"class":787},[688,16702,2072],{"class":791},[688,16704,4867],{"class":787},[688,16706,911],{"class":797},[688,16708,16709],{"class":690,"line":5891},[688,16710,2280],{"class":791},[688,16712,16713],{"class":690,"line":5896},[688,16714,2088],{"emptyLinePlaceholder":1003},[688,16716,16717],{"class":690,"line":5901},[688,16718,1951],{"class":859},[688,16720,16721],{"class":690,"line":5906},[688,16722,5909],{"class":859},[688,16724,16725,16727,16729,16731,16733],{"class":690,"line":5912},[688,16726,1961],{"class":859},[688,16728,1964],{"class":776},[688,16730,1968],{"class":1967},[688,16732,5921],{"class":1980},[688,16734,5924],{"class":859},[688,16736,16737,16739,16741,16743,16745],{"class":690,"line":5927},[688,16738,1961],{"class":859},[688,16740,1964],{"class":776},[688,16742,1968],{"class":1967},[688,16744,2544],{"class":1980},[688,16746,5938],{"class":859},[688,16748,16749],{"class":690,"line":5941},[688,16750,2008],{"class":859},[688,16752,16753,16755,16757,16759,16761,16763,16765,16767,16769,16771,16773,16775,16777,16779,16781,16783,16785,16787,16789,16791],{"class":690,"line":5946},[688,16754,777],{"class":776},[688,16756,5121],{"class":2013},[688,16758,5953],{"class":787},[688,16760,2303],{"class":791},[688,16762,5129],{"class":2013},[688,16764,4776],{"class":791},[688,16766,5962],{"class":1980},[688,16768,801],{"class":791},[688,16770,4878],{"class":694},[688,16772,2129],{"class":791},[688,16774,2544],{"class":1980},[688,16776,801],{"class":791},[688,16778,5289],{"class":694},[688,16780,4875],{"class":791},[688,16782,5135],{"class":694},[688,16784,935],{"class":791},[688,16786,1975],{"class":694},[688,16788,5142],{"class":791},[688,16790,2207],{"class":2013},[688,16792,871],{"class":791},[688,16794,16795,16797,16799,16801,16803,16805,16807],{"class":690,"line":5991},[688,16796,2040],{"class":2013},[688,16798,5996],{"class":787},[688,16800,2046],{"class":791},[688,16802,5442],{"class":783},[688,16804,788],{"class":797},[688,16806,5962],{"class":787},[688,16808,911],{"class":797},[688,16810,16811,16813,16815,16817,16819,16821,16823,16825],{"class":690,"line":6009},[688,16812,2040],{"class":2013},[688,16814,6014],{"class":787},[688,16816,2046],{"class":791},[688,16818,2049],{"class":791},[688,16820,2172],{"class":783},[688,16822,788],{"class":797},[688,16824,6025],{"class":787},[688,16826,911],{"class":797},[688,16828,16829],{"class":690,"line":6030},[688,16830,6033],{"class":859},[688,16832,16833,16835,16837,16839,16841,16843,16845,16847,16849,16851,16853,16855,16857,16859,16861,16863],{"class":690,"line":6036},[688,16834,2040],{"class":2013},[688,16836,2650],{"class":787},[688,16838,801],{"class":791},[688,16840,2172],{"class":694},[688,16842,935],{"class":791},[688,16844,2832],{"class":694},[688,16846,5142],{"class":791},[688,16848,2046],{"class":791},[688,16850,6014],{"class":787},[688,16852,2072],{"class":791},[688,16854,6059],{"class":783},[688,16856,788],{"class":797},[688,16858,2240],{"class":2220},[688,16860,2129],{"class":791},[688,16862,6068],{"class":2220},[688,16864,911],{"class":797},[688,16866,16867],{"class":690,"line":6073},[688,16868,6076],{"class":859},[688,16870,16871,16873,16875,16877,16879,16881,16883,16885,16887,16889,16891,16893,16895,16897],{"class":690,"line":6079},[688,16872,2040],{"class":2013},[688,16874,2690],{"class":787},[688,16876,801],{"class":791},[688,16878,2172],{"class":694},[688,16880,935],{"class":791},[688,16882,2832],{"class":694},[688,16884,5142],{"class":791},[688,16886,2046],{"class":791},[688,16888,6014],{"class":787},[688,16890,2072],{"class":791},[688,16892,6059],{"class":783},[688,16894,788],{"class":797},[688,16896,2670],{"class":2220},[688,16898,911],{"class":797},[688,16900,16901],{"class":690,"line":6110},[688,16902,2930],{"class":859},[688,16904,16905,16907,16909,16911,16913,16915,16917,16919,16921,16923,16925,16927,16929,16931,16933,16935,16937,16939,16941,16943,16945,16947,16949,16951,16953,16955,16957],{"class":690,"line":6115},[688,16906,2040],{"class":2013},[688,16908,2937],{"class":787},[688,16910,801],{"class":791},[688,16912,4872],{"class":694},[688,16914,2046],{"class":791},[688,16916,2106],{"class":776},[688,16918,4816],{"class":787},[688,16920,2072],{"class":791},[688,16922,2467],{"class":783},[688,16924,788],{"class":797},[688,16926,5747],{"class":791},[688,16928,3397],{"class":797},[688,16930,801],{"class":791},[688,16932,831],{"class":791},[688,16934,2415],{"class":697},[688,16936,807],{"class":791},[688,16938,2129],{"class":791},[688,16940,2650],{"class":797},[688,16942,801],{"class":791},[688,16944,2650],{"class":787},[688,16946,4357],{"class":791},[688,16948,2544],{"class":787},[688,16950,2129],{"class":791},[688,16952,2690],{"class":787},[688,16954,2072],{"class":791},[688,16956,4867],{"class":787},[688,16958,911],{"class":797},[688,16960,16961,16963,16965,16967,16969,16971],{"class":690,"line":6172},[688,16962,2040],{"class":2013},[688,16964,3019],{"class":787},[688,16966,2046],{"class":791},[688,16968,2049],{"class":791},[688,16970,3026],{"class":783},[688,16972,5640],{"class":797},[688,16974,16975,16977,16979,16981,16983,16985,16987],{"class":690,"line":6187},[688,16976,2270],{"class":776},[688,16978,3019],{"class":787},[688,16980,2072],{"class":791},[688,16982,3041],{"class":783},[688,16984,788],{"class":797},[688,16986,3046],{"class":787},[688,16988,911],{"class":797},[688,16990,16991],{"class":690,"line":6204},[688,16992,2280],{"class":791},[13,16994,6209],{},[13,16996,6212],{},[679,16998,16999],{"className":766,"code":6215,"filename":6216,"language":769,"meta":502,"style":502},[42,17000,17001,17035,17049,17055,17073,17095,17099,17103,17107,17111,17129,17133,17137,17159,17181,17185,17189,17215,17237,17241,17245,17249,17253,17273,17277,17281,17303,17307,17311,17337,17359,17373,17395,17399],{"__ignoreMap":502},[688,17002,17003,17005,17007,17009,17011,17013,17015,17017,17019,17021,17023,17025,17027,17029,17031,17033],{"class":690,"line":691},[688,17004,6223],{"class":776},[688,17006,1971],{"class":791},[688,17008,2908],{"class":787},[688,17010,2129],{"class":791},[688,17012,2578],{"class":787},[688,17014,2129],{"class":791},[688,17016,6236],{"class":787},[688,17018,2129],{"class":791},[688,17020,2374],{"class":787},[688,17022,2129],{"class":791},[688,17024,6245],{"class":787},[688,17026,6248],{"class":791},[688,17028,6251],{"class":776},[688,17030,831],{"class":791},[688,17032,4544],{"class":697},[688,17034,6258],{"class":791},[688,17036,17037,17039,17041,17043,17045,17047],{"class":690,"line":506},[688,17038,6263],{"class":791},[688,17040,788],{"class":787},[688,17042,2014],{"class":2013},[688,17044,6270],{"class":791},[688,17046,2207],{"class":2013},[688,17048,871],{"class":791},[688,17050,17051,17053],{"class":690,"line":535},[688,17052,6279],{"class":776},[688,17054,871],{"class":791},[688,17056,17057,17059,17061,17063,17065,17067,17069,17071],{"class":690,"line":609},[688,17058,6286],{"class":2013},[688,17060,6289],{"class":787},[688,17062,801],{"class":791},[688,17064,4878],{"class":694},[688,17066,2046],{"class":791},[688,17068,831],{"class":791},[688,17070,6300],{"class":697},[688,17072,6258],{"class":791},[688,17074,17075,17077,17079,17081,17083,17085,17087,17089,17091,17093],{"class":690,"line":624},[688,17076,6307],{"class":787},[688,17078,2072],{"class":791},[688,17080,6312],{"class":783},[688,17082,788],{"class":797},[688,17084,807],{"class":791},[688,17086,6319],{"class":697},[688,17088,807],{"class":791},[688,17090,2129],{"class":791},[688,17092,6289],{"class":787},[688,17094,911],{"class":797},[688,17096,17097],{"class":690,"line":856},[688,17098,2088],{"emptyLinePlaceholder":1003},[688,17100,17101],{"class":690,"line":863},[688,17102,6336],{"class":859},[688,17104,17105],{"class":690,"line":874},[688,17106,6341],{"class":859},[688,17108,17109],{"class":690,"line":890},[688,17110,6336],{"class":859},[688,17112,17113,17115,17117,17119,17121,17123,17125,17127],{"class":690,"line":896},[688,17114,6286],{"class":2013},[688,17116,6352],{"class":787},[688,17118,801],{"class":791},[688,17120,5289],{"class":694},[688,17122,2046],{"class":791},[688,17124,2106],{"class":776},[688,17126,2374],{"class":783},[688,17128,5640],{"class":797},[688,17130,17131],{"class":690,"line":905},[688,17132,2088],{"emptyLinePlaceholder":1003},[688,17134,17135],{"class":690,"line":2096},[688,17136,6373],{"class":859},[688,17138,17139,17141,17143,17145,17147,17149,17151,17153,17155,17157],{"class":690,"line":2138},[688,17140,6286],{"class":2013},[688,17142,6380],{"class":787},[688,17144,801],{"class":791},[688,17146,4878],{"class":694},[688,17148,2046],{"class":791},[688,17150,2106],{"class":776},[688,17152,6236],{"class":783},[688,17154,788],{"class":797},[688,17156,6395],{"class":787},[688,17158,911],{"class":797},[688,17160,17161,17163,17165,17167,17169,17171,17173,17175,17177,17179],{"class":690,"line":2143},[688,17162,6307],{"class":787},[688,17164,2072],{"class":791},[688,17166,6312],{"class":783},[688,17168,788],{"class":797},[688,17170,807],{"class":791},[688,17172,6412],{"class":697},[688,17174,807],{"class":791},[688,17176,2129],{"class":791},[688,17178,6380],{"class":787},[688,17180,911],{"class":797},[688,17182,17183],{"class":690,"line":2149},[688,17184,2088],{"emptyLinePlaceholder":1003},[688,17186,17187],{"class":690,"line":2185},[688,17188,6429],{"class":859},[688,17190,17191,17193,17195,17197,17199,17201,17203,17205,17207,17209,17211,17213],{"class":690,"line":2261},[688,17192,6286],{"class":2013},[688,17194,6436],{"class":787},[688,17196,801],{"class":791},[688,17198,4878],{"class":694},[688,17200,2046],{"class":791},[688,17202,2106],{"class":776},[688,17204,2578],{"class":783},[688,17206,788],{"class":797},[688,17208,6451],{"class":787},[688,17210,2129],{"class":791},[688,17212,6352],{"class":787},[688,17214,911],{"class":797},[688,17216,17217,17219,17221,17223,17225,17227,17229,17231,17233,17235],{"class":690,"line":2267},[688,17218,6307],{"class":787},[688,17220,2072],{"class":791},[688,17222,6312],{"class":783},[688,17224,788],{"class":797},[688,17226,807],{"class":791},[688,17228,6472],{"class":697},[688,17230,807],{"class":791},[688,17232,2129],{"class":791},[688,17234,6436],{"class":787},[688,17236,911],{"class":797},[688,17238,17239],{"class":690,"line":2277},[688,17240,2088],{"emptyLinePlaceholder":1003},[688,17242,17243],{"class":690,"line":2283},[688,17244,6336],{"class":859},[688,17246,17247],{"class":690,"line":2288},[688,17248,6493],{"class":859},[688,17250,17251],{"class":690,"line":2294},[688,17252,6336],{"class":859},[688,17254,17255,17257,17259,17261,17263,17265,17267,17269,17271],{"class":690,"line":2761},[688,17256,6307],{"class":787},[688,17258,2072],{"class":791},[688,17260,6312],{"class":783},[688,17262,788],{"class":797},[688,17264,807],{"class":791},[688,17266,6512],{"class":787},[688,17268,6515],{"class":697},[688,17270,807],{"class":791},[688,17272,911],{"class":797},[688,17274,17275],{"class":690,"line":2768},[688,17276,2088],{"emptyLinePlaceholder":1003},[688,17278,17279],{"class":690,"line":2773},[688,17280,6528],{"class":859},[688,17282,17283,17285,17287,17289,17291,17293,17295,17297,17299,17301],{"class":690,"line":2779},[688,17284,6286],{"class":2013},[688,17286,6535],{"class":787},[688,17288,801],{"class":791},[688,17290,5289],{"class":694},[688,17292,2046],{"class":791},[688,17294,2106],{"class":776},[688,17296,6245],{"class":783},[688,17298,788],{"class":797},[688,17300,6550],{"class":787},[688,17302,911],{"class":797},[688,17304,17305],{"class":690,"line":2795},[688,17306,2088],{"emptyLinePlaceholder":1003},[688,17308,17309],{"class":690,"line":5013},[688,17310,6561],{"class":859},[688,17312,17313,17315,17317,17319,17321,17323,17325,17327,17329,17331,17333,17335],{"class":690,"line":5032},[688,17314,6286],{"class":2013},[688,17316,6568],{"class":787},[688,17318,801],{"class":791},[688,17320,4878],{"class":694},[688,17322,2046],{"class":791},[688,17324,2106],{"class":776},[688,17326,2908],{"class":783},[688,17328,788],{"class":797},[688,17330,6583],{"class":787},[688,17332,2129],{"class":791},[688,17334,6535],{"class":787},[688,17336,911],{"class":797},[688,17338,17339,17341,17343,17345,17347,17349,17351,17353,17355,17357],{"class":690,"line":5078},[688,17340,6307],{"class":787},[688,17342,2072],{"class":791},[688,17344,6312],{"class":783},[688,17346,788],{"class":797},[688,17348,807],{"class":791},[688,17350,6604],{"class":697},[688,17352,807],{"class":791},[688,17354,2129],{"class":791},[688,17356,6568],{"class":787},[688,17358,911],{"class":797},[688,17360,17361,17363,17365,17367,17369,17371],{"class":690,"line":5090},[688,17362,6617],{"class":791},[688,17364,6620],{"class":776},[688,17366,4776],{"class":797},[688,17368,6625],{"class":787},[688,17370,6628],{"class":797},[688,17372,792],{"class":791},[688,17374,17375,17377,17379,17381,17383,17385,17387,17389,17391,17393],{"class":690,"line":5095},[688,17376,6307],{"class":787},[688,17378,2072],{"class":791},[688,17380,6625],{"class":783},[688,17382,788],{"class":797},[688,17384,807],{"class":791},[688,17386,6645],{"class":697},[688,17388,807],{"class":791},[688,17390,2129],{"class":791},[688,17392,6652],{"class":787},[688,17394,911],{"class":797},[688,17396,17397],{"class":690,"line":5100},[688,17398,893],{"class":791},[688,17400,17401,17403],{"class":690,"line":5105},[688,17402,908],{"class":791},[688,17404,6665],{"class":787},[968,17406,6668],{},{"title":502,"searchDepth":535,"depth":535,"links":17408},[17409,17410,17411,17412,17420,17421,17422,17428,17429,17430],{"id":1040,"depth":506,"text":1041},{"id":1065,"depth":506,"text":1066},{"id":1178,"depth":506,"text":1179},{"id":1199,"depth":506,"text":1200,"children":17413},[17414,17415,17416,17417,17418,17419],{"id":1206,"depth":535,"text":1207},{"id":1246,"depth":535,"text":1247},{"id":1309,"depth":535,"text":1310},{"id":1358,"depth":535,"text":1359},{"id":1391,"depth":535,"text":1392},{"id":1430,"depth":535,"text":1431},{"id":1513,"depth":506,"text":1514},{"id":1864,"depth":506,"text":1865},{"id":1917,"depth":506,"text":1918,"children":17423},[17424,17425,17426,17427],{"id":1924,"depth":535,"text":1925},{"id":3063,"depth":535,"text":3064},{"id":3577,"depth":535,"text":3578},{"id":4102,"depth":535,"text":4103},{"id":4405,"depth":506,"text":4406},{"id":4502,"depth":506,"text":4503},{"id":4712,"depth":506,"text":4713},{"name":6694,"symbol":6695,"icon":6696,"id":896},{"type":10,"value":17433},[17434,17436],[13,17435,6702],{},[13,17437,6705],{},{},{"title":1033,"description":1044},{"loc":6707},[2096],[17443],{"name":6716,"symbol":6717,"icon":6718,"id":2096},{"id":6723,"title":6724,"articleId":6725,"articleThumb":6726,"body":17445,"categoryId":624,"categoryInfo":18025,"createDate":7498,"description":7499,"excerpt":18026,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":18030,"navigation":1003,"path":7506,"rawbody":7507,"readingTime":2185,"seo":18031,"sitemap":18032,"stem":7517,"tagIds":18040,"tagInfo":18041,"updateDate":7525,"wordCount":7526,"__hash__":7527},{"type":10,"value":17446,"toc":18009},[17447,17449,17451,17453,17455,17460,17467,17471,17479,17483,17488,17490,17492,17497,17510,17516,17518,17520,17522,17528,17552,17554,17556,17558,17564,17569,17571,17575,17577,17581,17583,17587,17589,17591,17601,17733,17735,17737,17742,17748,17750,17752,17756,17761,17765,17769,17773,17779,17913,17917,17927,17929,17995,17997,17999,18001,18003,18005,18007],[13,17448,6731],{},[13,17450,6734],{},[13,17452,6737],{},[17,17454,6741],{"id":6740},[13,17456,6744,17457,6750],{},[104,17458,6749],{"href":6747,"rel":17459,"target":28},[108],[13,17461,17462,6755,17464,6760],{},[42,17463,6749],{"color":116},[104,17465,6759],{"href":6747,"rel":17466,"target":28},[108],[13,17468,17469],{},[71,17470,6765],{},[128,17472,17473,17475,17477],{},[68,17474,6770],{},[68,17476,6773],{},[68,17478,6776],{},[13,17480,17481,6782],{},[71,17482,6781],{},[13,17484,6785,17485],{},[104,17486,6789],{"href":6747,"rel":17487},[108],[123,17489,6793],{"id":6792},[13,17491,6796],{},[13,17493,6799,17494,6805],{},[104,17495,6804],{"href":6802,"rel":17496,"target":28},[108],[6807,17498,17499],{"color":1058,"icon":6809},[13,17500,6812,17501,6815,17503,6819,17505,6760,17508,6826],{},[290,17502],{},[71,17504,6818],{},[104,17506,6818],{"href":6822,"rel":17507,"target":28},[108],[290,17509],{},[13,17511,6829,17512,6834,17514,2028],{},[6831,17513],{"name":6833},[71,17515,6818],{},[13,17517,6839],{},[123,17519,6843],{"id":6842},[13,17521,6846],{},[13,17523,6849,17524,6852,17526,6855],{},[290,17525],{},[290,17527],{},[679,17529,17530],{"className":6858,"code":6859,"language":6860,"meta":502,"style":502},[42,17531,17532],{"__ignoreMap":502},[688,17533,17534,17536,17538,17540,17542,17544,17546,17548,17550],{"class":690,"line":691},[688,17535,6867],{"class":694},[688,17537,6870],{"class":697},[688,17539,6873],{"class":697},[688,17541,6876],{"class":697},[688,17543,6879],{"class":2220},[688,17545,6882],{"class":697},[688,17547,3155],{"class":791},[688,17549,6887],{"class":697},[688,17551,6890],{"class":791},[13,17553,6893],{},[13,17555,6896],{},[13,17557,6899],{},[13,17559,6902,17560,6906,17562,6910],{},[42,17561,6905],{"color":116},[42,17563,6909],{"color":116},[13,17565,6913,17566,6760],{},[104,17567,6918],{"href":6916,"rel":17568,"target":28},[108],[123,17570,6922],{"id":6921},[13,17572,6925,17573],{},[419,17574],{"alt":502,"src":6928},[123,17576,6932],{"id":6931},[13,17578,6935,17579],{},[419,17580],{"alt":502,"src":6938},[123,17582,6942],{"id":6941},[13,17584,6945,17585],{},[419,17586],{"alt":502,"src":6948},[123,17588,6952],{"id":6951},[13,17590,6955],{},[13,17592,6958,17593,17595,17597,6968,17599,6972],{},[419,17594],{"alt":502,"src":6961},[419,17596],{"alt":502,"src":6964},[419,17598],{"alt":502,"src":6967},[42,17600,6971],{"color":116},[679,17602,17603],{"className":6975,"code":6976,"filename":6977,"language":6978,"meta":502,"style":502},[42,17604,17605,17613,17619,17625,17631,17635,17641,17647,17653,17661,17667,17677,17685,17691,17695,17703,17709,17713,17721,17725],{"__ignoreMap":502},[688,17606,17607,17609,17611],{"class":690,"line":691},[688,17608,6985],{"class":797},[688,17610,801],{"class":791},[688,17612,6990],{"class":697},[688,17614,17615,17617],{"class":690,"line":506},[688,17616,6995],{"class":2442},[688,17618,6998],{"class":791},[688,17620,17621,17623],{"class":690,"line":535},[688,17622,7003],{"class":797},[688,17624,6998],{"class":791},[688,17626,17627,17629],{"class":690,"line":609},[688,17628,7010],{"class":797},[688,17630,6998],{"class":791},[688,17632,17633],{"class":690,"line":624},[688,17634,7017],{"class":859},[688,17636,17637,17639],{"class":690,"line":856},[688,17638,7022],{"class":791},[688,17640,7025],{"class":697},[688,17642,17643,17645],{"class":690,"line":863},[688,17644,7030],{"class":797},[688,17646,6998],{"class":791},[688,17648,17649,17651],{"class":690,"line":874},[688,17650,7037],{"class":797},[688,17652,6998],{"class":791},[688,17654,17655,17657,17659],{"class":690,"line":890},[688,17656,7044],{"class":797},[688,17658,801],{"class":791},[688,17660,7049],{"class":697},[688,17662,17663,17665],{"class":690,"line":896},[688,17664,7054],{"class":797},[688,17666,6998],{"class":791},[688,17668,17669,17671,17673,17675],{"class":690,"line":905},[688,17670,7022],{"class":791},[688,17672,3397],{"class":797},[688,17674,801],{"class":791},[688,17676,6990],{"class":697},[688,17678,17679,17681,17683],{"class":690,"line":2096},[688,17680,7071],{"class":797},[688,17682,801],{"class":791},[688,17684,7076],{"class":697},[688,17686,17687,17689],{"class":690,"line":2138},[688,17688,7081],{"class":797},[688,17690,6998],{"class":791},[688,17692,17693],{"class":690,"line":2143},[688,17694,7088],{"class":859},[688,17696,17697,17699,17701],{"class":690,"line":2149},[688,17698,7093],{"class":797},[688,17700,801],{"class":791},[688,17702,7098],{"class":697},[688,17704,17705,17707],{"class":690,"line":2185},[688,17706,7103],{"class":797},[688,17708,6998],{"class":791},[688,17710,17711],{"class":690,"line":2261},[688,17712,7110],{"class":859},[688,17714,17715,17717,17719],{"class":690,"line":2267},[688,17716,7115],{"class":797},[688,17718,801],{"class":791},[688,17720,7120],{"class":697},[688,17722,17723],{"class":690,"line":2277},[688,17724,7125],{"class":859},[688,17726,17727,17729,17731],{"class":690,"line":2283},[688,17728,7130],{"class":797},[688,17730,801],{"class":791},[688,17732,7135],{"class":697},[13,17734,7138],{},[17,17736,7142],{"id":7141},[13,17738,7145,17739,7151],{},[104,17740,7150],{"href":7148,"rel":17741,"target":28},[108],[13,17743,7154,17744,648,17746,7161],{},[71,17745,7157],{},[71,17747,7160],{},[123,17749,7165],{"id":7164},[13,17751,7168],{},[13,17753,17754],{},[71,17755,7173],{},[13,17757,7176,17758,7182],{},[104,17759,7181],{"href":7179,"rel":17760,"target":28},[108],[13,17762,17763],{},[71,17764,7187],{},[13,17766,7190,17767,6760],{},[104,17768,7194],{"href":7193},[13,17770,17771],{},[71,17772,7199],{},[13,17774,7202,17775,7206,17777,6972],{},[104,17776,6952],{"href":7205},[42,17778,7209],{"color":116},[679,17780,17781],{"className":6975,"code":7212,"filename":7213,"language":6978,"meta":502,"style":502},[42,17782,17783,17791,17797,17803,17807,17821,17827,17833,17841,17847,17857,17865,17871,17875,17883,17889,17893,17901,17905],{"__ignoreMap":502},[688,17784,17785,17787,17789],{"class":690,"line":691},[688,17786,6985],{"class":797},[688,17788,801],{"class":791},[688,17790,7224],{"class":697},[688,17792,17793,17795],{"class":690,"line":506},[688,17794,6995],{"class":2442},[688,17796,6998],{"class":791},[688,17798,17799,17801],{"class":690,"line":535},[688,17800,7235],{"class":797},[688,17802,6998],{"class":791},[688,17804,17805],{"class":690,"line":609},[688,17806,7242],{"class":859},[688,17808,17809,17811,17813,17815,17817,17819],{"class":690,"line":624},[688,17810,7247],{"class":791},[688,17812,7250],{"class":797},[688,17814,801],{"class":791},[688,17816,7255],{"class":791},[688,17818,7258],{"class":697},[688,17820,6258],{"class":791},[688,17822,17823,17825],{"class":690,"line":856},[688,17824,7030],{"class":797},[688,17826,6998],{"class":791},[688,17828,17829,17831],{"class":690,"line":863},[688,17830,7037],{"class":797},[688,17832,6998],{"class":791},[688,17834,17835,17837,17839],{"class":690,"line":874},[688,17836,7044],{"class":797},[688,17838,801],{"class":791},[688,17840,7049],{"class":697},[688,17842,17843,17845],{"class":690,"line":890},[688,17844,7054],{"class":797},[688,17846,6998],{"class":791},[688,17848,17849,17851,17853,17855],{"class":690,"line":896},[688,17850,7022],{"class":791},[688,17852,3397],{"class":797},[688,17854,801],{"class":791},[688,17856,7224],{"class":697},[688,17858,17859,17861,17863],{"class":690,"line":905},[688,17860,7071],{"class":797},[688,17862,801],{"class":791},[688,17864,7076],{"class":697},[688,17866,17867,17869],{"class":690,"line":2096},[688,17868,7081],{"class":797},[688,17870,6998],{"class":791},[688,17872,17873],{"class":690,"line":2138},[688,17874,7088],{"class":859},[688,17876,17877,17879,17881],{"class":690,"line":2143},[688,17878,7093],{"class":797},[688,17880,801],{"class":791},[688,17882,7098],{"class":697},[688,17884,17885,17887],{"class":690,"line":2149},[688,17886,7103],{"class":797},[688,17888,6998],{"class":791},[688,17890,17891],{"class":690,"line":2185},[688,17892,7333],{"class":859},[688,17894,17895,17897,17899],{"class":690,"line":2261},[688,17896,7115],{"class":797},[688,17898,801],{"class":791},[688,17900,7135],{"class":697},[688,17902,17903],{"class":690,"line":2267},[688,17904,7346],{"class":859},[688,17906,17907,17909,17911],{"class":690,"line":2277},[688,17908,7130],{"class":797},[688,17910,801],{"class":791},[688,17912,7120],{"class":697},[13,17914,7357,17915,7361],{},[42,17916,7360],{"color":116},[6807,17918,17919],{"color":1058,"icon":6809},[13,17920,6812,17921,7368,17923,7371,17925,7374],{},[290,17922],{},[290,17924],{},[290,17926],{},[13,17928,7377],{},[679,17930,17931],{"className":6975,"code":7380,"language":6978,"meta":502,"style":502},[42,17932,17933,17939,17945,17953,17959,17969,17977,17983],{"__ignoreMap":502},[688,17934,17935,17937],{"class":690,"line":691},[688,17936,7030],{"class":797},[688,17938,6998],{"class":791},[688,17940,17941,17943],{"class":690,"line":506},[688,17942,7393],{"class":797},[688,17944,6998],{"class":791},[688,17946,17947,17949,17951],{"class":690,"line":535},[688,17948,7400],{"class":797},[688,17950,801],{"class":791},[688,17952,7049],{"class":697},[688,17954,17955,17957],{"class":690,"line":609},[688,17956,7409],{"class":797},[688,17958,6998],{"class":791},[688,17960,17961,17963,17965,17967],{"class":690,"line":624},[688,17962,7247],{"class":791},[688,17964,3397],{"class":797},[688,17966,801],{"class":791},[688,17968,7422],{"class":697},[688,17970,17971,17973,17975],{"class":690,"line":856},[688,17972,7427],{"class":797},[688,17974,801],{"class":791},[688,17976,7432],{"class":697},[688,17978,17979,17981],{"class":690,"line":863},[688,17980,7437],{"class":797},[688,17982,6998],{"class":791},[688,17984,17985,17987,17989,17991,17993],{"class":690,"line":874},[688,17986,7444],{"class":797},[688,17988,801],{"class":791},[688,17990,3155],{"class":791},[688,17992,7451],{"class":697},[688,17994,6890],{"class":791},[13,17996,7456],{},[123,17998,7460],{"id":7459},[13,18000,7463],{},[13,18002,7466],{},[17,18004,7470],{"id":7469},[17,18006,7474],{"id":7473},[968,18008,7477],{},{"title":502,"searchDepth":535,"depth":535,"links":18010},[18011,18019,18023,18024],{"id":6740,"depth":506,"text":6741,"children":18012},[18013,18014,18015,18016,18017,18018],{"id":6792,"depth":535,"text":6793},{"id":6842,"depth":535,"text":6843},{"id":6921,"depth":535,"text":6922},{"id":6931,"depth":535,"text":6932},{"id":6941,"depth":535,"text":6942},{"id":6951,"depth":535,"text":6952},{"id":7141,"depth":506,"text":7142,"children":18020},[18021,18022],{"id":7164,"depth":535,"text":7165},{"id":7459,"depth":535,"text":7460},{"id":7469,"depth":506,"text":7470},{"id":7473,"depth":506,"text":7474},{"name":7495,"symbol":7496,"icon":7497,"id":624},{"type":10,"value":18027},[18028],[13,18029,7504],{},{},{"title":6724,"description":7499},{"loc":7506,"images":18033},[18034,18035,18036,18037,18038,18039],{"loc":6928},{"loc":6938},{"loc":6948},{"loc":6961},{"loc":6964},{"loc":6967},[506,535],[18042,18043],{"name":6804,"icon":7521,"symbol":6804,"id":506},{"name":7523,"symbol":7523,"icon":7524,"id":535},{"id":7529,"title":7530,"articleId":7531,"articleThumb":7532,"body":18045,"categoryId":609,"categoryInfo":18559,"createDate":8212,"description":8213,"excerpt":18560,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":18564,"navigation":1003,"path":8220,"rawbody":8221,"readingTime":8222,"seo":18565,"sitemap":18566,"stem":8227,"tagIds":18569,"tagInfo":18570,"updateDate":8233,"wordCount":8234,"__hash__":8235},{"type":10,"value":18046,"toc":18548},[18047,18049,18053,18057,18059,18061,18065,18067,18071,18075,18079,18083,18087,18091,18095,18099,18103,18107,18111,18115,18119,18123,18127,18129,18135,18143,18147,18155,18157,18159,18283,18285,18287,18289,18294,18334,18336,18372,18383,18423,18427,18429,18469,18471,18499,18501,18503,18507,18509,18514,18516,18518,18520,18522,18524,18542,18546],[17,18048,7538],{"id":7537},[13,18050,7541,18051,7544],{},[290,18052],{},[13,18054,7547,18055,7550],{},[290,18056],{},[17,18058,7554],{"id":7553},[13,18060,7557],{},[13,18062,18063],{},[419,18064],{"alt":502,"src":7562},[13,18066,7565],{},[13,18068,18069,7571],{},[71,18070,7570],{},[13,18072,18073,7577],{},[71,18074,7576],{},[13,18076,18077,7583],{},[71,18078,7582],{},[13,18080,18081,7589],{},[71,18082,7588],{},[13,18084,18085,7595],{},[71,18086,7594],{},[13,18088,18089,7601],{},[71,18090,7600],{},[13,18092,18093,7607],{},[71,18094,7606],{},[13,18096,18097,7613],{},[71,18098,7612],{},[13,18100,18101,7619],{},[71,18102,7618],{},[13,18104,18105,7625],{},[71,18106,7624],{},[13,18108,18109,7631],{},[71,18110,7630],{},[13,18112,18113,7637],{},[71,18114,7636],{},[13,18116,18117,7643],{},[71,18118,7642],{},[13,18120,18121,7649],{},[71,18122,7648],{},[13,18124,18125,7655],{},[71,18126,7654],{},[17,18128,7659],{"id":7658},[13,18130,7662,18131,18133],{},[290,18132],{},[71,18134,7667],{},[128,18136,18137,18139,18141],{},[68,18138,7672],{},[68,18140,7675],{},[68,18142,7678],{},[13,18144,18145],{},[71,18146,7683],{},[128,18148,18149,18151,18153],{},[68,18150,7688],{},[68,18152,7691],{},[68,18154,7694],{},[123,18156,7698],{"id":7697},[13,18158,7701],{},[679,18160,18161],{"className":7704,"code":7705,"language":7706,"meta":502,"style":502},[42,18162,18163,18169,18183,18225,18235,18245,18255,18259,18265,18279],{"__ignoreMap":502},[688,18164,18165,18167],{"class":690,"line":691},[688,18166,7713],{"class":776},[688,18168,871],{"class":791},[688,18170,18171,18173,18175,18177,18179,18181],{"class":690,"line":506},[688,18172,7721],{"class":7720},[688,18174,801],{"class":791},[688,18176,831],{"class":791},[688,18178,7728],{"class":697},[688,18180,807],{"class":791},[688,18182,2058],{"class":791},[688,18184,18185,18187,18189,18191,18193,18195,18197,18199,18201,18203,18205,18207,18209,18211,18213,18215,18217,18219,18221,18223],{"class":690,"line":535},[688,18186,7737],{"class":7720},[688,18188,801],{"class":791},[688,18190,7742],{"class":783},[688,18192,788],{"class":791},[688,18194,2312],{"class":791},[688,18196,7728],{"class":697},[688,18198,2312],{"class":791},[688,18200,7753],{"class":791},[688,18202,7756],{"class":783},[688,18204,788],{"class":791},[688,18206,2312],{"class":791},[688,18208,7763],{"class":697},[688,18210,2312],{"class":791},[688,18212,2028],{"class":791},[688,18214,7770],{"class":783},[688,18216,788],{"class":791},[688,18218,2312],{"class":791},[688,18220,7777],{"class":697},[688,18222,2312],{"class":791},[688,18224,7782],{"class":791},[688,18226,18227,18229,18231,18233],{"class":690,"line":609},[688,18228,7787],{"class":7720},[688,18230,801],{"class":791},[688,18232,7792],{"class":787},[688,18234,2058],{"class":791},[688,18236,18237,18239,18241,18243],{"class":690,"line":624},[688,18238,7799],{"class":7720},[688,18240,801],{"class":791},[688,18242,7804],{"class":787},[688,18244,2058],{"class":791},[688,18246,18247,18249,18251,18253],{"class":690,"line":856},[688,18248,7811],{"class":7720},[688,18250,801],{"class":791},[688,18252,7816],{"class":2220},[688,18254,2058],{"class":791},[688,18256,18257],{"class":690,"line":863},[688,18258,2280],{"class":791},[688,18260,18261,18263],{"class":690,"line":874},[688,18262,7827],{"class":694},[688,18264,792],{"class":791},[688,18266,18267,18269,18271,18273,18275,18277],{"class":690,"line":890},[688,18268,7834],{"class":7720},[688,18270,801],{"class":791},[688,18272,831],{"class":791},[688,18274,7728],{"class":697},[688,18276,807],{"class":791},[688,18278,2058],{"class":791},[688,18280,18281],{"class":690,"line":896},[688,18282,2280],{"class":791},[13,18284,7851],{},[123,18286,7855],{"id":7854},[13,18288,7858],{},[13,18290,7861,18291,7867],{},[104,18292,7866],{"href":7864,"rel":18293,"target":28},[108],[679,18295,18296],{"className":7704,"code":7870,"language":7706,"meta":502,"style":502},[42,18297,18298],{"__ignoreMap":502},[688,18299,18300,18302,18304,18306,18308,18310,18312,18314,18316,18318,18320,18322,18324,18326,18328,18330,18332],{"class":690,"line":691},[688,18301,935],{"class":787},[688,18303,7879],{"class":694},[688,18305,7882],{"class":787},[688,18307,2072],{"class":791},[688,18309,7887],{"class":694},[688,18311,7890],{"class":787},[688,18313,7893],{"class":791},[688,18315,7896],{"class":787},[688,18317,2129],{"class":791},[688,18319,7901],{"class":787},[688,18321,2072],{"class":791},[688,18323,7906],{"class":787},[688,18325,2129],{"class":791},[688,18327,7911],{"class":787},[688,18329,2072],{"class":791},[688,18331,7916],{"class":787},[688,18333,941],{"class":791},[13,18335,7921],{},[679,18337,18338],{"className":7704,"code":7924,"language":7706,"meta":502,"style":502},[42,18339,18340,18350,18368],{"__ignoreMap":502},[688,18341,18342,18344,18346,18348],{"class":690,"line":691},[688,18343,7827],{"class":694},[688,18345,2129],{"class":791},[688,18347,7935],{"class":694},[688,18349,871],{"class":791},[688,18351,18352,18354,18356,18358,18360,18362,18364,18366],{"class":690,"line":506},[688,18353,7942],{"class":7720},[688,18355,801],{"class":791},[688,18357,3155],{"class":791},[688,18359,7866],{"class":697},[688,18361,2312],{"class":791},[688,18363,2129],{"class":791},[688,18365,7955],{"class":787},[688,18367,2058],{"class":791},[688,18369,18370],{"class":690,"line":535},[688,18371,2280],{"class":791},[13,18373,7964,18374,7968,18376,7974,18379,7978,18381,7982],{},[42,18375,7967],{},[104,18377,7973],{"href":7971,"rel":18378},[108],[42,18380,7977],{},[42,18382,7981],{},[679,18384,18385],{"className":7704,"code":7985,"language":7706,"meta":502,"style":502},[42,18386,18387],{"__ignoreMap":502},[688,18388,18389,18391,18393,18395,18397,18399,18401,18403,18405,18407,18409,18411,18413,18415,18417,18419,18421],{"class":690,"line":691},[688,18390,935],{"class":787},[688,18392,7879],{"class":694},[688,18394,7882],{"class":787},[688,18396,2072],{"class":791},[688,18398,8000],{"class":694},[688,18400,8003],{"class":787},[688,18402,7893],{"class":791},[688,18404,7896],{"class":787},[688,18406,2129],{"class":791},[688,18408,7901],{"class":787},[688,18410,2072],{"class":791},[688,18412,7906],{"class":787},[688,18414,2129],{"class":791},[688,18416,7911],{"class":787},[688,18418,2072],{"class":791},[688,18420,7916],{"class":787},[688,18422,941],{"class":791},[13,18424,8028,18425,8033],{},[104,18426,8032],{"href":8031,"target":28},[13,18428,8036],{},[679,18430,18431],{"className":6858,"code":8039,"language":6860,"meta":502,"style":502},[42,18432,18433],{"__ignoreMap":502},[688,18434,18435,18437,18439,18441,18443,18445,18447,18449,18451,18453,18455,18457,18459,18461,18463,18465,18467],{"class":690,"line":691},[688,18436,935],{"class":791},[688,18438,8048],{"class":787},[688,18440,2303],{"class":791},[688,18442,2312],{"class":791},[688,18444,8055],{"class":697},[688,18446,2312],{"class":791},[688,18448,8060],{"class":787},[688,18450,2303],{"class":791},[688,18452,2312],{"class":791},[688,18454,8067],{"class":697},[688,18456,2312],{"class":791},[688,18458,8072],{"class":787},[688,18460,2303],{"class":791},[688,18462,2312],{"class":791},[688,18464,8079],{"class":697},[688,18466,2312],{"class":791},[688,18468,941],{"class":791},[13,18470,7921],{},[679,18472,18473],{"className":7704,"code":8088,"language":7706,"meta":502,"style":502},[42,18474,18475,18485,18495],{"__ignoreMap":502},[688,18476,18477,18479,18481,18483],{"class":690,"line":691},[688,18478,7827],{"class":694},[688,18480,2129],{"class":791},[688,18482,7935],{"class":694},[688,18484,871],{"class":791},[688,18486,18487,18489,18491,18493],{"class":690,"line":506},[688,18488,7834],{"class":7720},[688,18490,801],{"class":791},[688,18492,8109],{"class":787},[688,18494,2058],{"class":791},[688,18496,18497],{"class":690,"line":535},[688,18498,2280],{"class":791},[17,18500,8119],{"id":8118},[13,18502,8122],{},[13,18504,8125,18505,8129],{},[42,18506,8128],{"color":116},[13,18508,8132],{},[13,18510,18511,8140],{},[104,18512,8139],{"href":8137,"rel":18513},[108],[17,18515,8144],{"id":8143},[13,18517,8147],{},[13,18519,8150],{},[13,18521,8153],{},[17,18523,8157],{"id":8156},[22,18525,18526,18530,18534,18538],{},[25,18527,18528],{"icon":8162,"target":28,"title":8163,"to":8164},[13,18529,8167],{},[25,18531,18532],{"icon":8162,"target":28,"title":8139,"to":8170},[13,18533,8173],{},[25,18535,18536],{"icon":8162,"target":28,"title":8176,"to":8177},[13,18537,8180],{},[25,18539,18540],{"icon":8162,"target":28,"title":8183,"to":8184},[13,18541,8187],{},[13,18543,8190,18544],{},[104,18545,8194],{"href":8193,"target":28},[968,18547,8197],{},{"title":502,"searchDepth":535,"depth":535,"links":18549},[18550,18551,18552,18556,18557,18558],{"id":7537,"depth":506,"text":7538},{"id":7553,"depth":506,"text":7554},{"id":7658,"depth":506,"text":7659,"children":18553},[18554,18555],{"id":7697,"depth":535,"text":7698},{"id":7854,"depth":535,"text":7855},{"id":8118,"depth":506,"text":8119},{"id":8143,"depth":506,"text":8144},{"id":8156,"depth":506,"text":8157},{"name":8210,"symbol":7706,"icon":8211,"id":609},{"type":10,"value":18561},[18562],[13,18563,8218],{},{},{"title":7530,"description":8213},{"loc":8220,"images":18567},[18568],{"loc":7562},[863],[18571],{"name":8231,"symbol":8000,"icon":8232,"id":863},{"id":8237,"title":8032,"articleId":8238,"articleThumb":8239,"body":18573,"categoryId":863,"categoryInfo":18937,"createDate":8705,"description":8706,"excerpt":18938,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":18942,"navigation":1003,"path":8713,"rawbody":8714,"readingTime":8715,"seo":18943,"sitemap":18944,"stem":8720,"tagIds":18947,"tagInfo":18948,"updateDate":8727,"wordCount":8728,"__hash__":8729},{"type":10,"value":18574,"toc":18932},[18575,18577,18597,18637,18643,18656,18658,18672,18822,18824,18826,18834,18918,18920,18930],[17,18576,8245],{"id":8244},[13,18578,8248,18579,18582,8254,18584,8260,18587,8263,18589,8266,18591,8269,18593,8272,18595,2072],{},[104,18580,7179],{"href":7179,"rel":18581,"target":28},[108],[290,18583],{},[104,18585,8259],{"href":8257,"rel":18586,"target":28},[108],[290,18588],{},[42,18590,8259],{"color":116},[290,18592],{},[290,18594],{},[42,18596,8275],{"color":116},[679,18598,18599],{"className":6858,"code":8278,"language":6860,"meta":502,"style":502},[42,18600,18601,18607,18613,18619,18625,18631],{"__ignoreMap":502},[688,18602,18603,18605],{"class":690,"line":691},[688,18604,8285],{"class":694},[688,18606,8288],{"class":697},[688,18608,18609,18611],{"class":690,"line":506},[688,18610,8293],{"class":694},[688,18612,8296],{"class":697},[688,18614,18615,18617],{"class":690,"line":535},[688,18616,8301],{"class":694},[688,18618,8304],{"class":697},[688,18620,18621,18623],{"class":690,"line":609},[688,18622,8309],{"class":694},[688,18624,8312],{"class":697},[688,18626,18627,18629],{"class":690,"line":624},[688,18628,8317],{"class":694},[688,18630,8320],{"class":697},[688,18632,18633,18635],{"class":690,"line":856},[688,18634,8325],{"class":694},[688,18636,8328],{"class":697},[13,18638,8331,18639,8335,18641],{},[42,18640,8334],{"color":116},[419,18642],{"alt":502,"src":8338},[3056,18644,18645,18653],{},[13,18646,8343,18647,8346,18649,8349,18651,8352],{},[290,18648],{},[290,18650],{},[290,18652],{},[8354,18654,8358],{"className":18655},[8357],[17,18657,8362],{"id":8361},[13,18659,8365,18660,8370,18663,8375,18666,8378,18668,8381,18670,8385],{},[104,18661,8368],{"href":8368,"rel":18662,"target":28},[108],[104,18664,8373],{"href":8373,"rel":18665,"target":28},[108],[290,18667],{},[42,18669,8334],{},[42,18671,8384],{},[679,18673,18674],{"className":8388,"code":8389,"language":8390,"meta":502,"style":502},[42,18675,18676,18680,18698,18716,18734,18746,18758,18770,18782,18794,18806,18810,18814,18818],{"__ignoreMap":502},[688,18677,18678],{"class":690,"line":691},[688,18679,792],{"class":791},[688,18681,18682,18684,18686,18688,18690,18692,18694,18696],{"class":690,"line":506},[688,18683,8401],{"class":791},[688,18685,8404],{"class":2013},[688,18687,2312],{"class":791},[688,18689,801],{"class":791},[688,18691,3155],{"class":791},[688,18693,8413],{"class":697},[688,18695,2312],{"class":791},[688,18697,838],{"class":791},[688,18699,18700,18702,18704,18706,18708,18710,18712,18714],{"class":690,"line":535},[688,18701,8401],{"class":791},[688,18703,8424],{"class":2013},[688,18705,2312],{"class":791},[688,18707,801],{"class":791},[688,18709,3155],{"class":791},[688,18711,8433],{"class":697},[688,18713,2312],{"class":791},[688,18715,838],{"class":791},[688,18717,18718,18720,18722,18724,18726,18728,18730,18732],{"class":690,"line":609},[688,18719,8401],{"class":791},[688,18721,8444],{"class":2013},[688,18723,2312],{"class":791},[688,18725,801],{"class":791},[688,18727,3155],{"class":791},[688,18729,8453],{"class":697},[688,18731,2312],{"class":791},[688,18733,838],{"class":791},[688,18735,18736,18738,18740,18742,18744],{"class":690,"line":624},[688,18737,8401],{"class":791},[688,18739,8464],{"class":2013},[688,18741,2312],{"class":791},[688,18743,801],{"class":791},[688,18745,871],{"class":791},[688,18747,18748,18750,18752,18754,18756],{"class":690,"line":856},[688,18749,8475],{"class":791},[688,18751,8478],{"class":694},[688,18753,2312],{"class":791},[688,18755,801],{"class":791},[688,18757,871],{"class":791},[688,18759,18760,18762,18764,18766,18768],{"class":690,"line":863},[688,18761,8489],{"class":791},[688,18763,8492],{"class":2220},[688,18765,2312],{"class":791},[688,18767,801],{"class":791},[688,18769,8499],{"class":791},[688,18771,18772,18774,18776,18778,18780],{"class":690,"line":874},[688,18773,8489],{"class":791},[688,18775,8506],{"class":2220},[688,18777,2312],{"class":791},[688,18779,801],{"class":791},[688,18781,871],{"class":791},[688,18783,18784,18786,18788,18790,18792],{"class":690,"line":890},[688,18785,4327],{"class":791},[688,18787,8519],{"class":797},[688,18789,2312],{"class":791},[688,18791,801],{"class":791},[688,18793,8526],{"class":791},[688,18795,18796,18798,18800,18802,18804],{"class":690,"line":896},[688,18797,4327],{"class":791},[688,18799,8533],{"class":797},[688,18801,2312],{"class":791},[688,18803,801],{"class":791},[688,18805,8540],{"class":791},[688,18807,18808],{"class":690,"line":905},[688,18809,8545],{"class":791},[688,18811,18812],{"class":690,"line":2096},[688,18813,893],{"class":791},[688,18815,18816],{"class":690,"line":2138},[688,18817,8554],{"class":791},[688,18819,18820],{"class":690,"line":2143},[688,18821,2280],{"class":791},[13,18823,8561],{},[17,18825,8565],{"id":8564},[13,18827,8568,18828,8572,18830,8575,18832,8578],{},[42,18829,8571],{"color":116},[290,18831],{},[42,18833,8571],{"color":116},[260,18835,18836,18846],{},[263,18837,18838],{},[266,18839,18840,18842,18844],{},[269,18841,8587],{},[269,18843,8590],{},[269,18845,8593],{},[278,18847,18848,18858,18868,18878,18888,18898,18908],{},[266,18849,18850,18854,18856],{},[283,18851,18852],{},[42,18853,8571],{},[283,18855,8604],{},[283,18857,8607],{},[266,18859,18860,18864,18866],{},[283,18861,18862],{},[42,18863,8614],{},[283,18865,8617],{},[283,18867,8620],{},[266,18869,18870,18874,18876],{},[283,18871,18872],{},[42,18873,8627],{},[283,18875,8630],{},[283,18877,8620],{},[266,18879,18880,18884,18886],{},[283,18881,18882],{},[42,18883,8639],{},[283,18885,8642],{},[283,18887,8645],{},[266,18889,18890,18894,18896],{},[283,18891,18892],{},[42,18893,8652],{},[283,18895,8655],{},[283,18897,8645],{},[266,18899,18900,18904,18906],{},[283,18901,18902],{},[42,18903,8664],{},[283,18905,8655],{},[283,18907,8607],{},[266,18909,18910,18914,18916],{},[283,18911,18912],{},[42,18913,8675],{},[283,18915,8630],{},[283,18917,8607],{},[13,18919,8682],{},[128,18921,18922,18924,18926,18928],{},[68,18923,8614],{},[68,18925,8652],{},[68,18927,8627],{},[68,18929,8675],{},[968,18931,8695],{},{"title":502,"searchDepth":535,"depth":535,"links":18933},[18934,18935,18936],{"id":8244,"depth":506,"text":8245},{"id":8361,"depth":506,"text":8362},{"id":8564,"depth":506,"text":8565},{"name":8702,"symbol":8703,"icon":8704,"id":863},{"type":10,"value":18939},[18940],[13,18941,8711],{},{},{"title":8032,"description":8706},{"loc":8713,"images":18945},[18946],{"loc":8338},[856],[18949],{"name":8724,"symbol":8725,"icon":8726,"id":856},{"id":8731,"title":8732,"articleId":8733,"articleThumb":8734,"body":18951,"categoryId":535,"categoryInfo":19135,"createDate":9013,"description":9014,"excerpt":19136,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":19140,"navigation":1003,"path":9021,"rawbody":9022,"readingTime":863,"seo":19141,"sitemap":19142,"stem":9044,"tagIds":19162,"tagInfo":19163,"updateDate":9051,"wordCount":9052,"__hash__":9053},{"type":10,"value":18952,"toc":19126},[18953,18955,18957,18959,18961,18963,18965,18967,18969,18971,18976,18980,18985,18989,18994,18998,19000,19004,19006,19010,19012,19014,19020,19024,19028,19032,19040,19044,19046,19050,19054,19058,19064,19068,19070,19074,19076,19080,19082,19086,19088,19090,19094,19102,19106,19116,19120,19124],[17,18954,8740],{"id":8739},[13,18956,8743],{},[123,18958,8747],{"id":8746},[13,18960,8750],{},[123,18962,8754],{"id":8753},[13,18964,8757],{},[123,18966,8761],{"id":8760},[13,18968,8764],{},[13,18970,8767],{},[13,18972,8770,18973,8776],{},[104,18974,8775],{"href":8773,"rel":18975,"target":28},[108],[13,18977,18978],{},[419,18979],{"alt":502,"src":8781},[13,18981,8784,18982,8790],{},[104,18983,8789],{"href":8787,"rel":18984,"target":28},[108],[13,18986,18987],{},[419,18988],{"alt":502,"src":8795},[13,18990,8798,18991,8804],{},[104,18992,8803],{"href":8801,"rel":18993,"target":28},[108],[13,18995,18996],{},[419,18997],{"alt":502,"src":8809},[13,18999,8812],{},[13,19001,19002],{},[419,19003],{"alt":502,"src":8817},[13,19005,8820],{},[13,19007,19008],{},[419,19009],{"alt":502,"src":8825},[13,19011,8828],{},[17,19013,8832],{"id":8831},[13,19015,8835,19016,8839,19018,8842],{},[42,19017,8838],{"color":116},[42,19019,8838],{"color":116},[13,19021,19022],{},[419,19023],{"alt":502,"src":8847},[13,19025,8850,19026],{},[42,19027,8853],{"color":116},[13,19029,19030],{},[419,19031],{"alt":502,"src":8858},[13,19033,8861,19034,8864,19036,8868,19038,8871],{},[42,19035,8853],{"color":116},[42,19037,8867],{"color":116},[42,19039,8853],{"color":116},[13,19041,19042],{},[419,19043],{"alt":502,"src":8876},[13,19045,8879],{},[13,19047,19048],{},[419,19049],{"alt":502,"src":8884},[13,19051,8887,19052,8891],{},[42,19053,8890],{"color":116},[13,19055,19056],{},[419,19057],{"alt":502,"src":8896},[13,19059,8899,19060,8903,19062,8907],{},[42,19061,8902],{"color":116},[42,19063,8906],{"color":116},[13,19065,19066],{},[419,19067],{"alt":502,"src":8912},[13,19069,8915],{},[13,19071,19072],{},[419,19073],{"alt":502,"src":8920},[13,19075,8923],{},[13,19077,19078],{},[419,19079],{"alt":502,"src":8928},[13,19081,8931],{},[13,19083,19084],{},[419,19085],{"alt":502,"src":8936},[17,19087,8940],{"id":8939},[13,19089,8943],{},[13,19091,19092],{},[419,19093],{"alt":502,"src":8948},[13,19095,8951,19096,567,19098,8958,19100,8962],{},[42,19097,8954],{"color":116},[42,19099,8957],{"color":116},[42,19101,8961],{"color":116},[13,19103,19104],{},[419,19105],{"alt":502,"src":8967},[13,19107,8970,19108,8974,19110,8978,19112,8982,19114,8986],{},[42,19109,8973],{"color":116},[42,19111,8977],{"color":116},[42,19113,8981],{"color":116},[42,19115,8985],{"color":116},[13,19117,19118],{},[419,19119],{"alt":502,"src":8991},[13,19121,19122],{},[419,19123],{"alt":502,"src":8996},[13,19125,8999],{},{"title":502,"searchDepth":535,"depth":535,"links":19127},[19128,19133,19134],{"id":8739,"depth":506,"text":8740,"children":19129},[19130,19131,19132],{"id":8746,"depth":535,"text":8747},{"id":8753,"depth":535,"text":8754},{"id":8760,"depth":535,"text":8761},{"id":8831,"depth":506,"text":8832},{"id":8939,"depth":506,"text":8940},{"name":9010,"symbol":9011,"icon":9012,"id":535},{"type":10,"value":19137},[19138],[13,19139,9019],{},{},{"title":8732,"description":9014},{"loc":9021,"images":19143},[19144,19145,19146,19147,19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161],{"loc":8781},{"loc":8795},{"loc":8809},{"loc":8817},{"loc":8825},{"loc":8847},{"loc":8858},{"loc":8876},{"loc":8884},{"loc":8896},{"loc":8912},{"loc":8920},{"loc":8928},{"loc":8936},{"loc":8948},{"loc":8967},{"loc":8991},{"loc":8996},[624],[19164],{"name":9048,"symbol":9049,"icon":9050,"id":624},{"id":9055,"title":9056,"articleId":9057,"articleThumb":9058,"body":19166,"categoryId":506,"categoryInfo":19732,"createDate":9864,"description":9865,"excerpt":19733,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":19737,"navigation":1003,"path":9872,"rawbody":9873,"readingTime":9874,"seo":19738,"sitemap":19739,"stem":9931,"tagIds":19794,"tagInfo":19795,"updateDate":9935,"wordCount":9936,"__hash__":9937},{"type":10,"value":19167,"toc":19715},[19168,19170,19172,19174,19176,19178,19180,19182,19186,19188,19193,19200,19204,19208,19212,19220,19232,19234,19240,19252,19259,19261,19263,19265,19269,19271,19275,19277,19281,19287,19291,19293,19297,19299,19303,19305,19309,19311,19315,19317,19321,19323,19327,19329,19333,19335,19339,19341,19345,19347,19351,19353,19355,19371,19373,19379,19381,19385,19389,19391,19395,19397,19401,19403,19411,19413,19417,19419,19423,19425,19429,19431,19435,19437,19441,19443,19447,19449,19453,19455,19459,19461,19465,19467,19471,19473,19477,19479,19483,19485,19489,19491,19495,19497,19501,19503,19507,19509,19513,19515,19519,19521,19525,19527,19531,19533,19535,19573,19575,19577,19581,19585,19587,19595,19597,19601,19603,19607,19609,19613,19615,19619,19621,19623,19625,19627,19629,19643,19645,19647,19649,19651,19655,19659,19665,19667,19691,19711,19713],[13,19169,9063],{},[17,19171,8740],{"id":8739},[13,19173,9068],{},[9070,19175],{"src":9072,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},[13,19177,9080],{},[123,19179,9084],{"id":9083},[13,19181,9087],{},[13,19183,9090,19184],{},[104,19185,8732],{"href":9093,"target":28},[123,19187,9097],{"id":9096},[13,19189,9100,19190,9106],{},[104,19191,9105],{"href":9103,"target":28,"rel":19192},[108],[13,19194,19195,19197],{},[71,19196,9111],{},[104,19198,9114],{"href":9114,"target":28,"rel":19199},[108],[13,19201,19202],{},[419,19203],{"alt":502,"src":9120},[13,19205,19206],{},[71,19207,9125],{},[13,19209,19210],{},[419,19211],{"alt":502,"src":9130},[13,19213,19214,19216,9138,19218,9142],{},[71,19215,9135],{},[290,19217],{},[419,19219],{"alt":502,"src":9141},[13,19221,19222,19224,9150,19226,9154,19228,9158,19230,9162],{},[71,19223,9147],{},[290,19225],{},[419,19227],{"alt":502,"src":9153},[42,19229,9157],{},[42,19231,9161],{},[123,19233,9166],{"id":9165},[13,19235,9169,19236,9173,19238,9176],{},[42,19237,9172],{"color":116},[42,19239,9172],{"color":116},[65,19241,19242,19247],{},[68,19243,9181,19244],{},[104,19245,9184],{"href":9184,"target":28,"rel":19246},[108],[68,19248,9188,19249],{},[104,19250,9191],{"href":9191,"target":28,"rel":19251},[108],[13,19253,9195,19254,9199,19256],{},[42,19255,9198],{},[104,19257,9202],{"href":9202,"target":28,"rel":19258},[108],[17,19260,9207],{"id":9206},[123,19262,9211],{"id":9210},[13,19264,9214],{},[13,19266,19267],{},[419,19268],{"alt":502,"src":9219},[13,19270,9222],{},[13,19272,19273],{},[419,19274],{"alt":502,"src":9227},[13,19276,9230],{},[13,19278,19279],{},[419,19280],{"alt":502,"src":9235},[13,19282,9238,19283,9242,19285],{},[42,19284,9241],{},[42,19286,9245],{},[13,19288,19289],{},[419,19290],{"alt":502,"src":9153},[13,19292,9252],{},[13,19294,19295],{},[419,19296],{"alt":502,"src":9257},[13,19298,9260],{},[13,19300,19301],{},[419,19302],{"alt":502,"src":9265},[13,19304,9268],{},[13,19306,19307],{},[419,19308],{"alt":502,"src":9273},[13,19310,9276],{},[13,19312,19313],{},[419,19314],{"alt":502,"src":9281},[13,19316,9284],{},[13,19318,19319],{},[419,19320],{"alt":502,"src":9289},[13,19322,9292],{},[13,19324,19325],{},[419,19326],{"alt":502,"src":9297},[13,19328,9300],{},[13,19330,19331],{},[419,19332],{"alt":502,"src":9305},[13,19334,9308],{},[13,19336,19337],{},[419,19338],{"alt":502,"src":9313},[13,19340,9316],{},[13,19342,19343],{},[419,19344],{"alt":502,"src":9321},[13,19346,9324],{},[13,19348,19349],{},[419,19350],{"alt":502,"src":9329},[123,19352,9333],{"id":9332},[13,19354,9336],{},[679,19356,19357],{"className":6858,"code":9339,"language":6860,"meta":502,"style":502},[42,19358,19359],{"__ignoreMap":502},[688,19360,19361,19363,19365,19367,19369],{"class":690,"line":691},[688,19362,9346],{"class":694},[688,19364,2046],{"class":697},[688,19366,3155],{"class":791},[688,19368,2240],{"class":697},[688,19370,6890],{"class":791},[13,19372,9357],{},[13,19374,9360,19375,9364,19377],{},[42,19376,9363],{},[419,19378],{"alt":502,"src":9367},[123,19380,9371],{"id":9370},[13,19382,9374,19383,9377],{},[42,19384,9363],{},[13,19386,19387],{},[419,19388],{"alt":502,"src":9382},[13,19390,9385],{},[13,19392,19393],{},[419,19394],{"alt":502,"src":9390},[13,19396,9393],{},[13,19398,19399],{},[419,19400],{"alt":502,"src":9398},[13,19402,9401],{},[13,19404,19405,19407,19409],{},[419,19406],{"alt":502,"src":9406},[419,19408],{"alt":502,"src":9409},[419,19410],{"alt":502,"src":9412},[13,19412,9415],{},[13,19414,19415],{},[419,19416],{"alt":502,"src":9420},[13,19418,9423],{},[13,19420,19421],{},[419,19422],{"alt":502,"src":9428},[13,19424,9431],{},[13,19426,19427],{},[419,19428],{"alt":502,"src":9436},[13,19430,9439],{},[13,19432,19433],{},[419,19434],{"alt":502,"src":9444},[13,19436,9447],{},[13,19438,19439],{},[419,19440],{"alt":502,"src":9452},[13,19442,9455],{},[13,19444,19445],{},[419,19446],{"alt":502,"src":9460},[13,19448,9463],{},[13,19450,19451],{},[419,19452],{"alt":502,"src":9468},[13,19454,9471],{},[13,19456,19457],{},[419,19458],{"alt":502,"src":9476},[13,19460,9479],{},[13,19462,19463],{},[419,19464],{"alt":502,"src":9484},[13,19466,9487],{},[13,19468,19469],{},[419,19470],{"alt":502,"src":9492},[13,19472,9495],{},[13,19474,19475],{},[419,19476],{"alt":502,"src":9500},[13,19478,9503],{},[13,19480,19481],{},[419,19482],{"alt":502,"src":9508},[13,19484,9511],{},[13,19486,19487],{},[419,19488],{"alt":502,"src":9516},[13,19490,9519],{},[13,19492,19493],{},[419,19494],{"alt":502,"src":9524},[13,19496,9527],{},[13,19498,19499],{},[419,19500],{"alt":502,"src":9532},[13,19502,9535],{},[13,19504,19505],{},[419,19506],{"alt":502,"src":9540},[13,19508,9543],{},[13,19510,19511],{},[419,19512],{"alt":502,"src":9548},[13,19514,9551],{},[13,19516,19517],{},[419,19518],{"alt":502,"src":9556},[13,19520,9559],{},[13,19522,19523],{},[419,19524],{"alt":502,"src":9564},[13,19526,9567],{},[13,19528,19529],{},[419,19530],{"alt":502,"src":9572},[123,19532,9576],{"id":9575},[13,19534,9579],{},[65,19536,19537,19545,19555,19563],{},[68,19538,9584,19539],{},[128,19540,19541,19543],{},[68,19542,9589],{},[68,19544,9592],{},[68,19546,9595,19547],{},[128,19548,19549,19551,19553],{},[68,19550,9600],{},[68,19552,9603],{},[68,19554,9606],{},[68,19556,9609,19557],{},[128,19558,19559,19561],{},[68,19560,9614],{},[68,19562,9617],{},[68,19564,9620,19565],{},[128,19566,19567,19569,19571],{},[68,19568,9625],{},[68,19570,9628],{},[68,19572,9631],{},[13,19574,9634],{},[13,19576,9637],{},[13,19578,9640,19579,9643],{},[290,19580],{},[13,19582,19583],{},[419,19584],{"alt":502,"src":9648},[13,19586,9651],{},[13,19588,19589,19591,19593],{},[419,19590],{"alt":502,"src":9656},[419,19592],{"alt":502,"src":9659},[419,19594],{"alt":502,"src":9662},[13,19596,9665],{},[13,19598,19599],{},[419,19600],{"alt":502,"src":9670},[13,19602,9673],{},[13,19604,19605],{},[419,19606],{"alt":502,"src":9678},[13,19608,9681],{},[13,19610,19611],{},[419,19612],{"alt":502,"src":9686},[13,19614,9689],{},[13,19616,19617],{},[419,19618],{"alt":502,"src":9694},[13,19620,9697],{},[13,19622,9700],{},[17,19624,9704],{"id":9703},[13,19626,9707],{},[123,19628,9711],{"id":9710},[13,19630,9714,19631,19633,9720,19635,19637,9726,19639,19641,9732],{},[290,19632],{},[71,19634,9719],{},[290,19636],{},[71,19638,9725],{},[290,19640],{},[71,19642,9731],{},[13,19644,9735],{},[9070,19646],{"src":9738,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},[123,19648,9742],{"id":9741},[13,19650,9745],{},[13,19652,19653,9751],{},[71,19654,9750],{},[13,19656,19657,9757],{},[71,19658,9756],{},[13,19660,9760,19661,9764,19663,9768],{},[42,19662,9763],{"color":116},[42,19664,9767],{"color":116},[9070,19666],{"src":9771,"scrolling":9073,"border":9074,"frameBorder":9073,"framespacing":2240,"allowFullScreen":9075,"width":9076,"height":9077},[13,19668,9774,19669,9777,19671,19674,9785,19676,19679,9792,19681,9795,19683,19686,9802,19688],{},[290,19670],{},[104,19672,9782],{"href":9780,"target":28,"rel":19673},[108],[290,19675],{},[104,19677,9782],{"href":9788,"target":28,"rel":19678},[108],[290,19680],{},[290,19682],{},[104,19684,9798],{"href":9798,"target":28,"rel":19685},[108],[290,19687],{},[104,19689,9805],{"href":9805,"target":28,"rel":19690},[108],[3056,19692,19693,19695],{},[13,19694,9811],{},[65,19696,19697,19699,19705,19709],{},[68,19698,9816],{},[68,19700,9819,19701,9823,19703,9827],{},[42,19702,9822],{},[42,19704,9826],{},[68,19706,9830,19707,9833],{},[42,19708,9826],{},[68,19710,9836],{},[13,19712,9839],{},[968,19714,9842],{},{"title":502,"searchDepth":535,"depth":535,"links":19716},[19717,19722,19728],{"id":8739,"depth":506,"text":8740,"children":19718},[19719,19720,19721],{"id":9083,"depth":535,"text":9084},{"id":9096,"depth":535,"text":9097},{"id":9165,"depth":535,"text":9166},{"id":9206,"depth":506,"text":9207,"children":19723},[19724,19725,19726,19727],{"id":9210,"depth":535,"text":9211},{"id":9332,"depth":535,"text":9333},{"id":9370,"depth":535,"text":9371},{"id":9575,"depth":535,"text":9576},{"id":9703,"depth":506,"text":9704,"children":19729},[19730,19731],{"id":9710,"depth":535,"text":9711},{"id":9741,"depth":535,"text":9742},{"name":9861,"symbol":9862,"icon":9863,"id":506},{"type":10,"value":19734},[19735],[13,19736,9870],{},{},{"title":9056,"description":9865},{"loc":9872,"images":19740},[19741,19742,19743,19744,19745,19746,19747,19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,19784,19785,19786,19787,19788,19789,19790,19791,19792,19793],{"loc":9120},{"loc":9130},{"loc":9141},{"loc":9153},{"loc":9219},{"loc":9227},{"loc":9235},{"loc":9153},{"loc":9257},{"loc":9265},{"loc":9273},{"loc":9281},{"loc":9289},{"loc":9297},{"loc":9305},{"loc":9313},{"loc":9321},{"loc":9329},{"loc":9367},{"loc":9382},{"loc":9390},{"loc":9398},{"loc":9406},{"loc":9409},{"loc":9412},{"loc":9420},{"loc":9428},{"loc":9436},{"loc":9444},{"loc":9452},{"loc":9460},{"loc":9468},{"loc":9476},{"loc":9484},{"loc":9492},{"loc":9500},{"loc":9508},{"loc":9516},{"loc":9524},{"loc":9532},{"loc":9540},{"loc":9548},{"loc":9556},{"loc":9564},{"loc":9572},{"loc":9648},{"loc":9656},{"loc":9659},{"loc":9662},{"loc":9670},{"loc":9678},{"loc":9686},{"loc":9694},[624],[19796],{"name":9048,"symbol":9049,"icon":9050,"id":624},{"id":9939,"title":9940,"articleId":9941,"articleThumb":9942,"body":19798,"categoryId":905,"categoryInfo":20479,"createDate":10821,"description":10822,"excerpt":20480,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1002,"isTop":1002,"meta":20484,"navigation":1003,"path":10829,"rawbody":10830,"readingTime":10831,"seo":20485,"sitemap":20486,"stem":10839,"tagIds":20492,"tagInfo":20493,"updateDate":10845,"wordCount":10846,"__hash__":10847},{"type":10,"value":19799,"toc":20468},[19800,19802,19804,19806,19808,19810,19820,19824,19826,19836,19840,19842,19848,19854,19862,19876,19880,19890,19896,19900,19912,19914,19928,19932,20130,20132,20138,20140,20174,20176,20194,20196,20198,20200,20206,20208,20212,20214,20250,20256,20292,20296,20298,20322,20328,20332,20334,20362,20364,20388,20392,20394,20430,20432,20464,20466],[17,19801,9948],{"id":9947},[13,19803,9951],{},[13,19805,9954],{},[123,19807,9958],{"id":9957},[13,19809,9961],{},[679,19811,19812],{"className":9964,"code":9965,"language":9966,"meta":502,"style":502},[42,19813,19814],{"__ignoreMap":502},[688,19815,19816,19818],{"class":690,"line":691},[688,19817,9973],{"class":694},[688,19819,9976],{"class":697},[13,19821,19822],{},[419,19823],{"alt":502,"src":9981},[13,19825,9984],{},[679,19827,19828],{"className":9964,"code":9987,"language":9966,"meta":502,"style":502},[42,19829,19830],{"__ignoreMap":502},[688,19831,19832,19834],{"class":690,"line":691},[688,19833,9994],{"class":694},[688,19835,9976],{"class":697},[13,19837,19838],{},[419,19839],{"alt":502,"src":10001},[123,19841,10005],{"id":10004},[13,19843,10008,19844,10012,19846,10016],{},[42,19845,10011],{"color":116},[42,19847,10015],{"color":116},[128,19849,19850],{},[68,19851,19852],{},[71,19853,10023],{},[13,19855,10026,19856,10030,19858,10033,19860,10036],{},[71,19857,10029],{},[42,19859,10011],{"color":116},[290,19861],{},[679,19863,19864],{"className":681,"code":10039,"language":684,"meta":502,"style":502},[42,19865,19866],{"__ignoreMap":502},[688,19867,19868,19870,19872,19874],{"class":690,"line":691},[688,19869,10046],{"class":791},[688,19871,10049],{"class":694},[688,19873,10052],{"class":787},[688,19875,10055],{"class":697},[13,19877,10058,19878,10061],{},[290,19879],{},[679,19881,19882],{"className":681,"code":10064,"language":684,"meta":502,"style":502},[42,19883,19884],{"__ignoreMap":502},[688,19885,19886,19888],{"class":690,"line":691},[688,19887,10071],{"class":694},[688,19889,10074],{"class":697},[128,19891,19892],{},[68,19893,19894],{},[71,19895,10081],{},[13,19897,10084,19898,10087],{},[290,19899],{},[679,19901,19902],{"className":681,"code":10090,"language":684,"meta":502,"style":502},[42,19903,19904],{"__ignoreMap":502},[688,19905,19906,19908,19910],{"class":690,"line":691},[688,19907,10097],{"class":694},[688,19909,10100],{"class":697},[688,19911,10103],{"class":697},[13,19913,10106],{},[679,19915,19916],{"className":681,"code":10039,"language":684,"meta":502,"style":502},[42,19917,19918],{"__ignoreMap":502},[688,19919,19920,19922,19924,19926],{"class":690,"line":691},[688,19921,10046],{"class":791},[688,19923,10049],{"class":694},[688,19925,10052],{"class":787},[688,19927,10055],{"class":697},[13,19929,10123,19930,10126],{},[290,19931],{},[6807,19933,19934,19944,20128],{"color":116,"icon":10129},[13,19935,6812,19936,10134,19938,10137,19940,10141,19942,10145],{},[290,19937],{},[290,19939],{},[42,19941,10140],{},[42,19943,10144],{},[679,19945,19946],{"className":681,"code":10148,"language":684,"meta":502,"style":502},[42,19947,19948,19954,19960,19966,19972,19978,19984,19990,19996,20002,20008,20014,20020,20026,20032,20038,20044,20050,20056,20062,20068,20074,20080,20086,20092,20098,20104,20110,20116,20122],{"__ignoreMap":502},[688,19949,19950,19952],{"class":690,"line":691},[688,19951,10155],{"class":694},[688,19953,10158],{"class":697},[688,19955,19956,19958],{"class":690,"line":506},[688,19957,10163],{"class":694},[688,19959,10166],{"class":697},[688,19961,19962,19964],{"class":690,"line":535},[688,19963,10171],{"class":694},[688,19965,10174],{"class":697},[688,19967,19968,19970],{"class":690,"line":609},[688,19969,10179],{"class":694},[688,19971,10182],{"class":697},[688,19973,19974,19976],{"class":690,"line":624},[688,19975,10187],{"class":694},[688,19977,10190],{"class":697},[688,19979,19980,19982],{"class":690,"line":856},[688,19981,10171],{"class":694},[688,19983,10197],{"class":697},[688,19985,19986,19988],{"class":690,"line":863},[688,19987,10202],{"class":694},[688,19989,10205],{"class":697},[688,19991,19992,19994],{"class":690,"line":874},[688,19993,10210],{"class":694},[688,19995,10213],{"class":697},[688,19997,19998,20000],{"class":690,"line":890},[688,19999,10218],{"class":694},[688,20001,10221],{"class":697},[688,20003,20004,20006],{"class":690,"line":896},[688,20005,10210],{"class":694},[688,20007,10228],{"class":697},[688,20009,20010,20012],{"class":690,"line":905},[688,20011,10233],{"class":694},[688,20013,10236],{"class":697},[688,20015,20016,20018],{"class":690,"line":2096},[688,20017,10241],{"class":694},[688,20019,10244],{"class":697},[688,20021,20022,20024],{"class":690,"line":2138},[688,20023,10171],{"class":694},[688,20025,10251],{"class":697},[688,20027,20028,20030],{"class":690,"line":2143},[688,20029,10171],{"class":694},[688,20031,10258],{"class":697},[688,20033,20034,20036],{"class":690,"line":2149},[688,20035,10187],{"class":694},[688,20037,10265],{"class":697},[688,20039,20040,20042],{"class":690,"line":2185},[688,20041,10171],{"class":694},[688,20043,10272],{"class":697},[688,20045,20046,20048],{"class":690,"line":2261},[688,20047,10171],{"class":694},[688,20049,10279],{"class":697},[688,20051,20052,20054],{"class":690,"line":2267},[688,20053,10284],{"class":694},[688,20055,10287],{"class":697},[688,20057,20058,20060],{"class":690,"line":2277},[688,20059,10171],{"class":694},[688,20061,10294],{"class":697},[688,20063,20064,20066],{"class":690,"line":2283},[688,20065,10171],{"class":694},[688,20067,10301],{"class":697},[688,20069,20070,20072],{"class":690,"line":2288},[688,20071,10284],{"class":694},[688,20073,10308],{"class":697},[688,20075,20076,20078],{"class":690,"line":2294},[688,20077,10313],{"class":694},[688,20079,10316],{"class":697},[688,20081,20082,20084],{"class":690,"line":2761},[688,20083,10321],{"class":694},[688,20085,10324],{"class":697},[688,20087,20088,20090],{"class":690,"line":2768},[688,20089,10329],{"class":694},[688,20091,10332],{"class":697},[688,20093,20094,20096],{"class":690,"line":2773},[688,20095,10337],{"class":694},[688,20097,10340],{"class":697},[688,20099,20100,20102],{"class":690,"line":2779},[688,20101,10345],{"class":694},[688,20103,10348],{"class":697},[688,20105,20106,20108],{"class":690,"line":2795},[688,20107,10353],{"class":694},[688,20109,10356],{"class":697},[688,20111,20112,20114],{"class":690,"line":5013},[688,20113,10361],{"class":694},[688,20115,10364],{"class":697},[688,20117,20118,20120],{"class":690,"line":5032},[688,20119,10369],{"class":694},[688,20121,10372],{"class":697},[688,20123,20124,20126],{"class":690,"line":5078},[688,20125,10171],{"class":694},[688,20127,10379],{"class":697},[13,20129,10382],{},[123,20131,10386],{"id":10385},[13,20133,10389,20134,10393,20136,10396],{},[42,20135,10392],{},[42,20137,10140],{},[13,20139,10399],{},[65,20141,20142,20146,20150,20154,20158,20162,20166,20170],{},[68,20143,20144,10407],{},[71,20145,10406],{},[68,20147,20148,10413],{},[71,20149,10412],{},[68,20151,20152,10419],{},[71,20153,10418],{},[68,20155,20156,10425],{},[71,20157,10424],{},[68,20159,20160,10431],{},[71,20161,10430],{},[68,20163,132,20164,10437],{},[71,20165,10436],{},[68,20167,132,20168,10443],{},[71,20169,10442],{},[68,20171,20172,10449],{},[71,20173,10448],{},[13,20175,10452],{},[128,20177,20178,20182,20186,20190],{},[68,20179,20180,10460],{},[71,20181,10459],{},[68,20183,20184,10466],{},[71,20185,10465],{},[68,20187,20188,10472],{},[71,20189,10471],{},[68,20191,20192,10478],{},[71,20193,10477],{},[17,20195,10482],{"id":10481},[13,20197,10485],{},[123,20199,10489],{"id":10488},[13,20201,10492,20202,10496,20204],{},[419,20203],{"alt":502,"src":10495},[419,20205],{"alt":502,"src":10499},[123,20207,10503],{"id":10502},[13,20209,20210],{},[71,20211,10508],{},[13,20213,10511],{},[679,20215,20216],{"className":681,"code":10514,"language":684,"meta":502,"style":502},[42,20217,20218,20222,20234,20238],{"__ignoreMap":502},[688,20219,20220],{"class":690,"line":691},[688,20221,10521],{"class":859},[688,20223,20224,20226,20228,20230,20232],{"class":690,"line":506},[688,20225,10526],{"class":694},[688,20227,10529],{"class":697},[688,20229,10532],{"class":697},[688,20231,10535],{"class":697},[688,20233,10538],{"class":697},[688,20235,20236],{"class":690,"line":535},[688,20237,10543],{"class":859},[688,20239,20240,20242,20244,20246,20248],{"class":690,"line":609},[688,20241,10526],{"class":694},[688,20243,10529],{"class":697},[688,20245,10532],{"class":697},[688,20247,10554],{"class":697},[688,20249,10557],{"class":697},[13,20251,744,20252,648,20254,10566],{},[42,20253,10562],{},[42,20255,10565],{},[679,20257,20258],{"className":681,"code":10569,"language":684,"meta":502,"style":502},[42,20259,20260,20264,20276,20280],{"__ignoreMap":502},[688,20261,20262],{"class":690,"line":691},[688,20263,10521],{"class":859},[688,20265,20266,20268,20270,20272,20274],{"class":690,"line":506},[688,20267,10526],{"class":694},[688,20269,10529],{"class":697},[688,20271,10532],{"class":697},[688,20273,10535],{"class":697},[688,20275,10588],{"class":697},[688,20277,20278],{"class":690,"line":535},[688,20279,10543],{"class":859},[688,20281,20282,20284,20286,20288,20290],{"class":690,"line":609},[688,20283,10526],{"class":694},[688,20285,10529],{"class":697},[688,20287,10532],{"class":697},[688,20289,10554],{"class":697},[688,20291,10605],{"class":697},[13,20293,20294],{},[71,20295,10610],{},[13,20297,10613],{},[679,20299,20300],{"className":681,"code":10616,"language":684,"meta":502,"style":502},[42,20301,20302,20312],{"__ignoreMap":502},[688,20303,20304,20306,20308,20310],{"class":690,"line":691},[688,20305,10526],{"class":694},[688,20307,10529],{"class":697},[688,20309,10535],{"class":697},[688,20311,10538],{"class":697},[688,20313,20314,20316,20318,20320],{"class":690,"line":506},[688,20315,10526],{"class":694},[688,20317,10529],{"class":697},[688,20319,10554],{"class":697},[688,20321,10557],{"class":697},[13,20323,10641,20324,648,20326,10646],{},[42,20325,10562],{},[42,20327,10565],{},[13,20329,20330],{},[71,20331,10651],{},[13,20333,10654],{},[679,20335,20336],{"className":681,"code":10657,"language":684,"meta":502,"style":502},[42,20337,20338,20350],{"__ignoreMap":502},[688,20339,20340,20342,20344,20346,20348],{"class":690,"line":691},[688,20341,10526],{"class":694},[688,20343,10529],{"class":697},[688,20345,10532],{"class":697},[688,20347,10670],{"class":697},[688,20349,10673],{"class":697},[688,20351,20352,20354,20356,20358,20360],{"class":690,"line":506},[688,20353,10526],{"class":694},[688,20355,10529],{"class":697},[688,20357,10532],{"class":697},[688,20359,10670],{"class":697},[688,20361,10686],{"class":697},[13,20363,10689],{},[679,20365,20366],{"className":681,"code":10692,"language":684,"meta":502,"style":502},[42,20367,20368,20378],{"__ignoreMap":502},[688,20369,20370,20372,20374,20376],{"class":690,"line":691},[688,20371,10526],{"class":694},[688,20373,10529],{"class":697},[688,20375,10670],{"class":697},[688,20377,10673],{"class":697},[688,20379,20380,20382,20384,20386],{"class":690,"line":506},[688,20381,10526],{"class":694},[688,20383,10529],{"class":697},[688,20385,10670],{"class":697},[688,20387,10686],{"class":697},[13,20389,20390],{},[71,20391,10719],{},[13,20393,10722],{},[679,20395,20396],{"className":681,"code":10725,"language":684,"meta":502,"style":502},[42,20397,20398,20402,20414,20418],{"__ignoreMap":502},[688,20399,20400],{"class":690,"line":691},[688,20401,10732],{"class":859},[688,20403,20404,20406,20408,20410,20412],{"class":690,"line":506},[688,20405,10526],{"class":694},[688,20407,10529],{"class":697},[688,20409,10532],{"class":697},[688,20411,10743],{"class":697},[688,20413,10746],{"class":697},[688,20415,20416],{"class":690,"line":535},[688,20417,10751],{"class":859},[688,20419,20420,20422,20424,20426,20428],{"class":690,"line":609},[688,20421,10526],{"class":694},[688,20423,10529],{"class":697},[688,20425,10532],{"class":697},[688,20427,10743],{"class":697},[688,20429,10764],{"class":697},[13,20431,10689],{},[679,20433,20434],{"className":681,"code":10769,"language":684,"meta":502,"style":502},[42,20435,20436,20440,20450,20454],{"__ignoreMap":502},[688,20437,20438],{"class":690,"line":691},[688,20439,10732],{"class":859},[688,20441,20442,20444,20446,20448],{"class":690,"line":506},[688,20443,10526],{"class":694},[688,20445,10529],{"class":697},[688,20447,10784],{"class":697},[688,20449,10746],{"class":697},[688,20451,20452],{"class":690,"line":535},[688,20453,10751],{"class":859},[688,20455,20456,20458,20460,20462],{"class":690,"line":609},[688,20457,10526],{"class":694},[688,20459,10529],{"class":697},[688,20461,10784],{"class":697},[688,20463,10764],{"class":697},[13,20465,10803],{},[968,20467,10806],{},{"title":502,"searchDepth":535,"depth":535,"links":20469},[20470,20475],{"id":9947,"depth":506,"text":9948,"children":20471},[20472,20473,20474],{"id":9957,"depth":535,"text":9958},{"id":10004,"depth":535,"text":10005},{"id":10385,"depth":535,"text":10386},{"id":10481,"depth":506,"text":10482,"children":20476},[20477,20478],{"id":10488,"depth":535,"text":10489},{"id":10502,"depth":535,"text":10503},{"name":10819,"symbol":7523,"icon":10820,"id":905},{"type":10,"value":20481},[20482],[13,20483,10827],{},{},{"title":9940,"description":10822},{"loc":10829,"images":20487},[20488,20489,20490,20491],{"loc":9981},{"loc":10001},{"loc":10495},{"loc":10499},[905],[20494],{"name":10843,"symbol":10526,"icon":10844,"id":905},{"id":10849,"title":10850,"articleId":10851,"articleThumb":10852,"body":20496,"categoryId":896,"categoryInfo":21286,"createDate":11878,"description":11879,"excerpt":21287,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1002,"meta":21291,"navigation":1003,"path":11886,"rawbody":11887,"readingTime":11888,"seo":21292,"sitemap":21293,"stem":11891,"tagIds":21294,"tagInfo":21295,"updateDate":11897,"wordCount":11898,"__hash__":11899},{"type":10,"value":20497,"toc":21272},[20498,20506,20508,20517,20549,20551,20563,20567,20572,20578,20580,20586,20590,20604,20608,20610,20620,20622,20624,20632,20636,20640,20660,20664,20684,20688,20690,20768,20774,20778,20790,20794,20806,20808,20810,20816,20818,20822,20898,20902,20910,20912,20942,20946,20950,20982,20986,21000,21002,21006,21018,21024,21028,21040,21044,21132,21136,21146,21148,21150,21154,21162,21166,21172,21174,21178,21184,21192,21196,21202,21248,21260,21270],[6807,20499,20500],{"color":116,"icon":6809,"target":28,"to":10857},[13,20501,10860,20502,10864,20504,10867],{},[42,20503,10863],{},[42,20505,10863],{},[17,20507,10871],{"id":10870},[13,20509,10874,20510,10880,20513,10883,20515,10886],{},[104,20511,10879],{"href":10877,"rel":20512},[108],[42,20514,10863],{},[42,20516,10863],{},[1058,20518,20519,20525],{},[13,20520,20521,10894,20523],{},[71,20522,10893],{},[290,20524],{},[65,20526,20527,20533],{},[68,20528,10901,20529,10904,20531,10907],{},[42,20530,10863],{},[42,20532,6694],{},[68,20534,10910,20535,10914,20537,10917,20539,10921,20541,10924,20543,10927,20545,10931,20547,10934],{},[42,20536,10913],{},[42,20538,6694],{},[42,20540,10920],{},[42,20542,6694],{},[42,20544,10920],{},[42,20546,10930],{},[42,20548,10920],{},[123,20550,10938],{"id":10937},[13,20552,10941,20553,10945,20555,10949,20557,10953,20559,10956,20561,10960],{},[42,20554,10944],{},[42,20556,10948],{},[42,20558,10952],{},[42,20560,10863],{},[42,20562,10959],{},[13,20564,20565],{},[71,20566,10965],{},[13,20568,10874,20569,10972],{},[104,20570,10948],{"href":10970,"rel":20571},[108],[128,20573,20574,20576],{},[68,20575,10977],{},[68,20577,10980],{},[13,20579,10983],{},[3056,20581,20582],{},[13,20583,10988,20584,10991],{},[42,20585,10863],{},[13,20587,20588],{},[71,20589,10996],{},[65,20591,20592,20594,20598,20602],{},[68,20593,11001],{},[68,20595,11004,20596,11007],{},[42,20597,10863],{},[68,20599,11010,20600,11013],{},[42,20601,6694],{},[68,20603,11016],{},[13,20605,20606],{},[71,20607,11021],{},[13,20609,11024],{},[679,20611,20612],{"className":6858,"code":11027,"language":6860,"meta":502,"style":502},[42,20613,20614],{"__ignoreMap":502},[688,20615,20616,20618],{"class":690,"line":691},[688,20617,10863],{"class":694},[688,20619,11036],{"class":697},[13,20621,11039],{},[123,20623,11043],{"id":11042},[13,20625,11046,20626,11049,20628,11053,20630,11057],{},[42,20627,10863],{},[42,20629,11052],{},[42,20631,11056],{},[13,20633,20634],{},[71,20635,11062],{},[128,20637,20638],{},[68,20639,11067],{},[679,20641,20642],{"className":766,"code":11070,"language":769,"meta":502,"style":502},[42,20643,20644],{"__ignoreMap":502},[688,20645,20646,20648,20650,20652,20654,20656,20658],{"class":690,"line":691},[688,20647,11077],{"class":787},[688,20649,11080],{"class":791},[688,20651,11083],{"class":787},[688,20653,11080],{"class":791},[688,20655,11088],{"class":694},[688,20657,801],{"class":791},[688,20659,11093],{"class":859},[128,20661,20662],{},[68,20663,11098],{},[679,20665,20666],{"className":766,"code":11101,"language":769,"meta":502,"style":502},[42,20667,20668],{"__ignoreMap":502},[688,20669,20670,20672,20674,20676,20678,20680,20682],{"class":690,"line":691},[688,20671,11108],{"class":787},[688,20673,11080],{"class":791},[688,20675,11113],{"class":787},[688,20677,11080],{"class":791},[688,20679,11088],{"class":694},[688,20681,801],{"class":791},[688,20683,11093],{"class":859},[13,20685,20686],{},[71,20687,11126],{},[13,20689,11129],{},[679,20691,20692],{"className":766,"code":11132,"language":769,"meta":502,"style":502},[42,20693,20694,20708,20738],{"__ignoreMap":502},[688,20695,20696,20698,20700,20702,20704,20706],{"class":690,"line":691},[688,20697,777],{"class":2013},[688,20699,11141],{"class":787},[688,20701,2303],{"class":791},[688,20703,2312],{"class":791},[688,20705,11148],{"class":697},[688,20707,6890],{"class":791},[688,20709,20710,20712,20714,20716,20718,20720,20722,20724,20726,20728,20730,20732,20734,20736],{"class":690,"line":506},[688,20711,11155],{"class":787},[688,20713,11080],{"class":791},[688,20715,11160],{"class":787},[688,20717,2312],{"class":791},[688,20719,11165],{"class":697},[688,20721,2312],{"class":791},[688,20723,11170],{"class":787},[688,20725,11173],{"class":791},[688,20727,11176],{"class":787},[688,20729,2072],{"class":791},[688,20731,3155],{"class":791},[688,20733,11165],{"class":697},[688,20735,2312],{"class":791},[688,20737,11187],{"class":787},[688,20739,20740,20742,20744,20746,20748,20750,20752,20754,20756,20758,20760,20762,20764,20766],{"class":690,"line":535},[688,20741,11155],{"class":787},[688,20743,11080],{"class":791},[688,20745,11160],{"class":787},[688,20747,2312],{"class":791},[688,20749,11200],{"class":697},[688,20751,2312],{"class":791},[688,20753,11170],{"class":787},[688,20755,11173],{"class":791},[688,20757,11176],{"class":787},[688,20759,2072],{"class":791},[688,20761,3155],{"class":791},[688,20763,11200],{"class":697},[688,20765,2312],{"class":791},[688,20767,11219],{"class":787},[223,20769,20770],{},[13,20771,11224,20772,11228],{},[42,20773,11227],{},[13,20775,20776],{},[71,20777,11233],{},[679,20779,20780],{"className":766,"code":11236,"language":769,"meta":502,"style":502},[42,20781,20782],{"__ignoreMap":502},[688,20783,20784,20786,20788],{"class":690,"line":691},[688,20785,11243],{"class":787},[688,20787,11246],{"class":791},[688,20789,11249],{"class":787},[13,20791,20792],{},[71,20793,11254],{},[679,20795,20796],{"className":766,"code":11027,"language":769,"meta":502,"style":502},[42,20797,20798],{"__ignoreMap":502},[688,20799,20800,20802,20804],{"class":690,"line":691},[688,20801,11263],{"class":787},[688,20803,11080],{"class":791},[688,20805,11268],{"class":787},[13,20807,11271],{},[17,20809,11275],{"id":11274},[13,20811,11278,20812,11281,20814,11284],{},[42,20813,10863],{},[42,20815,6694],{},[123,20817,11288],{"id":11287},[13,20819,20820],{},[71,20821,11293],{},[679,20823,20824],{"className":766,"code":11296,"language":769,"meta":502,"style":502},[42,20825,20826,20838,20842,20846,20854,20862,20870,20874,20886,20890],{"__ignoreMap":502},[688,20827,20828,20830,20832,20834,20836],{"class":690,"line":691},[688,20829,11303],{"class":787},[688,20831,2312],{"class":791},[688,20833,6695],{"class":697},[688,20835,2312],{"class":791},[688,20837,11312],{"class":787},[688,20839,20840],{"class":690,"line":506},[688,20841,11317],{"class":787},[688,20843,20844],{"class":690,"line":535},[688,20845,11322],{"class":787},[688,20847,20848,20850,20852],{"class":690,"line":609},[688,20849,11327],{"class":787},[688,20851,11330],{"class":791},[688,20853,11333],{"class":787},[688,20855,20856,20858,20860],{"class":690,"line":624},[688,20857,11338],{"class":787},[688,20859,2072],{"class":791},[688,20861,11343],{"class":787},[688,20863,20864,20866,20868],{"class":690,"line":856},[688,20865,11327],{"class":787},[688,20867,11350],{"class":2220},[688,20869,4149],{"class":787},[688,20871,20872],{"class":690,"line":863},[688,20873,11357],{"class":787},[688,20875,20876,20878,20880,20882,20884],{"class":690,"line":874},[688,20877,11327],{"class":787},[688,20879,11364],{"class":2220},[688,20881,2072],{"class":791},[688,20883,2240],{"class":2220},[688,20885,902],{"class":787},[688,20887,20888],{"class":690,"line":890},[688,20889,11375],{"class":787},[688,20891,20892,20894,20896],{"class":690,"line":896},[688,20893,11380],{"class":787},[688,20895,2072],{"class":791},[688,20897,11385],{"class":2220},[13,20899,20900],{},[71,20901,11390],{},[679,20903,20904],{"className":766,"code":11393,"language":769,"meta":502,"style":502},[42,20905,20906],{"__ignoreMap":502},[688,20907,20908],{"class":690,"line":691},[688,20909,11393],{"class":787},[13,20911,11402],{},[679,20913,20914],{"className":766,"code":11405,"language":769,"meta":502,"style":502},[42,20915,20916,20924,20932],{"__ignoreMap":502},[688,20917,20918,20920,20922],{"class":690,"line":691},[688,20919,11412],{"class":787},[688,20921,2072],{"class":791},[688,20923,11417],{"class":2220},[688,20925,20926,20928,20930],{"class":690,"line":506},[688,20927,11422],{"class":787},[688,20929,2072],{"class":791},[688,20931,11427],{"class":2220},[688,20933,20934,20936,20938,20940],{"class":690,"line":535},[688,20935,11432],{"class":791},[688,20937,11435],{"class":787},[688,20939,2072],{"class":791},[688,20941,11440],{"class":2220},[13,20943,11443,20944,11446],{},[42,20945,6694],{},[13,20947,20948],{},[71,20949,11451],{},[679,20951,20952],{"className":766,"code":11454,"language":769,"meta":502,"style":502},[42,20953,20954,20962,20968,20972],{"__ignoreMap":502},[688,20955,20956,20958,20960],{"class":690,"line":691},[688,20957,11461],{"class":787},[688,20959,2072],{"class":791},[688,20961,11466],{"class":787},[688,20963,20964,20966],{"class":690,"line":506},[688,20965,11471],{"class":787},[688,20967,11474],{"class":2220},[688,20969,20970],{"class":690,"line":535},[688,20971,11479],{"class":787},[688,20973,20974,20976,20978,20980],{"class":690,"line":609},[688,20975,11471],{"class":787},[688,20977,11364],{"class":2220},[688,20979,2072],{"class":791},[688,20981,11490],{"class":2220},[13,20983,20984],{},[71,20985,11495],{},[679,20987,20988],{"className":766,"code":11498,"language":769,"meta":502,"style":502},[42,20989,20990],{"__ignoreMap":502},[688,20991,20992,20994,20996,20998],{"class":690,"line":691},[688,20993,11505],{"class":787},[688,20995,11364],{"class":2220},[688,20997,2072],{"class":791},[688,20999,11490],{"class":2220},[123,21001,11515],{"id":11514},[13,21003,21004],{},[71,21005,11520],{},[679,21007,21008],{"className":766,"code":11523,"language":769,"meta":502,"style":502},[42,21009,21010],{"__ignoreMap":502},[688,21011,21012,21014,21016],{"class":690,"line":691},[688,21013,11530],{"class":787},[688,21015,11533],{"class":776},[688,21017,11536],{"class":2220},[13,21019,11539,21020,11542,21022,11545],{},[42,21021,6860],{},[42,21023,6694],{},[13,21025,21026],{},[71,21027,11550],{},[679,21029,21030],{"className":766,"code":11553,"language":769,"meta":502,"style":502},[42,21031,21032],{"__ignoreMap":502},[688,21033,21034,21036,21038],{"class":690,"line":691},[688,21035,11560],{"class":787},[688,21037,11080],{"class":791},[688,21039,11565],{"class":787},[13,21041,21042],{},[71,21043,11570],{},[679,21045,21046],{"className":766,"code":11573,"language":769,"meta":502,"style":502},[42,21047,21048,21052,21060,21080,21096,21116],{"__ignoreMap":502},[688,21049,21050],{"class":690,"line":691},[688,21051,11580],{"class":787},[688,21053,21054,21056,21058],{"class":690,"line":506},[688,21055,11585],{"class":787},[688,21057,11330],{"class":791},[688,21059,11590],{"class":787},[688,21061,21062,21064,21066,21068,21070,21072,21074,21076,21078],{"class":690,"line":535},[688,21063,11595],{"class":787},[688,21065,2072],{"class":791},[688,21067,11600],{"class":787},[688,21069,11603],{"class":2220},[688,21071,2072],{"class":791},[688,21073,3194],{"class":2220},[688,21075,11610],{"class":787},[688,21077,2072],{"class":791},[688,21079,11615],{"class":787},[688,21081,21082,21084,21086,21088,21090,21092,21094],{"class":690,"line":609},[688,21083,11620],{"class":787},[688,21085,11603],{"class":2220},[688,21087,2072],{"class":791},[688,21089,3194],{"class":2220},[688,21091,11629],{"class":787},[688,21093,11330],{"class":791},[688,21095,11590],{"class":787},[688,21097,21098,21100,21102,21104,21106,21108,21110,21112,21114],{"class":690,"line":624},[688,21099,11595],{"class":787},[688,21101,2072],{"class":791},[688,21103,11600],{"class":787},[688,21105,11603],{"class":2220},[688,21107,2072],{"class":791},[688,21109,3194],{"class":2220},[688,21111,11610],{"class":787},[688,21113,2072],{"class":791},[688,21115,11615],{"class":787},[688,21117,21118,21120,21122,21124,21126,21128,21130],{"class":690,"line":856},[688,21119,11658],{"class":787},[688,21121,11603],{"class":2220},[688,21123,2072],{"class":791},[688,21125,3194],{"class":2220},[688,21127,11629],{"class":787},[688,21129,11330],{"class":791},[688,21131,11590],{"class":787},[13,21133,21134],{},[71,21135,11675],{},[679,21137,21138],{"className":766,"code":11678,"language":769,"meta":502,"style":502},[42,21139,21140],{"__ignoreMap":502},[688,21141,21142,21144],{"class":690,"line":691},[688,21143,11685],{"class":787},[688,21145,11688],{"class":2220},[17,21147,11691],{"id":9703},[123,21149,11695],{"id":11694},[13,21151,21152],{},[71,21153,11700],{},[128,21155,21156,21158,21160],{},[68,21157,11705],{},[68,21159,11708],{},[68,21161,11711],{},[13,21163,21164],{},[71,21165,11716],{},[128,21167,21168,21170],{},[68,21169,11721],{},[68,21171,11724],{},[123,21173,11728],{"id":11727},[13,21175,21176],{},[71,21177,11733],{},[128,21179,21180,21182],{},[68,21181,11738],{},[68,21183,11741],{},[13,21185,11744,21186,11748,21188,11752,21190],{},[42,21187,11747],{"color":116},[42,21189,11751],{"color":116},[42,21191,11755],{"color":116},[13,21193,21194],{},[71,21195,11760],{},[13,21197,11763,21198,11766,21200,11769],{},[42,21199,10913],{},[42,21201,6694],{},[679,21203,21204],{"className":681,"code":11772,"language":684,"meta":502,"style":502},[42,21205,21206,21210,21216,21220,21230,21234,21238,21242],{"__ignoreMap":502},[688,21207,21208],{"class":690,"line":691},[688,21209,11779],{"class":859},[688,21211,21212,21214],{"class":690,"line":506},[688,21213,11784],{"class":694},[688,21215,11787],{"class":697},[688,21217,21218],{"class":690,"line":535},[688,21219,11792],{"class":859},[688,21221,21222,21224,21226,21228],{"class":690,"line":609},[688,21223,777],{"class":2013},[688,21225,11799],{"class":787},[688,21227,2303],{"class":791},[688,21229,11804],{"class":787},[688,21231,21232],{"class":690,"line":624},[688,21233,11809],{"class":859},[688,21235,21236],{"class":690,"line":856},[688,21237,11814],{"class":694},[688,21239,21240],{"class":690,"line":863},[688,21241,11819],{"class":859},[688,21243,21244,21246],{"class":690,"line":874},[688,21245,11824],{"class":783},[688,21247,11827],{"class":697},[13,21249,11763,21250,11833,21252,11836,21254,11839,21256,11842,21258,11846],{},[42,21251,11832],{},[42,21253,10879],{},[42,21255,6694],{},[42,21257,10863],{},[42,21259,11845],{},[679,21261,21262],{"className":681,"code":11849,"language":684,"meta":502,"style":502},[42,21263,21264],{"__ignoreMap":502},[688,21265,21266,21268],{"class":690,"line":691},[688,21267,11856],{"class":694},[688,21269,11859],{"class":697},[968,21271,11862],{},{"title":502,"searchDepth":535,"depth":535,"links":21273},[21274,21278,21282],{"id":10870,"depth":506,"text":10871,"children":21275},[21276,21277],{"id":10937,"depth":535,"text":10938},{"id":11042,"depth":535,"text":11043},{"id":11274,"depth":506,"text":11275,"children":21279},[21280,21281],{"id":11287,"depth":535,"text":11288},{"id":11514,"depth":535,"text":11515},{"id":9703,"depth":506,"text":11691,"children":21283},[21284,21285],{"id":11694,"depth":535,"text":11695},{"id":11727,"depth":535,"text":11728},{"name":6694,"symbol":6695,"icon":6696,"id":896},{"type":10,"value":21288},[21289],[13,21290,11884],{},{},{"title":10850,"description":11879},{"loc":11886},[896],[21296],{"name":11895,"icon":11896,"symbol":10863,"id":896},[21298,21963],{"id":5,"title":6,"articleId":7,"articleThumb":8,"body":21299,"categoryId":691,"categoryInfo":21940,"createDate":994,"description":995,"excerpt":21941,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1003,"meta":21945,"navigation":1003,"path":1005,"rawbody":1006,"readingTime":1007,"seo":21946,"sitemap":21947,"stem":1022,"tagIds":21960,"tagInfo":21961,"updateDate":1028,"wordCount":1029,"__hash__":1030},{"type":10,"value":21300,"toc":21920},[21301,21303,21305,21325,21327,21347,21349,21354,21360,21362,21400,21402,21420,21422,21424,21430,21432,21434,21444,21446,21448,21540,21542,21544,21553,21557,21569,21573,21575,21586,21601,21605,21609,21619,21623,21627,21633,21637,21639,21645,21649,21653,21659,21669,21671,21677,21681,21687,21699,21701,21710,21712,21756,21758,21772,21880,21882,21886,21914,21918],[13,21302,15],{},[17,21304,20],{"id":19},[22,21306,21307,21311,21317,21321],{},[25,21308,21309],{"icon":27,"target":28,"title":29,"to":30},[13,21310,33],{},[25,21312,21313],{"icon":27,"target":28,"title":36,"to":37},[13,21314,40,21315,45],{},[42,21316,44],{},[25,21318,21319],{"icon":27,"target":28,"title":48,"to":49},[13,21320,52],{},[25,21322,21323],{"icon":27,"target":28,"title":55,"to":56},[13,21324,59],{},[17,21326,63],{"id":62},[65,21328,21329,21333,21337,21341],{},[68,21330,21331,74],{},[71,21332,73],{},[68,21334,21335,80],{},[71,21336,79],{},[68,21338,21339,86],{},[71,21340,85],{},[68,21342,21343,92,21345,96],{},[71,21344,91],{},[42,21346,95],{},[17,21348,100],{"id":99},[13,21350,21351,110],{},[104,21352,109],{"href":106,"rel":21353,"target":28},[108],[13,21355,113,21356,117,21358,121],{},[42,21357,109],{"color":116},[42,21359,120],{"color":116},[123,21361,126],{"id":125},[128,21363,21364,21368,21372,21376,21380,21384,21388,21392,21396],{},[68,21365,132,21366,136],{},[71,21367,135],{},[68,21369,132,21370,142],{},[71,21371,141],{},[68,21373,132,21374,148],{},[71,21375,147],{},[68,21377,132,21378,154],{},[71,21379,153],{},[68,21381,21382,160],{},[71,21383,159],{},[68,21385,21386,166],{},[71,21387,165],{},[68,21389,21390,172],{},[71,21391,171],{},[68,21393,21394,178],{},[71,21395,177],{},[68,21397,21398,184],{},[71,21399,183],{},[123,21401,188],{"id":187},[128,21403,21404,21408,21412,21416],{},[68,21405,21406,196],{},[71,21407,195],{},[68,21409,21410,202],{},[71,21411,201],{},[68,21413,21414,208],{},[71,21415,207],{},[68,21417,21418,214],{},[71,21419,213],{},[123,21421,218],{"id":217},[13,21423,221],{},[223,21425,21426],{},[13,21427,227,21428,230],{},[42,21429,109],{},[123,21431,234],{"id":233},[13,21433,237],{},[65,21435,21436,21438,21440,21442],{},[68,21437,242],{},[68,21439,245],{},[68,21441,248],{},[68,21443,251],{},[17,21445,255],{"id":254},[13,21447,258],{},[260,21449,21450,21460],{},[263,21451,21452],{},[266,21453,21454,21456,21458],{},[269,21455,271],{},[269,21457,274],{},[269,21459,95],{},[278,21461,21462,21482,21494,21506,21528],{},[266,21463,21464,21466,21474],{},[283,21465,285],{},[283,21467,288,21468,292,21470,295,21472,298],{},[290,21469],{},[290,21471],{},[290,21473],{},[283,21475,301,21476,304,21478,307,21480,310],{},[290,21477],{},[290,21479],{},[290,21481],{},[266,21483,21484,21486,21490],{},[283,21485,315],{},[283,21487,318,21488,321],{},[290,21489],{},[283,21491,324,21492,327],{},[290,21493],{},[266,21495,21496,21498,21502],{},[283,21497,332],{},[283,21499,335,21500,338],{},[290,21501],{},[283,21503,341,21504,344],{},[290,21505],{},[266,21507,21508,21510,21520],{},[283,21509,349],{},[283,21511,352,21512,355,21514,358,21516,361,21518,364],{},[290,21513],{},[290,21515],{},[290,21517],{},[290,21519],{},[283,21521,367,21522,370,21524,373,21526,376],{},[290,21523],{},[290,21525],{},[290,21527],{},[266,21529,21530,21532,21534],{},[283,21531,381],{},[283,21533,384],{},[283,21535,387,21536,390,21538,393],{},[290,21537],{},[290,21539],{},[17,21541,397],{"id":396},[123,21543,401],{"id":400},[13,21545,404,21546,407,21548,410,21550,415],{},[42,21547,274],{},[42,21549,95],{},[104,21551,109],{"href":413,"rel":21552,"target":28},[108],[13,21554,21555],{},[419,21556],{"alt":421,"src":422},[13,21558,425,21559,428,21561,431,21563,435,21565,439,21567,443],{},[42,21560,274],{},[42,21562,95],{},[42,21564,434],{},[42,21566,438],{},[42,21568,442],{},[13,21570,21571],{},[419,21572],{"alt":448,"src":449},[123,21574,453],{"id":452},[13,21576,456,21577,459,21579,464,21582,468,21584,471],{},[42,21578,109],{},[104,21580,274],{"href":462,"rel":21581,"target":28},[108],[42,21583,467],{},[42,21585,109],{},[65,21587,21588],{},[68,21589,476,21590,482,21593,486,21595,489,21597,493,21599,497],{},[104,21591,481],{"href":479,"rel":21592},[108],[42,21594,485],{},[42,21596,95],{},[42,21598,492],{},[42,21600,496],{},[13,21602,21603],{},[419,21604],{"alt":502,"src":503},[65,21606,21607],{"start":506},[68,21608,509],{},[13,21610,512,21611,516,21613,519,21615,523,21617,527],{},[42,21612,515],{},[42,21614,442],{},[42,21616,522],{},[42,21618,526],{},[13,21620,21621],{},[419,21622],{"alt":502,"src":532},[65,21624,21625],{"start":535},[68,21626,538],{},[13,21628,541,21629,544,21631,548],{},[42,21630,496],{},[42,21632,547],{},[13,21634,21635],{},[419,21636],{"alt":502,"src":553},[13,21638,556],{},[13,21640,21641,21643],{},[419,21642],{"alt":502,"src":561},[419,21644],{"alt":502,"src":564},[13,21646,567,21647,497],{},[42,21648,570],{},[13,21650,21651],{},[419,21652],{"alt":502,"src":575},[13,21654,578,21655,582,21657,585],{},[42,21656,581],{},[42,21658,526],{},[13,21660,588,21661,592,21663,595,21665,599,21667,603],{},[42,21662,591],{},[42,21664,591],{},[42,21666,598],{},[42,21668,602],{},[13,21670,606],{},[65,21672,21673],{"start":609},[68,21674,612,21675,616],{},[42,21676,615],{},[13,21678,21679],{},[419,21680],{"alt":502,"src":621},[65,21682,21683],{"start":624},[68,21684,627,21685,631],{},[42,21686,630],{},[13,21688,21689,637,21691,641,21693,644,21695,648,21697,651],{},[419,21690],{"alt":502,"src":636},[42,21692,640],{},[42,21694,438],{},[42,21696,647],{},[42,21698,442],{},[17,21700,655],{"id":654},[13,21702,21703,663,21706,667,21708,670],{},[104,21704,662],{"href":660,"rel":21705,"target":28},[108],[42,21707,666],{},[42,21709,95],{},[123,21711,674],{"id":673},[676,21713,21714,21728,21742],{},[679,21715,21716],{"className":681,"code":682,"filename":683,"language":684,"meta":502,"style":502},[42,21717,21718],{"__ignoreMap":502},[688,21719,21720,21722,21724,21726],{"class":690,"line":691},[688,21721,683],{"class":694},[688,21723,698],{"class":697},[688,21725,701],{"class":697},[688,21727,704],{"class":697},[679,21729,21730],{"className":681,"code":707,"filename":708,"language":684,"meta":502,"style":502},[42,21731,21732],{"__ignoreMap":502},[688,21733,21734,21736,21738,21740],{"class":690,"line":691},[688,21735,708],{"class":694},[688,21737,698],{"class":697},[688,21739,701],{"class":697},[688,21741,704],{"class":697},[679,21743,21744],{"className":681,"code":723,"filename":724,"language":684,"meta":502,"style":502},[42,21745,21746],{"__ignoreMap":502},[688,21747,21748,21750,21752,21754],{"class":690,"line":691},[688,21749,724],{"class":694},[688,21751,733],{"class":697},[688,21753,701],{"class":697},[688,21755,704],{"class":697},[123,21757,741],{"id":740},[13,21759,744,21760,748,21762,752,21764,755,21766,644,21768,648,21770,763],{},[42,21761,747],{"color":116},[42,21763,751],{},[42,21765,95],{},[42,21767,758],{},[42,21769,434],{},[42,21771,442],{},[679,21773,21774],{"className":766,"code":767,"filename":768,"language":769,"meta":502,"style":502},[42,21775,21776,21788,21804,21810,21824,21838,21842,21850,21864,21868,21874],{"__ignoreMap":502},[688,21777,21778,21780,21782,21784,21786],{"class":690,"line":691},[688,21779,777],{"class":776},[688,21781,780],{"class":776},[688,21783,784],{"class":783},[688,21785,788],{"class":787},[688,21787,792],{"class":791},[688,21789,21790,21792,21794,21796,21798,21800,21802],{"class":690,"line":506},[688,21791,798],{"class":797},[688,21793,801],{"class":791},[688,21795,804],{"class":787},[688,21797,807],{"class":791},[688,21799,747],{"class":697},[688,21801,807],{"class":791},[688,21803,814],{"class":787},[688,21805,21806,21808],{"class":690,"line":535},[688,21807,819],{"class":787},[688,21809,792],{"class":791},[688,21811,21812,21814,21816,21818,21820,21822],{"class":690,"line":609},[688,21813,826],{"class":797},[688,21815,801],{"class":791},[688,21817,831],{"class":791},[688,21819,438],{"class":697},[688,21821,807],{"class":791},[688,21823,838],{"class":791},[688,21825,21826,21828,21830,21832,21834,21836],{"class":690,"line":624},[688,21827,843],{"class":797},[688,21829,801],{"class":791},[688,21831,831],{"class":791},[688,21833,647],{"class":697},[688,21835,807],{"class":791},[688,21837,838],{"class":791},[688,21839,21840],{"class":690,"line":856},[688,21841,860],{"class":859},[688,21843,21844,21846,21848],{"class":690,"line":863},[688,21845,866],{"class":797},[688,21847,801],{"class":791},[688,21849,871],{"class":791},[688,21851,21852,21854,21856,21858,21860,21862],{"class":690,"line":874},[688,21853,877],{"class":797},[688,21855,801],{"class":791},[688,21857,831],{"class":791},[688,21859,442],{"class":697},[688,21861,807],{"class":791},[688,21863,838],{"class":791},[688,21865,21866],{"class":690,"line":890},[688,21867,893],{"class":791},[688,21869,21870,21872],{"class":690,"line":896},[688,21871,899],{"class":791},[688,21873,902],{"class":787},[688,21875,21876,21878],{"class":690,"line":905},[688,21877,908],{"class":791},[688,21879,911],{"class":787},[123,21881,915],{"id":914},[13,21883,918,21884,922],{},[42,21885,921],{},[679,21887,21888],{"className":925,"code":926,"filename":927,"language":928,"meta":502,"style":502},[42,21889,21890,21898,21906],{"__ignoreMap":502},[688,21891,21892,21894,21896],{"class":690,"line":691},[688,21893,935],{"class":791},[688,21895,938],{"class":797},[688,21897,941],{"class":791},[688,21899,21900,21902,21904],{"class":690,"line":506},[688,21901,946],{"class":791},[688,21903,949],{"class":797},[688,21905,952],{"class":791},[688,21907,21908,21910,21912],{"class":690,"line":535},[688,21909,957],{"class":791},[688,21911,938],{"class":797},[688,21913,941],{"class":791},[13,21915,21916],{},[419,21917],{"alt":502,"src":966},[968,21919,970],{},{"title":502,"searchDepth":535,"depth":535,"links":21921},[21922,21923,21924,21930,21931,21935],{"id":19,"depth":506,"text":20},{"id":62,"depth":506,"text":63},{"id":99,"depth":506,"text":100,"children":21925},[21926,21927,21928,21929],{"id":125,"depth":535,"text":126},{"id":187,"depth":535,"text":188},{"id":217,"depth":535,"text":218},{"id":233,"depth":535,"text":234},{"id":254,"depth":506,"text":255},{"id":396,"depth":506,"text":397,"children":21932},[21933,21934],{"id":400,"depth":535,"text":401},{"id":452,"depth":535,"text":453},{"id":654,"depth":506,"text":655,"children":21936},[21937,21938,21939],{"id":673,"depth":535,"text":674},{"id":740,"depth":535,"text":741},{"id":914,"depth":535,"text":915},{"name":992,"symbol":492,"icon":993,"id":691},{"type":10,"value":21942},[21943],[13,21944,1000],{},{},{"title":6,"description":995},{"loc":1005,"images":21948},[21949,21950,21951,21952,21953,21954,21955,21956,21957,21958,21959],{"loc":422},{"loc":449},{"loc":503},{"loc":532},{"loc":553},{"loc":561},{"loc":564},{"loc":575},{"loc":621},{"loc":636},{"loc":966},[691],[21962],{"name":274,"icon":1026,"symbol":1027,"id":691},{"id":10849,"title":10850,"articleId":10851,"articleThumb":10852,"body":21964,"categoryId":896,"categoryInfo":22754,"createDate":11878,"description":11879,"excerpt":22755,"extension":1001,"isHidden":1002,"isHot":1003,"isRecommend":1003,"isTop":1002,"meta":22759,"navigation":1003,"path":11886,"rawbody":11887,"readingTime":11888,"seo":22760,"sitemap":22761,"stem":11891,"tagIds":22762,"tagInfo":22763,"updateDate":11897,"wordCount":11898,"__hash__":11899},{"type":10,"value":21965,"toc":22740},[21966,21974,21976,21985,22017,22019,22031,22035,22040,22046,22048,22054,22058,22072,22076,22078,22088,22090,22092,22100,22104,22108,22128,22132,22152,22156,22158,22236,22242,22246,22258,22262,22274,22276,22278,22284,22286,22290,22366,22370,22378,22380,22410,22414,22418,22450,22454,22468,22470,22474,22486,22492,22496,22508,22512,22600,22604,22614,22616,22618,22622,22630,22634,22640,22642,22646,22652,22660,22664,22670,22716,22728,22738],[6807,21967,21968],{"color":116,"icon":6809,"target":28,"to":10857},[13,21969,10860,21970,10864,21972,10867],{},[42,21971,10863],{},[42,21973,10863],{},[17,21975,10871],{"id":10870},[13,21977,10874,21978,10880,21981,10883,21983,10886],{},[104,21979,10879],{"href":10877,"rel":21980},[108],[42,21982,10863],{},[42,21984,10863],{},[1058,21986,21987,21993],{},[13,21988,21989,10894,21991],{},[71,21990,10893],{},[290,21992],{},[65,21994,21995,22001],{},[68,21996,10901,21997,10904,21999,10907],{},[42,21998,10863],{},[42,22000,6694],{},[68,22002,10910,22003,10914,22005,10917,22007,10921,22009,10924,22011,10927,22013,10931,22015,10934],{},[42,22004,10913],{},[42,22006,6694],{},[42,22008,10920],{},[42,22010,6694],{},[42,22012,10920],{},[42,22014,10930],{},[42,22016,10920],{},[123,22018,10938],{"id":10937},[13,22020,10941,22021,10945,22023,10949,22025,10953,22027,10956,22029,10960],{},[42,22022,10944],{},[42,22024,10948],{},[42,22026,10952],{},[42,22028,10863],{},[42,22030,10959],{},[13,22032,22033],{},[71,22034,10965],{},[13,22036,10874,22037,10972],{},[104,22038,10948],{"href":10970,"rel":22039},[108],[128,22041,22042,22044],{},[68,22043,10977],{},[68,22045,10980],{},[13,22047,10983],{},[3056,22049,22050],{},[13,22051,10988,22052,10991],{},[42,22053,10863],{},[13,22055,22056],{},[71,22057,10996],{},[65,22059,22060,22062,22066,22070],{},[68,22061,11001],{},[68,22063,11004,22064,11007],{},[42,22065,10863],{},[68,22067,11010,22068,11013],{},[42,22069,6694],{},[68,22071,11016],{},[13,22073,22074],{},[71,22075,11021],{},[13,22077,11024],{},[679,22079,22080],{"className":6858,"code":11027,"language":6860,"meta":502,"style":502},[42,22081,22082],{"__ignoreMap":502},[688,22083,22084,22086],{"class":690,"line":691},[688,22085,10863],{"class":694},[688,22087,11036],{"class":697},[13,22089,11039],{},[123,22091,11043],{"id":11042},[13,22093,11046,22094,11049,22096,11053,22098,11057],{},[42,22095,10863],{},[42,22097,11052],{},[42,22099,11056],{},[13,22101,22102],{},[71,22103,11062],{},[128,22105,22106],{},[68,22107,11067],{},[679,22109,22110],{"className":766,"code":11070,"language":769,"meta":502,"style":502},[42,22111,22112],{"__ignoreMap":502},[688,22113,22114,22116,22118,22120,22122,22124,22126],{"class":690,"line":691},[688,22115,11077],{"class":787},[688,22117,11080],{"class":791},[688,22119,11083],{"class":787},[688,22121,11080],{"class":791},[688,22123,11088],{"class":694},[688,22125,801],{"class":791},[688,22127,11093],{"class":859},[128,22129,22130],{},[68,22131,11098],{},[679,22133,22134],{"className":766,"code":11101,"language":769,"meta":502,"style":502},[42,22135,22136],{"__ignoreMap":502},[688,22137,22138,22140,22142,22144,22146,22148,22150],{"class":690,"line":691},[688,22139,11108],{"class":787},[688,22141,11080],{"class":791},[688,22143,11113],{"class":787},[688,22145,11080],{"class":791},[688,22147,11088],{"class":694},[688,22149,801],{"class":791},[688,22151,11093],{"class":859},[13,22153,22154],{},[71,22155,11126],{},[13,22157,11129],{},[679,22159,22160],{"className":766,"code":11132,"language":769,"meta":502,"style":502},[42,22161,22162,22176,22206],{"__ignoreMap":502},[688,22163,22164,22166,22168,22170,22172,22174],{"class":690,"line":691},[688,22165,777],{"class":2013},[688,22167,11141],{"class":787},[688,22169,2303],{"class":791},[688,22171,2312],{"class":791},[688,22173,11148],{"class":697},[688,22175,6890],{"class":791},[688,22177,22178,22180,22182,22184,22186,22188,22190,22192,22194,22196,22198,22200,22202,22204],{"class":690,"line":506},[688,22179,11155],{"class":787},[688,22181,11080],{"class":791},[688,22183,11160],{"class":787},[688,22185,2312],{"class":791},[688,22187,11165],{"class":697},[688,22189,2312],{"class":791},[688,22191,11170],{"class":787},[688,22193,11173],{"class":791},[688,22195,11176],{"class":787},[688,22197,2072],{"class":791},[688,22199,3155],{"class":791},[688,22201,11165],{"class":697},[688,22203,2312],{"class":791},[688,22205,11187],{"class":787},[688,22207,22208,22210,22212,22214,22216,22218,22220,22222,22224,22226,22228,22230,22232,22234],{"class":690,"line":535},[688,22209,11155],{"class":787},[688,22211,11080],{"class":791},[688,22213,11160],{"class":787},[688,22215,2312],{"class":791},[688,22217,11200],{"class":697},[688,22219,2312],{"class":791},[688,22221,11170],{"class":787},[688,22223,11173],{"class":791},[688,22225,11176],{"class":787},[688,22227,2072],{"class":791},[688,22229,3155],{"class":791},[688,22231,11200],{"class":697},[688,22233,2312],{"class":791},[688,22235,11219],{"class":787},[223,22237,22238],{},[13,22239,11224,22240,11228],{},[42,22241,11227],{},[13,22243,22244],{},[71,22245,11233],{},[679,22247,22248],{"className":766,"code":11236,"language":769,"meta":502,"style":502},[42,22249,22250],{"__ignoreMap":502},[688,22251,22252,22254,22256],{"class":690,"line":691},[688,22253,11243],{"class":787},[688,22255,11246],{"class":791},[688,22257,11249],{"class":787},[13,22259,22260],{},[71,22261,11254],{},[679,22263,22264],{"className":766,"code":11027,"language":769,"meta":502,"style":502},[42,22265,22266],{"__ignoreMap":502},[688,22267,22268,22270,22272],{"class":690,"line":691},[688,22269,11263],{"class":787},[688,22271,11080],{"class":791},[688,22273,11268],{"class":787},[13,22275,11271],{},[17,22277,11275],{"id":11274},[13,22279,11278,22280,11281,22282,11284],{},[42,22281,10863],{},[42,22283,6694],{},[123,22285,11288],{"id":11287},[13,22287,22288],{},[71,22289,11293],{},[679,22291,22292],{"className":766,"code":11296,"language":769,"meta":502,"style":502},[42,22293,22294,22306,22310,22314,22322,22330,22338,22342,22354,22358],{"__ignoreMap":502},[688,22295,22296,22298,22300,22302,22304],{"class":690,"line":691},[688,22297,11303],{"class":787},[688,22299,2312],{"class":791},[688,22301,6695],{"class":697},[688,22303,2312],{"class":791},[688,22305,11312],{"class":787},[688,22307,22308],{"class":690,"line":506},[688,22309,11317],{"class":787},[688,22311,22312],{"class":690,"line":535},[688,22313,11322],{"class":787},[688,22315,22316,22318,22320],{"class":690,"line":609},[688,22317,11327],{"class":787},[688,22319,11330],{"class":791},[688,22321,11333],{"class":787},[688,22323,22324,22326,22328],{"class":690,"line":624},[688,22325,11338],{"class":787},[688,22327,2072],{"class":791},[688,22329,11343],{"class":787},[688,22331,22332,22334,22336],{"class":690,"line":856},[688,22333,11327],{"class":787},[688,22335,11350],{"class":2220},[688,22337,4149],{"class":787},[688,22339,22340],{"class":690,"line":863},[688,22341,11357],{"class":787},[688,22343,22344,22346,22348,22350,22352],{"class":690,"line":874},[688,22345,11327],{"class":787},[688,22347,11364],{"class":2220},[688,22349,2072],{"class":791},[688,22351,2240],{"class":2220},[688,22353,902],{"class":787},[688,22355,22356],{"class":690,"line":890},[688,22357,11375],{"class":787},[688,22359,22360,22362,22364],{"class":690,"line":896},[688,22361,11380],{"class":787},[688,22363,2072],{"class":791},[688,22365,11385],{"class":2220},[13,22367,22368],{},[71,22369,11390],{},[679,22371,22372],{"className":766,"code":11393,"language":769,"meta":502,"style":502},[42,22373,22374],{"__ignoreMap":502},[688,22375,22376],{"class":690,"line":691},[688,22377,11393],{"class":787},[13,22379,11402],{},[679,22381,22382],{"className":766,"code":11405,"language":769,"meta":502,"style":502},[42,22383,22384,22392,22400],{"__ignoreMap":502},[688,22385,22386,22388,22390],{"class":690,"line":691},[688,22387,11412],{"class":787},[688,22389,2072],{"class":791},[688,22391,11417],{"class":2220},[688,22393,22394,22396,22398],{"class":690,"line":506},[688,22395,11422],{"class":787},[688,22397,2072],{"class":791},[688,22399,11427],{"class":2220},[688,22401,22402,22404,22406,22408],{"class":690,"line":535},[688,22403,11432],{"class":791},[688,22405,11435],{"class":787},[688,22407,2072],{"class":791},[688,22409,11440],{"class":2220},[13,22411,11443,22412,11446],{},[42,22413,6694],{},[13,22415,22416],{},[71,22417,11451],{},[679,22419,22420],{"className":766,"code":11454,"language":769,"meta":502,"style":502},[42,22421,22422,22430,22436,22440],{"__ignoreMap":502},[688,22423,22424,22426,22428],{"class":690,"line":691},[688,22425,11461],{"class":787},[688,22427,2072],{"class":791},[688,22429,11466],{"class":787},[688,22431,22432,22434],{"class":690,"line":506},[688,22433,11471],{"class":787},[688,22435,11474],{"class":2220},[688,22437,22438],{"class":690,"line":535},[688,22439,11479],{"class":787},[688,22441,22442,22444,22446,22448],{"class":690,"line":609},[688,22443,11471],{"class":787},[688,22445,11364],{"class":2220},[688,22447,2072],{"class":791},[688,22449,11490],{"class":2220},[13,22451,22452],{},[71,22453,11495],{},[679,22455,22456],{"className":766,"code":11498,"language":769,"meta":502,"style":502},[42,22457,22458],{"__ignoreMap":502},[688,22459,22460,22462,22464,22466],{"class":690,"line":691},[688,22461,11505],{"class":787},[688,22463,11364],{"class":2220},[688,22465,2072],{"class":791},[688,22467,11490],{"class":2220},[123,22469,11515],{"id":11514},[13,22471,22472],{},[71,22473,11520],{},[679,22475,22476],{"className":766,"code":11523,"language":769,"meta":502,"style":502},[42,22477,22478],{"__ignoreMap":502},[688,22479,22480,22482,22484],{"class":690,"line":691},[688,22481,11530],{"class":787},[688,22483,11533],{"class":776},[688,22485,11536],{"class":2220},[13,22487,11539,22488,11542,22490,11545],{},[42,22489,6860],{},[42,22491,6694],{},[13,22493,22494],{},[71,22495,11550],{},[679,22497,22498],{"className":766,"code":11553,"language":769,"meta":502,"style":502},[42,22499,22500],{"__ignoreMap":502},[688,22501,22502,22504,22506],{"class":690,"line":691},[688,22503,11560],{"class":787},[688,22505,11080],{"class":791},[688,22507,11565],{"class":787},[13,22509,22510],{},[71,22511,11570],{},[679,22513,22514],{"className":766,"code":11573,"language":769,"meta":502,"style":502},[42,22515,22516,22520,22528,22548,22564,22584],{"__ignoreMap":502},[688,22517,22518],{"class":690,"line":691},[688,22519,11580],{"class":787},[688,22521,22522,22524,22526],{"class":690,"line":506},[688,22523,11585],{"class":787},[688,22525,11330],{"class":791},[688,22527,11590],{"class":787},[688,22529,22530,22532,22534,22536,22538,22540,22542,22544,22546],{"class":690,"line":535},[688,22531,11595],{"class":787},[688,22533,2072],{"class":791},[688,22535,11600],{"class":787},[688,22537,11603],{"class":2220},[688,22539,2072],{"class":791},[688,22541,3194],{"class":2220},[688,22543,11610],{"class":787},[688,22545,2072],{"class":791},[688,22547,11615],{"class":787},[688,22549,22550,22552,22554,22556,22558,22560,22562],{"class":690,"line":609},[688,22551,11620],{"class":787},[688,22553,11603],{"class":2220},[688,22555,2072],{"class":791},[688,22557,3194],{"class":2220},[688,22559,11629],{"class":787},[688,22561,11330],{"class":791},[688,22563,11590],{"class":787},[688,22565,22566,22568,22570,22572,22574,22576,22578,22580,22582],{"class":690,"line":624},[688,22567,11595],{"class":787},[688,22569,2072],{"class":791},[688,22571,11600],{"class":787},[688,22573,11603],{"class":2220},[688,22575,2072],{"class":791},[688,22577,3194],{"class":2220},[688,22579,11610],{"class":787},[688,22581,2072],{"class":791},[688,22583,11615],{"class":787},[688,22585,22586,22588,22590,22592,22594,22596,22598],{"class":690,"line":856},[688,22587,11658],{"class":787},[688,22589,11603],{"class":2220},[688,22591,2072],{"class":791},[688,22593,3194],{"class":2220},[688,22595,11629],{"class":787},[688,22597,11330],{"class":791},[688,22599,11590],{"class":787},[13,22601,22602],{},[71,22603,11675],{},[679,22605,22606],{"className":766,"code":11678,"language":769,"meta":502,"style":502},[42,22607,22608],{"__ignoreMap":502},[688,22609,22610,22612],{"class":690,"line":691},[688,22611,11685],{"class":787},[688,22613,11688],{"class":2220},[17,22615,11691],{"id":9703},[123,22617,11695],{"id":11694},[13,22619,22620],{},[71,22621,11700],{},[128,22623,22624,22626,22628],{},[68,22625,11705],{},[68,22627,11708],{},[68,22629,11711],{},[13,22631,22632],{},[71,22633,11716],{},[128,22635,22636,22638],{},[68,22637,11721],{},[68,22639,11724],{},[123,22641,11728],{"id":11727},[13,22643,22644],{},[71,22645,11733],{},[128,22647,22648,22650],{},[68,22649,11738],{},[68,22651,11741],{},[13,22653,11744,22654,11748,22656,11752,22658],{},[42,22655,11747],{"color":116},[42,22657,11751],{"color":116},[42,22659,11755],{"color":116},[13,22661,22662],{},[71,22663,11760],{},[13,22665,11763,22666,11766,22668,11769],{},[42,22667,10913],{},[42,22669,6694],{},[679,22671,22672],{"className":681,"code":11772,"language":684,"meta":502,"style":502},[42,22673,22674,22678,22684,22688,22698,22702,22706,22710],{"__ignoreMap":502},[688,22675,22676],{"class":690,"line":691},[688,22677,11779],{"class":859},[688,22679,22680,22682],{"class":690,"line":506},[688,22681,11784],{"class":694},[688,22683,11787],{"class":697},[688,22685,22686],{"class":690,"line":535},[688,22687,11792],{"class":859},[688,22689,22690,22692,22694,22696],{"class":690,"line":609},[688,22691,777],{"class":2013},[688,22693,11799],{"class":787},[688,22695,2303],{"class":791},[688,22697,11804],{"class":787},[688,22699,22700],{"class":690,"line":624},[688,22701,11809],{"class":859},[688,22703,22704],{"class":690,"line":856},[688,22705,11814],{"class":694},[688,22707,22708],{"class":690,"line":863},[688,22709,11819],{"class":859},[688,22711,22712,22714],{"class":690,"line":874},[688,22713,11824],{"class":783},[688,22715,11827],{"class":697},[13,22717,11763,22718,11833,22720,11836,22722,11839,22724,11842,22726,11846],{},[42,22719,11832],{},[42,22721,10879],{},[42,22723,6694],{},[42,22725,10863],{},[42,22727,11845],{},[679,22729,22730],{"className":681,"code":11849,"language":684,"meta":502,"style":502},[42,22731,22732],{"__ignoreMap":502},[688,22733,22734,22736],{"class":690,"line":691},[688,22735,11856],{"class":694},[688,22737,11859],{"class":697},[968,22739,11862],{},{"title":502,"searchDepth":535,"depth":535,"links":22741},[22742,22746,22750],{"id":10870,"depth":506,"text":10871,"children":22743},[22744,22745],{"id":10937,"depth":535,"text":10938},{"id":11042,"depth":535,"text":11043},{"id":11274,"depth":506,"text":11275,"children":22747},[22748,22749],{"id":11287,"depth":535,"text":11288},{"id":11514,"depth":535,"text":11515},{"id":9703,"depth":506,"text":11691,"children":22751},[22752,22753],{"id":11694,"depth":535,"text":11695},{"id":11727,"depth":535,"text":11728},{"name":6694,"symbol":6695,"icon":6696,"id":896},{"type":10,"value":22756},[22757],[13,22758,11884],{},{},{"title":10850,"description":11879},{"loc":11886},[896],[22764],{"name":11895,"icon":11896,"symbol":10863,"id":896},1787994230116]