diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..23f83a9 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(pnpm install:*)", + "WebSearch", + "Bash(pnpm dlx:*)" + ] + } +} diff --git a/.gitignore b/.gitignore index b27dc4e..f737a78 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /node_modules /.vscode /dist +*.bkp diff --git a/README.md b/README.md index 3d967a6..85a51c3 100755 --- a/README.md +++ b/README.md @@ -1,17 +1,43 @@ +## 项目介绍 + - 这是 [JavaGuide](https://javaguide.cn/) 面试突击版本,适合突击面试的小伙伴。并且,提供了 PDF 下载,方便大家离线阅读/打印,阅读体验非常高。 -- 如果你准备面试的时间比较充足的话,建议阅读完整版,针对重要的知识点有更详细的讲解。地址:[javaguide.cn](https://javaguide.cn/) -- 专属面试小册/一对一交流/简历修改/专属求职指南,欢迎加入 **[JavaGuide 知识星球](./docs/about-the-author/zhishixingqiu-two-years.md)**(点击链接即可查看星球的详细介绍,一定确定自己真的需要再加入)。 +- 如果你准备面试的时间比较充足的话,建议阅读完整版,针对重要的知识点有更详细的讲解。地址:**[javaguide.cn](https://javaguide.cn/)**。 +- 专属面试小册/一对一交流/简历修改/专属求职指南,欢迎加入 **[JavaGuide 知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(点击链接即可查看星球的详细介绍,一定确定自己真的需要再加入)。 ## Java - [Java基础常见面试题总结](./docs/java/java-basis.md) +- [Java集合常见面试题总结](./docs/java/java-collection.md) +- [Java并发常见面试题总结](./docs/java/java-concurrent.md) +- [JVM常见面试题总结](./docs/java/java-jvm.md) + +## 计算机基础 + +- [计算机网络常见面试题总结](./docs/cs-basics/network.md) +- [操作系统常见面试题总结](./docs/cs-basics/operating-system.md) +- [数据结构常见面试题总结](./docs/cs-basics/data-structure.md) +- [算法常见面试题总结](./docs/cs-basics/algorithms.md) + +## 数据库和缓存 + +- [MySQL常见面试题总结](./docs/database/mysql.md) +- [Redis常见面试题总结](./docs/database/redis.md) +## 系统设计 +- [Spring和Spring Boot常见面试题总结](./docs/system-design/spring.md) +- [设计模式常见面试题总结](./docs/system-design/design-pattern.md) + +## 分布式系统 + +- [分布式系统常见面试题总结](./docs/distributed-system/distributed-system.md) + +## 测试开发 + +- [测试开发常见面试题总结](./docs/other/test-development.md) ## 公众号 如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) - - +JavaGuide 公众号 diff --git a/docs/.vuepress/client.ts b/docs/.vuepress/client.ts new file mode 100644 index 0000000..c5ebd97 --- /dev/null +++ b/docs/.vuepress/client.ts @@ -0,0 +1,7 @@ +import { defineClientConfig } from "vuepress/client"; +import { h } from "vue"; +import LayoutToggle from "./components/LayoutToggle.vue"; + +export default defineClientConfig({ + rootComponents: [() => h(LayoutToggle)], +}); diff --git a/docs/.vuepress/components/LayoutToggle.vue b/docs/.vuepress/components/LayoutToggle.vue new file mode 100644 index 0000000..e18e7f9 --- /dev/null +++ b/docs/.vuepress/components/LayoutToggle.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index 7f88f56..1a6cf7e 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -7,7 +7,7 @@ export default defineUserConfig({ title: "JavaGuide(面试突击版)", description: - "Java 学习&面试指南(Go、Python 后端面试通用,计算机基础面试总结) ", + "Java 学习&面试指南(Go、Python 后端面试通用,计算机基础面试总结)", lang: "zh-CN", head: [ diff --git a/docs/.vuepress/navbar.ts b/docs/.vuepress/navbar.ts index a7110f1..3b6f817 100644 --- a/docs/.vuepress/navbar.ts +++ b/docs/.vuepress/navbar.ts @@ -2,5 +2,6 @@ import { navbar } from "vuepress-theme-hope"; export default navbar([ { text: "Java 面试", icon: "java", link: "/home.md" }, - { text: "PDF 下载", icon: "java", link: "https://mp.weixin.qq.com/s/q14qXzdM4KTmawyMi5mFpg" }, + { text: "PDF 下载", icon: "pdf", link: "https://mp.weixin.qq.com/s/q14qXzdM4KTmawyMi5mFpg" }, + // { text: "后端面经", icon: "interview", link: "/system-design/design-pattern.md" }, ]); diff --git a/docs/.vuepress/sidebar/index.ts b/docs/.vuepress/sidebar/index.ts index 6987ec7..1707125 100644 --- a/docs/.vuepress/sidebar/index.ts +++ b/docs/.vuepress/sidebar/index.ts @@ -6,7 +6,7 @@ export default sidebar({ text: "项目介绍", icon: "star", collapsible: true, - prefix: "javaguide/", + prefix: "intro/", children: ["faq"], }, { @@ -36,31 +36,40 @@ export default sidebar({ "java-jvm", ], }, - { + { text: "计算机基础", - icon: "interview", + icon: "computer", collapsible: false, prefix: "cs-basics/", - children: [ - "network", - "operating-system", - "data-structure", - "algorithms", - ], + children: ["network", "operating-system", "data-structure", "algorithms"], }, { text: "数据库和缓存", - icon: "interview", + icon: "database", collapsible: false, prefix: "database/", children: ["mysql", "redis"], }, { text: "系统设计", - icon: "interview", + icon: "design", collapsible: false, prefix: "system-design/", - children: ["design-pattern"], + children: ["spring", "design-pattern"], + }, + { + text: "分布式系统", + icon: "network", + collapsible: false, + prefix: "distributed-system/", + children: ["distributed-system"], + }, + { + text: "测开", + icon: "framework", + collapsible: false, + prefix: "other/", + children: ["test-development"], }, ], }); diff --git a/docs/.vuepress/styles/index.scss b/docs/.vuepress/styles/index.scss index a895ab8..865c5f9 100644 --- a/docs/.vuepress/styles/index.scss +++ b/docs/.vuepress/styles/index.scss @@ -3,3 +3,140 @@ body { font-size: 16px; } } + +// ============================================ +// 沉浸式阅读模式 - 隐藏导航栏、侧边栏和目录 +// ============================================ + +// 过渡动画 +.vp-navbar, +.vp-sidebar, +.vp-page, +.theme-container .vp-page { + transition: + transform 0.3s ease, + opacity 0.3s ease, + margin 0.3s ease, + padding 0.3s ease, + width 0.3s ease; +} + +// 隐藏布局模式 +html.layout-hidden { + // 隐藏顶部导航栏 + .vp-navbar { + transform: translateY(-100%) !important; + opacity: 0 !important; + pointer-events: none !important; + } + + // 隐藏左侧边栏 + .vp-sidebar { + transform: translateX(-100%) !important; + opacity: 0 !important; + pointer-events: none !important; + width: 0 !important; + } + + // 隐藏侧边栏切换按钮(小屏幕下的展开按钮) + .toggle-sidebar-wrapper { + display: none !important; + opacity: 0 !important; + pointer-events: none !important; + } + + // 隐藏侧边栏遮罩层 + .vp-sidebar-mask { + display: none !important; + } + + // 侧边栏包装器 + .vp-sidebar-wrapper, + .sidebar-wrapper { + width: 0 !important; + min-width: 0 !important; + padding: 0 !important; + margin: 0 !important; + } + + // 隐藏右侧目录 (TOC) + .vp-toc-placeholder, + .toc-wrapper, + .vp-toc, + aside.vp-toc, + .toc { + display: none !important; + width: 0 !important; + } + + // 主容器调整 - 移除左侧 padding/margin + .theme-container { + padding-left: 0 !important; + padding-right: 0 !important; + + .vp-page { + padding-left: 2rem !important; + padding-right: 2rem !important; + padding-top: 1rem !important; + margin-left: 0 !important; + max-width: 100% !important; + width: 100% !important; + } + } + + // 主题内容区域调整 - 让内容更宽 + .theme-hope-content, + .vp-page-content, + .vp-content { + max-width: 100% !important; + width: 100% !important; + margin: 0 !important; + padding: 1rem 2rem !important; + } + + // 页面容器调整 + .vp-page-container { + padding-top: 1rem !important; + padding-left: 0 !important; + padding-right: 0 !important; + max-width: 100% !important; + } + + // 确保内容区域居中且宽度适中 + .theme-container > main { + margin-left: 0 !important; + padding-left: 0 !important; + max-width: 100% !important; + } + + // 响应式调整 + @media (min-width: 960px) { + .theme-container .vp-page { + margin-left: 0 !important; + padding-left: 3rem !important; + padding-right: 3rem !important; + } + + .theme-hope-content, + .vp-page-content, + .vp-content { + max-width: 100% !important; + padding: 1rem 2rem !important; + } + } + + @media (min-width: 1440px) { + .theme-container .vp-page { + margin-left: 0 !important; + padding-left: 4rem !important; + padding-right: 4rem !important; + } + + .theme-hope-content, + .vp-page-content, + .vp-content { + max-width: 100% !important; + padding: 1rem 3rem !important; + } + } +} diff --git a/docs/.vuepress/theme.ts b/docs/.vuepress/theme.ts index 8ced6ac..1e257f8 100644 --- a/docs/.vuepress/theme.ts +++ b/docs/.vuepress/theme.ts @@ -7,7 +7,7 @@ import sidebar from "./sidebar/index.js"; const __dirname = getDirname(import.meta.url); export default hopeTheme({ - hostname: "https://javaguide.cn/", + hostname: "https://interview.javaguide.cn/", logo: "/logo.png", favicon: "/favicon.ico", @@ -16,7 +16,7 @@ export default hopeTheme({ url: "https://javaguide.cn/article/", }, - repo: "https://github.com/Snailclimb/JavaGuide", + repo: "https://github.com/Snailclimb/JavaGuide-Interview", docsDir: "docs", pure: true, focus: false, @@ -32,6 +32,7 @@ export default hopeTheme({ markdown: { align: true, codeTabs: true, + mermaid: true, gfm: true, include: { resolvePath: (file, cwd) => { diff --git a/docs/README.md b/docs/README.md index 114779b..cea5102 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,38 +1,64 @@ --- home: true icon: home -title: Java 面试指南 +title: 后端面试突击指南 heroImage: /logo.svg -heroText: JavaGuide -tagline: 「Java学习 + 面试指南」涵盖 Java 程序员需要掌握的核心知识 +heroText: JavaGuide 面试突击版 +head: + - - meta + - name: keywords + content: JavaGuide,JavaGuide 面试突击版,Java面试,Java面试指南,Java八股文,后端面试,后端开发,数据库面试,MySQL面试,Redis面试,分布式,高并发,高性能,高可用,系统设计,消息队列,缓存,计算机网络,Linux + - - meta + - property: og:type + content: website + - - meta + - property: og:url + content: https://interview.javaguide.cn/ + - - meta + - property: og:image + content: https://interview.javaguide.cn/logo.png +tagline: Java 面试 & 后端通用面试突击指南,覆盖计算机基础、数据库、分布式、高并发与系统设计 actions: - text: 开始阅读 link: /home.md type: primary - text: 知识星球 - link: /about-the-author/zhishixingqiu-two-years.md + link: https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html type: default footer: |- 鄂ICP备2020015769号-1 | 主题: VuePress Theme Hope --- -## 关于网站 +## 🔥必看 -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。真心希望能够把这个项目做好,真正能够帮助到有需要的朋友! +- **面试资料补充**: + - [《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html):四年打磨,和 JavaGuide 开源版的内容互补,带你从零开始系统准备后端面试! + - [《后端面试高频系统设计&场景题》](https://javaguide.cn/zhuanlan/back-end-interview-high-frequency-system-design-and-scenario-questions.html):30+ 道高频系统设计和场景面试,助你应对当下中大厂面试趋势。 +- **大模型实战项目**: [⭐AI 智能面试辅助平台 + RAG 知识库](https://javaguide.cn/zhuanlan/interview-guide.html)(基于 Spring Boot 4.0 + Java 21 + Spring AI 2.0 ,非常适合作为学习和简历项目,学习门槛低)。 -如果觉得 JavaGuide 的内容对你有帮助的话,还请点个免费的 Star(绝不强制点 Star,觉得内容不错有收获再点赞就好),这是对我最大的鼓励,感谢各位一路同行,共勉!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 +## 🌟文章推荐 + +- **面试准备**: [Java 后端面试通关计划(涵盖后端通用体系)](https://javaguide.cn/interview-preparation/backend-interview-plan.html)(如果你想要系统准备 Java 后端面试但又不知道如何开始的,一定要看这篇) +- **高频考点**: + - [Java并发常见面试题总结](https://interview.javaguide.cn/java/java-concurrent.html) + - [MySQL常见面试题总结](https://interview.javaguide.cn/database/mysql.html) + - [Redis常见面试题总结](https://interview.javaguide.cn/database/redis.html) + - [计算机网络常见面试题总结](https://interview.javaguide.cn/cs-basics/network.html) +## 🚀 PDF 版本 & 面试交流群 -## 关于作者 +- 如果你更喜欢 **PDF**(比如通勤/离线阅读/打印学习),扫描下方二维码,后台回复“**PDF**”即可获取最新版(持续更新,详细介绍见:**[2026 最新后端面试 PDF 资料](./interview-preparation/pdf-interview-javaguide.md)**)。 +- 如果你需要加入后端面试交流群,扫描下方二维码,后台回复“**微信**”即可加群。 -- [我曾经也是网瘾少年](./about-the-author/internet-addiction-teenager.md) -- [害,毕业三年了!](./about-the-author/my-college-life.md) -- [我的知识星球快 3 岁了!](./about-the-author/zhishixingqiu-two-years.md) -- [坚持写技术博客六年了](./about-the-author/writing-technology-blog-six-years.md) +JavaGuide 公众号 -## 公众号 +## 🌐 关于网站 -最新更新会第一时间同步在公众号,推荐关注!另外,公众号上有很多干货不会同步在线阅读网站。 +JavaGuide 已经持续维护 6 年多了,累计提交了 **6000+** commit ,共有 **620+** 多位贡献者共同参与维护和完善。真心希望能够把这个项目做好,真正能够帮助到有需要的朋友! + +如果觉得 JavaGuide 的内容对你有帮助的话,还请点个免费的 Star(绝不强制点 Star,觉得内容不错有收获再点赞就好),这是对我最大的鼓励,感谢各位一路同行,共勉!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) +- [项目介绍](https://javaguide.cn/javaguide/intro.html)(JavaGuide 的诞生) +- [贡献指南](https://javaguide.cn/javaguide/contribution-guideline.html)(期待你的贡献,奖励丰富) +- [常见问题](https://javaguide.cn/javaguide/faq.html)(统一回复大家的一些疑问) \ No newline at end of file diff --git a/docs/cs-basics/algorithms.md b/docs/cs-basics/algorithms.md index 9d63cad..7178098 100755 --- a/docs/cs-basics/algorithms.md +++ b/docs/cs-basics/algorithms.md @@ -1,15 +1,13 @@ --- title: 算法常见面试题总结 +description: 算法高频面试题总结:十大经典排序算法、字符串与链表高频LeetCode题、剑指Offer编程题、常见算法思想如动态规划、贪心、回溯等速览,附资源链接与推荐合集,快速通关算法面试。 category: 计算机基础 tag: - 算法 head: - - meta - name: keywords - content: 算法面试突击,LeetCode高频题,十大排序算法,字符串算法题,链表算法题,剑指Offer编程题,数据结构经典题,算法思想总结 - - - meta - - name: description - content: 算法面试突击:十大经典排序+字符串/链表高频LeetCode、剑指Offer编程题、算法思想速览,一文附资源链接,3步刷题法+⭐️推荐合集,快速通关算法面试! + content: 算法面试题,LeetCode,十大排序算法,字符串算法,链表算法,剑指Offer,动态规划,贪心算法,回溯算法,二分查找,算法思想 --- ## 算法 diff --git a/docs/cs-basics/data-structure.md b/docs/cs-basics/data-structure.md index d9ccb35..7ec6808 100755 --- a/docs/cs-basics/data-structure.md +++ b/docs/cs-basics/data-structure.md @@ -1,15 +1,13 @@ --- title: 数据结构常见面试题总结 +description: 数据结构高频面试题总结:涵盖数组、链表、栈、队列等线性结构,图的邻接表与邻接矩阵、DFS/BFS遍历,红黑树、堆、树的遍历算法,布隆过滤器原理与应用,快速掌握大厂面试核心考点。 category: 计算机基础 tag: - 数据结构 head: - - meta - name: keywords - content: 数据结构面试突击,图DFS BFS,邻接表矩阵,红黑树详解,堆栈队列,线性结构,布隆过滤器,树遍历算法 - - - meta - - name: description - content: 数据结构面试突击:图邻接表/矩阵+DFS/BFS、红黑树/堆/栈队列、线性结构速览,一图一链全覆盖,3小时掌握大厂高频考点! + content: 数据结构面试题,数组,链表,栈,队列,图,DFS,BFS,邻接表,邻接矩阵,红黑树,堆,二叉树,树遍历,布隆过滤器,哈希表 --- 数据结构这部分的基础知识已经总结完成。 diff --git a/docs/cs-basics/network.md b/docs/cs-basics/network.md index 1c709ba..cf15df3 100755 --- a/docs/cs-basics/network.md +++ b/docs/cs-basics/network.md @@ -1,38 +1,16 @@ --- title: 计算机网络常见面试题总结 +description: 最新计算机网络高频面试题总结:OSI七层模型与TCP/IP四层模型详解、HTTP全版本对比、GET/POST区别、WebSocket实时通信、DNS解析流程,附图表与重点标注,一文搞定网络基础与应用层核心考点,快速备战后端面试。 category: 计算机基础 tag: - 计算机网络 head: - - meta - name: keywords - content: 计算机网络面试题,OSI七层模型,TCP/IP四层模型,HTTP vs HTTPS,HTTP/1.1 vs HTTP/2,HTTP/3 QUIC,GET vs POST,WebSocket vs HTTP,DNS解析过程,应用层面试,网络基础高频题,URL到页面展示,队头阻塞,Session vs Cookie - - - meta - - name: description - content: 最新计算机网络高频面试题总结:OSI/TCP/IP模型详解、HTTP全版本对比、GET/POST区别、WebSocket实时通信、DNS解析流程,附图表+⭐️重点标注,一文搞定网络基础&应用层核心考点,快速备战后端面试! + content: 计算机网络面试题,OSI七层模型,TCP/IP四层模型,HTTP,HTTPS,HTTP/2,HTTP/3,QUIC,GET POST区别,WebSocket,DNS解析,三次握手,四次挥手,TCP UDP区别,Session Cookie --- ------- - -![面试突击-计算机基础](https://oss.javaguide.cn/github/javaguide-interview/cover/network.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了⭐️标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: @@ -729,3 +707,5 @@ ARP 协议,全称 **地址解析协议(Address Resolution Protocol)**, ### ARP 协议的工作原理? [ARP 协议详解(网络层)](https://javaguide.cn/cs-basics/network/arp.html) + + diff --git a/docs/cs-basics/operating-system.md b/docs/cs-basics/operating-system.md index a38f605..5472006 100644 --- a/docs/cs-basics/operating-system.md +++ b/docs/cs-basics/operating-system.md @@ -1,39 +1,15 @@ --- title: 操作系统常见面试题总结 +description: 最新操作系统高频面试题总结:用户态与内核态、系统调用、进程与线程区别、多线程同步、死锁预防与避免、虚拟内存分页分段对比、TLB快表、页面置换算法、文件系统、硬链接软链接、磁盘调度算法,一图一表速记,快速通关后端面试。 category: 计算机基础 tag: - 操作系统 head: - - meta - name: keywords - content: 操作系统面试突击,用户态内核态,系统调用,进程线程区别,多线程同步,死锁预防避免,虚拟内存分页,TLB快表,页面置换算法,硬链接软链接,磁盘调度算法 - - - meta - - name: description - content: 最新操作系统高频面试题总结:用户态/内核态+系统调用、进程/线程/死锁高频题、虚拟内存分页分段对比、TLB+页缺失+LRU置换、文件系统&磁盘调度,一图一表速记,快速通关后端面试! + content: 操作系统面试题,用户态内核态,系统调用,进程线程区别,多线程同步,死锁预防,虚拟内存,分页分段,TLB快表,页面置换算法,LRU,硬链接软链接,磁盘调度算法 --- ------- - -![面试突击-操作系统](https://oss.javaguide.cn/github/javaguide-interview/cover/operating-system.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了⭐️标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) - 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: - [操作系统常见面试题总结(上)](https://javaguide.cn/cs-basics/operating-system/operating-system-basic-questions-01.html)(操作系统基础、进程和线程、死锁) @@ -816,3 +792,5 @@ LRU 算法是实际使用中应用的比较多,也被认为是最接近 OPT 4. **循环扫描算法(Circular Scan,C-SCAN)**:SCAN 算法的变体,只在磁盘的一侧进行扫描,并且只按照一个方向扫描,直到到达磁盘边界,然后回到磁盘起点,重新开始循环。 5. **边扫描边观察算法(LOOK)**:SCAN 算法中磁头到了磁盘的边界才改变移动方向,这样可能会做很多无用功,因为磁头移动方向上可能已经没有请求需要处理了。LOOK 算法对 SCAN 算法进行了改进,如果磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向,依此往复。也就是边扫描边观察指定方向上还有无请求,因此叫 LOOK。 6. **均衡循环扫描算法(C-LOOK)**:C-SCAN 只有到达磁盘边界时才能改变磁头移动方向,并且磁头返回时也需要返回到磁盘起点,这样可能会做很多无用功。C-LOOK 算法对 C-SCAN 算法进行了改进,如果磁头移动的方向上已经没有磁道访问请求了,就可以立即让磁头返回,并且磁头只需要返回到有磁道访问请求的位置即可。 + + diff --git "a/docs/cs-basics/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200\345\220\210\351\233\206.md" "b/docs/cs-basics/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200\345\220\210\351\233\206.md" index 9fe2b5e..8ca084e 100644 --- "a/docs/cs-basics/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200\345\220\210\351\233\206.md" +++ "b/docs/cs-basics/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200\345\220\210\351\233\206.md" @@ -1,6 +1,14 @@ -![面试突击-计算机基础](../images/cover/cs-basis.png) - ------- +--- +title: 计算机基础合集 +description: 计算机基础面试知识合集:涵盖计算机网络、操作系统、数据结构与算法等核心内容,适合Java后端面试快速突击复习使用。 +category: 计算机基础 +head: + - - meta + - name: keywords + content: 计算机基础,计算机网络,操作系统,数据结构,算法,面试突击,后端面试,计算机科学 +--- + + # 前言 diff --git a/docs/database/mysql.md b/docs/database/mysql.md index 6e28328..e94c153 100755 --- a/docs/database/mysql.md +++ b/docs/database/mysql.md @@ -1,5 +1,6 @@ --- title: MySQL常见面试题总结 +description: MySQL高频面试题精讲:涵盖MySQL基础架构、InnoDB存储引擎、索引原理与B+树、事务ACID特性、隔离级别、MVCC多版本并发控制、redo log/undo log/binlog日志、行锁与表锁、慢查询优化等核心考点,一文速通大厂必考点。 category: 数据库 tag: - MySQL @@ -7,33 +8,10 @@ tag: head: - - meta - name: keywords - content: MySQL面试题,MySQL基础架构,InnoDB存储引擎,MySQL索引,B+树索引,事务隔离级别,redo log,undo log,binlog,MVCC,行级锁,慢查询优化 - - - meta - - name: description - content: MySQL高频面试题精讲:基础架构、InnoDB引擎、索引原理、B+树、事务ACID、MVCC、redo/undo/binlog日志、行锁/表锁、慢查询优化,一文速通大厂必考点! + content: MySQL面试题,MySQL基础架构,InnoDB存储引擎,MySQL索引,B+树索引,事务隔离级别,redo log,undo log,binlog,MVCC,行级锁,表锁,慢查询优化,SQL优化 --- ------- - -![面试突击-MySQL](https://oss.javaguide.cn/github/javaguide-interview/cover/mysql.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了⭐️标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: @@ -323,7 +301,7 @@ MyISAM 不提供事务支持。 InnoDB 提供事务支持,实现了 SQL 标准定义了四个隔离级别,具有提交(commit)和回滚(rollback)事务的能力。并且,InnoDB 默认使用的 REPEATABLE-READ(可重读)隔离级别是可以解决幻读问题发生的(基于 MVCC 和 Next-Key Lock)。 -关于 MySQL 事务的详细介绍,可以看看我写的这篇文章:[MySQL 事务隔离级别详解](./transaction-isolation-level.md)。 +关于 MySQL 事务的详细介绍,可以看看我写的这篇文章:[MySQL 事务隔离级别详解](https://javaguide.cn/database/mysql/transaction-isolation-level.html)。 **3、是否支持外键** @@ -357,7 +335,7 @@ MyISAM 不支持,而 InnoDB 支持。 InnoDB 引擎中,其数据文件本身就是索引文件。相比 MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按 B+Tree 组织的一个索引结构,树的叶节点 data 域保存了完整的数据记录。 -详细区别,推荐你看看我写的这篇文章:[MySQL 索引详解](./mysql-index.md)。 +详细区别,推荐你看看我写的这篇文章:[MySQL 索引详解](https://javaguide.cn/database/mysql/mysql-index.html)。 **7、性能有差别。** @@ -440,7 +418,7 @@ InnoDB 使用缓冲池(Buffer Pool)缓存数据页和索引页,MyISAM 使 ### 为什么 InnoDB 没有使用哈希作为索引的数据结构? -> 我发现很多求职者甚至是面试官对这个问题都有误解,他们相当然的认为 MySQL 底层并没有使用哈希或者 B 树作为索引的数据结构。 +> 我发现很多求职者甚至是面试官对这个问题都有误解,他们想当然的认为 MySQL 底层并没有使用哈希或者 B 树作为索引的数据结构。 > > 实际上,不论是提问还是回答这个问题都要区分好存储引擎。像 MEMORY 引擎就同时支持哈希和 B 树。 @@ -995,3 +973,5 @@ MySQL 性能优化是一个系统性工程,涉及多个方面,在面试中 **5.总结** 在面试中,建议按优先级依次介绍慢 SQL 定位、索引优化、表结构设计和 SQL 优化等内容。架构层面的优化,如读写分离和分库分表、数据冷热分离应作为最后的手段,除非在特定场景下有明显的性能瓶颈,否则不应轻易使用,因其引入的复杂性会带来额外的维护成本。 + + diff --git a/docs/database/redis.md b/docs/database/redis.md index 7865f0d..71881c8 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -1,38 +1,16 @@ --- title: Redis常见面试题总结 +description: 最新Redis面试题全解析:涵盖Redis事务原理、性能优化pipeline与Lua脚本、bigkey与hotkey处理、缓存穿透击穿雪崩应对方案、慢查询与内存碎片、Redis Sentinel哨兵与Cluster集群详解,助你高分通过后端面试。 category: 数据库 tag: - Redis head: - - meta - name: keywords - content: Redis面试题, Redis事务, Redis性能优化, Redis缓存穿透, Redis缓存击穿, Redis缓存雪崩, Redis bigkey, Redis hotkey, Redis慢查询, Redis内存碎片, Redis集群, Redis Sentinel - - - meta - - name: description - content: 最新Redis面试题全解析:事务原理、性能优化(pipeline/Lua/bigkey/hotkey)、缓存穿透/击穿/雪崩应对、慢查询&内存碎片、Sentinel/Cluster集群详解,助你高分通过后端面试! + content: Redis面试题,Redis数据类型,Redis持久化,RDB,AOF,Redis事务,Redis性能优化,缓存穿透,缓存击穿,缓存雪崩,Redis bigkey,Redis hotkey,Redis Sentinel,Redis Cluster,分布式锁 --- ------- - -![面试突击-Redis](https://oss.javaguide.cn/github/javaguide-interview/cover/redis.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了⭐️标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: @@ -927,8 +905,6 @@ maxmemory-policy noeviction 关于淘汰策略的详细说明可以参考 Redis 官方文档:。 - - ## Redis 事务 ### 什么是 Redis 事务? @@ -1214,7 +1190,7 @@ bigkey 通常是由于下面这些原因产生的: bigkey 除了会消耗更多的内存空间和带宽,还会对性能造成比较大的影响。 -在 [Redis 常见阻塞原因总结](./redis-common-blocking-problems-summary.md) 这篇文章中我们提到:大 key 还会造成阻塞问题。具体来说,主要体现在下面三个方面: +在 [Redis 常见阻塞原因总结](https://javaguide.cn/database/redis/redis-common-blocking-problems-summary.html) 这篇文章中我们提到:大 key 还会造成阻塞问题。具体来说,主要体现在下面三个方面: 1. 客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。 2. 网络阻塞:每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。 @@ -1727,5 +1703,5 @@ Bloom Filter 会使用一个较大的 bit 数组来保存所有的数据,数 6. 控制 key 的生命周期:避免 Redis 中存放了太多不经常被访问的数据。 7. …… - + diff --git a/docs/distributed-system/distributed-system.md b/docs/distributed-system/distributed-system.md new file mode 100644 index 0000000..6c6237b --- /dev/null +++ b/docs/distributed-system/distributed-system.md @@ -0,0 +1,918 @@ +--- +title: 分布式系统常见面试题总结 +category: 分布式 +description: 分布式系统常见面试题总结:涵盖CAP/BASE理论、分布式锁、分布式ID、分布式事务、配置中心、API网关、RPC框架、ZooKeeper、分布式算法(Paxos/Raft/ZAB/Gossip)等核心知识点。 +tag: + - 分布式 +head: + - - meta + - name: keywords + content: 分布式系统,CAP定理,BASE理论,分布式锁,分布式ID,分布式事务,配置中心,API网关,RPC,Dubbo,ZooKeeper,Paxos,Raft,ZAB,Gossip,分布式面试题 + +--- + + + +这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章的重点: + +分布式理论&算法&协议: + +- [CAP 理论和 BASE 理论解读](https://javaguide.cn/distributed-system/protocol/cap-and-base-theorem.html) +- [Paxos 算法解读](https://javaguide.cn/distributed-system/protocol/paxos-algorithm.html) +- [Raft 算法解读](https://javaguide.cn/distributed-system/protocol/raft-algorithm.html) +- [ZAB 协议详解](https://javaguide.cn/distributed-system/protocol/zab.html) +- [Gossip 协议详解](https://javaguide.cn/distributed-system/protocol/gossip-protocol.html) +- [一致性哈希算法详解](https://javaguide.cn/distributed-system/protocol/consistent-hashing.html) + +RPC: + +- [RPC 基础常见面试题总结](https://javaguide.cn/distributed-system/rpc/rpc-intro.html) +- [Dubbo 常见面试题总结](https://javaguide.cn/distributed-system/rpc/dubbo.html) + +分布式 ID: + +- [分布式ID介绍&实现方案总结](https://javaguide.cn/distributed-system/distributed-id.html) +- [分布式 ID 设计指南](https://javaguide.cn/distributed-system/distributed-id-design.html) + +API网关: + +- [API 网关基础知识总结](https://javaguide.cn/distributed-system/api-gateway.html) +- [Spring Cloud Gateway 常见问题总结](https://javaguide.cn/distributed-system/spring-cloud-gateway-questions.html) + +分布式锁: + +- [分布式锁介绍](https://javaguide.cn/distributed-system/distributed-lock.html) +- [分布式锁常见实现方案总结](https://javaguide.cn/distributed-system/distributed-lock-implementations.html) + +## 分布式基础理论 + +### ⭐️什么是 CAP 定理? + +CAP 定理讨论 Consistency(一致性)、Availability(可用性)和 Partition Tolerance(分区容错)。 + +> **重要说明**:下文使用「偏 CP / 偏 AP」仅作直觉描述。严格按 CAP 定义(C=Linearizability,A=每个非故障节点都必须响应)时,许多系统并不能被干净归类——同一系统内不同操作的一致性/可用性特征不同,很多系统既不满足 CAP-C 也不满足 CAP-A。 + +![](https://oss.javaguide.cn/2020-11/cap.png) + +CAP 理论的提出者布鲁尔在提出 CAP 猜想的时候,并没有对 **Consistency**、**Availability**、**Partition Tolerance** 给出严格定义。 + +因此,对于 CAP 的民间解读有很多,比较常见、也更推荐的一种解读如下。 + +在理论计算机科学中,CAP 定理(CAP theorem)指出对于一个分布式系统来说,当设计读写操作时,只能同时满足以下三点中的两个: + +- **一致性(Consistency)**:在 Gilbert/Lynch(2002)的证明语境里,CAP 的一致性 C 指的是 **Atomic Consistency**,通常等同于 **Linearizability(线性一致性)**。即所有操作按实时顺序线性化,即写操作一旦完成,后续所有读操作都必须返回该写入的值(或更新的值)。**注意:** 这里的 Consistency 与数据库 ACID 中的 Consistency(一致性约束)含义不同,后者指事务执行前后数据库状态满足完整性约束。 +- **可用性(Availability)**:非故障的节点必须对每个请求返回响应(不讨论响应快慢)。**注意**:这是 CAP 理论中的严格定义,不包含工程中的延迟/SLA 指标(如「1s 内返回」)。 +- **分区容错性(Partition Tolerance)**:CAP 里的 P 本质上是在假设异步网络(可能延迟/丢包/分区),不是一个你「选择要不要」的功能。真正的权衡是:当分区发生时,你必须在**线性一致(CAP 的 Consistency=Linearizability)**与**CAP-Availability(任何非故障节点都要对请求给非错误响应)**之间做选择。 + +**什么是网络分区?** + +分布式系统中,多个节点之间的网络本来是连通的,但是因为某些故障(比如部分节点网络出了问题)某些节点之间不连通了,整个网络就分成了几块区域,这就叫 **网络分区**。 + +![partition-tolerance](https://oss.javaguide.cn/2020-11/partition-tolerance.png) + +### CAP 是 3 选 2 吗? + +这是一个常见的误区。实际上: + +1. **P 是必选的**:分布式系统中网络分区是必然发生的,无法避免 +2. **真正的选择是 CA**:当分区发生时,在一致性和可用性之间权衡 +3. **同一系统内不同操作可以有不同的选择**:如 Nacos 支持在 CP 和 AP 之间切换 + +对于分布式系统来说,P 是必须要有的,因为网络既然会存在分区问题(网络延迟、丢包、中断等),分区容错性也就成为了必然的选择。如果是单机系统,就没有分区的问题,也就没有 P 这回事了,这时候可以同时满足 CA。 + +### PACELC 理论是什么? + +PACELC 是 CAP 的扩展,更贴近实际系统设计: + +- **如果存在分区(P)**:必须在可用性(A)和一致性(C)之间选择 +- **否则(E)**:必须在延迟(L)和一致性(C)之间选择 + +**实际意义**:即使没有网络分区,系统仍需在低延迟和强一致性之间权衡。例如,同步复制可以保证强一致性但会增加延迟,异步复制可以降低延迟但会牺牲一致性。 + +### ⭐️什么是 BASE 理论? + +BASE 理论是对 CAP 中 AP 方案的延伸,是对 ACID 强一致性的替代方案。 + +**BASE 含义:** + +- **Basically Available(基本可用)**:系统出现故障时,允许损失部分可用性(如响应时间增加、功能降级)。比如在双十一秒杀活动中,为了保证系统的稳定性,部分用户可能会被引导到降级页面。 +- **Soft-state(软状态)**:允许系统存在中间状态,该状态不影响整体可用性。这里的中间状态是指数据在复制过程中可能存在短暂的不一致。 +- **Eventually Consistent(最终一致性)**:系统保证在一段时间内达到数据一致,而非实时一致。实际上,ACID 和 BASE 并非完全对立,ACID 是强一致性,而 BASE 是最终一致性,两者都是保证数据一致性的策略。 + +**BASE vs ACID:** + +| 特性 | ACID | BASE | +| -------- | ---------- | ---------- | +| 一致性 | 强一致 | 最终一致 | +| 可用性 | 较低 | 较高 | +| 性能 | 较低 | 较高 | +| 适用场景 | 传统数据库 | 分布式系统 | + +### 最终一致性的修复方式有哪些? + +**业界比较推崇最终一致性级别,但是某些对数据一致要求十分严格的场景比如银行转账还是要保证强一致性。** + +那实现最终一致性的具体方式是什么呢? + +- **读时修复(Read Repair)**:在读取数据时,检测数据的不一致,进行修复。适合读多写少场景。 +- **写时修复(Hinted Handoff)**:在写入数据时,如果目标节点不可用,将数据缓存下来,待节点恢复后重传。**写时修复** 优化了写入延迟,但增加了读取时的不一致风险(数据可能还在缓存队列中未落盘到目标节点)。 +- **异步修复(Anti-Entropy/反熵)**:通过后台比对副本数据差异并修复。工程实现中关键挑战是**高效检测数据差异**——暴力逐条比对(O(n))在大规模数据集下不可行,生产系统采用**默克尔树(Merkle Tree)**实现低开销差异定位。 + +### 为什么很多人把 BASE 当作 CAP 的补充? + +这是一个**部分正确但表述不够精确**的说法。更准确的理解是: + +1. **BASE 首先是 ACID 的替代品**:从论文标题[《Base: An ACID Alternative》](https://spawn-queue.acm.org/doi/10.1145/1394127.1394128)可以看出,BASE 理论的初衷是解决分布式事务场景下 ACID 过于严格的问题。 + +2. **BASE 与 CAP 的 AP 架构存在内在联系**: + + - 选择 AP 架构意味着放弃强一致性(C) + - 放弃强一致性后,系统如何达到收敛?答案是**最终一致性** + - 因此,BASE 理论(特别是最终一致性)是 AP 架构在工程实践中**必须采用**的指导原则 + +3. **误解产生的根源**:很多人把"BASE 与 AP 相关"误解为"BASE 是 CAP 的补充"。实际上: + - **BASE 不是对 CAP 理论的补充或修正** + - **BASE 是 AP 架构选择的工程实践指南**——当你选择了 AP,BASE 告诉你如何在工程实践中让系统最终达到一致 + +**正确的理解**: + +```mermaid +flowchart TB + %% 核心语义配色 + classDef cap fill:#E99151,color:#FFFFFF,stroke:none,rx:10,ry:10 + classDef base fill:#27AE60,color:#FFFFFF,stroke:none,rx:10,ry:10 + classDef acid fill:#3498DB,color:#FFFFFF,stroke:none,rx:10,ry:10 + classDef relation fill:#9B59B6,color:#FFFFFF,stroke:none,rx:10,ry:10 + + CAP[CAP 理论
分布式存储系统设计约束]:::cap + ACID[ACID 理论
数据库事务完整性]:::acid + BASE[BASE 理论
ACID 的分布式替代品]:::base + + CAP -->|AP 架构放弃强一致性| BASE + ACID -->|分布式场景放宽| BASE + + CAP -->|约束:不能同时满足 C+A| R1[实践意义]:::relation + BASE -->|实现:如何达到最终一致| R1 + + R1 --> Result[CAP 告诉我们限制
BASE 告诉我们做法]:::relation + + linkStyle default stroke-width:2px,stroke:#333333,opacity:0.8 +``` + +| 维度 | CAP 理论 | BASE 理论 | +| ---------- | ------------------------ | ------------------------------------------------ | +| 关注领域 | 分布式存储系统(带副本) | 所有分布式系统 | +| 一致性含义 | 数据一致性(副本同步) | 状态一致性(事务终态) | +| 可用性含义 | 节点故障时系统可用 | 部分节点故障时部分功能可用 | +| 核心关系 | - | ① ACID 的分布式替代品
② AP 架构的工程实践指南 | + +> **实践意义**:CAP 告诉我们在 AP 架构下无法保证强一致性,BASE 告诉我们在 AP 架构下如何通过最终一致性让系统达到收敛——两者是**约束与实现**的关系,而非补充关系。 + +如果说 CAP 是分布式存储系统的设计约束(告诉我们不能做什么),那么 BASE 就是分布式系统(尤其是业务系统)的实践指导(告诉我们如何做)——它告诉我们:**绝大多数应用场景不需要强一致性,通过接受中间态并最终达到一致性,是更务实的选择。** + +## 分布式算法 + +### ⭐️什么是共识算法? + +共识算法的核心目标,就是**让一群机器看起来像一台机器**。只要集群里超过半数的机器还活着,整个系统就能正常接客。 + +这通常是通过**复制状态机**来实现的:给每个节点发一本一模一样的账本(日志)。只要大家按照同样的顺序去执行账本上的命令,最后得到的结果自然完全一样。所以,共识算法本质上干的就是一件事——**保证所有节点的账本绝对一致**。共识是可容错系统中的一个基本问题:即使面对故障,服务器也可以在共享状态上达成一致。 + +![共识算法架构](https://oss.javaguide.cn/github/javaguide/paxos-rsm-architecture.png) + +### Basic Paxos 算法中存在哪些角色? + +Paxos 是最早被广泛认可的分布式共识算法(1990 年 Lamport 提出)。 + +Basic Paxos 中存在 3 个重要的角色: + +1. **提议者(Proposer)**:也可以叫做协调者(coordinator),负责接受客户端请求并发起提案。提案信息通常包括提案编号(proposal ID)和提议的值(value)。 +2. **接受者(Acceptor)**:也可以叫做投票员(voter),负责对提案进行投票,同时需要记住自己的投票历史。 +3. **学习者(Learner)**:负责学习(learn)已被选定的值。在复制状态机(RSM)实现中,该值通常对应一条待执行的命令,由状态机按序 apply 后再由对外服务层返回结果。 + +![Basic Paxos中的角色](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/up-890fa3212e8bf72886a595a34654918486c.png) + +**角色交互关系图**: + +```mermaid +flowchart LR + subgraph Roles["Paxos 三个核心角色"] + direction LR + Prop[Proposer
提议者
发起提案] + Acc[Acceptor
接受者
投票表决] + Lear[Learner
学习者
获取结果] + end + + Prop -->|Prepare| Acc + Acc -->|Promise| Prop + Prop -->|Accept| Acc + Acc -->|Accepted| Prop + Prop -->|通知选定| Lear + + style Roles fill:#F5F7FA,color:#333,stroke:#005D7B,stroke-width:2px + classDef role fill:#E99151,color:#FFFFFF,stroke:none,rx:10,ry:10 + + class Prop,Acc,Lear role +``` + +为了减少实现该算法所需的节点数,一个节点可以身兼多个角色。并且,一个提案被选定需要被半数以上的 Acceptor 接受。这样的话,Basic Paxos 算法还具备容错性,在少于一半的节点出现故障时,集群仍能正常工作。 + +**适用场景**:非拜占庭环境(无恶意节点) + +### Basic Paxos 的两阶段流程? + +**Phase 1: Prepare/Promise(准备阶段)** + +1. Proposer 选择提案编号 n,向多数 Acceptor 发送 Prepare(n) +2. Acceptor 收到 Prepare(n) 后,承诺不再接受编号小于 n 的提案,并返回已接受的编号最大的提案(如有) + +**Phase 2: Accept/Accepted(接受阶段)** + +1. Proposer 收到多数 Promise 后,发送 Accept(n, v),v 是收到的最大编号提案的值,或自己提议的值 +2. Acceptor 收到 Accept(n, v) 后,接受提案(除非已承诺更大的编号) + +**关键点**:必须获得**多数(Quorum)** 的 Accept 才算提案被选定。 + +### Multi-Paxos 的 Basic Paxos 有什么区别? + +Basic Paxos 算法仅能就单个值达成共识,为了能够对一系列的值达成共识,我们需要用到 Multi-Paxos 思想。 + +Multi-Paxos 的核心优化思想是**复用 Leader**:通过 Basic Paxos 选出一个稳定的 Proposer 作为 Leader,后续提案直接由该 Leader 发起,跳过 Phase 1 的 Prepare/Promise 阶段。 + +### ⭐️Raft 算法与 Paxos 的关系? + +- Raft 不是 Paxos 的变体,但借鉴了 Multi-Paxos 思想 +- Raft 设计目标是**易于理解** +- 将共识问题拆解为三个子问题:**Leader 选举**、**日志复制**、**安全性** + +### Raft 的三种节点状态? + +一个 Raft 集群包括若干服务器,以典型的 5 服务器集群举例。在任意的时间,每个服务器一定会处于以下三个状态中的一个: + +- **Leader(领导者)**:大当家。全权负责接待客户端、写账本、并把账本同步给小弟。为了防止别人篡位,他必须不断地向全员发送心跳,宣告“我还活着”。 +- **Follower(跟随者)**:安分守己的小弟。平时绝对不主动发起请求,只被动接收老大的心跳和账本同步。 +- **Candidate(候选人)**:临时状态。如果小弟迟迟等不到老大的心跳,就会觉得自己行了,变身候选人开始拉票。 + +在正常的情况下,只有一个服务器是 Leader,剩下的服务器是 Follower。Follower 是被动的,它们不会发送任何请求,只是响应来自 Leader 和 Candidate 的请求。 + +![Raft 服务器状态转换示意图](https://oss.javaguide.cn/github/javaguide/paxos-server-state.png) + +### ⭐️Raft 的 Leader 选举流程? + +1. Follower 在选举超时(election timeout)内未收到心跳,变为 Candidate +2. Candidate 自增 term,向所有节点发起 RequestVote +3. 收到多数选票则成为 Leader +4. 使用**随机选举超时**避免同时竞选(Split Vote) + +![Raft Leader 选举流程](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/raft-election.png) + +**随机选举超时**:每个节点的选举超时时间是随机的(如 150-300ms),这样可以减少多个节点同时发起选举的概率。 + +### ZAB 协议的两种广播模式? + +**ZAB(ZooKeeper Atomic Broadcast)** **正确的理解**是 ZooKeeper 专用的原子广播协议。 + +**两种模式**: + +- **消息广播模式**:正常处理写请求,类似简化版 2PC。Leader 将请求转化为事务提案,发送给所有 Follower,收到半数以上 ACK 后提交。 +- **崩溃恢复模式**:Leader 选举 + 数据同步。当 Leader 宕机或重启时,集群进入恢复模式。 + +![ZAB 消息广播模式](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/zab-message-broadcast-flow.png) + +![zab-crash-recovery-flow](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/zab-crash-recovery-flow.png) + +### ZAB 的 ZXID 结构? + +为了保证分布式环境下消息的绝对顺序性,ZAB 协议引入了一个全局单调递增的事务 ID——**ZXID**。 + +ZXID 是一个 64 位的长整型(long): + +- **高 32 位(Epoch 纪元):** 代表当前 Leader 的任期年代。当选出一个新的 Leader 时,Epoch 就会在前一个的基础上加 1。这相当于朝代更替。 +- **低 32 位(事务 ID):** 一个简单的递增计数器。针对客户端的每一个写请求,计数器都会加 1。新 Leader 上位时,这个低 32 位会被清零重置。 + +![ZXID 结构](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/zab-zxid-structure.png) + +### ⭐️ZAB 的 Leader 选举规则? + +按顺序比较:**Epoch > ZXID > myid** + +1. 首先比较 Epoch,Epoch 大的胜出 +2. Epoch 相同,比较 ZXID,ZXID 大的胜出(数据更新) +3. 都相同,比较 myid(服务器 ID),myid 大的胜出 + +获得过半选票的节点成为 Leader。 + +### Gossip 协议是什么? + +**Gossip(闲话协议)**也称 **Epidemic 协议**(流行病协议),是一种**去中心化**的信息传播协议: + +- 每个节点周期性随机选择若干节点交换信息 +- 像病毒传播一样扩散至整个网络 +- 在非拜占庭且不存在永久网络分区的前提下,达到**最终一致性** + +**关键特性**: + +- **去中心化**:无中心节点,所有节点地位平等 +- **容错性强**:容忍节点宕机、网络分区、动态增删节点 +- **概率收敛**:传播轮次期望为 O(log N) +- **消息冗余**:同一消息可能被多次接收,需去重机制 + +**典型应用**:Redis Cluster 节点通信、Cassandra 数据同步 + +### Gossip 的两种传播模式? + +| 要点 | 反熵(Anti-Entropy) | 谣言传播(Rumor-Mongering) | +| -------- | ----------------------- | --------------------------- | +| 传播内容 | 完整数据(或摘要) | 仅新增数据(Delta) | +| 适用场景 | 节点数量适中 | 节点数量较多/动态变化 | +| 消息开销 | 较大 | 较小 | +| 实现方式 | Push / Pull / Push-Pull | 节点收到更新后周期性传播 | + +![反熵机制:Push-Pull 交互时序图 (Anti-Entropy)](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/gossip-anti-entropy-pushpull.png) + +![Gossip 传播示意图](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/gossip-rumor-mongering.gif) + +> **生产级优化**:在大规模分布式存储(如 Cassandra、DynamoDB)中,使用 **Merkle Tree(默克尔树)** 进行增量差异比对,仅传输增量数据。 + +### ⭐️一致性哈希算法解决什么问题? + +解决传统哈希取模在节点增减时导致**大量数据迁移**的问题。 + +**普通哈希**:`hash(key) % N`,节点数 N 变化时,平均有 (N-1)/N 比例的数据需要迁移,这个比例**趋近于 100%**。 + +**一致性哈希**:节点变化时,只影响相邻节点的数据,影响范围非常小。 + +![哈希取模](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/consistent-hashing/hashqumo.png) + +### 一致性哈希的原理? + +1. 将哈希空间组织成**环形结构**(0 ~ 2^32-1) +2. 数据和节点都映射到环上:`hash(key) % 2^32`、`hash(服务器IP) % 2^32` +3. 数据顺时针找到的第一个节点就是其所属节点 + +![哈希环](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/consistent-hashing/consistent-hashing-circle.png) + +### 一致性哈希的数据倾斜问题如何解决? + +引入**虚拟节点**: + +- 每个物理节点对应多个虚拟节点(100-200 个,如 Nginx 选择 160 个) +- 虚拟节点均匀分布在环上,使数据分布更均衡 +- 节点宕机时,流量会**均匀分散**到多个物理节点,而不是集中到一个邻居节点 + +**引入虚拟节点的好处**: + +1. **数据均衡**:从根本上解决了数据倾斜问题 +2. **容错性增强**:当一个物理节点宕机,其多个虚拟节点同时下线,数据和流量会均匀分散到其他多个物理节点 + +![虚拟节点](https://oss.javaguide.cn/github/javaguide/distributed-system/protocol/consistent-hashing/consistent-hashing-circle-virtual-node.png) + +## 分布式锁 + +### ⭐️为什么需要分布式锁? + +**本地锁的局限性**: + +在多线程环境中,如果多个线程同时访问共享资源(例如商品库存、外卖订单),会发生数据竞争,可能会导致出现脏数据或者系统问题,威胁到程序的正常运行。 + +![共享资源未互斥访问导致出现问题](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/oversold-without-locking.png) + +对于单机多线程来说,在 Java 中,我们通常使用 `ReentrantLock` 类、`synchronized` 关键字这类 JDK 自带的 **本地锁** 来控制一个 JVM 进程内的多个线程对本地共享资源的访问。 + +![本地锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/jvm-local-lock.png) + +**分布式场景下的问题**: + +分布式系统下,不同的服务/客户端通常运行在独立的 JVM 进程上。如果多个 JVM 进程共享同一份资源的话,使用本地锁就没办法实现资源的互斥访问了。 + +举个例子:系统的订单服务一共部署了 3 份,都对外提供服务。用户下订单之前需要检查库存,为了防止超卖,这里需要加锁以实现对检查库存操作的同步访问。由于订单服务位于不同的 JVM 进程中,本地锁在这种情况下就没办法正常工作了。我们需要用到分布式锁,这样的话,即使多个线程不在同一个 JVM 进程中也能获取到同一把锁,进而实现共享资源的互斥访问。 + +![分布式锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock.png) + +**典型应用场景**: + +- 秒杀活动防止超卖 +- 库存扣减保证原子性 +- 订单处理防止重复 + +### 分布式锁应具备哪些条件? + +一个最基本的分布式锁需要满足: + +- **互斥**:任意一个时刻,锁只能被一个线程持有。 +- **高可用**:锁服务是高可用的,当一个锁服务出现问题,能够自动切换到另外一个锁服务。并且,即使客户端的释放锁的代码逻辑出现问题,锁最终一定还是会被释放,不会影响其他线程对共享资源的访问。这一般是通过超时机制实现的。 +- **可重入**:一个节点获取了锁之后,还可以再次获取锁。 + +除了上面这三个基本条件之外,一个好的分布式锁还需要满足下面这些条件: + +- **高性能**:获取和释放锁的操作应该快速完成,并且不应该对整个系统的性能造成过大影响。 +- **非阻塞**:如果获取不到锁,不能无限期等待,避免对系统正常运行造成影响。 + +### 分布式锁的常见实现方式有哪些? + +常见分布式锁实现方案如下: + +- 基于关系型数据库比如 MySQL 实现分布式锁。 +- 基于分布式协调服务 ZooKeeper 实现分布式锁。 +- 基于分布式键值存储系统比如 Redis 、Etcd 实现分布式锁。 + +关系型数据库的方式一般是通过唯一索引或者排他锁实现。不过,一般不会使用这种方式,问题太多比如性能太差、不具备锁失效机制。 + +基于 ZooKeeper 或者 Redis 实现分布式锁这两种实现方式要用的更多一些。 + +### ⭐️如何基于 Redis 实现分布式锁? + +**最简实现(SETNX)**: + +```bash +# 加锁 +SET lockKey uniqueValue NX EX 30 +# NX: key不存在才设置 EX: 设置过期时间30秒 + +# 释放锁(使用Lua脚本保证原子性) +if redis.call("get", KEYS[1]) == ARGV[1] then + return redis.call("del", KEYS[1]) +else + return 0 +end +``` + +**为什么需要 Lua 脚本释放锁?** + +释放锁需要先判断 value 是否一致再删除,这两步操作需要保证原子性,否则可能出现误删其他客户端锁的情况。 + +**具体流程**: + +1. 加锁时使用 `SET key value NX PX expireTime` 命令,保证原子性 +2. value 必须是唯一标识(如 UUID),用于识别锁的持有者 +3. 释放锁时先判断 value 是否一致,再执行删除,使用 Lua 脚本保证原子性 + +![Redis 实现简易分布式锁](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-setnx.png) + +**为什么要给锁设置一个过期时间?** + +为了避免锁无法被释放,我们可以想到的一个解决办法就是:**给这个 key(也就是锁) 设置一个过期时间** 。 + +```bash +127.0.0.1:6379> SET lockKey uniqueValue EX 3 NX +OK +``` + +- **lockKey**:加锁的锁名; +- **uniqueValue**:能够唯一标识锁的随机字符串; +- **NX**:只有当 lockKey 对应的 key 值不存在的时候才能 SET 成功; +- **EX**:过期时间设置(秒为单位)EX 3 标示这个锁有一个 3 秒的自动过期时间。与 EX 对应的是 PX(毫秒为单位),这两个都是过期时间设置。 + +**一定要保证设置指定 key 的值和过期时间是一个原子操作!!!** 不然的话,依然可能会出现锁无法被释放的问题。 + +这样确实可以解决问题,不过,这种解决办法同样存在漏洞:**如果操作共享资源的时间大于过期时间,就会出现锁提前过期的问题,进而导致分布式锁直接失效。如果锁的超时时间设置过长,又会影响到性能。** + +你或许在想:**如果操作共享资源的操作还未完成,锁过期时间能够自己续期就好了!** + +对于 Java 开发的小伙伴来说,已经有了现成的解决方案:**[Redisson](https://github.com/redisson/redisson)** 。其他语言的解决方案,可以在 Redis 官方文档中找到,地址: 。 + +![Distributed locks with Redis](https://oss.javaguide.cn/github/javaguide/redis-distributed-lock.png) + +Redisson 是一个开源的 Java 语言 Redis 客户端,提供了很多开箱即用的功能,不仅仅包括多种分布式锁的实现。并且,Redisson 还支持 Redis 单机、Redis Sentinel、Redis Cluster 等多种部署架构。 + +Redisson 中的分布式锁自带自动续期机制,使用起来非常简单,原理也比较简单,其提供了一个专门用来监控和续期锁的 **Watch Dog( 看门狗)**,如果操作共享资源的线程还未执行完成的话,Watch Dog 会不断地延长锁的过期时间,进而保证锁不会因为超时而被释放。 + +![Redisson 看门狗自动续期](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-redisson-renew-expiration.png) + +看门狗名字的由来于 `getLockWatchdogTimeout()` 方法,这个方法返回的是看门狗给锁续期的过期时间,默认为 30 秒([redisson-3.17.6](https://github.com/redisson/redisson/releases/tag/redisson-3.17.6))。 + +```java +//默认 30秒,支持修改 +private long lockWatchdogTimeout = 30 * 1000; + +public Config setLockWatchdogTimeout(long lockWatchdogTimeout) { + this.lockWatchdogTimeout = lockWatchdogTimeout; + return this; +} +public long getLockWatchdogTimeout() { + return lockWatchdogTimeout; +} +``` + +`renewExpiration()` 方法包含了看门狗的主要逻辑: + +```java +private void renewExpiration() { + //...... + Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() { + @Override + public void run(Timeout timeout) throws Exception { + //...... + // 异步续期,基于 Lua 脚本 + CompletionStage future = renewExpirationAsync(threadId); + future.whenComplete((res, e) -> { + if (e != null) { + // 无法续期 + log.error("Can't update lock " + getRawName() + " expiration", e); + EXPIRATION_RENEWAL_MAP.remove(getEntryName()); + return; + } + + if (res) { + // 递归调用实现续期 + renewExpiration(); + } else { + // 取消续期 + cancelExpirationRenewal(null); + } + }); + } + // 延迟 internalLockLeaseTime/3(默认 10s,也就是 30/3) 再调用 + }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS); + + ee.setTimeout(task); + } +``` + +默认情况下,每过 10 秒,看门狗就会执行续期操作,将锁的超时时间设置为 30 秒。看门狗续期前也会先判断是否需要执行续期操作,需要才会执行续期,否则取消续期操作。 + +Watch Dog 通过调用 `renewExpirationAsync()` 方法实现锁的异步续期: + +```java +protected CompletionStage renewExpirationAsync(long threadId) { + return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, + // 判断是否为持锁线程,如果是就执行续期操作,就锁的过期时间设置为 30s(默认) + "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + + "redis.call('pexpire', KEYS[1], ARGV[1]); " + + "return 1; " + + "end; " + + "return 0;", + Collections.singletonList(getRawName()), + internalLockLeaseTime, getLockName(threadId)); +} +``` + +可以看出, `renewExpirationAsync` 方法其实是调用 Lua 脚本实现的续期,这样做主要是为了保证续期操作的原子性。 + +我这里以 Redisson 的分布式可重入锁 `RLock` 为例来说明如何使用 Redisson 实现分布式锁: + +```java +// 1.获取指定的分布式锁对象 +RLock lock = redisson.getLock("lock"); +// 2.拿锁且不设置锁超时时间,具备 Watch Dog 自动续期机制 +lock.lock(); +// 3.执行业务 +... +// 4.释放锁 +lock.unlock(); +``` + +只有未指定锁超时时间,才会使用到 Watch Dog 自动续期机制。 + +```java +// 手动给锁设置过期时间,不具备 Watch Dog 自动续期机制 +lock.lock(10, TimeUnit.SECONDS); +``` + +如果使用 Redis 来实现分布式锁的话,还是比较推荐直接基于 Redisson 来做的。 + +### ⭐️如何实现可重入锁? + +所谓可重入锁指的是在一个线程中可以多次获取同一把锁,比如一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法即可重入 ,而无需重新获得锁。像 Java 中的 `synchronized` 和 `ReentrantLock` 都属于可重入锁。 + +**不可重入的分布式锁基本可以满足绝大部分业务场景了,一些特殊的场景可能会需要使用可重入的分布式锁。** + +可重入分布式锁的实现核心思路是线程在获取锁的时候判断是否为自己的锁,如果是的话,就不用再重新获取了。为此,我们可以为每个锁关联一个可重入计数器和一个占有它的线程。当可重入计数器大于 0 时,则锁被占有,需要判断占有该锁的线程和请求获取锁的线程是否为同一个。 + +实际项目中,我们不需要自己手动实现,推荐使用我们上面提到的 **Redisson** ,其内置了多种类型的锁比如可重入锁(Reentrant Lock)、自旋锁(Spin Lock)、公平锁(Fair Lock)、多重锁(MultiLock)、 红锁(RedLock)、 读写锁(ReadWriteLock)。 + +![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/redisson-readme-locks.png) + +### Redis 如何解决集群情况下分布式锁的可靠性? + +为了避免单点故障,生产环境下的 Redis 服务通常是集群化部署的。 + +Redis 集群下,上面介绍到的分布式锁的实现会存在一些问题。由于 Redis 集群数据同步到各个节点时是异步的,如果在 Redis 主节点获取到锁后,在没有同步到其他节点时,Redis 主节点宕机了,此时新的 Redis 主节点依然可以获取锁,所以多个应用服务就可以同时获取到锁。 + +![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/redis-master-slave-distributed-lock.png) + +针对这个问题,Redis 之父 antirez 设计了 [Redlock 算法](https://redis.io/topics/distlock) 来解决。 + +![](https://oss.javaguide.cn/github/javaguide/distributed-system/distributed-lock/distributed-lock-redis.io-realock.png) + +Redlock 算法的思想是让客户端向 Redis 集群中的多个独立的 Redis 实例依次请求申请加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁,否则加锁失败。 + +即使部分 Redis 节点出现问题,只要保证 Redis 集群中有半数以上的 Redis 节点可用,分布式锁服务就是正常的。 + +Redlock 是直接操作 Redis 节点的,并不是通过 Redis 集群操作的,这样才可以避免 Redis 集群主从切换导致的锁丢失问题。 + +Redlock 实现比较复杂,性能比较差,发生时钟变迁的情况下还存在安全性隐患。《数据密集型应用系统设计》一书的作者 Martin Kleppmann 曾经专门发文([How to do distributed locking - Martin Kleppmann - 2016](https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html))怼过 Redlock,他认为这是一个很差的分布式锁实现。感兴趣的朋友可以看看[Redis 锁从面试连环炮聊到神仙打架](https://mp.weixin.qq.com/s?__biz=Mzg3NjU3NTkwMQ==&mid=2247505097&idx=1&sn=5c03cb769c4458350f4d4a321ad51f5a&source=41#wechat_redirect)这篇文章,有详细介绍到 antirez 和 Martin Kleppmann 关于 Redlock 的激烈辩论。 + +实际项目中不建议使用 Redlock 算法,成本和收益不成正比,可以考虑基于 Redis 主从复制+哨兵模式实现分布式锁。 + +### ⭐️基于 ZooKeeper 实现分布式锁的原理? + +**实现方式**:基于**临时顺序节点**和 **Watcher 机制** + +**流程**: + +1. 客户端在锁节点下创建临时顺序节点 +2. 判断自己是否是最小序号节点,是则获取锁成功 +3. 否则监听前一个节点的删除事件 +4. 前一个节点删除后,收到通知再次检查是否为最小节点 + +**为什么使用临时顺序节点?** + +- **临时节点**:会话消失则节点消失,避免客户端宕机导致死锁 +- **顺序节点**:只需监听前一个节点,避免羊群效应(所有节点监听同一节点),提升性能 + +**羊群效应说明**:如果所有客户端都监听同一个节点,当该节点被删除时,所有客户端都会被唤醒去竞争锁,这对 ZooKeeper 服务器造成很大压力。使用顺序节点后,每个客户端只需要监听自己前一个节点,大大减少了通知的次数。 + +### Redis 和 ZooKeeper 分布式锁如何选择? + +| 对比项 | Redis | ZooKeeper | +| ---------- | ------------------------------ | ------------------------ | +| 性能 | 高 | 较低 | +| 可靠性 | 依赖主从复制,极端情况可能丢锁 | 临时节点机制,更可靠 | +| 实现复杂度 | 中等(需要处理续期、Lua脚本) | 较低(Curator 封装完善) | +| 部署 | 简单 | 较复杂 | + +**选择建议**: + +- 追求性能:选择 Redis + Redisson +- 追求可靠性:选择 ZooKeeper + Curator +- 不建议仅为分布式锁引入 ZooKeeper + +## 分布式ID + +### ⭐️什么是分布式ID?需要满足哪些要求? + +分布式 ID 是分布式系统下的 ID。分布式 ID 不存在与现实生活中,属于计算机系统中的一个概念。 + +我简单举一个分库分表的例子。 + +我司的一个项目,使用的是单机 MySQL 。但是,没想到的是,项目上线一个月之后,随着使用人数越来越多,整个系统的数据量将越来越大。单机 MySQL 已经没办法支撑了,需要进行分库分表(推荐 Sharding-JDBC)。 + +在分库之后, 数据遍布在不同服务器上的数据库,数据库的自增主键已经没办法满足生成的主键唯一了。**我们如何为不同的数据节点生成全局唯一主键呢?** + +这个时候就需要生成**分布式 ID**了。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/distributed-system/id-after-the-sub-table-not-conflict.png) + +分布式 ID 作为分布式系统中必不可少的一环,很多地方都要用到分布式 ID。 + +一个最基本的分布式 ID 需要满足下面这些要求: + +- **全局唯一**:ID 的全局唯一性肯定是首先要满足的! +- **高性能**:分布式 ID 的生成速度要快,对本地资源消耗要小。 +- **高可用**:生成分布式 ID 的服务要保证可用性无限接近于 100%。 +- **方便易用**:拿来即用,使用方便,快速接入! + +除了这些之外,一个比较好的分布式 ID 还应保证: + +- **安全**:ID 中不包含敏感信息。 +- **有序递增**:如果要把 ID 存放在数据库的话,ID 的有序性可以提升数据库写入速度。并且,很多时候 ,我们还很有可能会直接通过 ID 来进行排序。 +- **有具体的业务含义**:生成的 ID 如果能有具体的业务含义,可以让定位问题以及开发更透明化(通过 ID 就能确定是哪个业务)。 +- **独立部署**:也就是分布式系统单独有一个发号器服务,专门用来生成分布式 ID。这样就生成 ID 的服务可以和业务相关的服务解耦。不过,这样同样带来了网络调用消耗增加的问题。总的来说,如果需要用到分布式 ID 的场景比较多的话,独立部署的发号器服务还是很有必要的。 + +### ⭐️常见分布式ID生成方案对比? + +| **方案** | **性能** | **有序性** | **运维成本** | **适用场景** | +| -------------- | -------- | ---------- | ------------ | --------------------------------------- | +| **数据库自增** | 低 | 严格递增 | 低 | 业务量小、单机架构、后台系统 | +| **号段模式** | 高 | 趋势递增 | 中 | 高并发、追求极致吞吐量的互联网业务 | +| **Redis 方案** | 很高 | 严格递增 | 中 | 已有 Redis 集群,能容忍极小概率 ID 回退 | +| **Snowflake** | 高 | 趋势递增 | 低/中 | 大中型分布式系统、Java 生态(最主流) | +| **UUID v7** | 高 | 趋势递增 | 极低 | 云原生、无中心化集群、追求开箱即用 | + +### ⭐️Snowflake 雪花算法的组成结构? + +Snowflake 是 Twitter 开源的分布式 ID 生成算法。Snowflake 由 64 bit 的二进制数字组成,这 64bit 的二进制被分成了几部分,每一部分存储的数据都有特定的含义: + +``` +0 - 41位时间戳 - 10位机器ID - 12位序列号 +``` + +**结构详解**: + +| 部分 | 位数 | 说明 | +| ------ | ------- | -------------------------------------------------- | +| 符号位 | 1 bit | 始终为 0,代表生成的 ID 为正数 | +| 时间戳 | 41 bits | 相对时间戳(距自定义基点的毫秒数),可支撑约 69 年 | +| 机器ID | 10 bits | 5 位机房 ID + 5 位机器 ID(支持 1024 台机器) | +| 序列号 | 12 bits | 单机每毫秒最多生成 4096 个 ID | + +**理论峰值**:单机每毫秒 4096 个 ID,即单机每秒约 400 万 ID。 + +> **⚠️ 高并发警示**:如果某一毫秒内的并发请求超过 4096 个,算法会**阻塞等待直到下一毫秒**。这可能导致在高并发瞬间(如秒杀、大促)出现响应延迟毛刺。 + +### Snowflake 有什么问题?如何解决? + +**1. 时钟回拨问题** + +原因:NTP 同步、人工调整时间、硬件时钟漂移可能导致时间倒退 + +解决方案对比: + +| 方案 | 优点 | 缺点 | 适用场景 | +| -------------- | -------------- | ------------------------ | ---------------------- | +| 拒绝服务 | 实现简单 | 时钟回拨期间完全不可用 | 对可用性要求不高的场景 | +| 等待追回 | 保证 ID 唯一性 | 可能长时间阻塞 | 时钟稳定的内网环境 | +| 备用 Worker ID | 高可用 | 实现复杂,需考虑 ZK 脑裂 | 生产环境推荐 | + +**2. Worker ID 分配问题** + +原因:容器化部署(Kubernetes)环境下,Pod 的 IP 和名称是动态的,无法像物理机一样预先配置固定的 Worker ID + +解决方案: + +- ZooKeeper 注册:服务启动时在 ZK 创建临时节点,节点序号作为 Worker ID +- Redis SETNX 分配:使用 `SETNX` + 过期时间实现 Worker ID 申领 +- 数据库分配:启动时从数据库分配并持久化到本地文件 + +**推荐**:使用美团 Leaf 或滴滴 Tinyid,已内置这些问题处理。 + +## ⭐️分布式事务 + +分布式相关的问题非常重要,建议阅读这篇文章:[分布式事务常见解决方案总结](https://javaguide.cn/distributed-system/distributed-transaction.html)。 + +## 分布式配置中心 + +### ⭐️为什么需要配置中心? + +**传统配置文件的问题**: + +微服务架构下,业务发展通常会导致服务数量增加,进而导致程序配置(服务地址、数据库参数、功能开关等)增多。传统配置文件方式存在以下问题: + +- **无法动态更新**:配置放在代码库中,每次修改都需要重新发布新版本才能生效。 +- **安全性不足**:敏感配置(数据库密码、API Key)直接写在代码库中容易泄露。 +- **时效性差**:即使能修改配置文件,通常也需要重启服务才能生效。 +- **缺乏权限控制**:无法对配置的查看、修改、发布等操作进行细粒度权限管控。 +- **配置分散难管理**:多环境(开发/测试/生产)、多集群的配置分散在各处,难以统一维护。 + +**配置中心的优势**: + +- **版本管理**:记录每次配置变更的修改人、修改时间、修改内容,支持一键回滚。 +- **灰度发布**:先将配置推送给部分实例验证,降低变更风险(Apollo、Nacos 1.1.0+ 支持)。 +- **权限控制**:配置的查看、修改、发布需分级授权。 + +![Applo 配置中心](https://oss.javaguide.cn/github/javaguide/config-center/view-release-history.png) + +### 常见配置中心有哪些?如何选择 + +| 功能 | Apollo | Nacos | Spring Cloud Config | +| ------------ | ---------------- | ------------------ | ------------------- | +| 配置界面 | 支持(功能完善) | 支持 | 无(通过 Git 操作) | +| 配置实时生效 | 长轮询(1s内) | gRPC长连接(1s内) | 需触发 refresh | +| 灰度发布 | 完善 | 基础支持 | 不支持 | +| 权限管理 | 细粒度 | 支持 | 依赖 Git 平台 | +| 版本管理 | 原生支持 | 原生支持 | 依赖 Git | +| 部署复杂度 | 较高 | 简单 | 最简单 | + +**选型建议**: + +- 只需配置中心 → **Apollo**(功能最完善)或 **Nacos**(上手更简单) +- 需要配置中心 + 服务发现 → **Nacos** +- Spring Cloud 体系且追求简单 → **Spring Cloud Config** +- Kubernetes 环境 → **K8s ConfigMap 挂载 + 应用层文件监听**(由于 Kubelet 同步 Volume 存在 1~2 分钟延迟,需引入 inotify 或 Spring Cloud Kubernetes 实现热重载) + +### 配置推送的三种模式? + +| 模式 | 实时性 | 服务端压力 | 说明 | +| ------ | --------------- | ---------------- | -------------- | +| 推模式 | 高(毫秒级) | 高(需维护连接) | 服务端主动推送 | +| 拉模式 | 低(秒~分钟级) | 高(无效轮询) | 客户端定时拉取 | +| 长轮询 | 中高(1~30s) | 中等 | 主流方案 | + +**长轮询原理**: + +- **Apollo**:采用 HTTP 长轮询。客户端发起请求,服务端若有变更立即返回;无变更则挂起请求(默认 30s),期间一旦有变更立即响应。 +- **Nacos 2.x**:采用 gRPC 长连接双向流。相比 1.x 的 HTTP 长轮询,gRPC 连接更轻量,配置变更可毫秒级主动 Push 至客户端。 + +> **注意**:长轮询虽然比短轮询节省 CPU 和网络开销,但当客户端规模达到十万级时,服务端需维持海量挂起的 HTTP 请求,对内存和连接数上限仍有较大压力。 + +## API网关 + +### ⭐️什么是 API 网关?为什么需要网关? + +API 网关(API Gateway)是位于客户端与后端服务之间的**统一入口**,所有客户端请求先经过网关,再由网关路由到具体的目标服务。 + +在微服务架构下,一个系统被拆分为多个服务。像**安全认证、流量控制、日志、监控**等功能是每个服务都需要的。如果没有网关,我们需要在每个服务中单独实现这些功能,导致: + +- **代码重复**:相同逻辑在多个服务中冗余实现 +- **管理分散**:缺乏统一的配置和监控视图 +- **维护成本高**:功能变更需要修改所有服务 + +![网关示意图](https://oss.javaguide.cn/github/javaguide/system-design/distributed-system/api-gateway-overview.png) + +### 网关的核心职责? + +网关的功能虽然繁多,但核心可以概括为两件事: + +| 职责 | 说明 | 典型功能 | +| ------------ | ----------------------------------- | -------------------------------------- | +| **请求转发** | 将客户端请求路由到正确的目标服务 | 动态路由、负载均衡、协议转换 | +| **请求过滤** | 在请求到达后端服务前/后进行拦截处理 | 身份认证、权限校验、限流熔断、日志记录 | + +网关可以提供请求转发、安全认证(身份/权限认证)、流量控制、负载均衡、降级熔断、日志、监控、参数校验、协议转换等功能。 + +**网关在微服务架构中的位置**:所有客户端请求先到达网关,网关负责统一的认证鉴权、流量控制、路由分发,后端服务专注于业务逻辑处理。 + +### 常见网关系统对比?如何选择? + +| 特性 | Zuul 1.x | Zuul 2.x | Spring Cloud Gateway | Kong | APISIX | Shenyu | +| -------------- | -------- | -------------- | ------------------------- | ----------------------------- | ---------------- | --------------- | +| **IO 模型** | 同步阻塞 | 异步非阻塞 | 异步非阻塞 | 异步非阻塞 | 异步非阻塞 | 异步非阻塞 | +| **底层技术** | Servlet | Netty | WebFlux + Netty | OpenResty (Nginx + Lua) | OpenResty + etcd | WebFlux + Netty | +| **性能** | 低 | 高 | 高 | 很高 | 很高 | 高 | +| **动态配置** | 需重启 | 支持 | 支持 | 支持 | 支持(热更新) | 支持 | +| **配置存储** | 内存 | 内存 | 内存 | 数据库 / YAML / K8s CRD | etcd(分布式) | 内存/数据库 | +| **限流熔断** | 需集成 | 需集成 | 内置(集成 Resilience4j) | 插件 | 插件 | 插件 | +| **生态系统** | Netflix | Netflix | Spring Cloud | CNCF / Kong | Apache | Apache | +| **运维复杂度** | 低 | 中 | 低 | 中(DB-less) / 高(DB Mode) | 中 | 中 | +| **学习曲线** | 平缓 | 平缓 | 平缓 | 陡峭(Lua) | 陡峭(Lua) | 平缓(Java) | +| **适用场景** | 遗留系统 | Netflix 技术栈 | Spring Cloud 生态 | 云原生、多语言 | 云原生、高性能 | Java 生态 | + +选择 API 网关需要综合考虑技术栈、性能要求、团队能力和运维成本。 + +| 场景 | 推荐方案 | 理由 | +| --------------------- | ---------------------------------------------------------- | ------------------------------------------------------------ | +| **Spring Cloud 生态** | Spring Cloud Gateway | 与 Spring Boot/Spring Cloud 无缝集成,配置简单 | +| **高性能 / 云原生** | APISIX | 基于 etcd 的热更新、性能优异、云原生架构 | +| **多语言生态** | Kong | 插件丰富、支持多语言开发、社区成熟 | +| **Netflix 技术栈** | Zuul 2.x | 与 Eureka、Ribbon、Hystrix 等组件无缝配合 | +| **双层架构(推荐)** | Kong/APISIX(流量网关) + Spring Cloud Gateway(业务网关) | 流量网关处理 SSL、WAF、全局限流;业务网关处理微服务鉴权、参数聚合 | + +## RPC框架 + +### ⭐️什么是 RPC? + +**RPC(Remote Procedure Call)远程过程调用**:调用远程方法像调用本地方法一样简单。 + +**为什么要 RPC?** 因为,两个不同的服务器上的服务提供的方法不在一个内存空间,所以,需要通过网络编程才能传递方法调用所需要的参数。并且,方法调用的结果也需要通过网络编程来接收。 + +**RPC 能帮助我们做什么呢?** 简单来说,通过 RPC 可以帮助我们调用远程计算机上某个服务的方法,这个过程就像调用本地方法一样简单。并且!我们不需要了解底层网络编程的具体细节。 + +一言蔽之:**RPC 的出现就是为了让你调用远程方法像调用本地方法一样简单。** + +### RPC 的核心原理? + +为了能够帮助小伙伴们理解 RPC 原理,我们可以将整个 RPC 的 核心功能看作是下面 5 个部分实现的: + +1. **客户端(服务消费端)**:调用远程方法的一端。 +2. **客户端 Stub(桩)**:这其实就是一代理类。代理类主要做的事情很简单,就是把你调用方法、类、方法参数等信息传递到服务端。 +3. **网络传输**:网络传输就是你要把你调用的方法的信息比如说参数啊这些东西传输到服务端,然后服务端执行完之后再把返回结果通过网络传输给你传输回来。网络传输的实现方式有很多种比如最基本的 Socket 或者性能以及封装更加优秀的 Netty(推荐)。 +4. **服务端 Stub(桩)**:这里的服务端 Stub 实际指的就是接收到客户端执行方法的请求后,去执行对应的方法然后返回结果给客户端的类。 +5. **服务端(服务提供端)**:提供远程方法的一端。 + +**调用流程**: + +1. 服务消费端(client)以本地调用的方式调用远程服务; +2. 客户端 Stub(client stub) 接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体(序列化):`RpcRequest`; +3. 客户端 Stub(client stub) 找到远程服务的地址,并将消息发送到服务提供端; +4. 服务端 Stub(桩)收到消息将消息反序列化为 Java 对象: `RpcRequest`; +5. 服务端 Stub(桩)根据`RpcRequest`中的类、方法、方法参数等信息调用本地的方法; +6. 服务端 Stub(桩)得到方法执行结果并将组装成能够进行网络传输的消息体:`RpcResponse`(序列化)发送至消费方; +7. 客户端 Stub(client stub)接收到消息并将消息反序列化为 Java 对象:`RpcResponse` ,这样也就得到了最终结果。 + +### ⭐️HTTP 和 RPC 有什么区别? + +| 对比项 | HTTP | RPC | +| -------- | ----------------------- | -------------------------- | +| 本质 | 应用层协议 | 调用方式(可基于任意协议) | +| 传输内容 | JSON/XML,冗余多 | Protobuf,更紧凑 | +| 连接复用 | HTTP1.1 支持 keep-alive | 通常有连接池 | +| 服务发现 | 依赖 DNS | 使用注册中心 | +| 性能 | 较低 | 较高 | + +**注意**:gRPC 就基于 HTTP/2 实现,说明 RPC 和 HTTP 不是对立关系。 + +### Dubbo 的核心架构角色? + +- **Container**:服务运行容器 +- **Provider**:服务提供方,向注册中心注册服务 +- **Consumer**:服务消费方,向注册中心订阅服务 +- **Registry**:注册中心(Nacos、ZooKeeper) +- **Monitor**:监控中心 + +### Dubbo 的负载均衡策略? + +| 策略 | 说明 | +| ------------------------- | ---------------------------------- | +| RandomLoadBalance | 加权随机(默认) | +| RoundRobinLoadBalance | 加权轮询 | +| LeastActiveLoadBalance | 最小活跃数(性能好者优先) | +| ConsistentHashLoadBalance | 一致性哈希(相同参数到同一提供者) | + +### 常见 RPC 框架对比? + +| 框架 | 特点 | 适用场景 | +| ---------- | ----------------------------- | ------------------- | +| **Dubbo** | 功能完善、生态丰富、社区活跃 | Java 后端技术栈首选 | +| **gRPC** | 跨语言、基于 HTTP/2、Protobuf | 多语言场景 | +| **Thrift** | 跨语言、Facebook 开源 | 多语言场景 | +| **Motan** | 微博开源、精简版 Dubbo | 不推荐使用 | + +## ZooKeeper + +ZooKeeper 目前面试考察不多,如果你的项目用到了再准备,否则的话,可以考虑跳过: + +- [ZooKeeper相关概念总结(入门)](https://javaguide.cn/distributed-system/distributed-process-coordination/zookeeper/zookeeper-intro.html) +- [ZooKeeper相关概念总结(进阶)](https://javaguide.cn/distributed-system/distributed-process-coordination/zookeeper/zookeeper-plus.html) + + diff --git a/docs/home.md b/docs/home.md index 2dfdbf6..a1b175d 100644 --- a/docs/home.md +++ b/docs/home.md @@ -1,19 +1,57 @@ --- +title: Java 学习&面试指南(Go、Python 后端面试通用,计算机基础面试总结) +description: JavaGuide面试突击版:专为Java后端面试打造的学习指南,涵盖Java基础、集合、并发、JVM、MySQL、Redis、Spring、计算机网络、操作系统等核心面试知识点,适合快速复习备战面试。 icon: creative -title: JavaGuide(Java学习&面试指南) +head: + - - meta + - name: keywords + content: Java面试,JavaGuide,Java学习,后端面试,Java基础,Java集合,Java并发,JVM,MySQL面试,Redis面试,Spring面试,计算机网络,操作系统,数据结构,算法 --- -::: tip 友情提示 +## 项目介绍 -- **知识星球**:专属面试小册/一对一交流/简历修改/专属求职指南,欢迎加入 **[JavaGuide 知识星球](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)**(点击链接即可查看星球的详细介绍,一定确定自己真的需要再加入)。 -- **求个 Star**:如果觉得 JavaGuide 的内容对你有帮助的话,还请点个免费的 Star,这是对我最大的鼓励,感谢各位一起同行,共勉!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 +- **这是 [JavaGuide](https://javaguide.cn/) 面试突击版本,适合突击面试的小伙伴。** 并且,提供了 PDF 下载,方便大家离线阅读/打印,阅读体验非常高。 +- 如果你准备面试的时间比较充足的话,建议阅读完整版,针对重要的知识点有更详细的讲解。地址:**[javaguide.cn](https://javaguide.cn/)**。 +- **不只是 Java 面试能用!** 网站中的数据库和缓存(MySQL、Redis)、计算机基础(计算机网络、操作系统)、系统设计(设计模式)等内容是后端通用的,适用于各种语言的后端面试。 +- **Go 面试题正在筹备中**,将会以高质量的内容与大家见面,敬请期待!如果大家还有其他什么需要的,也欢迎给我提供建议。 +- **专属面试小册/一对一交流/简历修改/专属求职指南**,欢迎加入 **[JavaGuide 知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(点击链接即可查看星球的详细介绍,一定确定自己真的需要再加入)。 -::: +## Java +- [Java基础常见面试题总结](./java/java-basis.md) +- [Java集合常见面试题总结](./java/java-collection.md) +- [Java并发常见面试题总结](./java/java-concurrent.md) +- [JVM常见面试题总结](./java/java-jvm.md) +## 计算机基础 + +- [计算机网络常见面试题总结](./cs-basics/network.md) +- [操作系统常见面试题总结](./cs-basics/operating-system.md) +- [数据结构常见面试题总结](./cs-basics/data-structure.md) +- [算法常见面试题总结](./cs-basics/algorithms.md) + +## 数据库和缓存 + +- [MySQL常见面试题总结](./database/mysql.md) +- [Redis常见面试题总结](./database/redis.md) + +## 系统设计 + +- [Spring和Spring Boot常见面试题总结](./system-design/spring.md) +- [设计模式常见面试题总结](./system-design/design-pattern.md) + +## 分布式 + +- [分布式系统常见面试题总结](./distributed-system/distributed-system.md) + +## 测试开发 + +- [测试开发常见面试题总结](./other/test-development.md) ## 公众号 -如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号“**JavaGuide**”。 +如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。 + +JavaGuide 公众号 -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + diff --git a/docs/interview-preparation/how-to-handle-interview-nerves.md b/docs/interview-preparation/how-to-handle-interview-nerves.md index 1a1a794..a622236 100644 --- a/docs/interview-preparation/how-to-handle-interview-nerves.md +++ b/docs/interview-preparation/how-to-handle-interview-nerves.md @@ -1,7 +1,12 @@ --- title: 面试太紧张怎么办? +description: 面试太紧张怎么办:分享应对面试紧张情绪的实用技巧,包括调整心态、充分准备、模拟面试、遇到不会的问题如何处理,以及面试后复盘的方法。 category: 面试准备 icon: security-fill +head: + - - meta + - name: keywords + content: 面试紧张,面试心态,面试技巧,克服面试紧张,面试准备,模拟面试,面试复盘,技术面试,面试经验 --- 很多小伙伴在第一次技术面试时都会感到紧张甚至害怕,面试结束后还会有种“懵懵的”感觉。我也经历过类似的状况,可以说是深有体会。其实,**紧张是很正常的**——它代表你对面试的重视,也来自于对未知结果的担忧。但如果过度紧张,反而会影响你的临场发挥。 diff --git a/docs/interview-preparation/internship-experience.md b/docs/interview-preparation/internship-experience.md index 4e16fc7..97ab2fe 100644 --- a/docs/interview-preparation/internship-experience.md +++ b/docs/interview-preparation/internship-experience.md @@ -1,7 +1,12 @@ --- title: 校招没有实习经历怎么办? +description: 校招没有实习经历怎么办:针对没有实习经验的应届生,详解如何通过补强项目经历、完善简历、准备技术面试三个方面来弥补,提升求职竞争力。 category: 面试准备 icon: experience +head: + - - meta + - name: keywords + content: 没有实习经历,校招,应届生求职,项目经历,简历优化,技术面试,实习,Java校招,求职攻略 --- 由于目前的面试太卷,对于犹豫是否要找实习的同学来说,个人建议不论是本科生还是研究生都应该在参加校招面试之前,争取一下不错的实习机会,尤其是大厂的实习机会,日常实习或者暑期实习都可以。当然,如果大厂实习面不上,中小厂实习也是可以接受的。 diff --git a/docs/interview-preparation/interview-experience.md b/docs/interview-preparation/interview-experience.md index a2f32fd..3d05903 100644 --- a/docs/interview-preparation/interview-experience.md +++ b/docs/interview-preparation/interview-experience.md @@ -1,7 +1,12 @@ --- title: 优质面经汇总(付费) +description: 优质Java后端面经汇总:精选15+篇高质量Java后端面经,涵盖校招社招、大厂中小厂,帮助你了解真实面试流程和常见问题,为面试做好充分准备。 category: 知识星球 icon: experience +head: + - - meta + - name: keywords + content: Java面经,面试经验,大厂面经,校招面经,社招面经,后端面经,面试题,面试真题,Java后端面经,技术面试 --- 古人云:“**他山之石,可以攻玉**” 。善于学习借鉴别人的面试的成功经验或者失败的教训,可以让自己少走许多弯路。 @@ -26,5 +31,3 @@ icon: experience 1. 参考资料解释的要更详细一些,还可以顺便让你把相关的知识点复习一下。 2. 给出的参考资料基本都是我的原创,假如后续我想对面试问题的答案进行完善,就不需要挨个把之前的面经写的答案给修改了(面试中的很多问题都是比较类似的)。当然了,我的原创文章也不太可能覆盖到面试的每个点,部分面试问题的答案,我是精选的其他技术博主写的优质文章,文章质量都很高。 - - diff --git a/docs/interview-preparation/java-roadmap.md b/docs/interview-preparation/java-roadmap.md index 44de032..264ae19 100644 --- a/docs/interview-preparation/java-roadmap.md +++ b/docs/interview-preparation/java-roadmap.md @@ -1,7 +1,12 @@ --- title: Java 学习路线(最新版,4w+字) +description: 2025最新Java学习路线图:4万字详细讲解Java后端开发完整学习路径,从Java基础到进阶,涵盖Spring全家桶、MySQL、Redis、分布式微服务等技术栈,附配套学习资源推荐。 category: 面试准备 icon: path +head: + - - meta + - name: keywords + content: Java学习路线,Java后端学习,Java学习计划,Java入门,Java进阶,Java技术栈,Spring学习,MySQL学习,Redis学习,分布式学习 --- ::: tip 重要说明 diff --git a/docs/interview-preparation/key-points-of-interview.md b/docs/interview-preparation/key-points-of-interview.md index e60f4ef..143c424 100644 --- a/docs/interview-preparation/key-points-of-interview.md +++ b/docs/interview-preparation/key-points-of-interview.md @@ -1,17 +1,28 @@ --- title: Java后端面试重点总结 +description: Java后端面试重点总结:系统梳理面试核心知识点优先级,包括Java基础、集合、并发、MySQL、Redis、Spring等必考内容,以及如何根据目标公司调整复习策略,高效准备八股文。 category: 面试准备 icon: star +head: + - - meta + - name: keywords + content: Java面试重点,面试八股文,Java后端面试,面试知识点,面试复习,Java基础面试,MySQL面试,Redis面试,Spring面试,面试准备 --- + + ::: tip 友情提示 -本文节选自 **[《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)**。这是一份教你如何更高效地准备面试的专栏,内容和 JavaGuide 互补,涵盖常见八股文(系统设计、常见框架、分布式、高并发 ……)、优质面经等内容。 +本文节选自 **[《Java 面试指北》](../zhuanlan/java-mian-shi-zhi-bei.md)**。这是一份教你如何更高效地准备面试的专栏,内容和 JavaGuide 互补,涵盖常见八股文(系统设计、常见框架、分布式、高并发 ……)、优质面经等内容。 ::: ## Java 后端面试哪些知识点是重点? **准备面试的时候,具体哪些知识点是重点呢?如何把握重点?** +先来一张图(后续会详细解读): + +![Java 后端面试重点](https://oss.javaguide.cn/github/javaguide/interview-preparation/back-end-interview-focus.png) + 给你几点靠谱的建议: 1. Java 基础、集合、并发、MySQL、Redis 、Spring、Spring Boot 这些 Java 后端开发必备的知识点(MySQL + Redis >= Java > Spring + Spring Boot)。大厂以及中小厂的面试问的比较多的就是这些知识点。Spring 和 Spring Boot 这俩框架类的知识点相对前面的知识点来说重要性要稍低一些,但一般面试也会问一些,尤其是中小厂。并发知识一般中大厂提问更多也更难,尤其是大厂喜欢深挖底层,很容易把人问倒。计算机基础相关的内容会在下面提到。 @@ -19,13 +30,15 @@ icon: star 3. 针对自身找工作的需求,你又可以适当地调整复习的重点。像中小厂一般问计算机基础比较少一些,有些大厂比如字节比较重视计算机基础尤其是算法。这样的话,如果你的目标是中小厂的话,计算机基础就准备面试来说不是那么重要了。如果复习时间不够的话,可以暂时先放放,腾出时间给其他重要的知识点。 4. 一般校招的面试不会强制要求你会分布式/微服务、高并发的知识(不排除个别岗位有这方面的硬性要求),所以到底要不要掌握还是要看你个人当前的实际情况。如果你会这方面的知识的话,对面试相对来说还是会更有利一些(想要让项目经历有亮点,还是得会一些性能优化的知识。性能优化的知识这也算是高并发知识的一个小分支了)。如果你的技能介绍或者项目经历涉及到分布式/微服务、高并发的知识,那建议你尽量也要抽时间去认真准备一下,面试中很可能会被问到,尤其是项目经历用到的时候。不过,也还是主要准备写在简历上的那些知识点就好。 5. JVM 相关的知识点,一般是大厂(例如美团、阿里)和一些不错的中厂(例如携程、顺丰、招银网络)才会问到,面试国企、差一点的中厂和小厂就没必要准备了。JVM 面试中比较常问的是 [Java 内存区域](https://javaguide.cn/java/jvm/memory-area.html)、[JVM 垃圾回收](https://javaguide.cn/java/jvm/jvm-garbage-collection.html)、[类加载器和双亲委派模型](https://javaguide.cn/java/jvm/classloader.html) 以及 JVM 调优和问题排查(我之前分享过一些[常见的线上问题案例](https://t.zsxq.com/0bsAac47U),里面就有 JVM 相关的)。 -6. 不同的大厂面试侧重点也会不同。比如说你要去阿里这种公司的话,项目和八股文就是重点,阿里笔试一般会有代码题,进入面试后就很少问代码题了,但是对原理性的问题问的比较深,经常会问一些你对技术的思考。再比如说你要面试字节这种公司,那计算机基础,尤其是算法是重点,字节的面试十分注重代码功底,有时候开始面试就会直接甩给你一道代码题,写出来再谈别的。也会问面试八股文,以及项目,不过,相对来说要少很多。建议你看一下这篇文章 [为了解开互联网大厂秋招内幕,我把他们全面了一遍](https://mp.weixin.qq.com/s/pBsGQNxvRupZeWt4qZReIA),了解一下常见大厂的面试题侧重点。 +6. 不同的大厂面试侧重点也会不同。比如说你要去阿里这种公司的话,项目和八股文就是重点,阿里笔试一般会有代码题,进入面试后就很少问代码题了,但是对原理性的问题问的比较深,经常会问一些你对技术的思考。再比如说你要面试字节这种公司,那计算机基础,尤其是算法是重点,字节的面试十分注重代码功底,有时候开始面试就会直接甩给你一道代码题,写出来再谈别的。也会问面试八股文,以及项目,不过,相对来说要少很多。 7. 多去找一些面经看看,尤其你目标公司或者类似公司对应岗位的面经。这样可以实现针对性的复习,还能顺便自测一波,检查一下自己的掌握情况。 看似 Java 后端八股文很多,实际把复习范围一缩小,重要的东西就是那些。考虑到时间问题,你不可能连一些比较冷门的知识点也给准备了。这没必要,主要精力先放在那些重要的知识点即可。 ## 如何更高效地准备八股文? + + 对于技术八股文来说,尽量不要死记硬背,这种方式非常枯燥且对自身能力提升有限!但是!想要一点不背是不太现实的,只是说要结合实际应用场景和实战来理解记忆。 我一直觉得面试八股文最好是和实际应用场景和实战相结合。很多同学现在的方向都错了,上来就是直接背八股文,硬生生学成了文科,那当然无趣了。 diff --git a/docs/interview-preparation/project-experience-guide.md b/docs/interview-preparation/project-experience-guide.md index 13465ef..1653394 100644 --- a/docs/interview-preparation/project-experience-guide.md +++ b/docs/interview-preparation/project-experience-guide.md @@ -1,7 +1,12 @@ --- title: 项目经验指南 +description: 项目经验指南:针对应届生和程序员如何获取项目经验的完整指南,包括实战项目视频专栏、开源项目推荐、从头开始做项目、参加技术比赛等多种途径,以及如何优化项目让面试更有竞争力。 category: 面试准备 icon: project +head: + - - meta + - name: keywords + content: 项目经验,实战项目,项目经历,没有项目经验怎么办,Java项目,开源项目,项目推荐,面试项目,简历项目,校招项目 --- ::: tip 友情提示 @@ -26,7 +31,7 @@ icon: project 我面试过很多求职者,简历上看着有微服务的项目经验,结果随便问两个问题就知道根本不是自己做的或者说做的时候压根没认真思考。这种情况会给我留下非常不好的印象。 -我在 **[《Java 面试指北》](../zhuanlan/java-mian-shi-zhi-bei.md)** 的「面试准备篇」中也说过: +我在 **[《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)** 的「面试准备篇」中也说过: > 个人认为也没必要非要去做微服务或者分布式项目,不一定对你面试有利。微服务或者分布式项目涉及的知识点太多,一般人很难吃透。并且,这类项目其实对于校招生来说稍微有一点超标了。即使你做出来,很多面试官也会认为不是你独立完成的。 > @@ -72,7 +77,7 @@ GitHub 或者码云上面有很多实战类别项目,你可以选择一个来 ## 有没有还不错的项目推荐? -**[《Java 面试指北》](../zhuanlan/java-mian-shi-zhi-bei.md)** 的「面试准备篇」中有一篇文章专门整理了一些比较高质量的实战项目,包含业务项目、轮子项目、国外公开课 Lab 和视频类实战项目教程推荐,非常适合用来学习或者作为项目经验。 +**[《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)** 的「面试准备篇」中有一篇文章专门整理了一些比较高质量的实战项目,包含业务项目、轮子项目、国外公开课 Lab 和视频类实战项目教程推荐,非常适合用来学习或者作为项目经验。 ![优质 Java 实战项目推荐](https://oss.javaguide.cn/javamianshizhibei/project-experience-guide.png) diff --git a/docs/interview-preparation/resume-guide.md b/docs/interview-preparation/resume-guide.md index e0123ae..847e715 100644 --- a/docs/interview-preparation/resume-guide.md +++ b/docs/interview-preparation/resume-guide.md @@ -1,7 +1,12 @@ --- title: 程序员简历编写指南 +description: 程序员简历编写指南:涵盖简历模板推荐、简历排版技巧、个人信息填写、求职意向、教育经历、专业技能描述、项目经历撰写等核心内容,助你写出一份高质量的技术简历。 category: 面试准备 icon: jianli +head: + - - meta + - name: keywords + content: 程序员简历,简历模板,简历编写,Java简历,技术简历,求职简历,简历排版,项目经历,技能介绍,校招简历,社招简历 --- ::: tip 友情提示 @@ -288,7 +293,7 @@ FAB 法则由下面 3 个单词组成(FAB 法则的名字就是由它们的首 下面是星球提供的部分服务(点击下方图片即可获取知识星球的详细介绍): -[![星球服务](https://oss.javaguide.cn/xingqiu/xingqiufuwu.png)](../about-the-author/zhishixingqiu-two-years.md) +[![星球服务](https://oss.javaguide.cn/xingqiu/xingqiufuwu.png)](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html) 这里再提供一份限时专属优惠卷: diff --git a/docs/interview-preparation/self-test-of-common-interview-questions.md b/docs/interview-preparation/self-test-of-common-interview-questions.md index 9a454c8..14e93fb 100644 --- a/docs/interview-preparation/self-test-of-common-interview-questions.md +++ b/docs/interview-preparation/self-test-of-common-interview-questions.md @@ -1,7 +1,12 @@ --- title: 常见面试题自测(付费) +description: Java常见面试题自测:按照面试提问方式整理Java核心知识点的高频面试题,每道题都标注重要程度和提示信息,帮助你高效检验面试准备情况。 category: 知识星球 icon: security-fill +head: + - - meta + - name: keywords + content: Java面试题自测,面试题,Java面试题,技术面试自测,面试准备,八股文自测,Java后端面试题,面试题库 --- 面试之前,强烈建议大家多拿常见的面试题来进行自测,检查一下自己的掌握情况,这是一种非常实用的备战技术面试的小技巧。 @@ -15,5 +20,3 @@ icon: security-fill 在面试中如果你实在没有头绪的话,一个好的面试官也是会给你提示的。 ![](https://oss.javaguide.cn/xingqiu/image-20220628102848236.png) - - diff --git a/docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md b/docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md index 436a442..9ff435f 100644 --- a/docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md +++ b/docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md @@ -1,7 +1,12 @@ --- title: 如何高效准备Java面试? +description: 如何高效准备Java面试:从求职导向学习、了解招聘时间、获取招聘信息、完善简历到技术面试准备的完整攻略,帮助程序员系统性地备战面试,少走弯路。 category: 知识星球 icon: path +head: + - - meta + - name: keywords + content: Java面试准备,面试技巧,校招面试,社招面试,春招秋招,招聘信息,面试攻略,求职指南,技术面试,面试复习 --- ::: tip 友情提示 diff --git a/docs/intro/faq.md b/docs/intro/faq.md index f89cdbc..67af0dd 100644 --- a/docs/intro/faq.md +++ b/docs/intro/faq.md @@ -1,23 +1,27 @@ --- title: 常见问题 +description: JavaGuide面试突击版常见问题解答:介绍为什么要单独制作面试突击版、如何获取最新版本PDF、如何学习本项目以及如何参与贡献等常见问题。 category: 走近项目 icon: help +head: + - - meta + - name: keywords + content: JavaGuide常见问题,FAQ,面试突击版,PDF下载,JavaGuide学习,项目贡献 --- ## 为什么要再单独弄一个面试突击版? -JavaGuide 已经有了在线阅读版本(地址:https://javaguide.cn/),阅读体验也很不错,为什么我还要再花这么多时间单独弄一个面试突击版呢? +JavaGuide 已经有了在线阅读版本(地址:[javaguide.cn](https://javaguide.cn/) ),阅读体验也很不错,为什么我还要再花这么多时间单独弄一个面试突击版呢? 1. 很多同学由于某些原因比较喜欢看 PDF 电子版或者有打印的需求,[JavaGuide](https://javaguide.cn/) 原项目内容过多,不太适合整理成 PDF 版本; 2. 《JavaGuide 面试突击版》专为面试突击打造,内容相比于[JavaGuide](https://javaguide.cn/) 原项目更精简。 ## 如何获取最新版本? -你可以通过我的公众号获取到 **《JavaGuide 面试突击版》** 的最新版本。 +你可以通过我的公众号获取到 **《JavaGuide 面试突击版》** 的最新版本,后台回复“**PDF**”即可! + +JavaGuide 公众号 -
- -
## 如何学习本项目? 不论是在线版本还是 PDF 版本都提供了非常详细的目录,建议可以从头到尾看一遍,如果基础不错的话也可以挑自己需要的章节查看。看的过程中自己要多思考,碰到不懂的地方,自己记得要勤搜索,需要记忆的地方也不要吝啬自己的脑子。 @@ -39,8 +43,8 @@ JavaGuide 已经有了在线阅读版本(地址:https://javaguide.cn/), > > 参考文档(可选):相关的一些参考资料比如官方文档的描述、书籍中的描述。 -为了提高准确性已经不必要的时间花费,希望大家尽量确保自己想法的准确性。 - +为了提高准确性以及不必要的时间花费,希望大家尽量确保自己想法的准确性。 +⭐️**多次参与贡献,有机会获得现金、键盘、耳机、鼠标等奖励!** ------ diff --git a/docs/java/java-basis.md b/docs/java/java-basis.md index d4396a7..51686a5 100755 --- a/docs/java/java-basis.md +++ b/docs/java/java-basis.md @@ -1,38 +1,16 @@ --- title: Java基础常见面试题总结 +description: 系统梳理Java面试中最常考的基础知识与高频问题:涵盖JVM、JDK、JRE区别,字节码与编译解释执行机制,AOT与JIT对比及GraalVM,Oracle JDK与OpenJDK区别,8种基本数据类型与自动装箱、包装类型缓存机制,浮点数精度与BigDecimal,成员变量和局部变量、静态变量与方法,重载和重写,String不可变性与常量池,异常体系与try-with-resources,泛型、反射、SPI、序列化及I/O等核心考点。 category: Java tag: - Java基础 head: - - meta - name: keywords - content: Java特点,Java SE,Java EE,Java ME,Java虚拟机,JVM,JDK,JRE,字节码,Java编译与解释,AOT编译,云原生,AOT与JIT对比,GraalVM,Oracle JDK与OpenJDK区别,OpenJDK,LTS支持,多线程支持,静态变量,成员变量与局部变量区别,包装类型缓存机制,自动装箱与拆箱,浮点数精度丢失,BigDecimal,Java基本数据类型,Java标识符与关键字,移位运算符,Java注释,静态方法与实例方法,方法重载与重写,可变长参数,Java性能优化 - - - meta - - name: description - content: 全网质量最高的Java基础常见知识点和面试题总结,希望对你有帮助! + content: Java基础面试题,Java特点,JVM,JDK,JRE,字节码,AOT编译,JIT编译,GraalVM,Oracle JDK,OpenJDK,基本数据类型,自动装箱,包装类型缓存,BigDecimal,静态变量,方法重载,方法重写,String不可变,常量池,异常处理,泛型,反射,SPI,序列化 --- ------- - -![面试突击-Java基础](https://oss.javaguide.cn/github/javaguide-interview/cover/java-basis.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了**⭐️**标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入**[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: @@ -1644,6 +1622,14 @@ public static String getStr() { ![](https://oss.javaguide.cn/github/javaguide/java/basis/unchecked-exception.png) +### 你更倾向于使用 Checked Exception 还是 Unchecked Exception? + +默认使用 Unchecked Exception,只在必要时才用 Checked Exception。 + +我们可以把 Unchecked Exception(比如 `NullPointerException`)看作是代码 Bug。对待 Bug,最好的方式是让它暴露出来然后去修复代码,而不是用 `try-catch` 去掩盖它。 + +一般来说,只在一种情况下使用 Checked Exception:当这个异常是业务逻辑的一部分,并且调用方必须处理它时。比如说,一个余额不足异常。这不是 bug,而是一个正常的业务分支,我需要用 Checked Exception 来强制调用者去处理这种情况,比如提示用户去充值。这样就能在保证关键业务逻辑完整性的同时,让代码尽可能保持简洁。 + ### try-catch-finally 如何使用? - `try`块:用于捕获异常。其后可接零个或多个 `catch` 块,如果没有 `catch` 块,则必须跟一个 `finally` 块。 @@ -1911,6 +1897,56 @@ public class DebugInvocationHandler implements InvocationHandler { 像 MyBatis、Hibernate 这种框架,能帮你把数据库查出来的一行行数据,自动变成一个个 Java 对象。它是怎么知道数据库字段对应哪个 Java 属性的?还是靠反射。它通过反射获取 Java 类的属性列表,然后把查询结果按名字或配置对应起来,再用反射调用 setter 或直接修改字段值。反过来,保存对象到数据库时,也是用反射读取属性值来拼 SQL。 +## 代理 + +关于 Java 代理的详细介绍,可以看看笔者写的 [Java 代理模式详解](https://javaguide.cn/java/basis/proxy.html "Java 代理模式详解")这篇文章。 + +### 如何实现动态代理? + +动态代理是一种非常强大的设计模式,它允许我们在**不修改源代码**的情况下,对一个类或对象的方法进行**功能增强(Enhancement)**。 + +在 Java 中,实现动态代理最主流的方式有两种:**JDK 动态代理** 和 **CGLIB 动态代理**。 + +**第一种:JDK 动态代理** + +Java 官方提供的,其核心要求是目标类必须实现一个或多个接口。JDK 动态代理在运行时,会利用 `Proxy.newProxyInstance()` 方法,动态地创建一个实现了这些接口的代理类的实例。这个代理类在内存中生成,你看不到它的 `.java` 或 `.class` 文件。 + +当你调用代理对象的任何一个方法时,这个调用都会被转发到我们提供的一个 `InvocationHandler` 接口的 `invoke` 方法中。在 `invoke` 方法里,我们就可以在调用原始方法(目标方法)之前或之后,加入我们自己的增强逻辑。 + +**第二种:CGLIB 动态代理** + +CGLIB 是一个第三方的代码生成库。它的原理与 JDK 完全不同,它不要求被代理的类实现接口。它在运行时,动态生成目标类的子类作为代理类(通过 ASM 字节码操作技术)。然后,它会重写父类(也就是被代理类)中所有非 `final`、`private` 和 `static` 的方法。 + +当你调用代理对象的任何一个方法时,这个调用会被 CGLIB 的 `MethodInterceptor` 接口的 `intercept` 方法拦截。和 `InvocationHandler` 的 `invoke` 方法一样,我们可以在 `intercept` 方法里,在调用原始的父类方法之前或之后,加入我们的增强逻辑。 + +### 静态代理和动态代理有什么区别? + +静态代理和动态代理的核心差异在于 **代理关系的确定时机、实现灵活性及维护成本** 。 + +| 对比维度 | 静态代理 (Static Proxy) | 动态代理 (Dynamic Proxy) | +| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 代理关系确定时机 | 编译期(编译后生成固定的 `.class` 字节码文件) | 运行时(动态生成代理类字节码并加载到 JVM) | +| 实现方式 | 手动编写代理类,需与目标类实现同一接口,一对一绑定 | 无需手动编写代理类,通过 `Handler`/`Interceptor` 封装增强逻辑,一对多复用 | +| 接口依赖 | 必须实现接口(代理类与目标类遵循同一接口规范) | 支持代理接口或直接代理实现类 | +| 代码量与维护性 | 代码量大(目标类越多,代理类越多),维护成本高;接口新增方法时,目标类与代理类需同步修改 | 代码量极少(通用增强逻辑可复用),维护性好;与接口解耦,接口变更不影响代理逻辑 | +| 核心优势 | 实现简单、逻辑直观,无额外框架依赖 | 灵活性强、复用性高,降低重复编码,适配复杂场景 | +| 典型应用场景 | 简单的装饰器模式、少量固定类的增强需求 | Spring AOP、RPC 框架(如 Dubbo)、ORM 框架 | + +### ⭐️JDK 动态代理和 CGLIB 动态代理有什么区别? + +1. JDK 动态代理是官方的,它要求被代理的类必须实现接口。它的原理是动态生成一个接口的实现类来作为代理。CGLIB 是第三方的,它不需要接口。它的原理是动态生成一个被代理类的子类来作为代理。但也正因为是继承,所以它不能代理 `final` 的类,被代理的方法也不能是 `final` 或 `private` 。 +2. 就二者的效率来说,大部分情况都是 JDK 动态代理更优秀,随着 JDK 版本的升级,这个优势更加明显。 + +### ⭐️介绍一下动态代理在框架中的实际应用场景 + +动态代理最典型的应用场景就是**Spring AOP**。 + +AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。 + +Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 **JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: + +![SpringAOPProcess](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/230ae587a322d6e4d09510161987d346.jpeg) + ## 注解 ### 何谓注解? @@ -2073,7 +2109,7 @@ Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来 参考答案:[Java IO 设计模式总结](https://javaguide.cn/java/io/io-design-patterns.html) -### BIO、NIO 和 AIO 的区别? +### ⭐️BIO、NIO 和 AIO 的区别? 参考答案:[Java IO 模型详解](https://javaguide.cn/java/io/io-model.html) diff --git a/docs/java/java-collection.md b/docs/java/java-collection.md index 171530f..7623a87 100755 --- a/docs/java/java-collection.md +++ b/docs/java/java-collection.md @@ -1,38 +1,16 @@ --- title: Java集合常见面试题总结 +description: 系统梳理Java集合框架常见知识点与高频面试题,覆盖List、Set、Queue、Map及其典型实现如ArrayList、LinkedList、HashSet、HashMap、ConcurrentHashMap、BlockingQueue等,并结合源码讲解扩容机制、时间复杂度、线程安全与fail-fast/fail-safe等关键细节。 category: Java tag: - Java集合 head: - - meta - name: keywords - content: Collection,List,Set,Queue,Deque,PriorityQueue,HashMap,ConcurrentHashMap,Hashtable - - - meta - - name: description - content: Java集合常见知识点和面试题总结,希望对你有帮助! + content: Java集合面试题,Collection,List,ArrayList,LinkedList,Set,HashSet,TreeSet,Queue,Deque,ArrayDeque,PriorityQueue,BlockingQueue,HashMap,TreeMap,ConcurrentHashMap,Hashtable,fail-fast,fail-safe,扩容机制 --- ------- - -![面试突击-Java集合](https://oss.javaguide.cn/github/javaguide-interview/cover/java-collection.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了**⭐️**标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: diff --git a/docs/java/java-concurrent.md b/docs/java/java-concurrent.md index 35917b5..44c3f92 100755 --- a/docs/java/java-concurrent.md +++ b/docs/java/java-concurrent.md @@ -1,38 +1,16 @@ --- title: Java并发常见面试题总结 +description: Java并发编程核心知识点与高频面试题总结:涵盖线程与进程、并发与并行、线程生命周期、死锁、synchronized、ReentrantLock、volatile、ThreadLocal、线程池、CAS、AQS等重要概念与实战应用。 category: Java tag: - Java并发 head: - - meta - name: keywords - content: 线程和进程,并发和并行,多线程,死锁,线程的生命周期,synchronized,ReentrantLock,volatile,ThreadLocal,线程池,CAS,AQS - - - meta - - name: description - content: Java并发常见知识点和面试题总结(含详细解答),希望对你有帮助! + content: Java并发面试题,线程和进程,并发和并行,多线程,死锁,线程生命周期,synchronized,ReentrantLock,volatile,ThreadLocal,线程池,CAS,AQS,并发编程,锁机制 --- ------- - -![面试突击-Java并发](https://oss.javaguide.cn/github/javaguide-interview/cover/java-concurrent.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了**⭐️**标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: diff --git a/docs/java/java-jvm.md b/docs/java/java-jvm.md index a544891..720e48a 100755 --- a/docs/java/java-jvm.md +++ b/docs/java/java-jvm.md @@ -1,38 +1,16 @@ --- title: JVM常见面试题总结 +description: JVM核心知识点与高频面试题精炼总结:涵盖内存区域划分、垃圾回收算法与收集器、类加载机制、双亲委派模型、G1/ZGC垃圾收集器、OutOfMemoryError排查、Heap Dump分析、JVM性能调优参数等,含图解与实战案例。 category: Java tag: - JVM head: - - meta - name: keywords - content: JVM内存区域,JVM垃圾回收,类加载机制,双亲委派模型,GC算法,G1,ZGC,OutOfMemoryError,Heap Dump,性能优化,JVM参数 - - - meta - - name: description - content: JVM核心知识点与高频面试题精炼总结:内存区域、垃圾回收、类加载、双亲委派、G1/ZGC、OOM排查、Heap Dump、性能参数等,含图解与实战案例。 + content: JVM面试题,JVM内存区域,JVM垃圾回收,类加载机制,双亲委派模型,GC算法,G1,ZGC,OutOfMemoryError,OOM排查,Heap Dump,JVM调优,JVM参数 --- ------- - -![面试突击-JVM](https://oss.javaguide.cn/github/javaguide-interview/cover/java-jvm.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了**⭐️**标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + 这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: diff --git a/docs/other/test-development.drawio b/docs/other/test-development.drawio new file mode 100644 index 0000000..9bd24f2 --- /dev/null +++ b/docs/other/test-development.drawio @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/other/test-development.md b/docs/other/test-development.md new file mode 100644 index 0000000..d2a5a31 --- /dev/null +++ b/docs/other/test-development.md @@ -0,0 +1,433 @@ +--- +title: 测试开发常见面试题总结 +description: 测试开发高频面试题系统总结,覆盖测试开发基础、Bug处理与协作、测试用例设计、自动化测试、压力测试、白盒测试黑盒测试区别、端到端测试等实战问题与参考答案,适合冲击中大厂测开岗位的同学快速复盘与刷题。 +category: 测试开发 +tag: + - 测试开发 + - 软件测试 +head: + - - meta + - name: keywords + content: 测试开发面试题,测开面试,软件测试面试题,测试用例设计,自动化测试,压力测试,Web测试,白盒测试,黑盒测试,端到端测试,功能测试,性能测试,测试左移 +--- + + + +很多读者选择了测开方向来冲一波中大厂。在国内当前的测开面试中,面试官不仅会考察测试领域的基础知识和实践能力,往往也会考察候选人的后端开发功底。 + +这是因为优秀的测开工程师需要深入理解系统架构,能够编写高质量的自动化测试代码,进行性能测试分析,甚至参与到测试工具和平台的开发中。所以,像多线程、Redis、MySQL 等后端开发的核心知识点,在测开面试中被问到是常态。 + +Guide 这里整理并总结了一些在测开面试中偏测试方向的高频问题,并附上详细的参考答案(如答案过长,还会提供简化版回答): + +1. **测试开发基础** + - 为什么想做测开?/ 为什么从开发转测开? + - 你认为软件测试的核心竞争力是什么? + - 什么是软件测试?为什么要做? + - 软件测试的流程是怎样的? + - 你如何看待测试覆盖率这个指标? + - 什么是“测试左移”(Shift-Left Testing)?你在项目中是如何实践的? +2. **Bug 处理与协作** + - 如果有一个 Bug 不能复现,怎么去跟开发沟通? + - 你在实习/项目期间测出过什么印象深刻的 Bug? +3. **测试用例** + - 什么是测试用例?一个好的测试用例需要满足什么标准? + - 怎么设计测试用例?/ 常用的测试用例设计方法有哪些? + - 设计 xxx 场景(例如电商直播间、充值、数据迁移系统)的测试用例 +4. **测试类型** + - 什么是自动化测试?为什么需要? + - 什么是 Web 应用的自动化测试?怎么做? + - 怎么进行压测? + - 白盒测试和黑盒测试的主要区别是什么? + - 什么是单元测试?集成测试?系统测试?回归测试?验收测试? + - 单元测试、集成测试、系统测试、回归测试、验收测试最重要的是那一步? + - 什么是端到端测试? + - 移动端与 Web 端测试有什么区别? + - 如何测试 Web 应用的安全性?你会关注哪些常见漏洞? + - API 功能测试如何做? + - 什么是正向测试和反向测试?能否举例说明 + - 可用性测试和用户体验测试有什么区别? + +## 测试开发基础 + +### 为什么想做测开?/ 为什么从开发转测开? + +我在之前的 Java 后端开发经历中,积累了比较扎实的编程基础和系统设计能力(可以具体提 1-2 个技术点,如熟悉微服务、数据库等)。我发现自己对保证软件质量、提升系统稳定性有浓厚的兴趣。我觉得测开岗位能很好地结合我的开发背景和对软件质量保障的关注。 + +我个人的话,也比较注重细节,有耐心,也乐于从用户的角度去思考问题,我觉得这些特质也挺适合做质量保障工作的。 + +我认为测开不仅仅是功能测试,更需要通过技术手段,比如自动化测试、性能测试、构建 CI/CD 流程中的质量门禁,来提高测试效率和深度,从源头保障软件质量。 + +### 你认为软件测试的核心竞争力是什么? + +我认为优秀测试工程师的核心竞争力主要体现在三点: + +1. **强大的质量意识和业务理解能力**,能从用户和业务视角拆解需求、识别高风险场景; +2. **系统性设计测试策略和用例的能力**,合理运用等价类、边界值、组合覆盖等方法,把有限的测试资源用在最关键的地方; +3. **工程化与自动化能力**,熟悉测试工具、脚本和 CI/CD,把测试深度嵌入开发流程,实现持续、可重复、可量化的质量保障。 + +简单说,就是:**懂业务、会分析、能工程化落地的质量保障能力**。 + +### 什么是软件测试?为什么要做? + +软件测试是通过设计和执行一系列用例,在不同场景下运行软件,去发现缺陷、验证功能和质量是否符合需求与标准的系统化活动。 + +回答这个问题的时候需要注意:**一定不要认为软件测试就是在找 bug。** + +为什么要做它?主要有三个原因: + +1. **控制风险,降低成本**:在开发阶段就把 bug 找出来,远比等它在线上造成事故再修复要便宜得多。这是一种风险控制。 +2. **验证业务需求**:确保我们开发的功能,确实是产品和用户想要的,**没做偏**。 +3. **提供质量反馈,赋能持续交付**:在敏捷开发里,没有自动化测试作为安全网,我们根本不敢频繁发布新版本。测试是持续交付的基础。 + +一句话概括:**软件测试就是用有计划的方式尽早暴露问题、评估质量,让软件在交付给用户前尽可能“可预测、可依赖”。** + +### 软件测试的流程是怎样的? + +![软件测试的流程](https://oss.javaguide.cn/github/javaguide/interview-preparation/test-development-testing-process.png) + +一个相对完整的软件测试流程,我理解大致包含这几个阶段: + +- **需求分析:** 首先是深入理解需求文档,分析需求的可测性,有时候还需要参与需求评审,尽早发现需求层面的问题。 +- **测试计划:** 然后是制定测试计划,明确测试范围、测试策略(比如哪些功能需要重点测、采用什么测试方法)、资源投入、时间安排以及风险评估。 +- **测试设计:** 接下来是设计测试用例(Test Case),这需要用到像等价类、边界值、场景法等方法,确保用例能有效覆盖需求。同时,可能还需要准备测试数据。 +- **测试执行:** 之后就是执行测试用例,记录测试结果,发现 Bug 要及时提交到缺陷管理系统(比如 Jira、禅道)。 +- **缺陷跟踪与管理:** 对提交的 Bug 进行跟踪,验证开发修复后的 Bug,直到 Bug 关闭。 +- **测试报告与评估:** 测试结束后,需要输出测试报告,总结测试情况,评估产品质量风险,给出是否可以上线的建议。 +- **回归测试:** 在修复 Bug 或有新版本迭代时,还需要进行回归测试,确保旧功能没问题,新改动不引入新问题。 + +在敏捷开发模式下,这些流程可能会更快速地迭代进行。 + +**简化版回答:** 通常我会先和 PM、开发团队沟通需求,然后根据需求来制定测试计划和设计测试用例,之后就是执行测试用例并记录发现的问题。缺陷修复后要做回归测试,确保没有引入新问题,最后再评估版本是否满足上线标准,才会提交上线。 + +### 你如何看待测试覆盖率这个指标? + +我认为测试覆盖率是一个**有用但有限、甚至有时带点欺骗性**的指标。 + +**高覆盖率 ≠ 高质量测试**:覆盖率只反映"代码是否被执行",无法验证: + +- 断言是否充分合理 +- 边界条件和异常场景是否覆盖 +- 业务逻辑是否被正确验证(例如,一个只调用方法但不验证结果的测试也能提高覆盖率) + +**低覆盖率 ≈ 测试很可能不充分**:核心模块若覆盖率低于 70%(尤其是新功能),通常意味着测试深度不足,但也要结合业务风险评估(如简单 DTO 类覆盖率低可能影响不大)。 + +**比较推荐的实践原则**: + +- **设定合理阈值**:核心模块要求 80%+行覆盖,关键路径 100%分支覆盖;非核心模块 60%+即可、 +- **关注"有意义"的覆盖率**:结合变更覆盖率(只关注本次修改的代码)和关键路径覆盖率。 +- **质量优先于数字**:宁可接受 70%的高质量测试,也不要 90%的"形式主义"测试。 +- **工具辅助但不盲从**:使用 JaCoCo/Sonar 等工具监控趋势,但不设硬性 KPI。 + +**一句话总结**:覆盖率是发现盲区的探照灯,而非质量合格的证明书。它最有价值的用法是识别"明显缺失测试"的区域,而非证明"测试充分"。 + +### 什么是“测试左移”(Shift-Left Testing)?你在项目中是如何实践的? + +**测试左移**的本质是:**将质量保障活动尽量前移到软件生命周期的早期阶段**,通过"早发现、早修复"来降低缺陷修复成本。行业经验表明(参考《代码大全》等经典著作),缺陷在不同阶段发现和修复的成本呈指数级增长:需求阶段修复成本约为 1,开发阶段约为 5-10,测试阶段约为 15-50,生产环境可达 100+。 + +也就是说,不再把测试只放在“开发完之后”,而是在**需求、设计、开发阶段就开始介入质量活动**,让缺陷在最早的环节被发现和预防。 + +**比较推荐的实践原则**: + +1. **早介入需求与设计** + - 测试人员参与需求评审、设计评审, + - 提前梳理业务流程、异常场景, + - 发现需求歧义、遗漏的边界条件。 +2. **开发阶段的自测与单元测试** + - 要求开发为核心业务逻辑和关键模块编写单元测试、基础集成测试; + - 将单元测试通过率作为代码提交 / 合并的前置条件之一; + - 倡导“先写用例,再写实现”的思路(TDD/UT 驱动,可选,国内较难实现)。 +3. **CI 中尽早运行自动化检查** : + - 对每次提交或合并请求自动执行:静态代码扫描(如 Sonar 等)、单元测试和关键集成测试; + - 让问题在“提交当下”就暴露,而不是拖到系统测试甚至上线前。 +4. **测试用例提前设计** + - 在需求/设计阶段就开始梳理测试思路和关键用例, + - 指导后续自动化脚本和手工测试计划。 + +可以总结为一句话:测试左移就是**把“发现问题”尽量变成“预防问题”**,让测试从“事后把关”变成“全流程参与”。 + +## Bug 处理与协作 + +### 如果有一个 Bug 不能复现,怎么去跟开发沟通? + +- **先自我排查:** 首先,我会自己再努力尝试复现几次,确保不是我操作失误或者遗漏了什么前提条件。我会尝试更换不同的测试环境、不同的测试账号或数据,看看问题是否在特定条件下出现。 +- **收集详细信息:** 如果确实难以稳定复现,我会尽可能详细地记录下当时发现问题的场景信息,比如: + - **具体的操作步骤:** 尽可能回忆并描述清楚每一步操作。 + - **环境信息:** 包括操作系统、浏览器版本(如果是 Web 端)、App 版本(如果是移动端)、网络状况、测试设备型号等。 + - **测试数据:** 当时使用的具体账号或关键数据是什么。 + - **日志信息:** 查看并附上当时客户端(浏览器控制台、App 日志)和服务器端的相关日志,特别是报错信息或异常堆栈。 + - **截图或录屏:** 如果有当时问题现象的截图或录屏是最好的。 + - **出现频率:** 大概尝试了多少次,出现了几次,或者是在什么特定时间段出现的。 +- **有效沟通:** 然后,我会整理好这些信息,找到对应的开发同学,不是直接去质问,而是客观地描述:‘我遇到了这样一个现象(描述现象),尝试了这些方法(描述排查步骤)后暂时无法稳定复现,但这里有当时收集到的信息(展示日志、截图等),你看这些信息对你定位问题有没有帮助?或者我们是不是可以一起看看,或者你那边有没有更详细的日志能查到当时的请求?’ +- **协作解决:** 目的是提供尽可能多的线索,协助开发去分析可能的原因,比如是不是偶发的环境问题、并发问题、脏数据问题等,共同把问题解决掉。 + +**简化版回答:** 我自己会先在不同的情况下,多次复现尝试。如果确实难以稳定复现,我会尽量给开发提供当时的详细操作步骤、环境信息、相关日志和截图,甚至录屏等必要信息,这可以帮助开发更好地排查和定位。同时,我也会协助开发去分析可能的原因。 + +### 你在实习/项目期间测出过什么印象深刻的 Bug? + +一定要讲清楚具体场景(例如优惠卷计算错误、重复点击多次提交订单) + 原因(分析一下导致这个问题的原因) + 修复过程(这个问题最重视如何修复的,后续如何避免)。 + +最好是能够体现个人积极思考和追根究底的态度。 + +## 测试用例 + +### 什么是测试用例?一个好的测试用例需要满足什么标准? + +测试用例是用来验证软件是否符合需求的一组明确的测试步骤和结果,它相当于一个计划书,指导你在特定条件下执行测试,并观察系统的表现是否与预期一致。简单来说,测试用例就是一个操作指南,告诉你: + +- 在什么条件下测试(前置条件)。 +- 做什么操作(输入或操作步骤)。 +- 期望看到什么结果(预期输出)。 + +例如,测一个登录功能,一个测试用例可能就是:输入正确的用户名和密码,点击登录,预期结果是成功登录并跳转到主页。另一个用例可能是:输入错误的密码,点击登录,预期结果是提示密码错误。 + +一个好的测试用例,不是单纯指它能发现问题,而是它能帮助你全面、精准地验证软件的功能和质量。打个比方,如果把软件看作一个池塘,软件缺陷是池塘里的鱼,那么“好的”测试用例就是一张编织得紧密、覆盖全面的渔网——只要池塘里有鱼,这张网就能捞上来;而如果捞不到鱼,就可以确定池塘里没有鱼。 + +所以,好的测试用例的关键不在于发现了多少缺陷,而是它是否全面、科学,能确保测试需求被完整覆盖。具体来说,一个好的测试用例应该满足以下几个标准: + +- **覆盖全面**:把该测的需求、功能点都包含了。比如测试一个表单输入框,测试用例集合需要覆盖正常输入、特殊字符输入、空输入、超长输入、非法输入等所有可能的场景,而不能只测试一种输入情况。 +- **分组精准**:通过等价类划分,减少冗余测试,确保效率和准确性。比如测试一个年龄输入框,18-60 的范围可以作为一个等价类,测试一个值(比如 25)即可,而不需要测试每个值。 +- **边界清晰**:把所有可能的边界、异常情况都考虑并测试到了。比如测试一个输入要求“1-100”的数值框时,边界值测试包括 0、1、100、101,异常情况测试包括负数、字符串输入、空值等。 + +**简化版回答:** 简单来说,测试用例就是测试说明书,它告诉测试人员:"在什么条件下,怎么操作,应该得到什么结果"。一个好的测试用例应该满足覆盖全面、分组精准和边界清晰这三个条件。 + +### 怎么设计测试用例?/ 常用的测试用例设计方法有哪些? + +设计测试用例的目标是全面覆盖软件需求,同时确保测试效率。我通常会结合多种方法,以达到最佳的测试覆盖率: + +- **等价类划分法:** 将所有可能的输入数据划分为若干个互不相交的“等价类”,然后从每个等价类中选取一个或少量具有代表性的数据作为测试用例。例如,测试一个处理用户注册的模块,针对“用户名”输入框,可以划分等价类为:有效用户名(3-20 个字符)、无效用户名(小于 3 个字符、大于 20 个字符、包含非法字符)。 +- **边界值分析法:** 作为等价类划分的补充,它专注于测试等价类边界上的值,因为错误往往更容易发生在边界处。例如,对于上述用户名长度的例子,我们需要测试 3 个字符、20 个字符,以及 2 个字符、21 个字符这些边界值。 +- **判定表法(决策表法):** 当存在多个输入条件,且这些条件的组合会产生不同的输出结果时,使用判定表法可以清晰地展示各种情况。例如,一个机票预订系统,影响预订价格的因素可能有:是否是会员、是否是节假日、提前预订天数等。通过判定表,可以列出所有条件组合及其对应的价格计算规则。 +- **场景法(流程图法):** 模拟用户在实际使用软件时的各种场景和操作流程来设计测试用例。通过绘制流程图,可以清晰地展示用户可能的操作路径,包括主流程和各种异常分支流程。例如,测试一个在线购物的流程,可以模拟用户从浏览商品、加入购物车、提交订单、支付、确认收货等一系列操作。 +- **错误推测法:** 凭借测试人员的经验、知识和直觉,推测程序中可能存在的错误,并以此设计测试用例。例如,针对文件上传功能,可以推测可能出现的错误包括:上传空文件、上传超大文件、上传病毒文件、上传与指定格式不符的文件等。 +- **状态迁移法:** 适用于测试具有多种状态且状态会发生变化的对象。例如,测试一个电梯控制系统,电梯有静止、上升、下降等状态,状态之间会根据用户的操作(如按下楼层按钮)发生迁移。需要测试在各种状态下,电梯的行为是否符合预期,以及状态迁移是否正确。 + +在实际工作中,通常需要根据被测功能的特点,灵活地组合使用这些方法,以达到最佳的测试效果,发现潜在的缺陷。同时,测试用例的设计也需要不断地评审和更新,以适应软件的迭代和变化。 + +**简化版回答:** 设计测试用例的目标是全面覆盖需求,同时保证效率。我通常会结合几种方法,比如等价类划分,将输入数据分成不同的“等价类”,从每个类中选代表性的数据测试;边界值分析,重点测试等价类边界上的值;以及错误推测,基于经验,推测程序可能出错的地方来设计用例。 + +### 设计 xxx 场景(例如电商直播间、充值、数据迁移系统)的测试用例 + +回答这类问题一般不需要详细列出所有用例,关键是展现你的分析思路和覆盖维度。 + +这里以**电商直播间**为例,分享一下回答思路: + +- **功能测试:** 这是基础。需要覆盖直播间的所有核心功能点,正常场景和异常场景都需要考虑,包括: + - **主播端:** 创建/开始直播、推流稳定性、添加/讲解商品、发优惠券、互动(评论、点赞、连麦)、结束直播、查看数据统计等。 + - **用户端:** 进入/退出直播间、观看流畅度(清晰度切换、卡顿情况)、浏览/搜索商品列表、查看商品详情、领取优惠券、加购/下单流程、评论/点赞/送礼互动、分享直播间、关注主播等。 + - **后台管理:** 直播间管理、内容审核、禁言/踢人、商品管理、订单管理、数据报表等。 +- **兼容性测试:** 需要考虑在不同平台和设备上的表现: + - **移动端:** 不同操作系统版本(iOS/Android)、不同手机品牌和型号、不同屏幕分辨率、App 版本兼容性。 + - **Web 端/PC 端:** 不同浏览器(Chrome, Firefox, Safari, Edge 等)及其版本、不同操作系统(Windows/Mac)。 +- **性能测试:** 直播间对性能要求很高: + - **压力测试:** 模拟大量用户同时在线观看、评论、下单,看服务器的响应时间(RT)、吞吐量(TPS)、错误率、CPU/内存/带宽使用率等指标。 + - **稳定性测试:** 长时间运行直播,观察系统资源是否有泄漏、服务是否稳定。 + - **客户端性能:** App 的启动速度、进入直播间速度、滑动流畅度、CPU/内存/电量消耗等。 +- **网络测试:** 模拟不同网络环境下的表现,如 WiFi、4G、5G、弱网(高延迟、丢包)下的音视频流畅度、互动响应速度等。 +- **安全测试:** 考虑潜在的安全风险,比如用户信息泄露、接口是否可以被恶意调用、防刷(评论、点赞、下单)、支付安全等。 +- **UI/UX 测试:** 界面布局是否合理美观、交互是否符合用户习惯、提示信息是否清晰友好等。 + +针对每个维度,再结合具体的功能点,使用前面提到的测试用例设计方法(如边界值、场景法)来生成具体的测试用例。 + +**简化版回答:** 首先是功能测试,我会覆盖直播间核心功能,包括主播端(如开播、推流、商品添加)和用户端(如进入观看、互动、下单)的各种场景,确保功能正常。其次是兼容性测试,考虑在不同平台和设备上的表现,比如 iOS/Android 手机、不同浏览器等。第三是性能测试,模拟大量用户并发,关注服务器的响应时间、稳定性以及客户端的流畅度。第四是网络测试,模拟弱网环境,确保音视频和互动流畅。最后,我还会考虑安全测试,比如用户信息保护和支付安全。针对每个维度,我会结合具体功能点,运用等价类划分、边界值分析等方法来设计测试用例,确保覆盖到各种潜在问题。 + +## 测试类型 + +### 什么是自动化测试?为什么需要? + +简单来说,自动化测试就是用代码或脚本让电脑自动运行测试,而不是让人工手动点击。你可以把它理解为编写代码来测试其他代码。 + +自动化测试的优势在于: + +- **搞定重复劳动:** 它擅长运行重复性的任务(比如更新后检查旧功能——回归测试),比人工更快、更稳定。再也不用让人痛苦地点击几个小时了。 +- **解放脑力:** 通过自动化那些枯燥的事情,测试人员可以专注于更聪明的工作:设计更好的测试、探索棘手的边界情况、检查可用性——这些都需要人类的直觉。 +- **解决难题:** 它使困难或不切实际的手动测试成为可能,比如模拟成千上万的用户同时访问网站(性能/负载测试)或连续几天不停地运行检查(稳定性测试)。 +- **随时运行:** 你可以安排这些测试频繁运行,甚至在夜间或周末,无需人员在场就能提供更快的反馈。 +- **一致性是关键:** 机器每次都精确地按照指令执行,消除了人为错误,比如忘记步骤或误解结果。 + +自动化测试的价值需要权衡:ROI = (节省的手工测试时间 × 执行频率) - (脚本开发时间 + 维护成本)。实践中,适用于自动化测试的场景包括:重复执行频率高(如回归测试)、步骤确定性高(UI 元素稳定)、执行耗时长(如性能测试);不适用场景包括:一次性功能、UI 频繁变动、探索性测试。 + +### 什么是 Web 应用的自动化测试?怎么做? + +Web 应用自动化测试挺深的,面试中问到抓住几个关键点聊就好了。 + +Web 应用的自动化测试,简单说就是**用代码(脚本)来控制工具,模拟真实用户操作浏览器,自动执行预设的测试步骤并验证结果**。比如自动打开网页、点击按钮、输入文字、检查页面显示是否正确等等。 + +实践中,Web 应用自动化测试通常这样做: + +1. **选择合适的工具/框架**:选择时需考虑工具特点与项目匹配度。Selenium(成熟稳定、支持多语言、社区大、但执行相对较慢)、Cypress(开发者友好、调试方便、JS-only、不支持多浏览器并行)、Playwright(现代化、速度快、支持多语言、API 测试能力强)。推荐优先级:团队技术栈(JS/Java/Python)、测试类型(UI/API/混合)、CI/CD 集成需求。 +2. **编写测试脚本**:针对应用的核心功能和关键业务流程编写自动化脚本。 + - **重点是功能和回归测试**:确保核心流程(如登录、购物、关键操作)能正常工作,并且在新代码提交后这些功能没有被意外破坏。 + - **适当进行 UI 验证**:可以检查关键元素是否存在、是否可见,但过于精细的像素级 UI 对比通常投入产出比较低,容易失败。 + - **考虑兼容性**:同一套脚本可以在不同浏览器(Chrome, Firefox, Safari 等)或不同环境配置下运行,以检查兼容性。 +3. **集成到 CI/CD 流程**:这是发挥自动化价值的关键一步。把自动化测试加入到持续集成/持续部署(CI/CD)管道中(例如使用 Jenkins, GitLab CI, GitHub Actions)。这样,每次开发者提交代码后,测试就会自动运行,快速反馈结果。通过清晰的测试报告,团队能迅速定位并修复失败的测试,保证代码质量。 + +### 怎么进行压测? + +压测,全称压力测试,是指通过模拟大量用户并发访问,或者在极端条件下运行系统,来评估系统在负载下的性能、稳定性和可靠性。 简单来说,就是给系统施加压力,看看它能不能扛得住。 压测可以帮助我们发现系统的瓶颈,比如 CPU、内存、数据库连接数等,从而进行优化,提高系统的性能和稳定性。 + +压测的步骤大致如下: + +1. **确定压测目标:** 你想通过压测了解什么?是想看系统能否支撑 1000 用户在线?还是想知道下单接口的最大 TPS 是多少?响应时间要求低于 500ms?先把这些具体的、可量化的性能指标定下来。同时确定压测的范围,是测试整个系统,还是某个核心模块或接口? +2. **准备测试环境:** 准备接近生产环境的测试环境。建议:硬件配置为生产环境的 50-80%(如核心 CPU/内存)、数据量为生产环境的 20-50%(可使用脱敏数据)、网络带宽模拟生产环境延迟、关键依赖(数据库、缓存、消息队列)使用同版本、关闭不必要的调试日志。压测环境应与日常测试环境隔离,避免干扰。 +3. **选择合适的压测工具:** JMeter 是最常用、免费开源的选择,功能强大。其他流行的还有 k6 (现代化的,用 JavaScript 写脚本)、LoadRunner (商业,功能全面)、Gatling (用 Scala 写脚本,性能较好)。根据团队技术栈和需求选择。 +4. **编写/录制测试脚本:** 使用选定的工具,根据设计的测试场景,编写或录制模拟用户操作的请求脚本。 +5. **配置压测工具并执行测试:** 设置并发用户数、请求频率等参数。配置完成后,执行测试。 +6. **监控和分析结果:** 密切关注压测工具的指标(TPS、响应时间、错误率)和服务器端的性能指标(CPU、内存、磁盘 I/O、网络、数据库连接数、中间件指标等)。找出系统的瓶颈,比如数据库连接数、CPU 利用率等。 +7. **调优和再测试:** 根据分析结果,定位瓶颈并进行优化(代码优化、配置调整、硬件升级等)。优化后,重复执行之前的测试,验证优化效果,看性能指标是否有提升。这是一个迭代的过程。 + +**简化版回答:** 首先确定压测目标和范围,然后准备接近生产环境的测试环境。选择合适的压测工具(如 JMeter),编写模拟用户操作的脚本,配置工具并执行测试。密切监控压测工具和服务器端的性能指标,找出瓶颈并进行优化,最后重复测试验证优化效果,直至达到性能目标。 + +### 白盒测试和黑盒测试的主要区别是什么? + +白盒测试和黑盒测试最主要的区别在于**是否关注被测对象的内部结构和实现逻辑:** + +- 黑盒测试把被测系统看作一个‘黑盒子’,完全不关心它内部是怎么实现的,主要是针对系统对外功能进行验证,比如给定输入,是否得到预期输出。测试人员站在用户的角度,根据需求文档或规格说明,检查系统功能是否符合预期。常用的方法就是前面提到的等价类、边界值、场景法等。” +- 白盒测试则需要了解被测对象的内部代码逻辑、结构和算法。测试的目的是检查代码内部路径是否都能按预期执行、逻辑判断是否正确、是否存在潜在的代码缺陷等。 + +### 什么是单元测试?集成测试?系统测试?回归测试?验收测试? + +- **单元测试(Unit Test)** + - 针对:最小可测试单元(函数、类、模块)。 + - 目标:验证该单元的功能和逻辑是否正确,边界、异常是否处理到位。 + - 特点:依赖少(外部依赖多用 Mock),执行快,通常由开发编写并自动化执行。 +- **集成测试(Integration Test)** + - 针对:多个模块 / 服务之间的组合和交互。 + - 目标:验证接口、数据传递、依赖关系是否正确,模块间能否协同工作。 + - 特点:会使用真实或接近真实的数据库、接口等,关注的是“模块之间”。 +- **系统测试(System Test)** + - 针对:完整系统(所有模块与外部接口集成后)。 + - 目标:从整体上验证系统是否满足需求规格,包括功能、性能、安全、兼容性等。 + - 特点:由测试团队执行,从“系统视角”验证,不关注具体代码实现细节。 +- **回归测试(Regression Test)** + - 针对:每次修改代码后的系统(修 bug、新功能、重构之后)。 + - 目标:确认本次改动没有破坏已有功能,老功能依然按原来方式工作。 + - 特点:高度依赖自动化用例,常在每次迭代、发布前重复执行。 +- **验收测试(Acceptance Test / UAT)** + - 针对:接近上线的完整系统。 + - 目标:由客户 / 业务方 / 产品代表确认系统是否满足业务需求、合同约定,是否可以交付上线。 + - 特点:贴近真实业务场景和生产环境,更关注“是否满足业务和用户预期”。 + +实际项目中,一般遵循"测试金字塔":单元测试自动化率最高(>90%),其上依次是集成测试(60–80%)和少量关键系统/UI 自动化(20–40%),回归尽量依赖自动化,而验收测试则以人工探索和真实业务场景为主。 + +![测试金字塔](https://oss.javaguide.cn/github/javaguide/test-development/test-development-testing-pyramid.png) + +### 单元测试、集成测试、系统测试、回归测试、验收测试最重要的是那一步? + +严格来说,这几个阶段**都重要、互相补充**,但如果面试官逼问“最重要是哪一步”,可以这样回答(重点是**理由**): + +- **单元测试**:是质量的第一道防线,越早发现问题,修复成本越低;它保证代码构件本身是可靠的。 +- **集成测试 & 系统测试**:从整体角度保证“拼在一起能不能用”、“业务链路能不能跑通”,避免线上出现大面积故障。 +- **回归测试**:保证迭代过程中老功能不被破坏,是持续交付、敏捷开发中非常关键的一环。 +- **验收测试**:从业务和用户角度做最终把关,决定能不能交付上线。 + +如果必须选一个**对业务结果影响最大**的阶段,可以说是: +**系统测试 / 验收测试更关键**,因为它们直接决定系统整体是否可用、能否交付给用户; + +但从“工程实践”和“长期质量保障”来看,**单元测试和回归测试**是最值得投入的,它们决定了团队能否稳定、可持续地迭代。 + +### 什么是端到端测试? + +**端到端测试**(End-to-End Test,E2E)是指**从用户交互入口到系统最终输出结果**,按照真实业务场景,将前端界面、后端服务、数据库、缓存、消息队列、第三方依赖等全部组件串联起来进行的**全流程集成验证**。它模拟真实用户行为,验证整个系统在近生产环境条件下是否满足业务需求。 + +**特点**: + +- 覆盖“完整业务链路”,例如:注册 → 登录 → 下单 → 支付 → 查询订单状态; +- 尽量使用与生产环境相似的配置和数据; +- 更关注系统整体可用性和业务流是否跑通,而不是某个单点模块的细节; +- 数量相对较少,但每条用例价值高,适合作为**关键路径回归**和**上线前的最后验证**。 + +### 移动端与 Web 端测试有什么区别? + +| 维度 | 移动端 App 测试 | Web 端测试 | +| ----------- | -------------------------------------------- | -------------------------------------- | +| 架构 & 入口 | C/S 架构,需要安装 App | B/S 架构,通过浏览器访问 | +| 运行环境 | 受机型、系统版本、厂商 ROM 影响大 | 受浏览器内核/版本、操作系统影响 | +| 主要兼容性 | 不同机型、分辨率、iOS/Android 各版本 | 不同浏览器(Chrome/Firefox/Safari 等) | +| 网络相关 | 2G/3G/4G/5G/Wi‑Fi 切换、弱网/无网、前后台 | 不同带宽下页面加载、缓存策略、断网降级 | +| 中断场景 | 来电、短信、通知、锁屏、前后台切换 | 标签页切换、刷新,系统中断较少 | +| UI/交互 | 手势操作、软键盘弹出/收起、全面屏安全区域 | 响应式布局、鼠标键盘操作、窗口缩放 | +| 性能关注点 | 启动时间、流畅度、CPU/内存、耗电、流量 | 首屏时间、资源体积、前端性能、后端响应 | +| 发布方式 | 应用市场发版,有审核;灰度、热更新受平台限制 | 服务器部署,上线/回滚更快,灰度灵活 | +| 典型难点 | 机型/OS 碎片化、网络复杂、功耗与流量 | 浏览器兼容性、复杂前端与多终端适配 | + +### 如何测试 Web 应用的安全性?你会关注哪些常见漏洞? + +重点关注 **OWASP Top 10** 类常见漏洞,针对 Web 端典型场景设计测试: + +**1. XSS(跨站脚本攻击)** + +- 测试位置:输入框、URL 参数、富文本编辑器、评论区 +- 测试用例:`、" onmouseover="alert(1)、` +- 验证点:页面是否执行脚本、是否正确转义/过滤 + +**2. SQL 注入** + +- 测试位置:登录、搜索、筛选、排序等数据库查询场景 +- 测试用例:`' OR '1'='1 --`(登录绕过)、`' UNION SELECT database(),user() --`(信息泄露);时间盲注:`AND SLEEP(5)`、布尔盲注:`AND (SELECT COUNT(*) FROM users)>0` +- 验证点:是否使用参数化查询、是否暴露数据库错误信息、是否对输入做类型校验 + +**3. CSRF(跨站请求伪造)** + +- 测试场景:修改密码、转账、删除数据等敏感操作 +- 测试方法:检查是否有 CSRF Token,尝试第三方页面构造伪造请求 +- 验证点:Token 验证机制、Referer / Origin 校验 + +**4. 身份认证与会话管理** + +- 测试位置:登录/退出流程、会话保持 +- 测试方法:Session 固定攻击测试,退出后 Token 有效性验证 +- 验证点:会话是否及时失效,是否允许暴力破解 + +**5. 敏感信息泄露** + +- 测试位置:API 响应、错误页面、前端代码 +- 测试方法:密码/密钥/内部路径是否暴露,错误信息是否过度详细 +- 验证点:敏感数据是否脱敏,错误信息是否通用化 + +**6. 访问控制失效** + +- 测试位置:用户资料查看、订单数据、文件下载、管理员接口、导出接口 +- 测试方法:越权访问,提升权限 +- 验证点:是否返回他人数据;RBAC(角色访问控制)是否生效 + +### API 功能测试如何做? + +API 功能测试的核心目的其实很简单:**确认你的 API 是否按照设计(例如 API 文档或需求)准确工作**。它并不在乎界面的美观程度,而是关心当我们调用该 API 时,能否正确接收请求、处理业务逻辑并返回预期的响应,以及是否会产生相应的“副作用”(例如对数据库记录的增删改)。 + +1. **仔细阅读 API 文档(如 Swagger/OpenAPI)** :了解请求的 URL 及方法(GET、POST 等),参数类型(路径参数、查询参数)、请求体格式(JSON、XML)以及成功/失败时对应的状态码等信息。 +2. **设计覆盖多种场景的测试用例** :在充分理解 API 的基础上,编写不同维度的用例,包括正确输入、无效输入、非法输入以及边界值等,以确保各种情况得到测试。 +3. **准备相关数据与认证信息** :可能需要在数据库中预先插入初始数据或异常数据。根据场景需求,还要配置 API Key、Token 等认证信息,以便顺利调用接口。 +4. **选用合适的测试工具并执行测试** :可使用 Postman、Reqable、Insomnia 等工具。根据测试用例构造 HTTP 请求(设置方法、URL、Headers、Body 等),执行后得到实际响应(状态码、响应头、响应体)并进行校验。 +5. **对比实际响应与预期结果** :关注状态码是否正确,返回数据是否与预期一致,数据库记录是否跟随请求生效等。任何偏差都可能意味着缺陷或需求不匹配。 +6. **记录测试结果并报告问题(Bug)** :对于用例执行失败的情况,需要在报告中包括完整的请求信息、预期结果、实际结果以及重现步骤,方便团队排查修复。 + +**简化版回答:** API 功能测试的核心是确认接口是否按设计正确工作,主要做法是先阅读文档,弄清楚请求方法、参数和返回值,然后设计覆盖正常、异常与边界场景的用例,准备好测试环境和认证信息,再利用 Postman 等工具发起请求并查看状态码和响应体,接着核对数据库等是否与预期一致,最后将失败用例的请求、预期和实际结果记录下来,方便快速定位并修复问题。 + +### 什么是正向测试和反向测试?能否举例说明 + +**解释**: + +- 正向测试(Positive Testing):使用**合法、合理、期望的输入**,验证系统在正常使用场景下是否按需求工作。 +- 反向测试(Negative Testing):使用**非法、异常、边界或恶意的输入/操作**,验证系统对异常情况的处理能力和鲁棒性。 + +**例子(登录功能)**: + +- 正向测试:输入正确账号 + 正确密码 → 登录成功。 +- 反向测试:账号为空 / 密码为空、密码错误、输入超长字符串、注入脚本、多次输错触发锁定/验证码。 + +### 可用性测试和用户体验测试有什么区别? + +可用性测试评估系统是否易学、易用、易理解,关注点在于:操作流程是否顺畅、提示是否清晰、错误率高低。 + +用户体验测试(UX)评估整体主观感受,关注点在于:用户情绪、满意度、视觉美感、品牌感知等。 + +| **维度** | **可用性测试 (Usability Testing)** | **用户体验测试 (UX Testing)** | +| ------------ | ------------------------------------------ | ---------------------------------------------------- | +| **核心目标** | 产品能否被高效、准确地使用 | 使用过程是否愉悦、有价值、令人满意 | +| **关注范围** | 任务执行效率(交互流程、认知负荷、容错性) | 完整体验旅程(使用前期待 + 使用中感受 + 使用后回忆) | +| **测试维度** | 功能层面 | 情感+功能+审美全方位 | +| **衡量指标** | 任务完成率、时间、错误数 | 满意度评分、NPS、情感反馈 | +| **相互关系** | 是 UX 的基础子集 | 包含可用性 + 情感/价值层面 | +| **测试时机** | 常在开发中后期进行功能验证 | 贯穿产品全生命周期(概念验证到迭代优化) | + + diff --git a/docs/real-interview-experience/dachang/2025-alibaba-taotian-1.md b/docs/real-interview-experience/dachang/2025-alibaba-taotian-1.md new file mode 100644 index 0000000..fa115aa --- /dev/null +++ b/docs/real-interview-experience/dachang/2025-alibaba-taotian-1.md @@ -0,0 +1,444 @@ +--- +title: 2025阿里淘天一面面经 +description: 2025年阿里淘天一面真实面经分享:涵盖阿里招聘流程、面试技巧、技术八股文如GET/POST区别、反射应用、SQL优化等高频面试题,以及在线编程考核内容,助你备战阿里面试。 +category: 真实面经 +tag: + - 阿里 + - 淘天 + - 大厂面经 +head: + - - meta + - name: keywords + content: 阿里面经,淘天面经,2025面经,阿里面试,大厂面经,Java面经,后端面经,阿里技术面试,GET POST区别,反射,SQL优化 +--- + +过去两年,阿里的招聘策略正在悄悄发生结构性变化。 + +一方面,阿里整体调整组织架构,形成淘天、阿里云、夸克等多个相对独立的业务方向;另一方面,不少应届生明显感受到:**阿里开始“卡学历”了。** + +从我这段时间收到的反馈来看—— + +- 淘天、高德、蚂蚁、阿里云等核心业务线 **对双非学历的过滤明显增强**,进入难度比前几年高很多; +- 社招相对宽松,但学历同样会影响初筛通过率; +- 部门之间的招聘标准差异极大: **有的部门卡得很严,有的部门依旧相对友好。** + +还有一个投递小技巧:阿里不同部门之间的投递 **是可以分开算的**。 同学们别傻傻只投一个 JD,被拒了连第二次机会都没有。 + +至于面试流程,阿里整体依然保持“技术主导”,一般是: + +- 两轮或三轮技术面(极少出现四轮) +- 技术通过后才会约 HR 面 +- HR 面依旧“玄学”,也需要重视 + +**千万不要以为:技术面过了 = 稳了。** + +这是一位来自四川大学的同学分享的 **阿里淘天一面** 面经。从整体感受来看,这次面试偏轻松,面试官提问比较随意(有点像是 KPI 面试),主要分为三个部分: + +1. 非技术类问题(自我介绍、实习经历等) +2. 小型笔试题(在线编程,不是 LeetCode 偏难题) +3. 基础技术八股(如 GET/POST 区别、反射应用场景、SQL 优化等) + +面试时长约 **一个半小时**。整体难度比较简单,最让我意外的事竟然考察了三道笔试题,不是那种纯粹的 LeetCode 问题,偏向于考察对 Java 语言的掌握,挺简单的! + +![](https://static001.geekbang.org/infoq/6a/6a07333e392e0b710fb5bf2b3ae28652.png) + +> 这篇是24届同学的面经,当时分享过,但笔试题的答案需要重新完善一下。根据我的观察来看,阿里的面试一般不会考察这么多笔试题,所以说有点像是 KPI 面试。 + +## 非技术问题 + +### 自我介绍 + +面试时的自我介绍,其实是你给面试官的“第一印象浓缩版”。它不需要面面俱到,但要精准、自信地展现你的核心价值和与岗位的匹配度。通常控制在 1-2 分钟内比较合适。一个好的自我介绍应该包含这几点要素: + +1. 用简单的话说清楚自己主要的技术栈于擅长的领域,例如 Java 后端开发、分布式系统开发; +2. 把重点放在自己的优势上,重点突出自己的能力,最好能用一个简短的例子支撑,例如:我比较擅长定位和解决复杂问题。在[某项目/实习]中,我曾通过[简述方法,如日志分析、源码追踪、压力测试]成功解决了[某个具体问题,如一个棘手的性能瓶颈/一个偶现的 Bug],将[某个指标]提升了[百分比/具体数值]。 +3. 简要提及 1-2 个最能体现你能力和与岗位要求匹配的项目经历、实习经历或竞赛成绩。不需要展开细节,目的是引出面试官后续的提问。 +4. 如果时间允许,可以非常简短地表达对所申请岗位的兴趣和对公司的向往,表明你是有备而来。 + +### 讲一下实习经历以及遇到的难点 + +实习经历的描述一定要避免空谈,尽量列举出你在实习期间取得的成就和具体贡献,使用具体的数据和指标来量化你的工作成果。 + +示例(这里假设项目细节放在实习经历这里介绍,你也可以选择将实习经历参与的项目放到项目经历中): + +1. 参与项目订单模块的开发,负责订单创建、删除、查询等功能。 +2. 排查并解决扣费模块由于扣费父任务和反作弊子任务使用同一个线程池导致的死锁问题。 +3. 使用 CompletableFuture 并行加载后台用户统计模块的数据信息,平均相应时间从 3.5s 降低到 1s。 +4. 使用 Redis+Caffeine 多级缓存优化热门数据(如首页、热门商品)的访问,解决了缓存击穿和穿透问题,查询速度毫秒级,QPS 30w+。 +5. 在实习期间,共完成了 10 个需求开发和 5 个问题修复,编写了 2000 行代码和 100 个测试用例,通过了代码评审和测试验收,上线运行稳定无故障。 + +关于实习经历这块再多提一点。很多同学实习期间可能接触不到什么实际的开发任务,大部分时间可能都是在熟悉和维护项目。对于这种情况,你可以适当润色这段实习经历,找一些简单的功能研究透,包装成自己做的,很多同学都是这么做的。不过,我更建议你在实习期间主动去承担一些开发任务,甚至说对原系统进行优化改造。常见的性能优化方向实践(涉及到多线程、JVM、数据库/缓存、数据结构优化这 4 个常见的性能优化方向)总结请看:https://t.zsxq.com/0c1uS7q2Y (这块内容分享在 [知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html) 里了,你也可以自己按照我的思路总结,效果是一样的)。 + +![](https://mmbiz.qpic.cn/mmbiz_png/iaIdQfEric9TxXGicjSaF6UyjV4csrgaupfKjoAicvzudEdsneGxSVXKpZWHJ89sEcABibf318JJb1qyhu8joLibzicAg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1) + +### 说一下自己以后的发展发向 + +> [工作五年之后,对技术和业务的思考](https://javaguide.cn/high-quality-technical-articles/advanced-programmer/thinking-about-technology-and-business-after-five-years-of-work.html) 这篇文章是我在两年前看到的一篇对我触动比较深的文章,介绍了作者工作五年之后,对于技术和业务的深度思考。 + +建议: + +- 如果你的想法是干个两三年就跳槽或者换行业的话,尽量不要直说,一定要体现出自己的稳定性。 +- 绝大部分人的职业目标都可以从技术精进、项目管理和个人影响力三个方面来回答。 + +参考回答: + +在接下来的五年里,我的职业目标主要集中在技术精进、项目管理和个人影响力三个方面。 + +首先,技术上,我会深入专研 Java 后端开发,争取早日成为 Java 后端开发领域的技术专家。为此,我将不断深入学习 Java 的核心技术和最新技术进展。 + +其次,项目管理上,我会慢慢尝试着在工作中承担更多的项目管理职责,积累项目管理经验,争取早日能够拥有独立带领中小型项目的能力。 + +最后,个人影响力上,我希望通过我的专业技能对公司的核心产品做出重大贡献,解决技术难题,提升产品性能和用户体验。同时,我也计划积极参与贡献开源项目和技术社区。 + +## 笔试题 + +笔试的形式是给你的邮箱发个链接,点进去就是一个在线的编辑器。 + +### 写三种单例模式的实现方式 + +**1、枚举(推荐)**: + +```java +public enum Singleton { + INSTANCE; + public void doSomething(String str) { + System.out.println(str); + } +} +``` + +《Effective Java》作者推荐的一种单例实现方式,简单高效,无需加锁,线程安全,可以避免通过反射破坏枚举单例。 + +**2、静态内部类(推荐)**: + +```java +public class Singleton { + // 私有化构造方法 + private Singleton() { + } + + // 对外提供获取实例的公共方法 + public static Singleton getInstance() { + return SingletonInner.INSTANCE; + } + + // 定义静态内部类 + private static class SingletonInner{ + private final static Singleton INSTANCE = new Singleton(); + } + +} +``` + +当外部类 `Singleton` 被加载的时候,并不会创建静态内部类 `SingletonInner` 的实例对象。只有当调用 `getInstance()` 方法时,`SingletonInner` 才会被加载,这个时候才会创建单例对象 `INSTANCE`。`INSTANCE` 的唯一性、创建过程的线程安全性,都由 JVM 来保证。 + +这种方式同样简单高效,无需加锁,线程安全,并且支持延时加载。 + +**3、双重校验锁**: + +```java +public class Singleton { + + private volatile static Singleton uniqueInstance; + + // 私有化构造方法 + private Singleton() { + } + + public static Singleton getUniqueInstance() { + //先判断对象是否已经实例过,没有实例化过才进入加锁代码 + if (uniqueInstance == null) { + //类对象加锁 + synchronized (Singleton.class) { + if (uniqueInstance == null) { + uniqueInstance = new Singleton(); + } + } + } + return uniqueInstance; + } +} +``` + +`uniqueInstance` 采用 `volatile` 关键字修饰也是很有必要的, `uniqueInstance = new Singleton();` 这段代码其实是分为三步执行: + +1. 为 `uniqueInstance` 分配内存空间 +2. 初始化 `uniqueInstance` +3. 将 `uniqueInstance` 指向分配的内存地址 + +但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 T1 执行了 1 和 3,此时 T2 调用 `getUniqueInstance`() 后发现 `uniqueInstance` 不为空,因此返回 `uniqueInstance`,但此时 `uniqueInstance` 还未被初始化。 + +这种方式实现起来较麻烦,但同样线程安全,支持延时加载。 + +推荐阅读:[Java 并发常见面试题总结(中)](https://javaguide.cn/java/concurrent/java-concurrent-questions-02.html)。 + +### 编号为 1-n 的循环报 1-3,报道 3 的出列,求最后一人的编号 + +问题描述:编号为 1-n 的循环报 1-3,报道 3 的出列,求最后一人的编号 + +标准的约瑟夫环问题。有 n 个人围成一个圈,从某个人开始报数,报到某个特定数字(本题中为 3 )时该人出圈,直到只剩下一个人为止。 + +解决约瑟夫环问题,可以分两种情况: + +1. 我们要求出最后留下的那个人的编号(本题要求)。 +2. 求全过程,即要算出每轮出局的人。 + +有多种方法可以解决约瑟夫环问题,其中一种是使用递归的方式。 + +本题的约瑟夫环问题的公式为: **(f(n - 1, k) + k - 1) % n + 1** 。f(n,k) 表示 n 个人报数,每次报数报到 k 的人出局,最终最后一个人的编号。 + +假设 n 为 10,k 为 3 ,逆推过程如下: + +- f(1, 3) = 1(当 n = 1 时,只有一个人,最后一人的编号就为 1); +- f(2,3) =(f(1,3) + 3 -1)%2 + 1 = 3%2 + 1 = 2(当 n = 2 时,最后一人的编号为 2); +- f(3,3) = (f(2,3) + 3 - 1))%3 + 1 = 4%3 + 1 = 2(当 n = 3 时,最后一人的编号为 2); +- f(4,3) = (f(3,3) + 3 - 1) % 4 + 1 = 4%4 + 1 = 1(当 n = 4 时,最后一人的编号为 1); +- ... +- f(10,3) = 3 (当 n = 10 时,最后一人的编号为 4); + +这个问题对应[剑指 Offer 62. 圆圈中最后剩下的数字](https://leetcode.cn/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/) ,两者意思是类似的,比较简单。 + +```java +public class Josephus { + + // 定义递归函数 + public static int f(int n, int k) { + // 如果只有一个人,则返回 1 + if (n == 1) { + return 1; + } + return (f(n - 1, k) + k - 1) % n + 1; + } + + public static void main(String[] args) { + int n = 10; + int k = 3; + System.out.println("最后留下的那个人的编号是:" + f(n, k)); + } +} +``` + +输出: + +```plain +最后留下的那个人的编号是:4 +``` + +### 写两个线程打印 1-n,一个线程打印奇数,一个线程打印偶数 + +问题描述:写两个线程打印 1-100,一个线程打印奇数,一个线程打印偶数。 + +这道题的实现方式还是挺多的,线程的等待/通知机制(`wait()`和`notify()`)、信号量 `Semaphore`等都可以实现。 + +#### synchronized+wait/notify 实现 + +我们先定义一个类 `ParityPrinter` 用于打印奇数和偶数。 + +```java +public class ParityPrinter { + private final int max; + // 从1开始计数 + private int count = 1; + private final Object lock = new Object(); + + public ParityPrinter(int max) { + this.max = max; + } + + public void printOdd() { + print(true); + } + + public void printEven() { + print(false); + } + + private void print(boolean isOdd) { + for (int i = 1; i <= max; i += 2) { + // 确保同一时间只有一个线程可以执行内部代码块 + synchronized (lock) { + // 等待直到轮到当前线程打印 + // count为奇数时奇数线程打印,count为偶数时偶数线程打印 + while (isOdd == (count % 2 == 0)) { + try { + lock.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } + System.out.println(Thread.currentThread().getName() + " : " + count++); + // 通知等待的线程 + lock.notify(); + } + } + } +} +``` + +`ParityPrinter`类中的变量和方法介绍: + +- `max`: 最大打印数值,由构造函数传入。 +- `count`: 从 1 开始的计数器,用于追踪当前打印到的数字。 +- `lock`: 一个对象锁,用于线程间的同步控制。 +- `printOdd()`和`printEven()`: 分别启动打印奇数和偶数的逻辑,实际上调用了私有的`print()`方法,并传入线程名称前缀和一个布尔值表示打印奇数(`true`)还是偶数(`false`)。 + +接着,我们创建两个线程,一个负责打印奇数,一个负责打印偶数。 + +```java + // 打印 1-100 + ParityPrinter printer = new ParityPrinter(100); + // 创建打印奇数和偶数的线程 + Thread t1 = new Thread(printer::printOdd, "Odd"); + Thread t2 = new Thread(printer::printEven, "Even"); + t1.start(); + t2.start(); +``` + +输出: + +```plain +Odd : 1 +Even : 2 +Odd : 3 +Even : 4 +Odd : 5 +... +Odd : 95 +Even : 96 +Odd : 97 +Even : 98 +Odd : 99 +Even : 100 +``` + +#### Semaphore 实现 + +如果想要把上面的代码修改为基于 `Semaphore`实现也挺简单的。 + +```java +public class ParityPrinter { + private final int max; + private int count = 1; + // 初始为1,奇数线程先获取 + private final Semaphore oddSemaphore = new Semaphore(1); + // 初始为0,偶数线程等待 + private final Semaphore evenSemaphore = new Semaphore(0); + + public ParityPrinter(int max) { + this.max = max; + } + + public void printOdd() { + print(oddSemaphore, evenSemaphore); + } + + public void printEven() { + print(evenSemaphore, oddSemaphore); + } + + private void print(Semaphore currentSemaphore, Semaphore nextSemaphore) { + for (int i = 1; i <= max; i += 2) { + try { + // 获取当前信号量 + currentSemaphore.acquire(); + System.out.println(Thread.currentThread().getName() + " : " + count++); + // 释放下一个信号量 + nextSemaphore.release(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } + } +} +``` + +可以看到,我们这里使用两个信号量 `oddSemaphore` 和 `evenSemaphore` 来确保两个线程交替执行。`oddSemaphore` 信号量先获取,也就是先执行奇数输出。一个线程执行完之后,就释放下一个信号量。 + +## 技术问题 + +### GET 和 POST 的区别 + +这个问题在知乎上被讨论的挺火热的,地址: 。 + +![](https://static001.geekbang.org/infoq/04/0454a5fff1437c32754f1dfcc3881148.png) + +GET 和 POST 是 HTTP 协议中两种常用的请求方法,它们在不同的场景和目的下有不同的特点和用法。一般来说,可以从以下几个方面来区分它们(重点搞清两者在语义上的区别即可): + +- 语义(主要区别):GET 通常用于获取或查询资源,而 POST 通常用于创建或修改资源。 +- 幂等:GET 请求是幂等的,即多次重复执行不会改变资源的状态,而 POST 请求是不幂等的,即每次执行可能会产生不同的结果或影响资源的状态。 +- 格式:GET 请求的参数通常放在 URL 中,形成查询字符串(querystring),而 POST 请求的参数通常放在请求体(body)中,可以有多种编码格式,如 application/x-www-form-urlencoded、multipart/form-data、application/json 等。GET 请求的 URL 长度受到浏览器和服务器的限制,而 POST 请求的 body 大小则没有明确的限制。不过,实际上 GET 请求也可以用 body 传输数据,只是并不推荐这样做,因为这样可能会导致一些兼容性或者语义上的问题。 +- 缓存:由于 GET 请求是幂等的,它可以被浏览器或其他中间节点(如代理、网关)缓存起来,以提高性能和效率。而 POST 请求则不适合被缓存,因为它可能有副作用,每次执行可能需要实时的响应。 +- 安全性:GET 请求和 POST 请求如果使用 HTTP 协议的话,那都不安全,因为 HTTP 协议本身是明文传输的,必须使用 HTTPS 协议来加密传输数据。另外,GET 请求相比 POST 请求更容易泄露敏感数据,因为 GET 请求的参数通常放在 URL 中。 + +再次提示,重点搞清两者在语义上的区别即可,实际使用过程中,也是通过语义来区分使用 GET 还是 POST。不过,也有一些项目所有的请求都用 POST,这个并不是固定的,项目组达成共识即可。 + +### 如何优化 MySQL 查询 + +回答这个问题的核心是先提到开启慢查询日志和使用 EXPLAIN 进行执行计划分析。 + +慢查询日志捕获那些执行时间超过阈值的SQL语句,这是发现问题的起点。拿到慢SQL后,用 `EXPLAIN` 关键字分析这条SQL的执行计划,分析原因。 + +基于 `EXPLAIN` 的分析结果,进行针对性优化。比较常见的 SQL优化手段如下: + +1. 索引优化(最常用) +2. 避免 `SELECT *` +3. 深度分页优化 +4. 尽量避免多表做 join +5. 选择合适的字段类型 +6. ...... + +[《Java 面试指北》](https://mp.weixin.qq.com/s/JNJIKnUMc0MU_i2VNXb50A)的技术面试题篇总结了常见的高并发面试问题,其中包含常见的 SQL 优化手段,内容非常全面。 + +![img](https://oss.javaguide.cn/javamianshizhibei/sql-optimization.png) + +推荐顺带看看下面这两篇文章: + +- [MySQL 高性能优化规范建议总结](https://javaguide.cn/database/mysql/mysql-high-performance-optimization-specification-recommendations.html) +- [MySQL 执行计划分析](https://javaguide.cn/database/mysql/mysql-query-execution-plan.html) + +### 反射及应用场景 + +简单来说,Java 反射 (Reflection) 是一种**在程序运行时,动态地获取类的信息并操作类或对象(方法、属性)的能力**。 + +通常情况下,我们写的代码在编译时类型就已经确定了,要调用哪个方法、访问哪个字段都是明确的。但反射允许我们在**运行时**才去探知一个类有哪些方法、哪些属性、它的构造函数是怎样的,甚至可以动态地创建对象、调用方法或修改属性,哪怕这些方法或属性是私有的。 + +正是这种在运行时“反观自身”并进行操作的能力,使得反射成为许多**通用框架和库的基石**。它让代码更加灵活,能够处理在编译时未知的类型。 + +我们平时写业务代码可能很少直接跟 Java 的反射(Reflection)打交道。但你可能没意识到,你天天都在享受反射带来的便利!**很多流行的框架,比如 Spring/Spring Boot、MyBatis 等,底层都大量运用了反射机制**,这才让它们能够那么灵活和强大。 + +下面简单列举几个最场景的场景帮助大家理解。 + +**1.依赖注入与控制反转(IoC)** + +以 Spring/Spring Boot 为代表的 IoC 框架,会在启动时扫描带有特定注解(如 `@Component`, `@Service`, `@Repository`, `@Controller`)的类,利用反射实例化对象(Bean),并通过反射注入依赖(如 `@Autowired`、构造器注入等)。 + +**2.注解处理** + +注解本身只是个“标记”,得有人去读这个标记才知道要做什么。反射就是那个“读取器”。框架通过反射检查类、方法、字段上有没有特定的注解,然后根据注解信息执行相应的逻辑。比如,看到 `@Value`,就用反射读取注解内容,去配置文件找对应的值,再用反射把值设置给字段。 + +**3.动态代理与 AOP** + +想在调用某个方法前后自动加点料(比如打日志、开事务、做权限检查)?AOP(面向切面编程)就是干这个的,而动态代理是实现 AOP 的常用手段。JDK 自带的动态代理(Proxy 和 InvocationHandler)就离不开反射。代理对象在内部调用真实对象的方法时,就是通过反射的 `Method.invoke` 来完成的。 + +```java +public class DebugInvocationHandler implements InvocationHandler { + private final Object target; // 真实对象 + + public DebugInvocationHandler(Object target) { this.target = target; } + + // proxy: 代理对象, method: 被调用的方法, args: 方法参数 + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("切面逻辑:调用方法 " + method.getName() + " 之前"); + // 通过反射调用真实对象的同名方法 + Object result = method.invoke(target, args); + System.out.println("切面逻辑:调用方法 " + method.getName() + " 之后"); + return result; + } +} +``` + +**4.对象关系映射(ORM)** + +像 MyBatis、Hibernate 这种框架,能帮你把数据库查出来的一行行数据,自动变成一个个 Java 对象。它是怎么知道数据库字段对应哪个 Java 属性的?还是靠反射。它通过反射获取 Java 类的属性列表,然后把查询结果按名字或配置对应起来,再用反射调用 setter 或直接修改字段值。反过来,保存对象到数据库时,也是用反射读取属性值来拼 SQL。 \ No newline at end of file diff --git a/docs/snippets/article-footer.snippet.md b/docs/snippets/article-footer.snippet.md new file mode 100644 index 0000000..72e3fad --- /dev/null +++ b/docs/snippets/article-footer.snippet.md @@ -0,0 +1,9 @@ +## 写在最后 + +感谢你能看到这里,也希望这篇文章对你有点用。 + +JavaGuide 坚持更新 6 年多,近 6000 次提交、600+ 位贡献者一起打磨。如果这些内容对你有帮助,非常欢迎点个免费的 Star 支持下(完全自愿,觉得有收获再点就好):[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 + +如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的[知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心! + +JavaGuide 公众号 \ No newline at end of file diff --git a/docs/snippets/article-header.snippet.md b/docs/snippets/article-header.snippet.md new file mode 100644 index 0000000..192f235 --- /dev/null +++ b/docs/snippets/article-header.snippet.md @@ -0,0 +1,19 @@ +[![《SpringAI 智能面试平台+RAG 知识库》](https://oss.javaguide.cn/xingqiu/interview-guide-banner.png)](https://javaguide.cn/zhuanlan/interview-guide.html) + +## 前言 + +这是 **JavaGuide 面试突击版本**,只保留最常问的面试题,并对重点内容进行了 ⭐️ 标注。提供亮色和暗色两个主题,需要打印的朋友请选择亮色版本。 + +时间充裕的朋友,推荐使用 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面深入。 + +如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的[知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心! + +面试突击最新版可在公众号回复「**PDF**」获取(知识星球会提前同步最新版)。 + +![JavaGuide 公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghao-javaguide.png) + +::: tip 重要说明 + +本站所有面试题保持**年度系统性优化完善**,严格同步 Java 技术生态与招聘市场的最新动态,**确保内容时效性与前瞻性**。 + +::: diff --git a/docs/snippets/small-advertisement.snippet.md b/docs/snippets/small-advertisement.snippet.md new file mode 100644 index 0000000..cf5f285 --- /dev/null +++ b/docs/snippets/small-advertisement.snippet.md @@ -0,0 +1,19 @@ +[![JavaGuide官方知识星球](https://oss.javaguide.cn/xingqiu/xingqiu.png)](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html) + +## 前言 + +这是 **JavaGuide 面试突击版本**,只保留最常问的面试题,并对重点内容进行了 ⭐️ 标注。提供亮色和暗色两个主题,需要打印的朋友请选择亮色版本。 + +时间充裕的朋友,推荐使用 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面深入。 + +如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的[知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心! + +面试突击最新版可在公众号回复「**PDF**」获取(知识星球会提前同步最新版)。 + +![JavaGuide 公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghao-javaguide.png) + +::: tip 重要说明 + +本站所有面试题保持**年度系统性优化完善**,严格同步 Java 技术生态与招聘市场的最新动态,**确保内容时效性与前瞻性**。 + +::: diff --git a/docs/system-design/design-pattern.md b/docs/system-design/design-pattern.md index 6d38bde..b63b3d8 100644 --- a/docs/system-design/design-pattern.md +++ b/docs/system-design/design-pattern.md @@ -1,38 +1,16 @@ --- title: 设计模式常见面试题总结 +description: 23种设计模式高频面试题精讲:涵盖创建型、结构型、行为型三大类设计模式详解,包含单例模式、工厂模式、观察者模式、策略模式等经典案例与UML类图,系统设计必备知识点速记。 category: 系统设计 tag: - 设计模式 head: - - meta - name: keywords - content: 设计模式面试题,创建型模式,结构型模式,行为型模式,单例模式,工厂模式,观察者模式,策略模式,23种设计模式,UML类图,系统设计 - - - meta - - name: description - content: 23种设计模式高频面试题精讲:创建/结构/行为型模式详解,含单例、工厂、观察者、策略等经典案例+UML类图,系统设计必备速记! + content: 设计模式面试题,23种设计模式,创建型模式,结构型模式,行为型模式,单例模式,工厂模式,抽象工厂,建造者模式,观察者模式,策略模式,代理模式,装饰器模式,UML类图 --- ------- - -![design-pattern](https://oss.javaguide.cn/github/javaguide-interview/cover/design-pattern.png) - ------- - -## 前言 - -由于很多读者都有突击面试的需求,所以我在几年前就弄了 **JavaGuide 面试突击版本**(JavaGuide 内容精简版,只保留重点),并持续完善跟进。对于喜欢纸质阅读的朋友来说,也可以打印出来,整体阅读体验非常高! - -除了只保留最常问的面试题之外,我还进一步对重点中的重点进行了**⭐️**标注。并且,有亮色(白天)和暗色(夜间)两个主题选择,需要打印出来的朋友记得选择亮色版本。 - -对于时间比较充裕的朋友,我个人还是更推荐 [JavaGuide](https://javaguide.cn/) 网站系统学习,内容更全面,更深入。 - -JavaGuide 已经持续维护 6 年多了,累计提交了接近 **6000** commit ,共有 **570+** 多位贡献者共同参与维护和完善。用心做原创优质内容,如果觉得有帮助的话,欢迎点赞分享!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。 - -对于需要更进一步面试辅导服务的读者,欢迎加入 **[JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)**(技术专栏/一对一提问/简历修改/求职指南/面试打卡),绝对物超所值! - -面试突击最新版本可以在我的公众号回复“**PDF**”获取([JavaGuide 官方知识星球](https://javaguide.cn/about-the-author/zhishixingqiu-two-years.html)会提前同步最新版,针对球友的一个小福利)。 - -![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png) + ## 软件设计原则有哪些? diff --git a/docs/system-design/spring.md b/docs/system-design/spring.md new file mode 100644 index 0000000..3fb05a5 --- /dev/null +++ b/docs/system-design/spring.md @@ -0,0 +1,1220 @@ +--- +title: Spring和Spring Boot常见面试题总结 +description: 系统梳理Spring和Spring Boot常见面试题与高频知识点,包括IoC与依赖注入原理、Bean的作用域与生命周期、AOP核心概念及通知类型、Spring MVC核心组件和请求处理流程、事务传播行为与隔离级别、循环依赖及三级缓存、@Transactional回滚规则、Spring Security权限控制与密码加密、Spring Boot自动配置和配置文件加载优先级等。 +category: 系统设计 +tag: + - 常见框架 +head: + - - meta + - name: keywords + content: Spring面试题,Spring Boot面试题,Spring IoC,依赖注入,Spring AOP,Spring MVC,Spring事务,事务传播行为,Spring循环依赖,三级缓存,Bean生命周期,Spring Security,自动配置 +--- + + + +这部分内容摘自 [JavaGuide](https://javaguide.cn/) 下面几篇文章中的重点: + +- [Spring 常见面试题总结](https://javaguide.cn/system-design/framework/spring/spring-knowledge-and-questions-summary.html)(Spring 基础、IoC、AOP、MVC、事务、循环依赖等) +- [SpringBoot 常见面试题总结](https://javaguide.cn/system-design/framework/spring/springboot-knowledge-and-questions-summary.html) +- [Spring&SpringBoot常用注解总结](https://javaguide.cn/system-design/framework/spring/spring-common-annotations.html) +- [IoC & AOP详解(快速搞懂)](https://javaguide.cn/system-design/framework/spring/ioc-and-aop.html) +- [Spring 事务详解](https://javaguide.cn/system-design/framework/spring/spring-transaction.html) +- [Spring 中的设计模式详解](https://javaguide.cn/system-design/framework/spring/spring-design-patterns-summary.html) +- [SpringBoot 自动装配原理详解](https://javaguide.cn/system-design/framework/spring/spring-boot-auto-assembly-principles.html) +- [Async 注解原理分析](https://javaguide.cn/system-design/framework/spring/async.html) + +## Spring IoC + +### ⭐️什么是 IoC? + +IoC (Inversion of Control )即控制反转/反转控制。它是一种思想不是一个技术实现。描述的是:Java 开发领域对象的创建以及管理的问题。 + +例如:现有类 A 依赖于类 B + +- **传统的开发方式** :往往是在类 A 中手动通过 new 关键字来 new 一个 B 的对象出来 +- **使用 IoC 思想的开发方式** :不通过 new 关键字来创建对象,而是通过 IoC 容器(Spring 框架) 来帮助我们实例化对象。我们需要哪个对象,直接从 IoC 容器里面去取即可。 + +从以上两种开发方式的对比来看:我们 “丧失了一个权力” (创建、管理对象的权力),从而也得到了一个好处(不用再考虑对象的创建、管理等一系列的事情) + +**为什么叫控制反转?** + +- **控制** :指的是对象创建(实例化、管理)的权力 +- **反转** :控制权交给外部环境(IoC 容器) + +![IoC 图解](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration.png) + +### ⭐️IoC 解决了什么问题? + +IoC 的思想就是两方之间不互相依赖,由第三方容器来管理相关资源。这样有什么好处呢? + +1. 对象之间的耦合度或者说依赖程度降低; +2. 资源变的容易管理;比如你用 Spring 容器提供的话很容易就可以实现一个单例。 + +例如:现有一个针对 User 的操作,利用 Service 和 Dao 两层结构进行开发 + +在没有使用 IoC 思想的情况下,Service 层想要使用 Dao 层的具体实现的话,需要通过 new 关键字在`UserServiceImpl` 中手动 new 出 `IUserDao` 的具体实现类 `UserDaoImpl`(不能直接 new 接口类)。 + +很完美,这种方式也是可以实现的,但是我们想象一下如下场景: + +开发过程中突然接到一个新的需求,针对`IUserDao` 接口开发出另一个具体实现类。因为 Server 层依赖了`IUserDao`的具体实现,所以我们需要修改`UserServiceImpl`中 new 的对象。如果只有一个类引用了`IUserDao`的具体实现,可能觉得还好,修改起来也不是很费力气,但是如果有许许多多的地方都引用了`IUserDao`的具体实现的话,一旦需要更换`IUserDao` 的实现方式,那修改起来将会非常的头疼。 + +![IoC&Aop-ioc-illustration-dao-service](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration-dao-service.png) + +使用 IoC 的思想,我们将对象的控制权(创建、管理)交由 IoC 容器去管理,我们在使用的时候直接向 IoC 容器 “要” 就可以了 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration-dao.png) + +### 什么是 Spring Bean? + +简单来说,Bean 代指的就是那些被 IoC 容器所管理的对象。 + +我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。 + +```xml + + + + +``` + +下图简单地展示了 IoC 容器如何使用配置元数据来管理对象。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/062b422bd7ac4d53afd28fb74b2bc94d.png) + +`org.springframework.beans`和 `org.springframework.context` 这两个包是 IoC 实现的基础,如果想要研究 IoC 相关的源码的话,可以去看看 + +### 将一个类声明为 Bean 的注解有哪些? + +- `@Component`:通用的注解,可标注任意类为 `Spring` 组件。如果一个 Bean 不知道属于哪个层,可以使用`@Component` 注解标注。 +- `@Repository` : 对应持久层即 Dao 层,主要用于数据库相关操作。 +- `@Service` : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。 +- `@Controller` : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 `Service` 层返回数据给前端页面。 + +### @Component 和 @Bean 的区别是什么? + +- `@Component` 注解作用于类,而`@Bean`注解作用于方法。 +- `@Component`通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 `@ComponentScan` 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。`@Bean` 注解通常是我们在标有该注解的方法中定义产生这个 bean,`@Bean`告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我。 +- `@Bean` 注解比 `@Component` 注解的自定义性更强,而且很多地方我们只能通过 `@Bean` 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 `Spring`容器时,则只能通过 `@Bean`来实现。 + +`@Bean`注解使用示例: + +```java +@Configuration +public class AppConfig { + @Bean + public TransferService transferService() { + return new TransferServiceImpl(); + } + +} +``` + +上面的代码相当于下面的 xml 配置 + +```xml + + + +``` + +下面这个例子是通过 `@Component` 无法实现的。 + +```java +@Bean +public OneService getService(status) { + case (status) { + when 1: + return new serviceImpl1(); + when 2: + return new serviceImpl2(); + when 3: + return new serviceImpl3(); + } +} +``` + +### 注入 Bean 的注解有哪些? + +Spring 内置的 `@Autowired` 以及 JDK 内置的 `@Resource` 和 `@Inject` 都可以用于注入 Bean。 + +| Annotation | Package | Source | +| ------------ | ---------------------------------- | ------------ | +| `@Autowired` | `org.springframework.bean.factory` | Spring 2.5+ | +| `@Resource` | `javax.annotation` | Java JSR-250 | +| `@Inject` | `javax.inject` | Java JSR-330 | + +`@Autowired` 和`@Resource`使用的比较多一些。 + +### ⭐️@Autowired 和 @Resource 的区别是什么? + +`@Autowired` 是 Spring 内置的注解,默认注入逻辑为**先按类型(byType)匹配,若存在多个同类型 Bean,则再尝试按名称(byName)筛选**。 + +具体来说: + +1. 优先根据接口 / 类的类型在 Spring 容器中查找匹配的 Bean。若只找到一个符合类型的 Bean,直接注入,无需考虑名称; +2. 若找到多个同类型的 Bean(例如一个接口有多个实现类),则会尝试通过**属性名或参数名**与 Bean 的名称进行匹配(默认 Bean 名称为类名首字母小写,除非通过 `@Bean(name = "...")` 或 `@Component("...")` 显式指定)。 + +当一个接口存在多个实现类时: + +- 若属性名与某个 Bean 的名称一致,则注入该 Bean; +- 若属性名与所有 Bean 名称都不匹配,会抛出 `NoUniqueBeanDefinitionException`,此时需要通过 `@Qualifier` 显式指定要注入的 Bean 名称。 + +举例说明: + +```java +// SmsService 接口有两个实现类:SmsServiceImpl1、SmsServiceImpl2(均被 Spring 管理) + +// 报错:byType 匹配到多个 Bean,且属性名 "smsService" 与两个实现类的默认名称(smsServiceImpl1、smsServiceImpl2)都不匹配 +@Autowired +private SmsService smsService; + +// 正确:属性名 "smsServiceImpl1" 与实现类 SmsServiceImpl1 的默认名称匹配 +@Autowired +private SmsService smsServiceImpl1; + +// 正确:通过 @Qualifier 显式指定 Bean 名称 "smsServiceImpl1" +@Autowired +@Qualifier(value = "smsServiceImpl1") +private SmsService smsService; +``` + +实际开发实践中,我们还是建议通过 `@Qualifier` 注解来显式指定名称而不是依赖变量的名称。 + +`@Resource`属于 JDK 提供的注解,默认注入逻辑为**先按名称(byName)匹配,若存在多个同类型 Bean,则再尝试按类型(byType)筛选**。 + +`@Resource` 有两个比较重要且日常开发常用的属性:`name`(名称)、`type`(类型)。 + +```java +public @interface Resource { + String name() default ""; + Class type() default Object.class; +} +``` + +如果仅指定 `name` 属性则注入方式为`byName`,如果仅指定`type`属性则注入方式为`byType`,如果同时指定`name` 和`type`属性(不建议这么做)则注入方式为`byType`+`byName`。 + +```java +// 报错,byName 和 byType 都无法匹配到 bean +@Resource +private SmsService smsService; +// 正确注入 SmsServiceImpl1 对象对应的 bean +@Resource +private SmsService smsServiceImpl1; +// 正确注入 SmsServiceImpl1 对象对应的 bean(比较推荐这种方式) +@Resource(name = "smsServiceImpl1") +private SmsService smsService; +``` + +**简单总结一下**: + +- `@Autowired` 是 Spring 提供的注解,`@Resource` 是 JDK 提供的注解。 +- `Autowired` 默认的注入方式为`byType`(根据类型进行匹配),`@Resource`默认注入方式为 `byName`(根据名称进行匹配)。 +- 当一个接口存在多个实现类的情况下,`@Autowired` 和`@Resource`都需要通过名称才能正确匹配到对应的 Bean。`Autowired` 可以通过 `@Qualifier` 注解来显式指定名称,`@Resource`可以通过 `name` 属性来显式指定名称。 +- `@Autowired` 支持在构造函数、方法、字段和参数上使用。`@Resource` 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。 + +考虑到 `@Resource` 的语义更清晰(名称优先),并且是 Java 标准,能减少对 Spring 框架的强耦合,我们通常**更推荐使用 `@Resource`**,尤其是在需要按名称注入的场景下。而 `@Autowired` 配合构造器注入,在实现依赖注入的不可变性和强制性方面有优势,也是一种非常好的实践。 + +### 注入 Bean 的方式有哪些? + +依赖注入 (Dependency Injection, DI) 的常见方式: + +1. 构造函数注入:通过类的构造函数来注入依赖项。 +1. Setter 注入:通过类的 Setter 方法来注入依赖项。 +1. Field(字段) 注入:直接在类的字段上使用注解(如 `@Autowired` 或 `@Resource`)来注入依赖项。 + +构造函数注入示例: + +```java +@Service +public class UserService { + + private final UserRepository userRepository; + + public UserService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + //... +} +``` + +Setter 注入示例: + +```java +@Service +public class UserService { + + private UserRepository userRepository; + + // 在 Spring 4.3 及以后的版本,特定情况下 @Autowired 可以省略不写 + @Autowired + public void setUserRepository(UserRepository userRepository) { + this.userRepository = userRepository; + } + + //... +} +``` + +Field 注入示例: + +```java +@Service +public class UserService { + + @Autowired + private UserRepository userRepository; + + //... +} +``` + +### ⭐️构造函数注入还是 Setter 注入? + +Spring 官方有对这个问题的回答:。 + +我这里主要提取总结完善一下 Spring 官方的建议。 + +**Spring 官方推荐构造函数注入**,这种注入方式的优势如下: + +1. 依赖完整性:确保所有必需依赖在对象创建时就被注入,避免了空指针异常的风险。 +2. 不可变性:有助于创建不可变对象,提高了线程安全性。 +3. 初始化保证:组件在使用前已完全初始化,减少了潜在的错误。 +4. 测试便利性:在单元测试中,可以直接通过构造函数传入模拟的依赖项,而不必依赖 Spring 容器进行注入。 + +构造函数注入适合处理**必需的依赖项**,而 **Setter 注入** 则更适合**可选的依赖项**,这些依赖项可以有默认值或在对象生命周期中动态设置。虽然 `@Autowired` 可以用于 Setter 方法来处理必需的依赖项,但构造函数注入仍然是更好的选择。 + +在某些情况下(例如第三方类不提供 Setter 方法),构造函数注入可能是**唯一的选择**。 + +### ⭐️Bean 的作用域有哪些? + +Spring 中 Bean 的作用域通常有下面几种: + +- **singleton** : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。 +- **prototype** : 每次获取都会创建一个新的 bean 实例。也就是说,连续 `getBean()` 两次,得到的是不同的 Bean 实例。 +- **request** (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。 +- **session** (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。 +- **application/global-session** (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。 +- **websocket** (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。 + +**如何配置 bean 的作用域呢?** + +xml 方式: + +```xml + +``` + +注解方式: + +```java +@Bean +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public Person personPrototype() { + return new Person(); +} +``` + +### ⭐️Bean 是线程安全的吗? + +Spring 框架中的 Bean 是否线程安全,取决于其作用域和状态。 + +我们这里以最常用的两种作用域 prototype 和 singleton 为例介绍。几乎所有场景的 Bean 作用域都是使用默认的 singleton ,重点关注 singleton 作用域即可。 + +prototype 作用域下,每次获取都会创建一个新的 bean 实例,不存在资源竞争问题,所以不存在线程安全问题。singleton 作用域下,IoC 容器中只有唯一的 bean 实例,可能会存在资源竞争问题(取决于 Bean 是否有状态)。如果这个 bean 是有状态的话,那就存在线程安全问题(有状态 Bean 是指包含可变的成员变量的对象)。 + +有状态 Bean 示例: + +```java +// 定义了一个购物车类,其中包含一个保存用户的购物车里商品的 List +@Component +public class ShoppingCart { + private List items = new ArrayList<>(); + + public void addItem(String item) { + items.add(item); + } + + public List getItems() { + return items; + } +} +``` + +不过,大部分 Bean 实际都是无状态(没有定义可变的成员变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。 + +无状态 Bean 示例: + +```java +// 定义了一个用户服务,它仅包含业务逻辑而不保存任何状态。 +@Component +public class UserService { + + public User findUserById(Long id) { + //... + } + //... +} +``` + +对于有状态单例 Bean 的线程安全问题,常见的三种解决办法是: + +1. **避免可变成员变量**: 尽量设计 Bean 为无状态。 +2. **使用`ThreadLocal`**: 将可变成员变量保存在 `ThreadLocal` 中,确保线程独立。 +3. **使用同步机制**: 利用 `synchronized` 或 `ReentrantLock` 来进行同步控制,确保线程安全。 + +这里以 `ThreadLocal`为例,演示一下`ThreadLocal` 保存用户登录信息的场景: + +```java +public class UserThreadLocal { + + private UserThreadLocal() {} + + private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> null); + + public static void put(SysUser sysUser) { + LOCAL.set(sysUser); + } + + public static SysUser get() { + return LOCAL.get(); + } + + public static void remove() { + LOCAL.remove(); + } +} +``` + +### ⭐️Bean 的生命周期了解么? + +1. **创建 Bean 的实例**:Bean 容器首先会找到配置文件中的 Bean 定义,然后使用 Java 反射 API 来创建 Bean 的实例。 +2. **Bean 属性赋值/填充**:为 Bean 设置相关属性和依赖,例如`@Autowired` 等注解注入的对象、`@Value` 注入的值、`setter`方法或构造函数注入依赖和值、`@Resource`注入的各种资源。 +3. **Bean 初始化**: + - 如果 Bean 实现了 `BeanNameAware` 接口,调用 `setBeanName()`方法,传入 Bean 的名字。 + - 如果 Bean 实现了 `BeanClassLoaderAware` 接口,调用 `setBeanClassLoader()`方法,传入 `ClassLoader`对象的实例。 + - 如果 Bean 实现了 `BeanFactoryAware` 接口,调用 `setBeanFactory()`方法,传入 `BeanFactory`对象的实例。 + - 与上面的类似,如果实现了其他 `*.Aware`接口,就调用相应的方法。 + - 如果有和加载这个 Bean 的 Spring 容器相关的 `BeanPostProcessor` 对象,执行`postProcessBeforeInitialization()` 方法 + - 如果 Bean 实现了`InitializingBean`接口,执行`afterPropertiesSet()`方法。 + - 如果 Bean 在配置文件中的定义包含 `init-method` 属性,执行指定的方法。 + - 如果有和加载这个 Bean 的 Spring 容器相关的 `BeanPostProcessor` 对象,执行`postProcessAfterInitialization()` 方法。 +4. **销毁 Bean**:销毁并不是说要立马把 Bean 给销毁掉,而是把 Bean 的销毁方法先记录下来,将来需要销毁 Bean 或者销毁容器的时候,就调用这些方法去释放 Bean 所持有的资源。 + - 如果 Bean 实现了 `DisposableBean` 接口,执行 `destroy()` 方法。 + - 如果 Bean 在配置文件中的定义包含 `destroy-method` 属性,执行指定的 Bean 销毁方法。或者,也可以直接通过`@PreDestroy` 注解标记 Bean 销毁之前执行的方法。 + +`AbstractAutowireCapableBeanFactory` 的 `doCreateBean()` 方法中能看到依次执行了这 4 个阶段: + +```java +protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) + throws BeanCreationException { + + // 1. 创建 Bean 的实例 + BeanWrapper instanceWrapper = null; + if (instanceWrapper == null) { + instanceWrapper = createBeanInstance(beanName, mbd, args); + } + + Object exposedObject = bean; + try { + // 2. Bean 属性赋值/填充 + populateBean(beanName, mbd, instanceWrapper); + // 3. Bean 初始化 + exposedObject = initializeBean(beanName, exposedObject, mbd); + } + + // 4. 销毁 Bean-注册回调接口 + try { + registerDisposableBeanIfNecessary(beanName, bean, mbd); + } + + return exposedObject; +} +``` + +`Aware` 接口能让 Bean 能拿到 Spring 容器资源。 + +Spring 中提供的 `Aware` 接口主要有: + +1. `BeanNameAware`:注入当前 bean 对应 beanName; +2. `BeanClassLoaderAware`:注入加载当前 bean 的 ClassLoader; +3. `BeanFactoryAware`:注入当前 `BeanFactory` 容器的引用。 + +`BeanPostProcessor` 接口是 Spring 为修改 Bean 提供的强大扩展点。 + +```java +public interface BeanPostProcessor { + + // 初始化前置处理 + default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + // 初始化后置处理 + default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + +} +``` + +- `postProcessBeforeInitialization`:Bean 实例化、属性注入完成后,`InitializingBean#afterPropertiesSet`方法以及自定义的 `init-method` 方法之前执行; +- `postProcessAfterInitialization`:类似于上面,不过是在 `InitializingBean#afterPropertiesSet`方法以及自定义的 `init-method` 方法之后执行。 + +`InitializingBean` 和 `init-method` 是 Spring 为 Bean 初始化提供的扩展点。 + +```java +public interface InitializingBean { + // 初始化逻辑 + void afterPropertiesSet() throws Exception; +} +``` + +指定 `init-method` 方法,指定初始化方法: + +```xml + + + + + + +``` + +**如何记忆呢?** + +1. 整体上可以简单分为四步:实例化 —> 属性赋值 —> 初始化 —> 销毁。 +2. 初始化这一步涉及到的步骤比较多,包含 `Aware` 接口的依赖注入、`BeanPostProcessor` 在初始化前后的处理以及 `InitializingBean` 和 `init-method` 的初始化操作。 +3. 销毁这一步会注册相关销毁回调接口,最后通过`DisposableBean` 和 `destory-method` 进行销毁。 + +最后,再分享一张清晰的图解(图源:[如何记忆 Spring Bean 的生命周期](https://chaycao.github.io/2020/02/15/如何记忆Spring-Bean的生命周期.html))。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/spring-bean-lifestyle.png) + +## Spring AOP + +### ⭐️谈谈自己对于 AOP 的了解 + +AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。 + +Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 **JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示: + +![SpringAOPProcess](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/230ae587a322d6e4d09510161987d346.jpeg) + +当然你也可以使用 **AspectJ** !Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。 + +AOP 切面编程涉及到的一些专业术语: + +| 术语 | 含义 | +| :---------------- | :----------------------------------------------------------: | +| 目标(Target) | 被通知的对象 | +| 代理(Proxy) | 向目标对象应用通知之后创建的代理对象 | +| 连接点(JoinPoint) | 目标对象的所属类中,定义的所有方法均为连接点 | +| 切入点(Pointcut) | 被切面拦截 / 增强的连接点(切入点一定是连接点,连接点不一定是切入点) | +| 通知(Advice) | 增强的逻辑 / 代码,也即拦截到目标对象的连接点之后要做的事情 | +| 切面(Aspect) | 切入点(Pointcut)+通知(Advice) | +| Weaving(织入) | 将通知应用到目标对象,进而生成代理对象的过程动作 | + +### ⭐️Spring AOP 和 AspectJ AOP 有什么区别? + +| 特性 | Spring AOP | AspectJ | +| -------------- | -------------------------------------------------------- | ------------------------------------------ | +| **增强方式** | 运行时增强(基于动态代理) | 编译时增强、类加载时增强(直接操作字节码) | +| **切入点支持** | 方法级(Spring Bean 范围内,不支持 final 和 staic 方法) | 方法级、字段、构造器、静态方法等 | +| **性能** | 运行时依赖代理,有一定开销,切面多时性能较低 | 运行时无代理开销,性能更高 | +| **复杂性** | 简单,易用,适合大多数场景 | 功能强大,但相对复杂 | +| **使用场景** | Spring 应用下比较简单的 AOP 需求 | 高性能、高复杂度的 AOP 需求 | + +**如何选择?** + +- **功能考量**:AspectJ 支持更复杂的 AOP 场景,Spring AOP 更简单易用。如果你需要增强 `final` 方法、静态方法、字段访问、构造器调用等,或者需要在非 Spring 管理的对象上应用增强逻辑,AspectJ 是唯一的选择。 +- **性能考量**:切面数量较少时两者性能差异不大,但切面较多时 AspectJ 性能更优。 + +**一句话总结**:简单场景优先使用 Spring AOP;复杂场景或高性能需求时,选择 AspectJ。 + +### ⭐️AOP 常见的通知类型有哪些? + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/aspectj-advice-types.jpg) + +- **Before**(前置通知):目标对象的方法调用之前触发 +- **After** (后置通知):目标对象的方法调用之后触发 +- **AfterReturning**(返回通知):目标对象的方法调用完成,在返回结果值之后触发 +- **AfterThrowing**(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。 +- **Around** (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法 + +### 多个切面的执行顺序如何控制? + +1、通常使用`@Order` 注解直接定义切面顺序 + +```java +// 值越小优先级越高 +@Order(3) +@Component +@Aspect +public class LoggingAspect implements Ordered { +``` + +**2、实现`Ordered` 接口重写 `getOrder` 方法。** + +```java +@Component +@Aspect +public class LoggingAspect implements Ordered { + + // .... + + @Override + public int getOrder() { + // 返回值越小优先级越高 + return 1; + } +} +``` + +## Spring MVC + +### 说说自己对于 Spring MVC 了解? + +MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。 + +![](https://oss.javaguide.cn/java-guide-blog/image-20210809181452421.png) + +网上有很多人说 MVC 不是设计模式,只是软件设计规范,我个人更倾向于 MVC 同样是众多设计模式中的一种。**[java-design-patterns](https://github.com/iluwatar/java-design-patterns)** 项目中就有关于 MVC 的相关介绍。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/159b3d3e70dd45e6afa81bf06d09264e.png) + +想要真正理解 Spring MVC,我们先来看看 Model 1 和 Model 2 这两个没有 Spring MVC 的时代。 + +**Model 1 时代** + +很多学 Java 后端比较晚的朋友可能并没有接触过 Model 1 时代下的 JavaWeb 应用开发。在 Model1 模式下,整个 Web 应用几乎全部用 JSP 页面组成,只用少量的 JavaBean 来处理数据库连接、访问等操作。 + +这个模式下 JSP 即是控制层(Controller)又是表现层(View)。显而易见,这种模式存在很多问题。比如控制逻辑和表现逻辑混杂在一起,导致代码重用率极低;再比如前端和后端相互依赖,难以进行测试维护并且开发效率极低。 + +![mvc-mode1](https://oss.javaguide.cn/java-guide-blog/mvc-mode1.png) + +**Model 2 时代** + +学过 Servlet 并做过相关 Demo 的朋友应该了解“Java Bean(Model)+ JSP(View)+Servlet(Controller) ”这种开发模式,这就是早期的 JavaWeb MVC 开发模式。 + +- Model:系统涉及的数据,也就是 dao 和 bean。 +- View:展示模型中的数据,只是用来展示。 +- Controller:接受用户请求,并将请求发送至 Model,最后返回数据给 JSP 并展示给用户 + +![](https://oss.javaguide.cn/java-guide-blog/mvc-model2.png) + +Model2 模式下还存在很多问题,Model2 的抽象和封装程度还远远不够,使用 Model2 进行开发时不可避免地会重复造轮子,这就大大降低了程序的可维护性和复用性。 + +于是,很多 JavaWeb 开发相关的 MVC 框架应运而生比如 Struts2,但是 Struts2 比较笨重。 + +**Spring MVC 时代** + +随着 Spring 轻量级开发框架的流行,Spring 生态圈出现了 Spring MVC 框架, Spring MVC 是当前最优秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加简单和方便,开发效率更高,并且 Spring MVC 运行速度更快。 + +MVC 是一种设计模式,Spring MVC 是一款很优秀的 MVC 框架。Spring MVC 可以帮助我们进行更简洁的 Web 层的开发,并且它天生与 Spring 框架集成。Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。 + +### Spring MVC 的核心组件有哪些? + +记住了下面这些组件,也就记住了 SpringMVC 的工作原理。 + +- **`DispatcherServlet`**:**核心的中央处理器**,负责接收请求、分发,并给予客户端响应。 +- **`HandlerMapping`**:**处理器映射器**,根据 URL 去匹配查找能处理的 `Handler` ,并会将请求涉及到的拦截器和 `Handler` 一起封装。 +- **`HandlerAdapter`**:**处理器适配器**,根据 `HandlerMapping` 找到的 `Handler` ,适配执行对应的 `Handler`; +- **`Handler`**:**请求处理器**,处理实际请求的处理器。 +- **`ViewResolver`**:**视图解析器**,根据 `Handler` 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 `DispatcherServlet` 响应客户端 + +### ⭐️SpringMVC 工作原理了解吗? + +**Spring MVC 原理如下图所示:** + +> SpringMVC 工作原理的图解我没有自己画,直接图省事在网上找了一个非常清晰直观的,原出处不明。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/de6d2b213f112297298f3e223bf08f28.png) + +**流程说明(重要):** + +1. 客户端(浏览器)发送请求, `DispatcherServlet`拦截请求。 +2. `DispatcherServlet` 根据请求信息调用 `HandlerMapping` 。`HandlerMapping` 根据 URL 去匹配查找能处理的 `Handler`(也就是我们平常说的 `Controller` 控制器) ,并会将请求涉及到的拦截器和 `Handler` 一起封装。 +3. `DispatcherServlet` 调用 `HandlerAdapter`适配器执行 `Handler` 。 +4. `Handler` 完成对用户请求的处理后,会返回一个 `ModelAndView` 对象给`DispatcherServlet`,`ModelAndView` 顾名思义,包含了数据模型以及相应的视图的信息。`Model` 是返回的数据对象,`View` 是个逻辑上的 `View`。 +5. `ViewResolver` 会根据逻辑 `View` 查找实际的 `View`。 +6. `DispaterServlet` 把返回的 `Model` 传给 `View`(视图渲染)。 +7. 把 `View` 返回给请求者(浏览器) + +上述流程是传统开发模式(JSP,Thymeleaf 等)的工作原理。然而现在主流的开发方式是前后端分离,这种情况下 Spring MVC 的 `View` 概念发生了一些变化。由于 `View` 通常由前端框架(Vue, React 等)来处理,后端不再负责渲染页面,而是只负责提供数据,因此: + +- 前后端分离时,后端通常不再返回具体的视图,而是返回**纯数据**(通常是 JSON 格式),由前端负责渲染和展示。 +- `View` 的部分在前后端分离的场景下往往不需要设置,Spring MVC 的控制器方法只需要返回数据,不再返回 `ModelAndView`,而是直接返回数据,Spring 会自动将其转换为 JSON 格式。相应的,`ViewResolver` 也将不再被使用。 + +怎么做到呢? + +- 使用 `@RestController` 注解代替传统的 `@Controller` 注解,这样所有方法默认会返回 JSON 格式的数据,而不是试图解析视图。 +- 如果你使用的是 `@Controller`,可以结合 `@ResponseBody` 注解来返回 JSON。 + +### 统一异常处理怎么做? + +推荐使用注解的方式统一异常处理,具体会使用到 `@ControllerAdvice` + `@ExceptionHandler` 这两个注解 。 + +```java +@ControllerAdvice +@ResponseBody +public class GlobalExceptionHandler { + + @ExceptionHandler(BaseException.class) + public ResponseEntity handleAppException(BaseException ex, HttpServletRequest request) { + //...... + } + + @ExceptionHandler(value = ResourceNotFoundException.class) + public ResponseEntity handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) { + //...... + } +} +``` + +这种异常处理方式下,会给所有或者指定的 `Controller` 织入异常处理的逻辑(AOP),当 `Controller` 中的方法抛出异常的时候,由被`@ExceptionHandler` 注解修饰的方法进行处理。 + +`ExceptionHandlerMethodResolver` 中 `getMappedMethod` 方法决定了异常具体被哪个被 `@ExceptionHandler` 注解修饰的方法处理异常。 + +```java +@Nullable + private Method getMappedMethod(Class exceptionType) { + List> matches = new ArrayList<>(); + //找到可以处理的所有异常信息。mappedMethods 中存放了异常和处理异常的方法的对应关系 + for (Class mappedException : this.mappedMethods.keySet()) { + if (mappedException.isAssignableFrom(exceptionType)) { + matches.add(mappedException); + } + } + // 不为空说明有方法处理异常 + if (!matches.isEmpty()) { + // 按照匹配程度从小到大排序 + matches.sort(new ExceptionDepthComparator(exceptionType)); + // 返回处理异常的方法 + return this.mappedMethods.get(matches.get(0)); + } + else { + return null; + } + } +``` + +从源代码看出:**`getMappedMethod()`会首先找到可以匹配处理异常的所有方法信息,然后对其进行从小到大的排序,最后取最小的那一个匹配的方法(即匹配度最高的那个)。** + +## Spring 框架中用到了哪些设计模式? + +> 关于下面这些设计模式的详细介绍,可以看我写的 [Spring 中的设计模式详解](https://javaguide.cn/system-design/framework/spring/spring-design-patterns-summary.html) 这篇文章。 + +- **工厂设计模式** : Spring 使用工厂模式通过 `BeanFactory`、`ApplicationContext` 创建 bean 对象。 +- **代理设计模式** : Spring AOP 功能的实现。 +- **单例设计模式** : Spring 中的 Bean 默认都是单例的。 +- **模板方法模式** : Spring 中 `jdbcTemplate`、`hibernateTemplate` 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 +- **包装器设计模式** : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 +- **观察者模式:** Spring 事件驱动模型就是观察者模式很经典的一个应用。 +- **适配器模式** : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配`Controller`。 +- …… + +## ⭐️Spring 的循环依赖 + +### Spring 循环依赖了解吗,怎么解决? + +循环依赖是指 Bean 对象循环引用,是两个或多个 Bean 之间相互持有对方的引用,例如 CircularDependencyA → CircularDependencyB → CircularDependencyA。 + +```java +@Component +public class CircularDependencyA { + @Autowired + private CircularDependencyB circB; +} + +@Component +public class CircularDependencyB { + @Autowired + private CircularDependencyA circA; +} +``` + +单个对象的自我依赖也会出现循环依赖,但这种概率极低,属于是代码编写错误。 + +```java +@Component +public class CircularDependencyA { + @Autowired + private CircularDependencyA circA; +} +``` + +Spring 框架通过使用三级缓存来解决这个问题,确保即使在循环依赖的情况下也能正确创建 Bean。 + +Spring 中的三级缓存其实就是三个 Map,如下: + +```java +// 一级缓存 +/** Cache of singleton objects: bean name to bean instance. */ +private final Map singletonObjects = new ConcurrentHashMap<>(256); + +// 二级缓存 +/** Cache of early singleton objects: bean name to bean instance. */ +private final Map earlySingletonObjects = new HashMap<>(16); + +// 三级缓存 +/** Cache of singleton factories: bean name to ObjectFactory. */ +private final Map> singletonFactories = new HashMap<>(16); +``` + +简单来说,Spring 的三级缓存包括: + +1. **一级缓存(singletonObjects)**:存放最终形态的 Bean(已经实例化、属性填充、初始化),单例池,为“Spring 的单例属性”⽽⽣。一般情况我们获取 Bean 都是从这里获取的,但是并不是所有的 Bean 都在单例池里面,例如原型 Bean 就不在里面。 +2. **二级缓存(earlySingletonObjects)**:存放过渡 Bean(半成品,尚未属性填充),也就是三级缓存中`ObjectFactory`产生的对象,与三级缓存配合使用的,可以防止 AOP 的情况下,每次调用`ObjectFactory#getObject()`都是会产生新的代理对象的。 +3. **三级缓存(singletonFactories)**:存放`ObjectFactory`,`ObjectFactory`的`getObject()`方法(最终调用的是`getEarlyBeanReference()`方法)可以生成原始 Bean 对象或者代理对象(如果 Bean 被 AOP 切面代理)。三级缓存只会对单例 Bean 生效。 + +接下来说一下 Spring 创建 Bean 的流程: + +1. 先去 **一级缓存 `singletonObjects`** 中获取,存在就返回; +2. 如果不存在或者对象正在创建中,于是去 **二级缓存 `earlySingletonObjects`** 中获取; +3. 如果还没有获取到,就去 **三级缓存 `singletonFactories`** 中获取,通过执行 `ObjectFacotry` 的 `getObject()` 就可以获取该对象,获取成功之后,从三级缓存移除,并将该对象加入到二级缓存中。 + +在三级缓存中存储的是 `ObjectFacoty` : + +```java +public interface ObjectFactory { + T getObject() throws BeansException; +} +``` + +Spring 在创建 Bean 的时候,如果允许循环依赖的话,Spring 就会将刚刚实例化完成,但是属性还没有初始化完的 Bean 对象给提前暴露出去,这里通过 `addSingletonFactory` 方法,向三级缓存中添加一个 `ObjectFactory` 对象: + +```java +// AbstractAutowireCapableBeanFactory # doCreateBean # +public abstract class AbstractAutowireCapableBeanFactory ... { + protected Object doCreateBean(...) { + //... + + // 支撑循环依赖:将 ()->getEarlyBeanReference 作为一个 ObjectFactory 对象的 getObject() 方法加入到三级缓存中 + addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); + } +} +``` + +那么上边在说 Spring 创建 Bean 的流程时说了,如果一级缓存、二级缓存都取不到对象时,会去三级缓存中通过 `ObjectFactory` 的 `getObject` 方法获取对象。 + +```java +class A { + // 使用了 B + private B b; +} +class B { + // 使用了 A + private A a; +} +``` + +以上面的循环依赖代码为例,整个解决循环依赖的流程如下: + +- 当 Spring 创建 A 之后,发现 A 依赖了 B ,又去创建 B,B 依赖了 A ,又去创建 A; +- 在 B 创建 A 的时候,那么此时 A 就发生了循环依赖,由于 A 此时还没有初始化完成,因此在 **一二级缓存** 中肯定没有 A; +- 那么此时就去三级缓存中调用 `getObject()` 方法去获取 A 的 **前期暴露的对象** ,也就是调用上边加入的 `getEarlyBeanReference()` 方法,生成一个 A 的 **前期暴露对象**; +- 然后就将这个 `ObjectFactory` 从三级缓存中移除,并且将前期暴露对象放入到二级缓存中,那么 B 就将这个前期暴露对象注入到依赖,来支持循环依赖。 + +**只用两级缓存够吗?** 在没有 AOP 的情况下,确实可以只使用一级和二级缓存来解决循环依赖问题。但是,当涉及到 AOP 时,三级缓存就显得非常重要了,因为它确保了即使在 Bean 的创建过程中有多次对早期引用的请求,也始终只返回同一个代理对象,从而避免了同一个 Bean 有多个代理对象的问题。 + +**最后总结一下 Spring 如何解决三级缓存**: + +在三级缓存这一块,主要记一下 Spring 是如何支持循环依赖的即可,也就是如果发生循环依赖的话,就去 **三级缓存 `singletonFactories`** 中拿到三级缓存中存储的 `ObjectFactory` 并调用它的 `getObject()` 方法来获取这个循环依赖对象的前期暴露对象(虽然还没初始化完成,但是可以拿到该对象在堆中的存储地址了),并且将这个前期暴露对象放到二级缓存中,这样在循环依赖时,就不会重复初始化了! + +不过,这种机制也有一些缺点,比如增加了内存开销(需要维护三级缓存,也就是三个 Map),降低了性能(需要进行多次检查和转换)。并且,还有少部分情况是不支持循环依赖的,比如非单例的 bean 和`@Async`注解的 bean 无法支持循环依赖。 + +### @Lazy 能解决循环依赖吗? + +`@Lazy` 用来标识类是否需要懒加载/延迟加载,可以作用在类上、方法上、构造器上、方法参数上、成员变量中。 + +Spring Boot 2.2 新增了**全局懒加载属性**,开启后全局 bean 被设置为懒加载,需要时再去创建。 + +配置文件配置全局懒加载: + +```properties +#默认false +spring.main.lazy-initialization=true +``` + +编码的方式设置全局懒加载: + +```java +SpringApplication springApplication=new SpringApplication(Start.class); +springApplication.setLazyInitialization(false); +springApplication.run(args); +``` + +如非必要,尽量不要用全局懒加载。全局懒加载会让 Bean 第一次使用的时候加载会变慢,并且它会延迟应用程序问题的发现(当 Bean 被初始化时,问题才会出现)。 + +如果一个 Bean 没有被标记为懒加载,那么它会在 Spring IoC 容器启动的过程中被创建和初始化。如果一个 Bean 被标记为懒加载,那么它不会在 Spring IoC 容器启动时立即实例化,而是在第一次被请求时才创建。这可以帮助减少应用启动时的初始化时间,也可以用来解决循环依赖问题。 + +循环依赖问题是如何通过`@Lazy` 解决的呢?这里举一个例子,比如说有两个 Bean,A 和 B,他们之间发生了循环依赖,那么 A 的构造器上添加 `@Lazy` 注解之后(延迟 Bean B 的实例化),加载的流程如下: + +- 首先 Spring 会去创建 A 的 Bean,创建时需要注入 B 的属性; +- 由于在 A 上标注了 `@Lazy` 注解,因此 Spring 会去创建一个 B 的代理对象,将这个代理对象注入到 A 中的 B 属性; +- 之后开始执行 B 的实例化、初始化,在注入 B 中的 A 属性时,此时 A 已经创建完毕了,就可以将 A 给注入进去。 + +从上面的加载流程可以看出: `@Lazy` 解决循环依赖的关键点在于代理对象的使用。 + +- **没有 `@Lazy` 的情况下**:在 Spring 容器初始化 `A` 时会立即尝试创建 `B`,而在创建 `B` 的过程中又会尝试创建 `A`,最终导致循环依赖(即无限递归,最终抛出异常)。 +- **使用 `@Lazy` 的情况下**:Spring 不会立即创建 `B`,而是会注入一个 `B` 的代理对象。由于此时 `B` 仍未被真正初始化,`A` 的初始化可以顺利完成。等到 `A` 实例实际调用 `B` 的方法时,代理对象才会触发 `B` 的真正初始化。 + +`@Lazy` 能够在一定程度上打破循环依赖链,允许 Spring 容器顺利地完成 Bean 的创建和注入。但这并不是一个根本性的解决方案,尤其是在构造函数注入、复杂的多级依赖等场景中,`@Lazy` 无法有效地解决问题。因此,最佳实践仍然是尽量避免设计上的循环依赖。 + +### SpringBoot 允许循环依赖发生么? + +SpringBoot 2.6.x 以前是默认允许循环依赖的,也就是说你的代码出现了循环依赖问题,一般情况下也不会报错。SpringBoot 2.6.x 以后官方不再推荐编写存在循环依赖的代码,建议开发者自己写代码的时候去减少不必要的互相依赖。这其实也是我们最应该去做的,循环依赖本身就是一种设计缺陷,我们不应该过度依赖 Spring 而忽视了编码的规范和质量,说不定未来某个 SpringBoot 版本就彻底禁止循环依赖的代码了。 + +SpringBoot 2.6.x 以后,如果你不想重构循环依赖的代码的话,也可以采用下面这些方法: + +- 在全局配置文件中设置允许循环依赖存在:`spring.main.allow-circular-references=true`。最简单粗暴的方式,不太推荐。 +- 在导致循环依赖的 Bean 上添加 `@Lazy` 注解,这是一种比较推荐的方式。`@Lazy` 用来标识类是否需要懒加载/延迟加载,可以作用在类上、方法上、构造器上、方法参数上、成员变量中。 +- …… + +## ⭐️Spring 事务 + +关于 Spring 事务的详细介绍,可以看我写的 [Spring 事务详解](https://javaguide.cn/system-design/framework/spring/spring-transaction.html) 这篇文章。 + +### Spring 管理事务的方式有几种? + +- **编程式事务**:在代码中硬编码(在分布式系统中推荐使用) : 通过 `TransactionTemplate`或者 `TransactionManager` 手动管理事务,事务范围过大会出现事务未提交导致超时,因此事务要比锁的粒度更小。 +- **声明式事务**:在 XML 配置文件中配置或者直接基于注解(单体应用或者简单业务系统推荐使用) : 实际是通过 AOP 实现(基于`@Transactional` 的全注解方式使用最多) + +### Spring 事务中哪几种事务传播行为? + +**事务传播行为是为了解决业务层方法之间互相调用的事务问题**。 + +当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。 + +正确的事务传播行为可能的值如下: + +**1.`TransactionDefinition.PROPAGATION_REQUIRED`** + +使用的最多的一个事务传播行为,我们平时经常使用的`@Transactional`注解默认使用就是这个事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 + +**`2.TransactionDefinition.PROPAGATION_REQUIRES_NEW`** + +创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,`Propagation.REQUIRES_NEW`修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。 + +**3.`TransactionDefinition.PROPAGATION_NESTED`** + +如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于`TransactionDefinition.PROPAGATION_REQUIRED`。 + +**4.`TransactionDefinition.PROPAGATION_MANDATORY`** + +如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性) + +这个使用的很少。 + +若是错误的配置以下 3 种事务传播行为,事务将不会发生回滚: + +- **`TransactionDefinition.PROPAGATION_SUPPORTS`**: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 +- **`TransactionDefinition.PROPAGATION_NOT_SUPPORTED`**: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 +- **`TransactionDefinition.PROPAGATION_NEVER`**: 以非事务方式运行,如果当前存在事务,则抛出异常。 + +### Spring 事务中的隔离级别有哪几种? + +和事务传播行为这块一样,为了方便使用,Spring 也相应地定义了一个枚举类:`Isolation` + +```java +public enum Isolation { + + DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), + READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), + READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), + REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), + SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE); + + private final int value; + + Isolation(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + +} +``` + +下面我依次对每一种事务隔离级别进行介绍: + +- **`TransactionDefinition.ISOLATION_DEFAULT`** :使用后端数据库默认的隔离级别,MySQL 默认采用的 `REPEATABLE_READ` 隔离级别 Oracle 默认采用的 `READ_COMMITTED` 隔离级别. +- **`TransactionDefinition.ISOLATION_READ_UNCOMMITTED`** :最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,**可能会导致脏读、幻读或不可重复读** +- **`TransactionDefinition.ISOLATION_READ_COMMITTED`** : 允许读取并发事务已经提交的数据,**可以阻止脏读,但是幻读或不可重复读仍有可能发生** +- **`TransactionDefinition.ISOLATION_REPEATABLE_READ`** : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,**可以阻止脏读和不可重复读,但幻读仍有可能发生。** +- **`TransactionDefinition.ISOLATION_SERIALIZABLE`** : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,**该级别可以防止脏读、不可重复读以及幻读**。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 + +### @Transactional(rollbackFor = Exception.class)注解了解吗? + +`Exception` 分为运行时异常 `RuntimeException` 和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 + +当 `@Transactional` 注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。 + +`@Transactional` 注解默认回滚策略是只有在遇到`RuntimeException`(运行时异常) 或者 `Error` 时才会回滚事务,而不会回滚 `Checked Exception`(受检查异常)。这是因为 Spring 认为`RuntimeException`和 Error 是不可预期的错误,而受检异常是可预期的错误,可以通过业务逻辑来处理。 + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/spring-transactional-rollbackfor.png) + +如果想要修改默认的回滚策略,可以使用 `@Transactional` 注解的 `rollbackFor` 和 `noRollbackFor` 属性来指定哪些异常需要回滚,哪些异常不需要回滚。例如,如果想要让所有的异常都回滚事务,可以使用如下的注解: + +```java +@Transactional(rollbackFor = Exception.class) +public void someMethod() { +// some business logic +} +``` + +如果想要让某些特定的异常不回滚事务,可以使用如下的注解: + +```java +@Transactional(noRollbackFor = CustomException.class) +public void someMethod() { +// some business logic +} +``` + +## Spring Security + +Spring Security 重要的是实战,这里仅对小部分知识点进行总结。 + +### 有哪些控制请求访问权限的方法? + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/image-20220728201854641.png) + +- `permitAll()`:无条件允许任何形式访问,不管你登录还是没有登录。 +- `anonymous()`:允许匿名访问,也就是没有登录才可以访问。 +- `denyAll()`:无条件决绝任何形式的访问。 +- `authenticated()`:只允许已认证的用户访问。 +- `fullyAuthenticated()`:只允许已经登录或者通过 remember-me 登录的用户访问。 +- `hasRole(String)` : 只允许指定的角色访问。 +- `hasAnyRole(String)` : 指定一个或者多个角色,满足其一的用户即可访问。 +- `hasAuthority(String)`:只允许具有指定权限的用户访问 +- `hasAnyAuthority(String)`:指定一个或者多个权限,满足其一的用户即可访问。 +- `hasIpAddress(String)` : 只允许指定 ip 的用户访问。 + +### hasRole 和 hasAuthority 有区别吗? + +可以看看松哥的这篇文章:[Spring Security 中的 hasRole 和 hasAuthority 有区别吗?](https://mp.weixin.qq.com/s/GTNOa2k9_n_H0w24upClRw),介绍的比较详细。 + +### ⭐️如何对密码进行加密? + +如果我们需要保存密码这类敏感数据到数据库的话,需要先加密再保存。 + +Spring Security 提供了多种加密算法的实现,开箱即用,非常方便。这些加密算法实现类的接口是 `PasswordEncoder` ,如果你想要自己实现一个加密算法的话,也需要实现 `PasswordEncoder` 接口。 + +`PasswordEncoder` 接口一共也就 3 个必须实现的方法。 + +```java +public interface PasswordEncoder { + // 加密也就是对原始密码进行编码 + String encode(CharSequence var1); + // 比对原始密码和数据库中保存的密码 + boolean matches(CharSequence var1, String var2); + // 判断加密密码是否需要再次进行加密,默认返回 false + default boolean upgradeEncoding(String encodedPassword) { + return false; + } +} +``` + +![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/image-20220728183540954.png) + +官方推荐使用基于 bcrypt 强哈希函数的加密算法实现类。 + +### 如何优雅更换系统使用的加密算法? + +如果我们在开发过程中,突然发现现有的加密算法无法满足我们的需求,需要更换成另外一个加密算法,这个时候应该怎么办呢? + +推荐的做法是通过 `DelegatingPasswordEncoder` 兼容多种不同的密码加密方案,以适应不同的业务需求。 + +从名字也能看出来,`DelegatingPasswordEncoder` 其实就是一个代理类,并非是一种全新的加密算法,它做的事情就是代理上面提到的加密算法实现类。在 Spring Security 5.0 之后,默认就是基于 `DelegatingPasswordEncoder` 进行密码加密的。 + +## SpringBoot + +### ⭐️Spring,Spring MVC,Spring Boot 之间什么关系? + +很多人对 Spring,Spring MVC,Spring Boot 这三者傻傻分不清楚!这里简单介绍一下这三者,其实很简单,没有什么高深的东西。 + +Spring 包含了多个功能模块(上面刚刚提到过),其中最重要的是 Spring-Core(主要提供 IoC 依赖注入功能的支持) 模块, Spring 中的其他模块(比如 Spring MVC)的功能实现基本都需要依赖于该模块。 + +下图对应的是 Spring4.x 版本。目前最新的 5.x 版本中 Web 模块的 Portlet 组件已经被废弃掉,同时增加了用于异步响应式处理的 WebFlux 组件。 + +![Spring主要模块](https://oss.javaguide.cn/github/javaguide/jvme0c60b4606711fc4a0b6faf03230247a.png) + +Spring MVC 是 Spring 中的一个很重要的模块,主要赋予 Spring 快速构建 MVC 架构的 Web 程序的能力。MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。 + +![](https://oss.javaguide.cn/java-guide-blog/image-20210809181452421.png) + +使用 Spring 进行开发各种配置过于麻烦比如开启某些 Spring 特性时,需要用 XML 或 Java 进行显式配置。于是,Spring Boot 诞生了! + +Spring 旨在简化 J2EE 企业应用程序开发。Spring Boot 旨在简化 Spring 开发(减少配置文件,开箱即用!)。 + +Spring Boot 只是简化了配置,如果你需要构建 MVC 架构的 Web 程序,你还是需要使用 Spring MVC 作为 MVC 框架,只是说 Spring Boot 帮你简化了 Spring MVC 的很多配置,真正做到开箱即用! + +### ⭐️Spring Boot 支持哪些内嵌 Servlet 容器?如何选择? + +Spring Boot 提供了三种内嵌 Web 容器,分别为 **Tomcat**、**Jetty** 和 **Undertow** 。 + +当你在项目中引入 `spring-boot-starter-web` 这个起步依赖时,Spring Boot 默认会包含并启用 Tomcat 作为内嵌 Servlet 容器。 + +如果你想使用 Jetty 或 Undertow,需要在构建文件(如 Maven 的 `pom.xml`或 Gradle 的 `build.gradle`)中,从 `spring-boot-starter-web` 中排除默认的 Tomcat 依赖 (`spring-boot-starter-tomcat`),添加你想使用的容器对应的 Starter 依赖(例如 `spring-boot-starter-jetty` 或 `spring-boot-starter-undertow`)。 + +```xml + + org.springframework.boot + spring-boot-starter-web + + + + spring-boot-starter-tomcat + org.springframework.boot + + + + + + + + spring-boot-starter-jetty + org.springframework.boot + +``` + +在 Spring Boot 项目中,我们可以根据具体应用场景和性能需求,灵活地选择不同的嵌入式 Servlet 容器来提供 HTTP 服务: + +1. **Tomcat**:适用于大多数常规 Web 应用程序和 RESTful 服务,易于使用和配置,但在高并发场景下确实可能不如 Undertow 表现出色。 +2. **Undertow**:Undertow 具有极低的启动时间和资源占用,支持非阻塞 IO(NIO),在高并发场景下表现出色,性能优于 Tomcat。 +3. **Jetty**:如果应用程序涉及即时通信、聊天系统或其他需要保持长连接的场景,Jetty 是一个更好的选择。它在处理长连接和 WebSocket 时表现优越。另外。Jetty 在性能和内存使用方面通常优于 Tomcat,虽然在极端高并发场景中可能略逊于 Undertow。 + +**⚠️** **注意** : + +Spring Boot 4.0 完全移除了对 Undertow 的内嵌支持——不仅删掉了 **spring-boot-starter-undertow**,也不再提供任何 Undertow 相关的自动配置。移除的根本原因是:Spring Boot 4.0 基线升级到 Servlet 6.1(也就是说必须支持 Servlet 6.1 才能留在 starter 列表里),而截至 2025-10 官方发布说明时,Undertow 尚未兼容该版本。 + +### Spring Boot 默认使用的日志框架是什么? + +Spring Boot 默认选用 SLF4J (Simple Logging Facade for Java) 作为其日志门面 (Facade) / 日志抽象层,并搭配 Logback 作为默认的具体日志实现库 (Implementation)。 + +### ⭐️Spring Boot 的自动配置是如何实现的? + +Spring Boot 的自动配置机制是通过 `@SpringBootApplication` 注解启动的,这个注解本质上是几个关键注解的组合。我们可以将 `@SpringBootApplication` 看作是 `@Configuration`、`@EnableAutoConfiguration` 和 `@ComponentScan` 注解的集合。 + +- **`@EnableAutoConfiguration`**: 启用 Spring Boot 的自动配置机制。它是自动配置的核心,允许 Spring Boot 根据项目的依赖和配置自动配置 Spring 应用的各个部分。 +- **`@ComponentScan`**: 启用组件扫描,扫描被 `@Component`(以及 `@Service`、`@Controller` 等)注解的类,并将这些类注册为 Spring 容器中的 Bean。默认情况下,它会扫描该类所在包及其子包下的所有类。 +- **`@Configuration`**: 允许在上下文中注册额外的 Bean 或导入其他配置类。它相当于一个具有 `@Bean` 方法的 Spring 配置类。 + +`@EnableAutoConfiguration`是启动自动配置的关键,源码如下(建议自己打断点调试,走一遍基本的流程): + +```java +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@AutoConfigurationPackage +@Import({AutoConfigurationImportSelector.class}) +public @interface EnableAutoConfiguration { + String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; + + Class[] exclude() default {}; + + String[] excludeName() default {}; +} +``` + +这个注解通过 `@Import` 导入了 `AutoConfigurationImportSelector` 类,而 `AutoConfigurationImportSelector` 是自动配置的核心类之一。`@Import` 注解的作用是将指定的配置类或 Bean 导入到当前的配置类中。 + +`AutoConfigurationImportSelector` 类的 `getCandidateConfigurations` 方法会加载所有可用的自动配置类,并将这些类的信息以 `List` 的形式返回。这些配置类会被 Spring 容器管理为 Bean,从而实现自动配置。 + +```java + protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { + List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), + getBeanClassLoader()); + Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + + "are using a custom packaging, make sure that file is correct."); + return configurations; + } +``` + +这里使用了 `SpringFactoriesLoader` 来加载位于 `META-INF/spring.factories` 文件中的自动配置类。这些配置类会根据应用的具体条件(例如类路径中的依赖)自动配置相应的组件。 + +**自动配置信息有了,那么自动配置还差什么呢?** + +`@Conditional` 注解!在自动配置类中,Spring Boot 使用了一系列条件注解(如 `@Conditional`、`@ConditionalOnClass`、`@ConditionalOnBean` 等)来判断某些配置是否应该生效。这些注解是 `@Conditional` 注解的扩展,用于在特定条件满足时才启用相应的配置。 + +例如,在 Spring Security 的自动配置中,有一个名为 `SecurityAutoConfiguration` 的自动配置类,它导入了 `WebSecurityEnablerConfiguration` 类。 + +`WebSecurityEnablerConfiguration` 类的源码如下: + +```java +@Configuration +@ConditionalOnBean(WebSecurityConfigurerAdapter.class) +@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@EnableWebSecurity +public class WebSecurityEnablerConfiguration { + +} +``` + +`WebSecurityEnablerConfiguration`类中使用`@ConditionalOnBean`指定了容器中必须还有`WebSecurityConfigurerAdapter` 类或其实现类。所以,一般情况下 Spring Security 配置类都会去实现 `WebSecurityConfigurerAdapter`,这样自动将配置就完成了。 + +最后,简单总结一下:Spring Boot 的自动配置机制通过 `@EnableAutoConfiguration` 启动。该注解利用 `@Import` 注解导入了 `AutoConfigurationImportSelector` 类,而 `AutoConfigurationImportSelector` 类则负责加载并管理所有的自动配置类。这些自动配置类通常在`META-INF/spring.factories` 文件中声明,并根据项目的依赖和配置条件,通过条件注解(如 `@ConditionalOnClass`、`@ConditionalOnBean` 等)判断是否应该生效。 + +⭐自动配置是详细的源码解读可以参考 [JavaGuide](https://javaguide.cn/) 上这篇文章:[SpringBoot 自动装配原理详解](https://javaguide.cn/system-design/framework/spring/spring-boot-auto-assembly-principles.html)。 + +### Spring Boot 如何加载配置文件?如果两种配置文件同时存在,会怎样处理? + +Spring Boot 会自动从类路径的根目录(通常是项目的 `src/main/resources/` 目录)下查找并加载名为 `application.properties` 或 `application.yml` (包括 `.yaml` 扩展名) 的文件。 + +如果在同一目录下同时存在 `application.properties` 和 `application.yml` 文件,`application.properties` 文件中的配置项优先级更高,会覆盖 `application.yml` 中相同的配置项。为了避免配置冲突和混淆,建议在一个项目中只使用一种格式。 + +如果开发者没有提供任何 `application.properties` 或 `application.yml` 文件,或者文件中没有定义某个特定的配置项,Spring Boot 将会使用其内置的默认配置值(如果该配置项有默认值的话)。 + +### Spring Boot 加载配置文件的优先级了解么? + +Spring Boot 加载配置文件的优先级设计得非常灵活,主要是为了方便我们在不同环境(开发、测试、生产)下覆盖或指定配置。它的原则是:**后加载的覆盖先加载的,而且离用户(或部署环境)越近的优先级越高**。 + +**加载顺序如下**: + +1. 当前项目根目录下 `config/` 子目录的配置文件 (`./config/application.yml` 或 `./config/application.properties`):优先级最高,通常放在运行 Jar 包同级的 `config` 目录里。 + +2. 当前项目根目录下的配置文件 (`./application.yml` 或 `./application.properties`): 直接放在运行 Jar 包同级目录里,优先级次之。 + +3. 类路径内 `config/` 子目录的配置文件 (`classpath:/config/application.yml` 或 `classpath:/config/application.properties`): 对应项目中的 `src/main/resources/config/` 下的文件,优先级再次之。 + +4. 类路径下的配置文件 (`classpath:/application.yml` 或 `classpath:/application.properties`): 对应项目中的 `src/main/resources/` 根目录下的文件,在这些位置里优先级最低。 + +总结:Jar 包外 `config/` > Jar 包外根目录 > Jar 包内 `config/`> Jar 包内根目录。 + + + +**简单记忆规则**: + +- **包外 > 包内**(方便部署时覆盖配置)。 +- **`config/` 目录 > 根目录**(无论包内还是包外,`config` 目录里的配置优先级更高)。 + +如果某个 Profile 文件(如 `application-dev.yml`)被激活(通过 `spring.profiles.active=dev` 指定),那么,**在同一个目录下**,Profile 文件的优先级高于通用文件。例如: + +- `src/main/resources/application-dev.yml` 的配置会覆盖 `src/main/resources/application.yml` 中的同名配置。 +- 同样地,Jar 包外的 `config/application-dev.yml` 会覆盖 `config/application.yml`。 + +通过这样的灵活设计,Spring Boot 能很好地适应各种环境的配置需求,同时确保配置文件的覆盖和管理清晰有序。 + +### ⭐️更多 SpringBoot 面试题 + +更多 **Spring Boot** 相关的面试题欢迎加入我的知识星球,已经整理到了[《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html)中。 + +很多 Spring Boot 重要的新特性都已经同步到了这篇文章中,质量很高,保证内容与时俱进! + +![SpringBoot 面试题](https://oss.javaguide.cn/javamianshizhibei/springboot-questions.png) diff --git a/package.json b/package.json index 740aebb..a0b6307 100644 --- a/package.json +++ b/package.json @@ -20,18 +20,19 @@ ".md": "markdownlint-cli2" }, "dependencies": { - "@vuepress/bundler-vite": "2.0.0-rc.24", - "@vuepress/plugin-feed": "2.0.0-rc.112", - "@vuepress/plugin-search": "2.0.0-rc.112", + "@vuepress/bundler-vite": "2.0.0-rc.26", + "@vuepress/plugin-feed": "2.0.0-rc.124", + "@vuepress/plugin-search": "2.0.0-rc.124", "husky": "9.1.7", "markdownlint-cli2": "0.17.1", "mathjax-full": "3.2.2", + "mermaid": "^11.13.0", "nano-staged": "0.8.0", "prettier": "3.4.2", - "sass-embedded": "1.89.2", - "vue": "^3.5.18", - "vuepress": "2.0.0-rc.24", - "vuepress-theme-hope": "2.0.0-rc.94" + "sass-embedded": "^1.97.3", + "vue": "^3.5.30", + "vuepress": "2.0.0-rc.26", + "vuepress-theme-hope": "2.0.0-rc.103" }, "packageManager": "pnpm@10.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7df2365..2396cb3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,14 @@ importers: .: dependencies: '@vuepress/bundler-vite': - specifier: 2.0.0-rc.24 - version: 2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2) + specifier: 2.0.0-rc.26 + version: 2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0) '@vuepress/plugin-feed': - specifier: 2.0.0-rc.112 - version: 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + specifier: 2.0.0-rc.124 + version: 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) '@vuepress/plugin-search': - specifier: 2.0.0-rc.112 - version: 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + specifier: 2.0.0-rc.124 + version: 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) husky: specifier: 9.1.7 version: 9.1.7 @@ -26,6 +26,9 @@ importers: mathjax-full: specifier: 3.2.2 version: 3.2.2 + mermaid: + specifier: ^11.13.0 + version: 11.13.0 nano-staged: specifier: 0.8.0 version: 0.8.0 @@ -33,20 +36,23 @@ importers: specifier: 3.4.2 version: 3.4.2 sass-embedded: - specifier: 1.89.2 - version: 1.89.2 + specifier: ^1.97.3 + version: 1.98.0 vue: - specifier: ^3.5.18 - version: 3.5.24 + specifier: ^3.5.30 + version: 3.5.30 vuepress: - specifier: 2.0.0-rc.24 - version: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + specifier: 2.0.0-rc.26 + version: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) vuepress-theme-hope: - specifier: 2.0.0-rc.94 - version: 2.0.0-rc.94(@vuepress/plugin-feed@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)))(@vuepress/plugin-search@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)))(katex@0.16.25)(markdown-it@14.1.0)(mathjax-full@3.2.2)(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + specifier: 2.0.0-rc.103 + version: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(@vuepress/plugin-feed@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(@vuepress/plugin-search@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(katex@0.16.38)(markdown-it@14.1.1)(mermaid@11.13.0)(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) packages: + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -55,17 +61,35 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@bufbuild/protobuf@2.10.1': - resolution: {integrity: sha512-ckS3+vyJb5qGpEYv/s1OebUHDi/xSNtfgw1wqKZo7MR9F2z+qXr0q5XagafAG/9O0QPVIUfST0smluYSTpYFkg==} + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@bufbuild/protobuf@2.11.0': + resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} + + '@chevrotain/cst-dts-gen@11.1.2': + resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} + + '@chevrotain/gast@11.1.2': + resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} + + '@chevrotain/regexp-to-ast@11.1.2': + resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} + + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + + '@chevrotain/utils@11.1.2': + resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} @@ -223,152 +247,179 @@ packages: cpu: [x64] os: [win32] + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@lit-labs/ssr-dom-shim@1.4.0': - resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + '@lit-labs/ssr-dom-shim@1.5.1': + resolution: {integrity: sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==} - '@lit/reactive-element@2.1.1': - resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} - '@mdit-vue/plugin-component@2.1.4': - resolution: {integrity: sha512-fiLbwcaE6gZE4c8Mkdkc4X38ltXh/EdnuPE1hepFT2dLiW6I4X8ho2Wq7nhYuT8RmV4OKlCFENwCuXlKcpV/sw==} + '@mdit-vue/plugin-component@3.0.2': + resolution: {integrity: sha512-Fu53MajrZMOAjOIPGMTdTXgHLgGU9KwTqKtYc6WNYtFZNKw04euSfJ/zFg8eBY/2MlciVngkF7Gyc2IL7e8Bsw==} + engines: {node: '>=20.0.0'} - '@mdit-vue/plugin-frontmatter@2.1.4': - resolution: {integrity: sha512-mOlavV176njnozIf0UZGFYymmQ2LK5S1rjrbJ1uGz4Df59tu0DQntdE7YZXqmJJA9MiSx7ViCTUQCNPKg7R8Ow==} + '@mdit-vue/plugin-frontmatter@3.0.2': + resolution: {integrity: sha512-QKKgIva31YtqHgSAz7S7hRcL7cHXiqdog4wxTfxeQCHo+9IP4Oi5/r1Y5E93nTPccpadDWzAwr3A0F+kAEnsVQ==} + engines: {node: '>=20.0.0'} - '@mdit-vue/plugin-headers@2.1.4': - resolution: {integrity: sha512-tyZwGZu2mYkNSqigFP1CK3aZYxuYwrqcrIh8ljd8tfD1UDPJkAbQeayq62U572po2IuWVB1BqIG8JIXp5POOTA==} + '@mdit-vue/plugin-headers@3.0.2': + resolution: {integrity: sha512-Z3PpDdwBTO5jlW2r617tQibkwtCc5unTnj/Ew1SCxTQaXjtKgwP9WngdSN+xxriISHoNOYzwpoUw/1CW8ntibA==} + engines: {node: '>=20.0.0'} - '@mdit-vue/plugin-sfc@2.1.4': - resolution: {integrity: sha512-oqAlMulkz280xUJIkormzp6Ps0x5WULZrwRivylWJWDEyVAFCj5VgR3Dx6CP2jdgyuPXwW3+gh2Kzw+Xe+kEIQ==} + '@mdit-vue/plugin-sfc@3.0.2': + resolution: {integrity: sha512-dhxIrCGu5Nd4Cgo9JJHLjdNy2lMEv+LpimetBHDSeEEJxJBC4TPN0Cljn+3/nV1uJdGyw33UZA86PGdgt1LsoA==} + engines: {node: '>=20.0.0'} - '@mdit-vue/plugin-title@2.1.4': - resolution: {integrity: sha512-uuF24gJvvLVIWG/VBtCDRqMndfd5JzOXoBoHPdKKLk3PA4P84dsB0u0NnnBUEl/YBOumdCotasn7OfFMmco9uQ==} + '@mdit-vue/plugin-title@3.0.2': + resolution: {integrity: sha512-KTDP7s68eKTwy4iYp5UauQuVJf+tDMdJZMO6K4feWYS8TX95ItmcxyX7RprfBWLTUwNXBYOifsL6CkIGlWcNjA==} + engines: {node: '>=20.0.0'} - '@mdit-vue/plugin-toc@2.1.4': - resolution: {integrity: sha512-vvOU7u6aNmvPwKXzmoHion1sv4zChBp20LDpSHlRlXc3btLwdYIA0DR+UiO5YeyLUAO0XSHQKBpsIWi57K9/3w==} + '@mdit-vue/plugin-toc@3.0.2': + resolution: {integrity: sha512-Dz0dURjD5wR4nBxFMiqb0BTGRAOkCE60byIemqLqnkF6ORKKJ8h5aLF5J5ssbLO87hwu81IikHiaXvqoiEneoQ==} + engines: {node: '>=20.0.0'} - '@mdit-vue/shared@2.1.4': - resolution: {integrity: sha512-Axd8g2iKQTMuHcPXZH5JY3hbSMeLyoeu0ftdgMrjuPzHpJnWiPSAnA0dAx5NQFQqZkXHhyIrAssLSrOWjFmPKg==} + '@mdit-vue/shared@3.0.2': + resolution: {integrity: sha512-anFGls154h0iVzUt5O43EaqYvPwzfUxQ34QpNQsUQML7pbEJMhcgkRNvYw9hZBspab+/TP45agdPw5joh6/BBA==} + engines: {node: '>=20.0.0'} - '@mdit-vue/types@2.1.4': - resolution: {integrity: sha512-QiGNZslz+zXUs2X8D11UQhB4KAMZ0DZghvYxa7+1B+VMLcDtz//XHpWbcuexjzE3kBXSxIUTPH3eSQCa0puZHA==} + '@mdit-vue/types@3.0.2': + resolution: {integrity: sha512-00aAZ0F0NLik6I6Yba2emGbHLxv+QYrPH00qQ5dFKXlAo1Ll2RHDXwY7nN2WAfrx2pP+WrvSRFTGFCNGdzBDHw==} + engines: {node: '>=20.0.0'} - '@mdit/helper@0.22.1': - resolution: {integrity: sha512-lDpajcdAk84aYCNAM/Mi3djw38DJq7ocLw5VOSMu/u2YKX3/OD37a6Qb59in8Uyp4SiAbQoSHa8px6hgHEpB5g==} - engines: {node: '>= 18'} + '@mdit/helper@0.23.1': + resolution: {integrity: sha512-ifWDG3VbUAx1ia7eBWEHm5vpv5QFUPY3kFLPPZzYBr15A7/d5w7D+8ZBg8xxqkvyC73Ys+zF14EQCq7eQAXYxg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-alert@0.22.3': - resolution: {integrity: sha512-9g99rjLCFd8upA/DXbhGmEM7GMFocy6SRk4OekxuAy9t1aDOE/r5IJgUbBIvc9kMkg39ug0yXtMkKwAt2zp5Hg==} + '@mdit/plugin-alert@0.23.1': + resolution: {integrity: sha512-vbWxewra32hfZKF+XeeWK/eoAzQbe0cSRfSattX9oxGOcaEbcVx2/g7nmI9//ItsOKO7XNRy7ZKLdnm+CaMPvg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-align@0.22.2': - resolution: {integrity: sha512-hy9TliRnjhjvJxb+mFnJtisTGo6e2rVM191ci1xJ3CZefJACYDJrczjQA9NA8zml4wuC9iIzeCbJH79STd8ePg==} - engines: {node: '>= 18'} + '@mdit/plugin-align@0.24.1': + resolution: {integrity: sha512-JgpvZrcfY20bbpRwPnCbdUoJBIJsc3hrNMKuA8x3eeo0yHqZZwPvK/kj4t9jgMrT9uqlapzn8CTAlrxQHG/eKw==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-attrs@0.23.3': - resolution: {integrity: sha512-DsPY1e1WCjEt0FnKib10vuM2l2g6IB39OmGKBupJ1PgU2jwmxssKQrD02ewhecuNh1QjNgjkx0riiSoUat8ecw==} - engines: {node: '>= 18'} + '@mdit/plugin-attrs@0.25.1': + resolution: {integrity: sha512-nJ8vZvREJOUcbih3D+BaCnbsYbA3MskOzWX6JAjRmnfQFFDmigK0WTx9Z5xLlo87D120AIYWGo3DGxZhwLCE0Q==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-container@0.22.2': - resolution: {integrity: sha512-QBBti5EyQzVl/qzFAD9YAhiAB9S2zF/4MPAS4kwm7VkmeYrcj2HpZpA7snMjnWh3CtriDcaIMInhg0vDtDwyfA==} - engines: {node: '>= 18'} + '@mdit/plugin-container@0.23.1': + resolution: {integrity: sha512-mHTp4+zvuE6uqhG6honfR6F5wLgAIcLlGVCu8xHIoO6H8Oc23lrjl+8Ieyr+PKLH3Lz0QFQf0fWdwNi44EsYSg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-demo@0.22.3': - resolution: {integrity: sha512-pK/iJVNPqflo72ZFHbf3a+H6R+l741SPXRnaftZ3ihiT2hlaizg2097eBz2llNkHpFtb3luapux0s/o9AZvA5g==} + '@mdit/plugin-demo@0.23.1': + resolution: {integrity: sha512-yyU/VxkLxw/qz/zpnNGWEBCRZmFl3hsIx03VUeBhWU9gWr2px7SCmWqeN+nhdbhTzlC/84c1caCWc+uSx2babA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-figure@0.22.2': - resolution: {integrity: sha512-mCbrhfbP8VopTzYHw1OnUAEnhh1C24Sx8ExAJpHgnM7HnNF54a+MXbywXZZJAbRZ22l3J2wrxL+IOxKYgNlgdg==} - engines: {node: '>= 18'} + '@mdit/plugin-figure@0.23.1': + resolution: {integrity: sha512-gdEnVk1IW9qZD8QSIs4jZhgdwk/BymKn+5GsVux4Pa7j/+sIkoR76dD6kJI/Q7qStI1sFrmTou1s/sQf7/NRwg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-footnote@0.22.3': - resolution: {integrity: sha512-4hkki9vlIsRDhb7BZLL53s/htRHcubOkjakHPa7Jkj8BZ8/C++0wF13dr73OXcLNVKe/3JWE6pEl1aKETG20Gw==} - engines: {node: '>= 18'} + '@mdit/plugin-footnote@0.23.1': + resolution: {integrity: sha512-biPYxrIo/2SynwGNVEl4FDh1na1SWxQXXjCtRPe1WN3WPke0D5WNxEHjgnsMuUoig2D1ttJpbzb5gQhChgVrmg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 - '@mdit/plugin-icon@0.22.2': - resolution: {integrity: sha512-ODVJOhCz1p2zmeuwhJ6mA2z/6MyaD4EVibGmfhsKPlIVMF1PRvx8esbe+25HnL0/Wln+n9JsRUHcxrt7TPsqkA==} + '@mdit/plugin-icon@0.24.1': + resolution: {integrity: sha512-nFkdGpVajAzXKN8KHUVIfH5qfABCQWuH52+Yl3r+OKOFUmFVjGu62CIEoNnlkFjHLIUD4QhvmuncoNW4zEDhEg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-img-lazyload@0.22.1': - resolution: {integrity: sha512-ombpBQqR1zYjtr4/7s8EvIVx/ymtiflWksXropYz81o0I9Bm9Os1UPuNgjwfT/DEhIit4HMaJhjpKhGkYrOKgA==} - engines: {node: '>= 18'} + '@mdit/plugin-img-lazyload@0.23.1': + resolution: {integrity: sha512-iaQhq++GTk9yv+Azlk88DBzRHUNB00whPaLJAwIzgslHfTyK92o/2yLIR9/nknWuerZjyqh883H/r1knPBUTaA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-img-mark@0.22.2': - resolution: {integrity: sha512-+dfw7HBSg9/ETWguCbhudpIEIsWN81Ro23agEuU8JO1RDpkiMAFVBcUAFqUWr9+4KHQhiBtyEWn1Y7l+d17RXg==} - engines: {node: '>= 18'} + '@mdit/plugin-img-mark@0.23.1': + resolution: {integrity: sha512-pOZ9m6wkn+mLKXByejKWLIW0HMr2AgkSdTrmwsQ0y8s9/XWckP+9r3alpPQCoqhcRas5NHmg6FR+CDOAXb9rpA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-img-size@0.22.3': - resolution: {integrity: sha512-dd2coSTYi5rDg+dIQYgIcHlLvE4C6Q7w8GQj5mdvHF0aek46V6PICZC9tQnPe+GcKKyAg5B1MGBo1+suJVXA5A==} - engines: {node: '>= 18'} + '@mdit/plugin-img-size@0.23.1': + resolution: {integrity: sha512-cpnXRpLWGBhBAxuIqq4YTeqcF5wLdmSFlKiEr4dBCKI/pj9Gsjd6WY40OzvpXyamSMoyAjYj4Fo+JO1ghwvarg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-include@0.22.2': - resolution: {integrity: sha512-H/zm9M7nVBo/eOSZG5YMd0qXk7lEw+z968Z8cjLgvOlh1IMSCX2ZwD3EVeIPGfEOjYQ9hzlZVkTxwZan0VgTJg==} + '@mdit/plugin-include@0.23.1': + resolution: {integrity: sha512-fvep++E2hZYGGnB0VacwKa7Yk8S3pD1lLJKqsaGnG8FDklpTXD6j3RfSYc7JV8xMUtnAwShfCj4FQlRvCfvc8Q==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-katex-slim@0.23.2': - resolution: {integrity: sha512-QZCzPFBeJkSOO/oMe6o4jjXNXWyibSkUMrqxGo8AVLbRfxfOIjHHVdbHaMhqLEoeRqTpDLReX+9U7czQ85lx7A==} - engines: {node: '>= 18'} + '@mdit/plugin-inline-rule@0.23.1': + resolution: {integrity: sha512-ShT+quzVWGxJXb7fo64F/9o05srhL75dspcLF0VbxlFKLQABFW0EI+lrzRortV5RlXhVY42ezpp4UgOnLSQ85A==} + engines: {node: '>= 20'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-katex-slim@0.26.1': + resolution: {integrity: sha512-bDc9CLFejgSTWUYuTiVcCCSR9Nmbd9dGzGzzzyv7p4iwHEI7cNgxizRodNNMRrxFj8AZQYk6UG9C+RRfhkURkA==} + engines: {node: '>= 20'} peerDependencies: katex: ^0.16.25 markdown-it: ^14.1.0 @@ -378,106 +429,122 @@ packages: markdown-it: optional: true - '@mdit/plugin-mark@0.22.1': - resolution: {integrity: sha512-2blMM/gGyqPARvaal44mt0pOi+8phmFpj7D4suG4qMd1j8aGDZl9R7p8inbr3BePOady1eloh0SWSCdskmutZg==} - engines: {node: '>= 18'} + '@mdit/plugin-layout@0.2.1': + resolution: {integrity: sha512-znfck6af+IdUbnZYU1CIiw4MT+1Nt5c57+ijRQca/yqlExDsm7sVBNawBLNAOyN/VaV7MiAvxuyK+cBE2m3Nog==} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-mathjax-slim@0.23.2': - resolution: {integrity: sha512-2KtNXJMLlV1YV+GDuOlWIjWUFhPQh0IpJp2u63JRkiJs1M620zVgFjKuQnbEzqVMTnqq/FQLQSER2V0otXtE0g==} - engines: {node: '>= 18'} + '@mdit/plugin-mark@0.23.1': + resolution: {integrity: sha512-ks/RRTzuDjxvclsNsMMOo2f9vfnKkIF+9sqpfScw7kxfUWPkfAnGQVv1AQHlfv/OlCyyLUQm2rXYEMr1t/XxGA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 - mathjax-full: ^3.2.2 peerDependenciesMeta: markdown-it: optional: true - mathjax-full: + + '@mdit/plugin-mathjax-slim@0.26.1': + resolution: {integrity: sha512-GriihQzCxrYeJ1OxSKvPWjBreSSSkJ+xIkz0CY7/UPKyGh4+5TpYo05EjTpoFmR5GEJPmka/9T2X4L/lkZ8mag==} + engines: {node: '>= 20'} + peerDependencies: + '@mathjax/mathjax-newcm-font': ^4.1.0 + '@mathjax/src': ^4.0.0 + markdown-it: ^14.1.0 + peerDependenciesMeta: + '@mathjax/mathjax-newcm-font': + optional: true + '@mathjax/src': + optional: true + markdown-it: optional: true - '@mdit/plugin-plantuml@0.22.3': - resolution: {integrity: sha512-vnMTNO8HsXGQq8DIux+4Y082M/IkT+ICEZhe0EIXgKfbCORa7jQiw1mCKX4L+okqntglOkM5ItvfSdyCbrqidQ==} + '@mdit/plugin-plantuml@0.24.1': + resolution: {integrity: sha512-tRPAnofSMjrrCypghiBDyqyF0cH/wBzS0zjSVjfc+RfMgURt3B4OKvXDc+PsXU6MvJPXVKuMW1ngM4nddPtUyg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-spoiler@0.22.2': - resolution: {integrity: sha512-XoL08KwYGaGeCzXuwvOcZLrRvvzvOAj96XF5iihbI1M5LSkzWLY0cWlfgF1mEM1+fAyauZxMYXOegKDqT/HRXg==} - engines: {node: '>= 18'} + '@mdit/plugin-spoiler@0.23.1': + resolution: {integrity: sha512-xfodFv8B5vHihKXeKDNeCKwxIi/rZOb4H2apEwB4BUqQMIQ9jl3Iv4CZMDaO5IpPxFz73H3+6zDRJ/noRLcMjQ==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-stylize@0.22.2': - resolution: {integrity: sha512-HpUIeH8T1kdIFvQbO5C9ldaxedkfdJmkoqDalAgUudoIdrDvoeEv6TLnQSS/c6NJ5UqjuwBentv5/I1cQYxLaQ==} - engines: {node: '>= 18'} + '@mdit/plugin-stylize@0.23.1': + resolution: {integrity: sha512-6WFfYbdN3eSq37u/JT+jd0ZGaGgxqXxwi/t1fbpDUsGtabstIYR692YlZG1S4CT2ljhrIZjBHkvKnA4ifQEGVA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-sub@0.22.2': - resolution: {integrity: sha512-+NSz8IMYNAfQWBRBX6jf3PMIubkQSwy3v4ElW5CP4a0U4r1Youw3MOcDa6FRwW9TZ/+t8E+E3DaBeYcRi/+bGw==} - engines: {node: '>= 18'} + '@mdit/plugin-sub@0.24.1': + resolution: {integrity: sha512-NqkwVlN6GVRNT+6klexUrfS5oyYvaBJUGND7SWYmlmY31TptpDpLWH9cW2UhWmGUKIKoL64Kk4Efd1VMyh2Mkg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-sup@0.22.2': - resolution: {integrity: sha512-xgpCAbNgyrJW8NyvB5vGbRVlnCSnNjiJ3zyHAqqr9IqPGH1jCWidOlLLWiIOtfqvUExsLmtyt4c76SZb5MiKYw==} - engines: {node: '>= 18'} + '@mdit/plugin-sup@0.24.1': + resolution: {integrity: sha512-yG/zI29K2bxaYXuQxWmaMtTG8gUrCZDNQpiVVurT2fOCD1WoKbdk7ICdjrdU4hvZzig1vECF2AsNP5kCynf0ZQ==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-tab@0.22.3': - resolution: {integrity: sha512-TPMHgVEsqvsCPVwt1KZGhJsVW/6XNyp9VXy2X2nNXvaklfK2+l6DJBWLeN+lPwzXvASnE5CkEFvaY4627zDt9A==} + '@mdit/plugin-tab@0.24.1': + resolution: {integrity: sha512-DSRNyGEBnEgqd1Pw3gt1ropVJv0n5AMCJREY4iq2GNUtxdzNP8jGO7UdXqdnmUPXTWSUZkE7pPu7tvL+38dBHQ==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-tasklist@0.22.2': - resolution: {integrity: sha512-tYxp4tDomTb9NzIphoDXWJxjQZxFuqP4PjU0H9AecUyWuSRP+HICCqe/HVNTTpB0+WDeuVtnxAW9kX08ekxUWw==} - engines: {node: '>= 18'} + '@mdit/plugin-tasklist@0.23.1': + resolution: {integrity: sha512-BNhTESurLLQxydlsfdsXf+e9U746UlHFl0l/rHQH225b6aaOdo/TH0H6PIAZIjx0oV97wg72s/WHKGMejps3Rg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-tex@0.22.2': - resolution: {integrity: sha512-iniJQ9BPZc8AGdLPRoyC+nDA0SoDSe+AETma4y2dOk/EbaSZMYgMaZO843mk5JV7eJkfRc6TWcTIE2CqY2/9Rg==} - engines: {node: '>= 18'} + '@mdit/plugin-tex@0.24.1': + resolution: {integrity: sha512-fWTdk8Zv7SNKS2CxTmCmo1J8QOExUUsYaMRIOc/U3sFzddn/6kesUoZGk+6wNDktgOIhQRWaaEWDRw2+0QiUpA==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true - '@mdit/plugin-uml@0.22.2': - resolution: {integrity: sha512-pe1p527i66rKThIxz6yOrBILyl1E+jZtDexuUHnNKAKEgXx+f10eCENLN7+9L59K2pbARj3PtdxDC0fs+e2DqA==} - engines: {node: '>= 18'} + '@mdit/plugin-uml@0.24.1': + resolution: {integrity: sha512-e/aStB1zb9HwV0KtBIkh7z68ZRW9TnmLTZ+kCZt7HbNywGQvRlHv8myZ0BWVAe5Gbo5LH+aFRSVE72pJ9QP1Xg==} + engines: {node: '>= 20'} peerDependencies: markdown-it: ^14.1.0 peerDependenciesMeta: markdown-it: optional: true + '@mermaid-js/parser@1.0.1': + resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -490,154 +557,270 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@rolldown/pluginutils@1.0.0-beta.29': - resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - '@rollup/rollup-android-arm-eabi@4.53.2': - resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.53.2': - resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.2': - resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.2': - resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.2': - resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.2': - resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': - resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.53.2': - resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.53.2': - resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.53.2': - resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.53.2': - resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.53.2': - resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.53.2': - resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.53.2': - resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.53.2': - resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.53.2': - resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.53.2': - resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openharmony-arm64@4.53.2': - resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.53.2': - resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.2': - resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.2': - resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.53.2': - resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] - '@shikijs/core@3.15.0': - resolution: {integrity: sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg==} + '@shikijs/core@4.0.2': + resolution: {integrity: sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==} + engines: {node: '>=20'} - '@shikijs/engine-javascript@3.15.0': - resolution: {integrity: sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg==} + '@shikijs/engine-javascript@4.0.2': + resolution: {integrity: sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==} + engines: {node: '>=20'} - '@shikijs/engine-oniguruma@3.15.0': - resolution: {integrity: sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA==} + '@shikijs/engine-oniguruma@4.0.2': + resolution: {integrity: sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==} + engines: {node: '>=20'} - '@shikijs/langs@3.15.0': - resolution: {integrity: sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A==} + '@shikijs/langs@4.0.2': + resolution: {integrity: sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==} + engines: {node: '>=20'} - '@shikijs/themes@3.15.0': - resolution: {integrity: sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ==} + '@shikijs/primitive@4.0.2': + resolution: {integrity: sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==} + engines: {node: '>=20'} - '@shikijs/transformers@3.15.0': - resolution: {integrity: sha512-Hmwip5ovvSkg+Kc41JTvSHHVfCYF+C8Cp1omb5AJj4Xvd+y9IXz2rKJwmFRGsuN0vpHxywcXJ1+Y4B9S7EG1/A==} + '@shikijs/themes@4.0.2': + resolution: {integrity: sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==} + engines: {node: '>=20'} - '@shikijs/types@3.15.0': - resolution: {integrity: sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw==} + '@shikijs/transformers@4.0.2': + resolution: {integrity: sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg==} + engines: {node: '>=20'} + + '@shikijs/types@4.0.2': + resolution: {integrity: sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==} + engines: {node: '>=20'} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} @@ -649,6 +832,99 @@ packages: '@stackblitz/sdk@1.11.0': resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==} + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -658,6 +934,9 @@ packages: '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + '@types/hash-sum@1.0.2': resolution: {integrity: sha512-UP28RddqY8xcU0SCEp9YKutQICXpaAq9N8U2klqF5hegGha7KzTOL8EdhIIV3bOSGBzjEpN9bU/d+nNZBdJYVw==} @@ -667,8 +946,8 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/katex@0.16.7': - resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} @@ -688,11 +967,14 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@17.0.45': - resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + + '@types/node@25.4.0': + resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/picomatch@4.0.2': + resolution: {integrity: sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA==} '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} @@ -712,114 +994,125 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@vitejs/plugin-vue@6.0.1': - resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + + '@vitejs/plugin-vue@6.0.4': + resolution: {integrity: sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 vue: ^3.2.25 - '@vue/compiler-core@3.5.24': - resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==} + '@vue/compiler-core@3.5.30': + resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} - '@vue/compiler-dom@3.5.24': - resolution: {integrity: sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==} + '@vue/compiler-dom@3.5.30': + resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} - '@vue/compiler-sfc@3.5.24': - resolution: {integrity: sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==} + '@vue/compiler-sfc@3.5.30': + resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} - '@vue/compiler-ssr@3.5.24': - resolution: {integrity: sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==} + '@vue/compiler-ssr@3.5.30': + resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-api@7.7.8': - resolution: {integrity: sha512-BtFcAmDbtXGwurWUFf8ogIbgZyR+rcVES1TSNEI8Em80fD8Anu+qTRN1Fc3J6vdRHlVM3fzPV1qIo+B4AiqGzw==} + '@vue/devtools-api@8.0.7': + resolution: {integrity: sha512-tc1TXAxclsn55JblLkFVcIRG7MeSJC4fWsPjfM7qu/IcmPUYnQ5Q8vzWwBpyDY24ZjmZTUCCwjRSNbx58IhlAA==} - '@vue/devtools-kit@7.7.8': - resolution: {integrity: sha512-4Y8op+AoxOJhB9fpcEF6d5vcJXWKgHxC3B0ytUB8zz15KbP9g9WgVzral05xluxi2fOeAy6t140rdQ943GcLRQ==} + '@vue/devtools-kit@8.0.7': + resolution: {integrity: sha512-H6esJGHGl5q0E9iV3m2EoBQHJ+V83WMW83A0/+Fn95eZ2iIvdsq4+UCS6yT/Fdd4cGZSchx/MdWDreM3WqMsDw==} - '@vue/devtools-shared@7.7.8': - resolution: {integrity: sha512-XHpO3jC5nOgYr40M9p8Z4mmKfTvUxKyRcUnpBAYg11pE78eaRFBKb0kG5yKLroMuJeeNH9LWmKp2zMU5LUc7CA==} + '@vue/devtools-shared@8.0.7': + resolution: {integrity: sha512-CgAb9oJH5NUmbQRdYDj/1zMiaICYSLtm+B1kxcP72LBrifGAjUmt8bx52dDH1gWRPlQgxGPqpAMKavzVirAEhA==} - '@vue/reactivity@3.5.24': - resolution: {integrity: sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==} + '@vue/reactivity@3.5.30': + resolution: {integrity: sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==} - '@vue/runtime-core@3.5.24': - resolution: {integrity: sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==} + '@vue/runtime-core@3.5.30': + resolution: {integrity: sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==} - '@vue/runtime-dom@3.5.24': - resolution: {integrity: sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==} + '@vue/runtime-dom@3.5.30': + resolution: {integrity: sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==} - '@vue/server-renderer@3.5.24': - resolution: {integrity: sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==} + '@vue/server-renderer@3.5.30': + resolution: {integrity: sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==} peerDependencies: - vue: 3.5.24 + vue: 3.5.30 - '@vue/shared@3.5.24': - resolution: {integrity: sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==} + '@vue/shared@3.5.30': + resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} - '@vuepress/bundler-vite@2.0.0-rc.24': - resolution: {integrity: sha512-prgT3f6xOBC43rhfvzlfXY0wJKsI+oV5RC4s0YyVPZ0s5VQKI3RRD1aY+euiVFPks3Mjx+DxEtKBOLsJ7I6crA==} + '@vuepress/bundler-vite@2.0.0-rc.26': + resolution: {integrity: sha512-4+YfKs2iOxuVSMW+L2tFzu2+X2HiGAREpo1DbkkYVDa5GyyPR+YsSueXNZMroTdzWDk5kAUz2Z1Tz1lIu7TO2g==} - '@vuepress/bundlerutils@2.0.0-rc.24': - resolution: {integrity: sha512-gtO0zhb57SyDotgdSI+TMAwJKg7KC75/G4UoWRwkyAHREsbWUInHQfXzzaFMnKmkdcB9YeXXbOnWGwZjRn74ew==} + '@vuepress/bundlerutils@2.0.0-rc.26': + resolution: {integrity: sha512-OnhUvzuJFEzPBjivZX7j6EhPE6sAwAIfyi3pAFmOpQDHPP7/l0q2I4bNVVGK4t9EZDu4N7Dl40/oFHhIMy5New==} - '@vuepress/cli@2.0.0-rc.24': - resolution: {integrity: sha512-3IJtADHg67U6q3i1n3klbBtm5TZZI3uO+MkEDq8efgK7kk27LAt+7GhxqxZCq5xJ+GPNZqElc+t3+eG9biDNFA==} + '@vuepress/cli@2.0.0-rc.26': + resolution: {integrity: sha512-63/4nIHrl9pbutUWs6SirWxmyykjvR9BWvu7bvczO1hAkWOyDQPcU18JXWy8q38CyMzPxCeedUfP3BQsZs3UgA==} hasBin: true - '@vuepress/client@2.0.0-rc.24': - resolution: {integrity: sha512-7W1FbrtsNDdWqkNoLfZKpZl8hv+j6sGCdmKtq90bRwzbaM+P2FJ6WYQ4Px4o/N0pqvr70k1zQe3A42QIeH0Ybw==} + '@vuepress/client@2.0.0-rc.26': + resolution: {integrity: sha512-+irF1HOTD6sAHdcTjp3yRcfuGlJYAW+YvDhq+7n3TPXeMH/wJbmGmAs2oRIDkx6Nlt3XkMMpFo7e9pOU22ut1w==} - '@vuepress/core@2.0.0-rc.24': - resolution: {integrity: sha512-NfNg6+vo5BJHBsLpoiXO8pU0zKaYCZxQinidW9r4KclNfZzC8PMkeBMeCT0uxcrb+XCaiHOrW19pF0/6NYNs0Q==} + '@vuepress/core@2.0.0-rc.26': + resolution: {integrity: sha512-Wyiv9oRvdT0lAPGU0Pj1HetjKicbX8/gqbBVYv2MmL7Y4a3r0tyQ92IdZ8LHiAgPvzctntQr/JXIELedvU1t/w==} - '@vuepress/helper@2.0.0-rc.112': - resolution: {integrity: sha512-gj19xHyYbG0wygcoJ6YypCNS+nybVt2AEJFyHTFvl+KiB2BfBhKWuCpWufp4c4Od1xkru4y56I+pSU2b8CGIBQ==} + '@vuepress/helper@2.0.0-rc.124': + resolution: {integrity: sha512-4Fn0prLhYX0F+I8P5YGm1vIZqajvy13pwiGsShzFA2enBKn4IHQ9n6sxDHr8NX9GjwovIb6xDit/hKUdxgbhEQ==} peerDependencies: - vuepress: 2.0.0-rc.24 + '@vuepress/bundler-vite': 2.0.0-rc.26 + '@vuepress/bundler-webpack': 2.0.0-rc.26 + vuepress: 2.0.0-rc.26 + peerDependenciesMeta: + '@vuepress/bundler-vite': + optional: true + '@vuepress/bundler-webpack': + optional: true - '@vuepress/highlighter-helper@2.0.0-rc.112': - resolution: {integrity: sha512-gDNGSOFR6yXS567ObWqn7vc8O8ZqCl1kn5wDdBfa0qe011CQgsJKQbGH6tFxfbi0JznZ1bjpKZmEaUKxsFRbtg==} + '@vuepress/highlighter-helper@2.0.0-rc.124': + resolution: {integrity: sha512-KdPOOoAWlAvNs7J4KQ0jzWLcHNVJm2JDfGlKgRBoLQ4KxiKiTRJa4xTatKJ1bXTONv4ihRGPidCO9/m7DPhS4w==} peerDependencies: - '@vueuse/core': ^13.5.0 - vuepress: 2.0.0-rc.24 + '@vuepress/helper': 2.0.0-rc.124 + '@vueuse/core': ^14.2.1 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: '@vueuse/core': optional: true - '@vuepress/markdown@2.0.0-rc.24': - resolution: {integrity: sha512-yYSo89cFbti2F/JWX3Odx9jbPje20PuVO+0SLkZX9AP5wuOv79Mx5QeRVEUS1YfD3faM98ya5LoIyuYWjPjJHw==} + '@vuepress/markdown@2.0.0-rc.26': + resolution: {integrity: sha512-ZAXkRxqPDjxqcG4j4vN2ZL5gmuRmgGH7n0s/7pcWIGFH3BJodp/PXMYCklnne1VwARIim9rqE3FKPB/ifJX0yA==} - '@vuepress/plugin-active-header-links@2.0.0-rc.112': - resolution: {integrity: sha512-D20vh2A/nPslD1fQdJMQh5BmViLCynJ41YcqaM3YEc9duI0rj6oVAFRALs9H2QipPtwPtibXkHERrR0WQxDsdA==} + '@vuepress/plugin-active-header-links@2.0.0-rc.124': + resolution: {integrity: sha512-O5UwL8P1G7Ol+TpF71onoWD1vpJlDnrma4/xgF9UDdctYZ/Xl0jUgpBlaQXaKZOZaBjThd00eOLQtwWcNRzF5Q==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-back-to-top@2.0.0-rc.112': - resolution: {integrity: sha512-R/JrM0jwMTzJxjzz+eCJB475sqAq/6p5SJYioRi7FMeuJ3pLheWVIh4gVV5TuJ71v6XyIJMeBr4Z9/sX+Lb3Bw==} + '@vuepress/plugin-back-to-top@2.0.0-rc.124': + resolution: {integrity: sha512-oc4qROifs82+ub9K8vcmu5xiDaul4HtBu3Z0FRl2bHPo/oVNwvU4yNUWHZPu388OfQQlFM24ywClKQi+qpX/VA==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-blog@2.0.0-rc.112': - resolution: {integrity: sha512-VZQG997jTAXx1E5UeLvf9spqH3UkHvwR8HtRMt/bQITHzAMDtoEFw3RDZd4rSdO41S4jksIsOhuqfz4zX+EQ3A==} + '@vuepress/plugin-blog@2.0.0-rc.124': + resolution: {integrity: sha512-zNuVMZ63W9racQNYevGOBiVSVF39A89yskaMzOOT8hZwmF5OgIhBSlIdb8/4I4vz2YiefQpwCxYAXSNT3UzS7A==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-catalog@2.0.0-rc.112': - resolution: {integrity: sha512-l4BbbwQ1t4jvJc9RurHIp42mQBo5H7H3MOo2bZj6qC3965mRihMztXjmFL8bb0A6pLthimmyYT9bJLvEDBy7Vg==} + '@vuepress/plugin-catalog@2.0.0-rc.124': + resolution: {integrity: sha512-Yzo6S1xFHgpA4zdLbL85oH9/hVS1e3gPhMtInA/+fgWmGu7Dml6ywJ4rh4mnZolEsV83prvzAvEaVD6pWU/VwQ==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-comment@2.0.0-rc.112': - resolution: {integrity: sha512-Ty7HE6oUI5Inlth4ykAWf7sug8kY7LD5t77p9zKLpITffRN6eIRipgAEyWRnogmwYYu6lj8THjrAj6Jc7+ACJw==} + '@vuepress/plugin-comment@2.0.0-rc.124': + resolution: {integrity: sha512-Dkg6P9f2cCE6a3JXCNUM2emTNwbCsCiHYYMNSxmUxM8lvi0E78hugvZ5d+G6rlioz6+DWW8NXpWibTOMrPkivQ==} peerDependencies: - '@waline/client': ^3.5.5 + '@waline/client': ^3.7.1 artalk: ^2.9.1 twikoo: ^1.6.41 - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: '@waline/client': optional: true @@ -828,47 +1121,47 @@ packages: twikoo: optional: true - '@vuepress/plugin-copy-code@2.0.0-rc.112': - resolution: {integrity: sha512-P0wrNU5O95/1s8LgXHNoMka66VhaJ9K9xiqVI8afJxJKtKOaanQ15pXqlJlhYIjnxMfV9Rh3YvM5qwiB9WSEyg==} + '@vuepress/plugin-copy-code@2.0.0-rc.124': + resolution: {integrity: sha512-qFhXrKOnqKaDk5eQqdmpg3ZtWwRLkud2G8Fm9rqNoYQ54n1ZMmLCdKIHoLKxf0woLL5Mjiii0eNnWrAgYFtlaw==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-copyright@2.0.0-rc.112': - resolution: {integrity: sha512-kpsIB8ntPufNO9Sbrr1YRdPLiWOUQuYWpey4L2Uiod5010gp79yOv9o3clKJdpKVPP6b5dfcuSYuekPJBbPE8Q==} + '@vuepress/plugin-copyright@2.0.0-rc.124': + resolution: {integrity: sha512-XNamMDJYywIB3sNGmZPwcA0rcGPbZlBMjG8lbf3Z3FZhayCrNmNSr7dnYtFdhLSyKMODQnXfj6JUksBV6sUHNw==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-feed@2.0.0-rc.112': - resolution: {integrity: sha512-K/7kvBxTilLDarqQne6lmmi41mP+PCrVCqMXAyaZR5VXcxUqE5cvNs/6N1AH8HXhRRtyAfsjlVYI3W0Yx5vYFA==} + '@vuepress/plugin-feed@2.0.0-rc.124': + resolution: {integrity: sha512-ZzqfzAizfUlHyL24X0dFaBX9an6bMo4wyJnEH6L8FGhREvKb5y+ZeHKXF/lueNQhFvyYw6VoOdXMFFYq2BluXA==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-git@2.0.0-rc.112': - resolution: {integrity: sha512-OKnw1wSgJuKFE6z2aFoqg+ldjUSRuTahzW8DVC9jOy32Uss0LDo0zXiL4UCk+XAkJXfERUOc2pXYOMs5seGDmQ==} + '@vuepress/plugin-git@2.0.0-rc.124': + resolution: {integrity: sha512-Wjn8Ykjl2KvxYWB/s0uOQstQka1T7q4CDVn+rmOizSnk7lWlyUmBTKt48Vfi8M0UbRGv+fKKLfiWLaJ2Kfzuvg==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-icon@2.0.0-rc.112': - resolution: {integrity: sha512-aufvjiIS9zHuTz2fQXZLCR6zSVtOifnCdnj+sQ8LYsT53OHikI1rNS8o0Dk68IyPP3eiFjdQ423+sKz17UPBYg==} + '@vuepress/plugin-icon@2.0.0-rc.124': + resolution: {integrity: sha512-mciTwwx8o/B/hqYOB5mrFNaCxiyKnzvfGRGsSnEjKCsmIX+T/Q7eA61UQ3M06xCpxG/gXDi1JP1vh98ORDYQ5Q==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-links-check@2.0.0-rc.112': - resolution: {integrity: sha512-UyxFAhJSXnxdeeoAToGPUbOzWLupAlIInLFBV6ZlQkyaOLEusAdxrfRxR+xJc7DhCVbzstP87PJC8VvO36unSA==} + '@vuepress/plugin-links-check@2.0.0-rc.124': + resolution: {integrity: sha512-SMQbpZ+ZoZ0hhHQ3P+aDn5RUexu31Ex/UHifHPLK4RgrJGCi9/tdIygECe2hYnVuqweRKBQ8u2ScTRLwrSV38A==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-chart@2.0.0-rc.112': - resolution: {integrity: sha512-mvmtYKSwD9m5B0ElrLHhqlwudkJbKtz9NstS5CmZ2exFOBkOGQBDeE9kbZGf2vUxHYbCZQQzjqAJB2bIIb+VZA==} + '@vuepress/plugin-markdown-chart@2.0.0-rc.124': + resolution: {integrity: sha512-7VCxXMwF6c2dab/E8q2d+GpKfN57+wFVsuoUhpvGm0Z0Paoo7+2nplUu/4DWk3CYgWw3v2xfmEQ+Ff4DxcvNxA==} peerDependencies: chart.js: ^4.4.7 - echarts: ^5.6.0 + echarts: ^6.0.0 flowchart.ts: ^3.0.1 markmap-lib: ^0.18.11 markmap-toolbar: ^0.18.10 markmap-view: ^0.18.10 - mermaid: ^11.8.0 - vuepress: 2.0.0-rc.24 + mermaid: ^11.12.0 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: chart.js: optional: true @@ -885,91 +1178,91 @@ packages: mermaid: optional: true - '@vuepress/plugin-markdown-ext@2.0.0-rc.112': - resolution: {integrity: sha512-fMaBKLmg/ux6s/PNDuIdBEogZOYys7sajZLnr7Xfp1gtQV/GnXAabBoBAINWbdy4Un0RRaMgLcqokR2AeS2poQ==} + '@vuepress/plugin-markdown-ext@2.0.0-rc.124': + resolution: {integrity: sha512-6ClJKNcNDppFU3a+HrZEnBNenG0fMony+ow5r+V8tzKvv9v3R2tcfRh/fKBgT5ipo6+yDALKQ69XraYbV2jPWQ==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-hint@2.0.0-rc.112': - resolution: {integrity: sha512-H4QCUIF3gvTh+/Etz0g3MBGCk48MLm9Dep/hJl2//Ke56lNSmldMac059itL8rzPQ4ntl0HoI55060e4zOprxw==} + '@vuepress/plugin-markdown-hint@2.0.0-rc.124': + resolution: {integrity: sha512-BFIOJpTSqpP59uroxTJE/bTUp7q2sisLZ3ZSXkG82v1D6+gf02a3FSew/WJHY/jDI0a31aLbOz5OBYIhpQHR7w==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-image@2.0.0-rc.112': - resolution: {integrity: sha512-E2Qju3SKtCLvRkBM1ZvtBWvOZW+eoIr2n1ZBawxcj9k1Zt74vvEy0BP7pKOSP5Qu9bwY6W1MAnT3H+R3QaDP+g==} + '@vuepress/plugin-markdown-image@2.0.0-rc.124': + resolution: {integrity: sha512-lb2HODcQAgTYqbDL1HvFcHEI5rXNOwoQjmbyQfaS3lFyz3YurxwhcnYe4wwAFOxqhQ1F89/NfZqbVdINC6BR4A==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-include@2.0.0-rc.112': - resolution: {integrity: sha512-zea8MlrUKbgAJm35Aqf/lDLz5Nu4LhVFV1C/IY0OlcvLwEbdyifPi/l1ZB+b2kfrW81GiuEb24a5Nr1JpDx2Gg==} + '@vuepress/plugin-markdown-include@2.0.0-rc.124': + resolution: {integrity: sha512-Wu0IMiz88kAs9/8iNb95VQB5DaflRmnLVoibwVKGNK+QBHTDJ3D4n3u/H7sQXV/1HR0HpjWWOroj9h2i7lhNMQ==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-math@2.0.0-rc.112': - resolution: {integrity: sha512-ZsIT3UKokslL+NUrdV5xTaOfuqEn41ZIlIL4PfCCgCpvUap/ziHbpQizU3sVgciq88mDsYYteVqgBqXcQzNiig==} + '@vuepress/plugin-markdown-math@2.0.0-rc.124': + resolution: {integrity: sha512-4rHd3WgXA5cfYfVbYvBrtIx5/XrY+dsOlsetQtYFmzGeGUtpQA+0BgbeQgbV4TW51A/qbG6fHDhHa3mmaFA4yg==} peerDependencies: + '@mathjax/src': ^4.0.0 katex: ^0.16.21 - mathjax-full: ^3.2.2 - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: - katex: + '@mathjax/src': optional: true - mathjax-full: + katex: optional: true - '@vuepress/plugin-markdown-preview@2.0.0-rc.112': - resolution: {integrity: sha512-R4Hl0JwapFZbzYPl3kC90w+cN/uecBXhpFER2xkX4oz7fPVYfF4I252JgzIyF1LofSsQMob7EUxbSmReVeliIA==} + '@vuepress/plugin-markdown-preview@2.0.0-rc.124': + resolution: {integrity: sha512-+QNDTd+jFe4ucfI8eMBSzyoSAIStNP4znEoRwKCL1EzFybBwgsH9IxIlVQYLOSO7/WKLWJf+FNLhLoGQKPmxdw==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-stylize@2.0.0-rc.112': - resolution: {integrity: sha512-M9wYDM1F/Qvo8jJgQcuhQbgrpZLLPe+KhkwBSKvSFOFD5QluEXBrd8S51eXSMlvLRJVE8VIj9Rh7TP9Q8wly/A==} + '@vuepress/plugin-markdown-stylize@2.0.0-rc.124': + resolution: {integrity: sha512-gkg3CEwxE3Svc/rQ+vyVjViNLrP+bEMW9+zmI+r9I60yj+qFCcbGrcA+MpboIenTSGA2Ei+a8VHurOqrzpB64w==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-markdown-tab@2.0.0-rc.112': - resolution: {integrity: sha512-Dnyn6ezrbl8KP7XD+8duPVAQL/E0TZTb3O4bRO/SLJSnbrbwSlNfm/ra5Vv2SgYQV9CnpFo6I+y7dETNK49t7A==} + '@vuepress/plugin-markdown-tab@2.0.0-rc.124': + resolution: {integrity: sha512-yBgWVINZB/J48E01LmcbC2SAvRbhZJpi8zm9WRon7qriMsSzjZea1yJDNQNt9tB93toGb7qKCzBvZ5D87XEf4Q==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-notice@2.0.0-rc.112': - resolution: {integrity: sha512-v6QRqWuH/42WNufosxu0FBUvGXh34j81Wiuio37DqSbMcgATkrPPEdXhMI27bg+zbXhms9UTukKJ4X8JJsN9Rg==} + '@vuepress/plugin-notice@2.0.0-rc.124': + resolution: {integrity: sha512-xcQI+E2we9nojMVsV9N8gbolR9xCEXKMavhlJg15egPiq/IkNI2wpog+sDQiBQDGIr8Eg/gE7cgUfP3zfGM2Og==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-nprogress@2.0.0-rc.112': - resolution: {integrity: sha512-kNz7SvVx7Z09aQFf4iwQ3C9h1WZBuefa7cKyYpSrWYFciFU2do98SUg3C5Wi8ttJ7oPcM+NmSiGbjJrjwpncig==} + '@vuepress/plugin-nprogress@2.0.0-rc.124': + resolution: {integrity: sha512-tAD+qM3uY3bffvxqs7vIRahJCP6wrZUx0M3T4OlW3hE28NIU82TOlNf+fMm6S5yNEE+kKbHOKp28u7/6fD9Q0Q==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-photo-swipe@2.0.0-rc.112': - resolution: {integrity: sha512-WkkPC9rjwAQCMuVwUqCl14hO8z2Odv5k1yF2pWH2XGBja5VyBJK5t+XUmS1ak7zcjTz40+AYmauglbXo06RUSQ==} + '@vuepress/plugin-photo-swipe@2.0.0-rc.124': + resolution: {integrity: sha512-o8gHuj3o/Z+T576qjEF+zsjwbLrs50dXX/4jKQoSbHrpItqHyNvHzQ2MQVNfOUPKFiD6i9BT86fPAsA3B/vPPQ==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-reading-time@2.0.0-rc.112': - resolution: {integrity: sha512-76t64Uvr+1ADAq1z/DbU9ftAXKhVOBjxGKplRkbffobyTQ0mrDjDBM2rArytQiK+8utDgGPTjblCt+oJkxovzg==} + '@vuepress/plugin-reading-time@2.0.0-rc.124': + resolution: {integrity: sha512-BSy+su85wrlYaFPQPKEqK1wv3H5MKVh/Rc9XMv2jFcRaSOatAgfAgwOUirc3OcSc2UrVGYNNoGpBAnJekZU43g==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-redirect@2.0.0-rc.112': - resolution: {integrity: sha512-IOSgVM3nUxO3zpQ7i4FY1kKM4A2I8iM9LCrCFALPrnvt1wfQ4SoTuCxqG3Z1BRgi30DzfMzoXsuVbMZkwk7n2g==} + '@vuepress/plugin-redirect@2.0.0-rc.124': + resolution: {integrity: sha512-0WS+c9A/4A/Aqq1Dpq8BgB3Nm+2YuEyRp6EjHzD31Z9RcUdYwdDan1NIMP78KdGq95DbIH7DQyEQ/dq7yicdvA==} hasBin: true peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-rtl@2.0.0-rc.112': - resolution: {integrity: sha512-wZwf1wE+FemynTECgXGOr7ly6p6hl3a2r39EQZLY7hIEp+MJIE8JKvP1EB2IuW0LCsEhnoSLX7wMC6EncUlnCQ==} + '@vuepress/plugin-rtl@2.0.0-rc.124': + resolution: {integrity: sha512-6ux/vBu9RmObqzPLnOMhyLCcDq/303zlUs/cHbNn4A7H4Wu1l7O5InLc8x+xrS8gFyJmZgAlNGeLlqXKecyktA==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-sass-palette@2.0.0-rc.112': - resolution: {integrity: sha512-luqYhX2AlGRBwABpR/JgnVuAm+5yxGdxoXNe7+cNF2dSRZq47WVT2alHvyWqECpDHxgMjVyUQN5PmD1zDs01sg==} + '@vuepress/plugin-sass-palette@2.0.0-rc.124': + resolution: {integrity: sha512-xZepBr8va9OjK3GnTCR7PolNT+kUngPM4QBVycFt3AdaPPKzBVe4JDZHaaJo27W2HwOuGsPchWjSLGduB9RKcQ==} peerDependencies: - sass: ^1.89.2 - sass-embedded: ^1.89.2 - sass-loader: ^16.0.5 - vuepress: 2.0.0-rc.24 + sass: ^1.95.0 + sass-embedded: ^1.95.0 + sass-loader: ^16.0.7 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: sass: optional: true @@ -978,51 +1271,51 @@ packages: sass-loader: optional: true - '@vuepress/plugin-search@2.0.0-rc.112': - resolution: {integrity: sha512-liQxClnwXRn3V8I3OORvS2/OwHSx2pi0c3F/V/ji++Zy4DVpSEzhMJAfHkHmo1KKzokqakSBiJz8bQudp5ZMFw==} + '@vuepress/plugin-search@2.0.0-rc.124': + resolution: {integrity: sha512-Jw0+7C54qQicSjpHga4WcjG9LhegmC4/traoeogxod6W86r/TdD9/rJIewoEx8GAmX3u899YCwydNv710zH6Sw==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-seo@2.0.0-rc.112': - resolution: {integrity: sha512-WWZ0Dx1MxF9Mj6UVdB8TP5GozTNv51ZQQP6EAKYzprKCw0RVQYg5/tXWlg7IWcSw72go5iFiMBj5wZQigN+t4g==} + '@vuepress/plugin-seo@2.0.0-rc.124': + resolution: {integrity: sha512-qpAuQfmEQWV3qgbcuqV1j1/nNzItk2MQscU+xN0jaWwfUY92MNFn3ulTS8xd+/rmSUhGpKKA1cWuAkzOPSkmOw==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-shiki@2.0.0-rc.112': - resolution: {integrity: sha512-jXPJuAl9zNrYqdMgLRdAakrYCJcHJJCoIJ/73ODtejfU1+78s7PL6HheFEyakWC8MGyReGw+e0vJs+9NisXxIQ==} + '@vuepress/plugin-shiki@2.0.0-rc.124': + resolution: {integrity: sha512-Ru62i98VGtIwdWimz3IN0inciJYXTLz06ToVKhnJKgyRaf9pOxKA11CdFvWBJN7s57RzsDAIpb9UIMro/jpbZA==} peerDependencies: - '@vuepress/shiki-twoslash': 2.0.0-rc.112 - vuepress: 2.0.0-rc.24 + '@vuepress/shiki-twoslash': 2.0.0-rc.124 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: '@vuepress/shiki-twoslash': optional: true - '@vuepress/plugin-sitemap@2.0.0-rc.112': - resolution: {integrity: sha512-64a/Kpu+2zY8r7o5AqFbZ1M3VKp44Z3RR6mGcr/747BEzVSl7ULk5ctx7Smtqm6Z2sSLEEU1aC6ZAtV5I+jqeQ==} + '@vuepress/plugin-sitemap@2.0.0-rc.124': + resolution: {integrity: sha512-Vi7boCrquHX2JOBjP/grGiy2FJ6KzQYrdYgzI3LFa8b1dxJcRPz1/tLd4WCoKd+wyhkk+TKWvsyucmsYhjTErg==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/plugin-theme-data@2.0.0-rc.112': - resolution: {integrity: sha512-QrCzB/wLxWmy76iEN140pZ1ZaigsFRimfGp1A65UOWAytEmkeRecEGBqZua4PDwiYOZQz/gf80xu5/SFsa8BAQ==} + '@vuepress/plugin-theme-data@2.0.0-rc.124': + resolution: {integrity: sha512-GVCcD9rIlwBQpbYDoYB6E2zdcn1Yfd2hYvy2z/DDzLosz7VprC/OaCPMVGLnr9ZQO4ApQEm32fLBLDbnj8bKcg==} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - '@vuepress/shared@2.0.0-rc.24': - resolution: {integrity: sha512-CAmJGMcDV5DnFEJ74f7IdCms2CBl8Md62uWbgAW8wEYiYanjRM8Rr1oIrz+cWoBSnWPf1HyPR3JoKYgw7OW4bw==} + '@vuepress/shared@2.0.0-rc.26': + resolution: {integrity: sha512-Zl9XNG/fYenZqzuYYGOfHzjmp1HCOj68gcJnJABOX1db0H35dkPSPsxuMjbTljClUqMlfj70CLeip/h04upGVw==} - '@vuepress/utils@2.0.0-rc.24': - resolution: {integrity: sha512-7D6o12Y64efevSdp+k84ivMZ3dSkZjQwbn79ywbHVbYtoZikvnpTE5GuG7lFOLcF3qZWQVqi7sRJVJdZnH9DuA==} + '@vuepress/utils@2.0.0-rc.26': + resolution: {integrity: sha512-RWzZrGQ0WLSWdELuxg7c6q1D9I22T5PfK/qNFkOsv9eD3gpUsU4jq4zAoumS8o+NRIWHovCJ9WnAhHD0Ns5zAw==} - '@vueuse/core@13.9.0': - resolution: {integrity: sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==} + '@vueuse/core@14.2.1': + resolution: {integrity: sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==} peerDependencies: vue: ^3.5.0 - '@vueuse/metadata@13.9.0': - resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==} + '@vueuse/metadata@14.2.1': + resolution: {integrity: sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==} - '@vueuse/shared@13.9.0': - resolution: {integrity: sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==} + '@vueuse/shared@14.2.1': + resolution: {integrity: sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==} peerDependencies: vue: ^3.5.0 @@ -1030,6 +1323,11 @@ packages: resolution: {integrity: sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==} engines: {node: '>=14.6'} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1042,10 +1340,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -1055,8 +1349,8 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - autoprefixer@10.4.22: - resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -1068,20 +1362,17 @@ packages: balloon-css@1.2.0: resolution: {integrity: sha512-urXwkHgwp6GsXVF+it01485Z2Cj4pnW02ICnM0TemOlkKmCNnDLmyy+ZZiRXBpwldUXO+aRNr7Hdia4CBvXJ5A==} - baseline-browser-mapping@2.8.28: - resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + baseline-browser-mapping@2.10.0: + resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + engines: {node: '>=6.0.0'} hasBin: true - bcrypt-ts@7.1.0: - resolution: {integrity: sha512-t/Dqr9YzYmn/+oPQBgotBPUuezpZD5CPBwapM5Ep1p3zsLmEycMdXOfZpWbztSBWJ41DlB7EluJBUDsAGSiUeQ==} + bcrypt-ts@8.0.1: + resolution: {integrity: sha512-ILrO7U7YieyG+71KVIVVuPCmjN8N9DY3gYs4OiEoJvW8A5HOe4eerRhLD0Rgo2CAyANRKssFGXmLF74zJz094g==} engines: {node: '>=20'} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - birpc@2.8.0: - resolution: {integrity: sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==} + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -1090,14 +1381,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.0: - resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer-builder@0.2.0: - resolution: {integrity: sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==} - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -1106,8 +1394,8 @@ packages: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - caniuse-lite@1.0.30001755: - resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} + caniuse-lite@1.0.30001778: + resolution: {integrity: sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1131,25 +1419,33 @@ packages: cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - cheerio@1.1.2: - resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} engines: {node: '>=20.18.1'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.1.2: + resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -1171,25 +1467,34 @@ packages: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} - copy-anything@4.0.5: - resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} - engines: {node: '>=18'} + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} - create-codepen@2.0.0: - resolution: {integrity: sha512-ehJ0Zw5RSV2G4+/azUb7vEZWRSA/K9cW7HDock1Y9ViDexkgSJUZJRcObdw/YAWeXKjreEQV9l/igNSsJ1yw5A==} - engines: {node: '>=18'} + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + create-codepen@2.0.1: + resolution: {integrity: sha512-qFOOo1dxz8/j5Fn8tJHi61/r5ko7sn2RLPZ6HISi5SeKR61y8zA9szsG7UssLzWeBILvN3c1TZNXrz5UR7KlGw==} + engines: {node: '>=20'} css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} @@ -1198,8 +1503,167 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} - csstype@3.2.2: - resolution: {integrity: sha512-D80T+tiqkd/8B0xNlbstWDG4x6aqVfO52+OlSUNIdkTvmNw0uQpJLeos2J/2XvpyidAFuTPmpad+tUxLndwj6g==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.1: + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -1214,13 +1678,20 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - decode-named-character-reference@1.2.0: - resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -1237,14 +1708,14 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + dompurify@3.3.3: + resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - electron-to-chromium@1.5.254: - resolution: {integrity: sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==} - - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + electron-to-chromium@1.5.313: + resolution: {integrity: sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1260,8 +1731,12 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} - envinfo@7.20.0: - resolution: {integrity: sha512-+zUomDcLXsVkQ37vUqWBvQwLaLlj8eZPSi61llaEFAVBY5mhcXdaSw1pSJVl4yTYD5g/gEfpNl28YYk4IPvrrg==} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} engines: {node: '>=4'} hasBin: true @@ -1297,8 +1772,8 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -1323,8 +1798,8 @@ packages: fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - fs-extra@11.3.2: - resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fsevents@2.3.3: @@ -1336,8 +1811,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} giscus@1.6.0: @@ -1351,10 +1826,6 @@ packages: resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} engines: {node: '>=18'} - globby@14.1.0: - resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} - engines: {node: '>=18'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -1362,6 +1833,9 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1396,8 +1870,8 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - htmlparser2@10.0.0: - resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} @@ -1412,12 +1886,15 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} - immutable@5.1.4: - resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -1425,10 +1902,6 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -1463,18 +1936,10 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - is-unicode-supported@2.1.0: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} - is-what@5.5.0: - resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} - engines: {node: '>=18'} - js-yaml@3.14.2: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true @@ -1493,14 +1958,27 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - katex@0.16.25: - resolution: {integrity: sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==} + katex@0.16.38: + resolution: {integrity: sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==} hasBin: true + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + langium@4.2.1: + resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -1508,21 +1986,24 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - lit-element@4.2.1: - resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} - lit-html@3.3.1: - resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + lit-html@3.3.2: + resolution: {integrity: sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==} - lit@3.3.1: - resolution: {integrity: sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==} + lit@3.3.2: + resolution: {integrity: sha512-NF9zbsP79l4ao2SNrH3NkfmFgN/hBYSQo90saIVI1o5GpjAdCPVstVzO1MrLOakHoEhYkrtRjPK6Ob521aoYWQ==} locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} engines: {node: '>=18'} magic-string@0.30.21: @@ -1534,6 +2015,16 @@ packages: '@types/markdown-it': '*' markdown-it: '*' + markdown-it-cjk-friendly@2.0.2: + resolution: {integrity: sha512-KXCl6sd129UqkAiRDb+NcAHrxC9xRa2WsGIsMMvtp2y1YlbeIaNYzArX2zfDoGhOjsyNMfJrGO7xGBss27YQSA==} + engines: {node: '>=18'} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + peerDependenciesMeta: + '@types/markdown-it': + optional: true + markdown-it-emoji@3.0.0: resolution: {integrity: sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==} @@ -1541,6 +2032,10 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + markdownlint-cli2-formatter-default@0.0.5: resolution: {integrity: sha512-4XKTwQ5m1+Txo2kuQ3Jgpo/KmnG+X90dWt4acufg6HVGadTUG5hzHF/wssp9b5MBYOMCnZ9RMPaU//uHsszF8Q==} peerDependencies: @@ -1555,12 +2050,17 @@ packages: resolution: {integrity: sha512-eoQqH0291YCCjd+Pe1PUQ9AmWthlVmS0XWgcionkZ8q34ceZyRI+pYvsWksXJJL8OBkWCPwp1h/pnXxrPFC4oA==} engines: {node: '>=18'} + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + mathjax-full@3.2.2: resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} deprecated: Version 4 replaces this package with the scoped package @mathjax/src - mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} @@ -1569,6 +2069,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + mermaid@11.13.0: + resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} + mhchemparser@4.2.1: resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} @@ -1655,12 +2158,12 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - mj-context-menu@0.6.1: resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==} + mlly@1.8.1: + resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1679,16 +2182,11 @@ packages: engines: {node: ^18 || >=20} hasBin: true - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -1700,12 +2198,12 @@ packages: oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} - oniguruma-to-es@4.3.3: - resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + oniguruma-to-es@4.3.4: + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} - ora@8.2.0: - resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} - engines: {node: '>=18'} + ora@9.3.0: + resolution: {integrity: sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw==} + engines: {node: '>=20'} p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} @@ -1719,6 +2217,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} @@ -1731,6 +2232,9 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1739,12 +2243,11 @@ packages: resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} engines: {node: '>=12'} - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} photoswipe@5.4.4: resolution: {integrity: sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==} @@ -1761,10 +2264,19 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pngjs@5.0.0: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -1786,8 +2298,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} prettier@3.4.2: @@ -1810,22 +2322,22 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + regex-recursion@6.0.2: resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} regex-utilities@2.3.0: resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - regex@6.0.1: - resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} @@ -1851,126 +2363,154 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rollup@4.53.2: - resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass-embedded-android-arm64@1.89.2: - resolution: {integrity: sha512-+pq7a7AUpItNyPu61sRlP6G2A8pSPpyazASb+8AK2pVlFayCSPAEgpwpCE9A2/Xj86xJZeMizzKUHxM2CBCUxA==} + sass-embedded-all-unknown@1.98.0: + resolution: {integrity: sha512-6n4RyK7/1mhdfYvpP3CClS3fGoYqDvRmLClCESS6I7+SAzqjxvGG6u5Fo+cb1nrPNbbilgbM4QKdgcgWHO9NCA==} + cpu: ['!arm', '!arm64', '!riscv64', '!x64'] + + sass-embedded-android-arm64@1.98.0: + resolution: {integrity: sha512-M9Ra98A6vYJHpwhoC/5EuH1eOshQ9ZyNwC8XifUDSbRl/cGeQceT1NReR9wFj3L7s1pIbmes1vMmaY2np0uAKQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] - sass-embedded-android-arm@1.89.2: - resolution: {integrity: sha512-oHAPTboBHRZlDBhyRB6dvDKh4KvFs+DZibDHXbkSI6dBZxMTT+Yb2ivocHnctVGucKTLQeT7+OM5DjWHyynL/A==} + sass-embedded-android-arm@1.98.0: + resolution: {integrity: sha512-LjGiMhHgu7VL1n7EJxTCre1x14bUsWd9d3dnkS2rku003IWOI/fxc7OXgaKagoVzok1kv09rzO3vFXJR5ZeONQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] - sass-embedded-android-riscv64@1.89.2: - resolution: {integrity: sha512-HfJJWp/S6XSYvlGAqNdakeEMPOdhBkj2s2lN6SHnON54rahKem+z9pUbCriUJfM65Z90lakdGuOfidY61R9TYg==} + sass-embedded-android-riscv64@1.98.0: + resolution: {integrity: sha512-WPe+0NbaJIZE1fq/RfCZANMeIgmy83x4f+SvFOG7LhUthHpZWcOcrPTsCKKmN3xMT3iw+4DXvqTYOCYGRL3hcQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] - sass-embedded-android-x64@1.89.2: - resolution: {integrity: sha512-BGPzq53VH5z5HN8de6jfMqJjnRe1E6sfnCWFd4pK+CAiuM7iw5Fx6BQZu3ikfI1l2GY0y6pRXzsVLdp/j4EKEA==} + sass-embedded-android-x64@1.98.0: + resolution: {integrity: sha512-zrD25dT7OHPEgLWuPEByybnIfx4rnCtfge4clBgjZdZ3lF6E7qNLRBtSBmoFflh6Vg0RlEjJo5VlpnTMBM5MQQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] - sass-embedded-darwin-arm64@1.89.2: - resolution: {integrity: sha512-UCm3RL/tzMpG7DsubARsvGUNXC5pgfQvP+RRFJo9XPIi6elopY5B6H4m9dRYDpHA+scjVthdiDwkPYr9+S/KGw==} + sass-embedded-darwin-arm64@1.98.0: + resolution: {integrity: sha512-cgr1z9rBnCdMf8K+JabIaYd9Rag2OJi5mjq08XJfbJGMZV/TA6hFJCLGkr5/+ZOn4/geTM5/3aSfQ8z5EIJAOg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - sass-embedded-darwin-x64@1.89.2: - resolution: {integrity: sha512-D9WxtDY5VYtMApXRuhQK9VkPHB8R79NIIR6xxVlN2MIdEid/TZWi1MHNweieETXhWGrKhRKglwnHxxyKdJYMnA==} + sass-embedded-darwin-x64@1.98.0: + resolution: {integrity: sha512-OLBOCs/NPeiMqTdOrMFbVHBQFj19GS3bSVSxIhcCq16ZyhouUkYJEZjxQgzv9SWA2q6Ki8GCqp4k6jMeUY9dcA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - sass-embedded-linux-arm64@1.89.2: - resolution: {integrity: sha512-2N4WW5LLsbtrWUJ7iTpjvhajGIbmDR18ZzYRywHdMLpfdPApuHPMDF5CYzHbS+LLx2UAx7CFKBnj5LLjY6eFgQ==} + sass-embedded-linux-arm64@1.98.0: + resolution: {integrity: sha512-axOE3t2MTBwCtkUCbrdM++Gj0gC0fdHJPrgzQ+q1WUmY9NoNMGqflBtk5mBZaWUeha2qYO3FawxCB8lctFwCtw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] + libc: glibc - sass-embedded-linux-arm@1.89.2: - resolution: {integrity: sha512-leP0t5U4r95dc90o8TCWfxNXwMAsQhpWxTkdtySDpngoqtTy3miMd7EYNYd1znI0FN1CBaUvbdCMbnbPwygDlA==} + sass-embedded-linux-arm@1.98.0: + resolution: {integrity: sha512-03baQZCxVyEp8v1NWBRlzGYrmVT/LK7ZrHlF1piscGiGxwfdxoLXVuxsylx3qn/dD/4i/rh7Bzk7reK1br9jvQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] + libc: glibc - sass-embedded-linux-musl-arm64@1.89.2: - resolution: {integrity: sha512-nTyuaBX6U1A/cG7WJh0pKD1gY8hbg1m2SnzsyoFG+exQ0lBX/lwTLHq3nyhF+0atv7YYhYKbmfz+sjPP8CZ9lw==} + sass-embedded-linux-musl-arm64@1.98.0: + resolution: {integrity: sha512-LeqNxQA8y4opjhe68CcFvMzCSrBuJqYVFbwElEj9bagHXQHTp9xVPJRn6VcrC+0VLEDq13HVXMv7RslIuU0zmA==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] + libc: musl - sass-embedded-linux-musl-arm@1.89.2: - resolution: {integrity: sha512-Z6gG2FiVEEdxYHRi2sS5VIYBmp17351bWtOCUZ/thBM66+e70yiN6Eyqjz80DjL8haRUegNQgy9ZJqsLAAmr9g==} + sass-embedded-linux-musl-arm@1.98.0: + resolution: {integrity: sha512-OBkjTDPYR4hSaueOGIM6FDpl9nt/VZwbSRpbNu9/eEJcxE8G/vynRugW8KRZmCFjPy8j/jkGBvvS+k9iOqKV3g==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] + libc: musl - sass-embedded-linux-musl-riscv64@1.89.2: - resolution: {integrity: sha512-N6oul+qALO0SwGY8JW7H/Vs0oZIMrRMBM4GqX3AjM/6y8JsJRxkAwnfd0fDyK+aICMFarDqQonQNIx99gdTZqw==} + sass-embedded-linux-musl-riscv64@1.98.0: + resolution: {integrity: sha512-7w6hSuOHKt8FZsmjRb3iGSxEzM87fO9+M8nt5JIQYMhHTj5C+JY/vcske0v715HCVj5e1xyTnbGXf8FcASeAIw==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] + libc: musl - sass-embedded-linux-musl-x64@1.89.2: - resolution: {integrity: sha512-K+FmWcdj/uyP8GiG9foxOCPfb5OAZG0uSVq80DKgVSC0U44AdGjvAvVZkrgFEcZ6cCqlNC2JfYmslB5iqdL7tg==} + sass-embedded-linux-musl-x64@1.98.0: + resolution: {integrity: sha512-QikNyDEJOVqPmxyCFkci8ZdCwEssdItfjQFJB+D+Uy5HFqcS5Lv3d3GxWNX/h1dSb23RPyQdQc267ok5SbEyJw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] + libc: musl - sass-embedded-linux-riscv64@1.89.2: - resolution: {integrity: sha512-g9nTbnD/3yhOaskeqeBQETbtfDQWRgsjHok6bn7DdAuwBsyrR3JlSFyqKc46pn9Xxd9SQQZU8AzM4IR+sY0A0w==} + sass-embedded-linux-riscv64@1.98.0: + resolution: {integrity: sha512-E7fNytc/v4xFBQKzgzBddV/jretA4ULAPO6XmtBiQu4zZBdBozuSxsQLe2+XXeb0X4S2GIl72V7IPABdqke/vA==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] + libc: glibc - sass-embedded-linux-x64@1.89.2: - resolution: {integrity: sha512-Ax7dKvzncyQzIl4r7012KCMBvJzOz4uwSNoyoM5IV6y5I1f5hEwI25+U4WfuTqdkv42taCMgpjZbh9ERr6JVMQ==} + sass-embedded-linux-x64@1.98.0: + resolution: {integrity: sha512-VsvP0t/uw00mMNPv3vwyYKUrFbqzxQHnRMO+bHdAMjvLw4NFf6mscpym9Bzf+NXwi1ZNKnB6DtXjmcpcvqFqYg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] + libc: glibc + + sass-embedded-unknown-all@1.98.0: + resolution: {integrity: sha512-C4MMzcAo3oEDQnW7L8SBgB9F2Fq5qHPnaYTZRMOH3Mp/7kM4OooBInXpCiiFjLnjY95hzP4KyctVx0uYR6MYlQ==} + os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-win32-arm64@1.89.2: - resolution: {integrity: sha512-j96iJni50ZUsfD6tRxDQE2QSYQ2WrfHxeiyAXf41Kw0V4w5KYR/Sf6rCZQLMTUOHnD16qTMVpQi20LQSqf4WGg==} + sass-embedded-win32-arm64@1.98.0: + resolution: {integrity: sha512-nP/10xbAiPbhQkMr3zQfXE4TuOxPzWRQe1Hgbi90jv2R4TbzbqQTuZVOaJf7KOAN4L2Bo6XCTRjK5XkVnwZuwQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - sass-embedded-win32-x64@1.89.2: - resolution: {integrity: sha512-cS2j5ljdkQsb4PaORiClaVYynE9OAPZG/XjbOMxpQmjRIf7UroY4PEIH+Waf+y47PfXFX9SyxhYuw2NIKGbEng==} + sass-embedded-win32-x64@1.98.0: + resolution: {integrity: sha512-/lbrVsfbcbdZQ5SJCWcV0NVPd6YRs+FtAnfedp4WbCkO/ZO7Zt/58MvI4X2BVpRY/Nt5ZBo1/7v2gYcQ+J4svQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - sass-embedded@1.89.2: - resolution: {integrity: sha512-Ack2K8rc57kCFcYlf3HXpZEJFNUX8xd8DILldksREmYXQkRHI879yy8q4mRDJgrojkySMZqmmmW1NxrFxMsYaA==} + sass-embedded@1.98.0: + resolution: {integrity: sha512-Do7u6iRb6K+lrllcTkB1BXcHwOxcKe3rEfOF/GcCLE2w3WpddakRAosJOHFUR37DpsvimQXEt5abs3NzUjEIqg==} engines: {node: '>=16.0.0'} hasBin: true - sax@1.4.3: - resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + sass@1.98.0: + resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.5.0: + resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} + engines: {node: '>=11.0.0'} section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} @@ -1979,16 +2519,17 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - shiki@3.15.0: - resolution: {integrity: sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw==} + shiki@4.0.2: + resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==} + engines: {node: '>=20'} signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sitemap@8.0.2: - resolution: {integrity: sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==} - engines: {node: '>=14.0.0', npm: '>=6.0.0'} + sitemap@9.0.1: + resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} + engines: {node: '>=20.19.5', npm: '>=10.8.2'} hasBin: true slash@5.1.0: @@ -2002,10 +2543,6 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - speech-rule-engine@4.1.2: resolution: {integrity: sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==} hasBin: true @@ -2013,17 +2550,17 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stdin-discarder@0.2.2: - resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + stdin-discarder@0.3.1: + resolution: {integrity: sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA==} engines: {node: '>=18'} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} + string-width@8.2.0: + resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} + engines: {node: '>=20'} stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -2032,17 +2569,16 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} - superjson@2.2.5: - resolution: {integrity: sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w==} - engines: {node: '>=16'} + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} @@ -2052,14 +2588,18 @@ packages: resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} engines: {node: '>=16.0.0'} - sync-message-port@1.1.3: - resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==} + sync-message-port@1.2.0: + resolution: {integrity: sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==} engines: {node: '>=16.0.0'} - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + synckit@0.11.12: + resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -2074,27 +2614,33 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@7.16.0: - resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} engines: {node: '>=20.18.1'} unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -2110,8 +2656,8 @@ packages: unist-util-visit-parents@6.0.2: resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -2121,12 +2667,16 @@ packages: resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} engines: {node: '>=4'} - update-browserslist-db@1.1.4: - resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + varint@6.0.0: resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} @@ -2139,8 +2689,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@7.0.8: - resolution: {integrity: sha512-cJBdq0/u+8rgstg9t7UkBilf8ipLmeXJO30NxD5HAHOivnj10ocV8YtR/XBvd2wQpN3TmcaxNKaHX3tN7o5F5A==} + vite@7.1.12: + resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2179,32 +2729,52 @@ packages: yaml: optional: true - vue-router@4.6.3: - resolution: {integrity: sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==} + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==} peerDependencies: vue: ^3.5.0 - vue@3.5.24: - resolution: {integrity: sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==} + vue@3.5.30: + resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - vuepress-plugin-components@2.0.0-rc.94: - resolution: {integrity: sha512-U6s7qWG1ETm7yvshD+gWe1SrTezjaFvW8gUvmmAZEoLTV5Pd+FC7BR7W8syPieOzUzOVjF2UeO5zVsZ/M9jp4A==} - engines: {node: '>= 20.6.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + vuepress-plugin-components@2.0.0-rc.103: + resolution: {integrity: sha512-RZEZgNpbRHwGMtubyipjR/KAsgHp7xnw0E4Ww5/IEVPY99LksuuTlnvjhHNmrsX17LxTo6pVJ/Nhc/sXQEknyg==} + engines: {node: '>=20.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: artplayer: ^5.0.0 dashjs: 4.7.4 hls.js: ^1.4.12 mpegts.js: ^1.7.3 - sass: ^1.89.2 - sass-embedded: ^1.89.2 - sass-loader: ^16.0.5 + sass: ^1.97.3 + sass-embedded: ^1.97.3 + sass-loader: ^16.0.7 vidstack: ^1.12.9 - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: artplayer: optional: true @@ -2223,17 +2793,17 @@ packages: vidstack: optional: true - vuepress-plugin-md-enhance@2.0.0-rc.94: - resolution: {integrity: sha512-oI9e3JvdcpQeK3w1nIowl+Tn49euLxicrIg1uKf0mUd7JB1ofo1XDuxBLtRASgRoqCRiiQsq1trYnyO9CiPGpQ==} - engines: {node: '>= 20.6.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + vuepress-plugin-md-enhance@2.0.0-rc.103: + resolution: {integrity: sha512-Lpr4bec4mzvzhahG7kjJR5fc8JN/kvlbbGInXL5yscby87baNGpsmVH7xpuym0vT3Q5h8LnDxQ/EvIitwSIFzg==} + engines: {node: '>= 20.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: '@vue/repl': ^4.1.1 kotlin-playground: ^1.23.0 sandpack-vue3: ^3.0.0 - sass: ^1.89.2 - sass-embedded: ^1.89.2 - sass-loader: ^16.0.5 - vuepress: 2.0.0-rc.24 + sass: ^1.97.3 + sass-embedded: ^1.97.3 + sass-loader: ^16.0.7 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: '@vue/repl': optional: true @@ -2248,31 +2818,30 @@ packages: sass-loader: optional: true - vuepress-shared@2.0.0-rc.94: - resolution: {integrity: sha512-ZlVIeRkCY7jt8QpELr3i5PGFkWk7VkTG1emn6BuOE2Hd+tI8zZH4a6lCGqtkhpu093tpM+tSANiR83RRNQCCCw==} - engines: {node: '>= 20.6.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + vuepress-shared@2.0.0-rc.103: + resolution: {integrity: sha512-F8/3mYmh4BEacG+cHCtu7BmF5HrxfcwiLYd0523h+XYN02abgcUS8EJ7mZo/6juj5ZhWjjsWLarctim4wmOvIw==} + engines: {node: '>= 20.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: - vuepress: 2.0.0-rc.24 + vuepress: 2.0.0-rc.26 - vuepress-theme-hope@2.0.0-rc.94: - resolution: {integrity: sha512-FA35vxdUY3tk1ORDSCTTozttoTNSmdCTms3v7871vUFeKmQ+MY+iCFGDVMeoCEcuCMGJ7F0+bcCUkH3ohFcdgQ==} - engines: {node: '>= 20.6.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + vuepress-theme-hope@2.0.0-rc.103: + resolution: {integrity: sha512-LPd5wy7YTUc/FPXpLgEzDOywwI2WGqAgfTnrIoLsPOkTBkZqvJRi47kueF7bTmkqupR2P2igAmHJVToBJIzVOw==} + engines: {node: '>= 20.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: - '@vuepress/plugin-docsearch': 2.0.0-rc.112 - '@vuepress/plugin-feed': 2.0.0-rc.112 - '@vuepress/plugin-meilisearch': 2.0.0-rc.112 - '@vuepress/plugin-prismjs': 2.0.0-rc.112 - '@vuepress/plugin-pwa': 2.0.0-rc.112 - '@vuepress/plugin-revealjs': 2.0.0-rc.112 - '@vuepress/plugin-search': 2.0.0-rc.112 - '@vuepress/plugin-slimsearch': 2.0.0-rc.112 - '@vuepress/plugin-watermark': 2.0.0-rc.112 - '@vuepress/shiki-twoslash': 2.0.0-rc.112 - nodejs-jieba: ^0.2.1 || ^0.3.0 - sass: ^1.89.2 - sass-embedded: ^1.89.2 - sass-loader: ^16.0.5 - vuepress: 2.0.0-rc.24 + '@vuepress/plugin-docsearch': 2.0.0-rc.124 + '@vuepress/plugin-feed': 2.0.0-rc.124 + '@vuepress/plugin-meilisearch': 2.0.0-rc.124 + '@vuepress/plugin-prismjs': 2.0.0-rc.124 + '@vuepress/plugin-pwa': 2.0.0-rc.124 + '@vuepress/plugin-revealjs': 2.0.0-rc.124 + '@vuepress/plugin-search': 2.0.0-rc.124 + '@vuepress/plugin-slimsearch': 2.0.0-rc.124 + '@vuepress/plugin-watermark': 2.0.0-rc.124 + '@vuepress/shiki-twoslash': 2.0.0-rc.124 + sass: ^1.97.3 + sass-embedded: ^1.97.3 + sass-loader: ^16.0.7 + vuepress: 2.0.0-rc.26 peerDependenciesMeta: '@vuepress/plugin-docsearch': optional: true @@ -2294,8 +2863,6 @@ packages: optional: true '@vuepress/shiki-twoslash': optional: true - nodejs-jieba: - optional: true sass: optional: true sass-embedded: @@ -2303,14 +2870,14 @@ packages: sass-loader: optional: true - vuepress@2.0.0-rc.24: - resolution: {integrity: sha512-56O9fAj3Fr1ezngeHDGyp5I1fWxBnP6gaGerjYjPNtr2RteSZtnqL/fQDzmiw5rFpuMVlfOTXESvQjQUlio8PQ==} + vuepress@2.0.0-rc.26: + resolution: {integrity: sha512-ztTS3m6Q2MAb6D26vM2UyU5nOuxIhIk37SSD3jTcKI00x4ha0FcwY3Cm0MAt6w58REBmkwNLPxN5iiulatHtbw==} engines: {node: ^20.9.0 || >=22.0.0} hasBin: true peerDependencies: - '@vuepress/bundler-vite': 2.0.0-rc.24 - '@vuepress/bundler-webpack': 2.0.0-rc.24 - vue: ^3.5.17 + '@vuepress/bundler-vite': 2.0.0-rc.26 + '@vuepress/bundler-webpack': 2.0.0-rc.26 + vue: ^3.5.22 peerDependenciesMeta: '@vuepress/bundler-vite': optional: true @@ -2353,25 +2920,53 @@ packages: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.0.2 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} - '@babel/parser@7.28.5': + '@babel/parser@7.29.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 - '@babel/types@7.28.5': + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@bufbuild/protobuf@2.10.1': {} + '@braintree/sanitize-url@7.1.2': {} + + '@bufbuild/protobuf@2.11.0': {} + + '@chevrotain/cst-dts-gen@11.1.2': + dependencies: + '@chevrotain/gast': 11.1.2 + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/gast@11.1.2': + dependencies: + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/regexp-to-ast@11.1.2': {} + + '@chevrotain/types@11.1.2': {} + + '@chevrotain/utils@11.1.2': {} '@esbuild/aix-ppc64@0.25.12': optional: true @@ -2451,225 +3046,251 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.1 + '@jridgewell/sourcemap-codec@1.5.5': {} - '@lit-labs/ssr-dom-shim@1.4.0': {} + '@lit-labs/ssr-dom-shim@1.5.1': {} - '@lit/reactive-element@2.1.1': + '@lit/reactive-element@2.1.2': dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit-labs/ssr-dom-shim': 1.5.1 - '@mdit-vue/plugin-component@2.1.4': + '@mdit-vue/plugin-component@3.0.2': dependencies: '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/plugin-frontmatter@2.1.4': + '@mdit-vue/plugin-frontmatter@3.0.2': dependencies: - '@mdit-vue/types': 2.1.4 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 gray-matter: 4.0.3 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/plugin-headers@2.1.4': + '@mdit-vue/plugin-headers@3.0.2': dependencies: - '@mdit-vue/shared': 2.1.4 - '@mdit-vue/types': 2.1.4 + '@mdit-vue/shared': 3.0.2 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/plugin-sfc@2.1.4': + '@mdit-vue/plugin-sfc@3.0.2': dependencies: - '@mdit-vue/types': 2.1.4 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/plugin-title@2.1.4': + '@mdit-vue/plugin-title@3.0.2': dependencies: - '@mdit-vue/shared': 2.1.4 - '@mdit-vue/types': 2.1.4 + '@mdit-vue/shared': 3.0.2 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/plugin-toc@2.1.4': + '@mdit-vue/plugin-toc@3.0.2': dependencies: - '@mdit-vue/shared': 2.1.4 - '@mdit-vue/types': 2.1.4 + '@mdit-vue/shared': 3.0.2 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/shared@2.1.4': + '@mdit-vue/shared@3.0.2': dependencies: - '@mdit-vue/types': 2.1.4 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit-vue/types@2.1.4': {} + '@mdit-vue/types@3.0.2': {} - '@mdit/helper@0.22.1(markdown-it@14.1.0)': + '@mdit/helper@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-alert@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-alert@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-align@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-align@0.24.1(markdown-it@14.1.1)': dependencies: - '@mdit/plugin-container': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-container': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-attrs@0.23.3(markdown-it@14.1.0)': + '@mdit/plugin-attrs@0.25.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-container@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-container@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-demo@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-demo@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-figure@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-figure@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-footnote@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-footnote@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-icon@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-icon@0.24.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-img-lazyload@0.22.1(markdown-it@14.1.0)': + '@mdit/plugin-img-lazyload@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-img-mark@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-img-mark@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-img-size@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-img-size@0.23.1(markdown-it@14.1.1)': dependencies: '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-include@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-include@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 upath: 2.0.1 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-katex-slim@0.23.2(katex@0.16.25)(markdown-it@14.1.0)': + '@mdit/plugin-inline-rule@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) - '@mdit/plugin-tex': 0.22.2(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - katex: 0.16.25 - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-mark@0.22.1(markdown-it@14.1.0)': + '@mdit/plugin-katex-slim@0.26.1(katex@0.16.38)(markdown-it@14.1.1)': dependencies: + '@mdit/helper': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-tex': 0.24.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + katex: 0.16.38 + markdown-it: 14.1.1 - '@mdit/plugin-mathjax-slim@0.23.2(markdown-it@14.1.0)(mathjax-full@3.2.2)': + '@mdit/plugin-layout@0.2.1(markdown-it@14.1.1)': dependencies: - '@mdit/plugin-tex': 0.22.2(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - upath: 2.0.1 optionalDependencies: - markdown-it: 14.1.0 - mathjax-full: 3.2.2 + markdown-it: 14.1.1 - '@mdit/plugin-plantuml@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-mark@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/plugin-uml': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-inline-rule': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-spoiler@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-mathjax-slim@0.26.1(markdown-it@14.1.1)': dependencies: + '@mdit/plugin-tex': 0.24.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-stylize@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-plantuml@0.24.1(markdown-it@14.1.1)': dependencies: + '@mdit/plugin-uml': 0.24.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-sub@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-spoiler@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) + '@mdit/plugin-inline-rule': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-sup@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-stylize@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-tab@0.22.3(markdown-it@14.1.0)': + '@mdit/plugin-sub@0.24.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) + '@mdit/plugin-inline-rule': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-tasklist@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-sup@0.24.1(markdown-it@14.1.1)': dependencies: + '@mdit/plugin-inline-rule': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-tex@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-tab@0.24.1(markdown-it@14.1.1)': dependencies: + '@mdit/helper': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 - '@mdit/plugin-uml@0.22.2(markdown-it@14.1.0)': + '@mdit/plugin-tasklist@0.23.1(markdown-it@14.1.1)': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) '@types/markdown-it': 14.1.2 optionalDependencies: - markdown-it: 14.1.0 + markdown-it: 14.1.1 + + '@mdit/plugin-tex@0.24.1(markdown-it@14.1.1)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.1 + + '@mdit/plugin-uml@0.24.1(markdown-it@14.1.1)': + dependencies: + '@mdit/helper': 0.23.1(markdown-it@14.1.1) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.1 + + '@mermaid-js/parser@1.0.1': + dependencies: + langium: 4.2.1 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -2678,113 +3299,190 @@ snapshots: '@nodelib/fs.stat@2.0.5': {} - '@nodelib/fs.walk@1.2.8': + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true '@pkgr/core@0.2.9': {} - '@rolldown/pluginutils@1.0.0-beta.29': {} + '@rolldown/pluginutils@1.0.0-rc.2': {} + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true - '@rollup/rollup-android-arm-eabi@4.53.2': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@rollup/rollup-android-arm64@4.53.2': + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-arm64@4.53.2': + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - '@rollup/rollup-darwin-x64@4.53.2': + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - '@rollup/rollup-freebsd-arm64@4.53.2': + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - '@rollup/rollup-freebsd-x64@4.53.2': + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.53.2': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.53.2': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.53.2': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.53.2': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.2': + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.2': + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.2': + '@rollup/rollup-linux-x64-musl@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.53.2': + '@rollup/rollup-openbsd-x64@4.59.0': optional: true - '@rollup/rollup-openharmony-arm64@4.53.2': + '@rollup/rollup-openharmony-arm64@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.2': + '@rollup/rollup-win32-arm64-msvc@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.2': + '@rollup/rollup-win32-ia32-msvc@4.59.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.2': + '@rollup/rollup-win32-x64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.2': + '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@shikijs/core@3.15.0': + '@shikijs/core@4.0.2': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/primitive': 4.0.2 + '@shikijs/types': 4.0.2 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.15.0': + '@shikijs/engine-javascript@4.0.2': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 4.0.2 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.3 + oniguruma-to-es: 4.3.4 - '@shikijs/engine-oniguruma@3.15.0': + '@shikijs/engine-oniguruma@4.0.2': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 4.0.2 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.15.0': + '@shikijs/langs@4.0.2': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 4.0.2 + + '@shikijs/primitive@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 - '@shikijs/themes@3.15.0': + '@shikijs/themes@4.0.2': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 4.0.2 - '@shikijs/transformers@3.15.0': + '@shikijs/transformers@4.0.2': dependencies: - '@shikijs/core': 3.15.0 - '@shikijs/types': 3.15.0 + '@shikijs/core': 4.0.2 + '@shikijs/types': 4.0.2 - '@shikijs/types@3.15.0': + '@shikijs/types@4.0.2': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -2795,6 +3493,123 @@ snapshots: '@stackblitz/sdk@1.11.0': {} + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + '@types/debug@4.1.12': dependencies: '@types/ms': 2.1.0 @@ -2804,7 +3619,9 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 24.10.1 + '@types/node': 25.4.0 + + '@types/geojson@7946.0.16': {} '@types/hash-sum@1.0.2': {} @@ -2814,9 +3631,9 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 24.10.1 + '@types/node': 25.4.0 - '@types/katex@0.16.7': {} + '@types/katex@0.16.8': {} '@types/linkify-it@5.0.0': {} @@ -2837,15 +3654,19 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@17.0.45': {} - - '@types/node@24.10.1': + '@types/node@24.12.0': dependencies: undici-types: 7.16.0 + '@types/node@25.4.0': + dependencies: + undici-types: 7.18.2 + + '@types/picomatch@4.0.2': {} + '@types/sax@1.2.7': dependencies: - '@types/node': 17.0.45 + '@types/node': 24.12.0 '@types/trusted-types@2.0.7': {} @@ -2857,102 +3678,102 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.1(vite@7.0.8(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)': + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + '@vitejs/plugin-vue@6.0.4(vite@7.1.12(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)': dependencies: - '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.0.8(@types/node@24.10.1)(sass-embedded@1.89.2) - vue: 3.5.24 + '@rolldown/pluginutils': 1.0.0-rc.2 + vite: 7.1.12(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0) + vue: 3.5.30 - '@vue/compiler-core@3.5.24': + '@vue/compiler-core@3.5.30': dependencies: - '@babel/parser': 7.28.5 - '@vue/shared': 3.5.24 - entities: 4.5.0 + '@babel/parser': 7.29.0 + '@vue/shared': 3.5.30 + entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.24': + '@vue/compiler-dom@3.5.30': dependencies: - '@vue/compiler-core': 3.5.24 - '@vue/shared': 3.5.24 + '@vue/compiler-core': 3.5.30 + '@vue/shared': 3.5.30 - '@vue/compiler-sfc@3.5.24': + '@vue/compiler-sfc@3.5.30': dependencies: - '@babel/parser': 7.28.5 - '@vue/compiler-core': 3.5.24 - '@vue/compiler-dom': 3.5.24 - '@vue/compiler-ssr': 3.5.24 - '@vue/shared': 3.5.24 + '@babel/parser': 7.29.0 + '@vue/compiler-core': 3.5.30 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.6 + postcss: 8.5.8 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.24': + '@vue/compiler-ssr@3.5.30': dependencies: - '@vue/compiler-dom': 3.5.24 - '@vue/shared': 3.5.24 + '@vue/compiler-dom': 3.5.30 + '@vue/shared': 3.5.30 '@vue/devtools-api@6.6.4': {} - '@vue/devtools-api@7.7.8': + '@vue/devtools-api@8.0.7': dependencies: - '@vue/devtools-kit': 7.7.8 + '@vue/devtools-kit': 8.0.7 - '@vue/devtools-kit@7.7.8': + '@vue/devtools-kit@8.0.7': dependencies: - '@vue/devtools-shared': 7.7.8 - birpc: 2.8.0 + '@vue/devtools-shared': 8.0.7 + birpc: 2.9.0 hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.5 + perfect-debounce: 2.1.0 - '@vue/devtools-shared@7.7.8': - dependencies: - rfdc: 1.4.1 + '@vue/devtools-shared@8.0.7': {} - '@vue/reactivity@3.5.24': + '@vue/reactivity@3.5.30': dependencies: - '@vue/shared': 3.5.24 + '@vue/shared': 3.5.30 - '@vue/runtime-core@3.5.24': + '@vue/runtime-core@3.5.30': dependencies: - '@vue/reactivity': 3.5.24 - '@vue/shared': 3.5.24 + '@vue/reactivity': 3.5.30 + '@vue/shared': 3.5.30 - '@vue/runtime-dom@3.5.24': + '@vue/runtime-dom@3.5.30': dependencies: - '@vue/reactivity': 3.5.24 - '@vue/runtime-core': 3.5.24 - '@vue/shared': 3.5.24 - csstype: 3.2.2 + '@vue/reactivity': 3.5.30 + '@vue/runtime-core': 3.5.30 + '@vue/shared': 3.5.30 + csstype: 3.2.3 - '@vue/server-renderer@3.5.24(vue@3.5.24)': + '@vue/server-renderer@3.5.30(vue@3.5.30)': dependencies: - '@vue/compiler-ssr': 3.5.24 - '@vue/shared': 3.5.24 - vue: 3.5.24 + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + vue: 3.5.30 - '@vue/shared@3.5.24': {} + '@vue/shared@3.5.30': {} - '@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2)': + '@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0)': dependencies: - '@vitejs/plugin-vue': 6.0.1(vite@7.0.8(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) - '@vuepress/bundlerutils': 2.0.0-rc.24 - '@vuepress/client': 2.0.0-rc.24 - '@vuepress/core': 2.0.0-rc.24 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 - autoprefixer: 10.4.22(postcss@8.5.6) + '@vitejs/plugin-vue': 6.0.4(vite@7.1.12(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + '@vuepress/bundlerutils': 2.0.0-rc.26 + '@vuepress/client': 2.0.0-rc.26 + '@vuepress/core': 2.0.0-rc.26 + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 + autoprefixer: 10.4.27(postcss@8.5.8) connect-history-api-fallback: 2.0.0 - postcss: 8.5.6 - postcss-load-config: 6.0.1(postcss@8.5.6) - rollup: 4.53.2 - vite: 7.0.8(@types/node@24.10.1)(sass-embedded@1.89.2) - vue: 3.5.24 - vue-router: 4.6.3(vue@3.5.24) + postcss: 8.5.8 + postcss-load-config: 6.0.1(postcss@8.5.8) + rollup: 4.59.0 + vite: 7.1.12(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0) + vue: 3.5.30 + vue-router: 4.6.4(vue@3.5.30) transitivePeerDependencies: - '@types/node' - jiti @@ -2968,454 +3789,526 @@ snapshots: - typescript - yaml - '@vuepress/bundlerutils@2.0.0-rc.24': + '@vuepress/bundlerutils@2.0.0-rc.26': dependencies: - '@vuepress/client': 2.0.0-rc.24 - '@vuepress/core': 2.0.0-rc.24 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 - vue: 3.5.24 - vue-router: 4.6.3(vue@3.5.24) + '@vuepress/client': 2.0.0-rc.26 + '@vuepress/core': 2.0.0-rc.26 + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 + vue: 3.5.30 + vue-router: 4.6.4(vue@3.5.30) transitivePeerDependencies: - supports-color - typescript - '@vuepress/cli@2.0.0-rc.24': + '@vuepress/cli@2.0.0-rc.26': dependencies: - '@vuepress/core': 2.0.0-rc.24 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 + '@vuepress/core': 2.0.0-rc.26 + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 cac: 6.7.14 - chokidar: 3.6.0 - envinfo: 7.20.0 + chokidar: 4.0.3 + envinfo: 7.21.0 esbuild: 0.25.12 transitivePeerDependencies: - supports-color - typescript - '@vuepress/client@2.0.0-rc.24': + '@vuepress/client@2.0.0-rc.26': dependencies: - '@vue/devtools-api': 7.7.8 - '@vue/devtools-kit': 7.7.8 - '@vuepress/shared': 2.0.0-rc.24 - vue: 3.5.24 - vue-router: 4.6.3(vue@3.5.24) + '@vue/devtools-api': 8.0.7 + '@vue/devtools-kit': 8.0.7 + '@vuepress/shared': 2.0.0-rc.26 + vue: 3.5.30 + vue-router: 4.6.4(vue@3.5.30) transitivePeerDependencies: - typescript - '@vuepress/core@2.0.0-rc.24': + '@vuepress/core@2.0.0-rc.26': dependencies: - '@vuepress/client': 2.0.0-rc.24 - '@vuepress/markdown': 2.0.0-rc.24 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 - vue: 3.5.24 + '@vuepress/client': 2.0.0-rc.26 + '@vuepress/markdown': 2.0.0-rc.26 + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 + vue: 3.5.30 transitivePeerDependencies: - supports-color - typescript - '@vuepress/helper@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/helper@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vue/shared': 3.5.24 - '@vueuse/core': 13.9.0(vue@3.5.24) - cheerio: 1.1.2 + '@vue/shared': 3.5.30 + '@vueuse/core': 14.2.1(vue@3.5.30) + cheerio: 1.2.0 fflate: 0.8.2 gray-matter: 4.0.3 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + optionalDependencies: + '@vuepress/bundler-vite': 2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0) transitivePeerDependencies: - typescript - '@vuepress/highlighter-helper@2.0.0-rc.112(@vueuse/core@13.9.0(vue@3.5.24))(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/highlighter-helper@2.0.0-rc.124(@vuepress/helper@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(@vueuse/core@14.2.1(vue@3.5.30))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) optionalDependencies: - '@vueuse/core': 13.9.0(vue@3.5.24) - - '@vuepress/markdown@2.0.0-rc.24': - dependencies: - '@mdit-vue/plugin-component': 2.1.4 - '@mdit-vue/plugin-frontmatter': 2.1.4 - '@mdit-vue/plugin-headers': 2.1.4 - '@mdit-vue/plugin-sfc': 2.1.4 - '@mdit-vue/plugin-title': 2.1.4 - '@mdit-vue/plugin-toc': 2.1.4 - '@mdit-vue/shared': 2.1.4 - '@mdit-vue/types': 2.1.4 + '@vueuse/core': 14.2.1(vue@3.5.30) + + '@vuepress/markdown@2.0.0-rc.26': + dependencies: + '@mdit-vue/plugin-component': 3.0.2 + '@mdit-vue/plugin-frontmatter': 3.0.2 + '@mdit-vue/plugin-headers': 3.0.2 + '@mdit-vue/plugin-sfc': 3.0.2 + '@mdit-vue/plugin-title': 3.0.2 + '@mdit-vue/plugin-toc': 3.0.2 + '@mdit-vue/shared': 3.0.2 + '@mdit-vue/types': 3.0.2 '@types/markdown-it': 14.1.2 '@types/markdown-it-emoji': 3.0.1 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 - markdown-it: 14.1.0 - markdown-it-anchor: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0) + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 + markdown-it: 14.1.1 + markdown-it-anchor: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.1) markdown-it-emoji: 3.0.0 mdurl: 2.0.0 transitivePeerDependencies: - supports-color - '@vuepress/plugin-active-header-links@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-active-header-links@2.0.0-rc.124(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: - typescript - '@vuepress/plugin-back-to-top@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-back-to-top@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-blog@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-blog@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - chokidar: 4.0.3 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + chokidar: 5.0.0 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-catalog@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-catalog@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-comment@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-comment@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) giscus: 1.6.0 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-copy-code@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-copy-code@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-copyright@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-copyright@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-feed@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-feed@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) xml-js: 1.6.11 transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-git@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-git@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) rehype-parse: 9.0.1 rehype-sanitize: 6.0.0 rehype-stringify: 10.0.1 unified: 11.0.5 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-icon@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-icon@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-icon': 0.22.2(markdown-it@14.1.0) - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@mdit/plugin-icon': 0.24.1(markdown-it@14.1.1) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-links-check@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-links-check@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-markdown-chart@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-chart@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(mermaid@11.13.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-container': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-plantuml': 0.22.3(markdown-it@14.1.0) - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@mdit/plugin-container': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-plantuml': 0.24.1(markdown-it@14.1.1) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + optionalDependencies: + mermaid: 11.13.0 transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-ext@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-ext@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-container': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-footnote': 0.22.3(markdown-it@14.1.0) - '@mdit/plugin-tasklist': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-container': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-footnote': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-tasklist': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) js-yaml: 4.1.1 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + markdown-it-cjk-friendly: 2.0.2(@types/markdown-it@14.1.2)(markdown-it@14.1.1) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-hint@2.0.0-rc.112(markdown-it@14.1.0)(vue@3.5.24)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-hint@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vue@3.5.30)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-alert': 0.22.3(markdown-it@14.1.0) - '@mdit/plugin-container': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-alert': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-container': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - vue - '@vuepress/plugin-markdown-image@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-image@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-figure': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-img-lazyload': 0.22.1(markdown-it@14.1.0) - '@mdit/plugin-img-mark': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-img-size': 0.22.3(markdown-it@14.1.0) + '@mdit/plugin-figure': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-img-lazyload': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-img-mark': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-img-size': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-include@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-include@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-include': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-include': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-math@2.0.0-rc.112(katex@0.16.25)(markdown-it@14.1.0)(mathjax-full@3.2.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-math@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(katex@0.16.38)(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-katex-slim': 0.23.2(katex@0.16.25)(markdown-it@14.1.0) - '@mdit/plugin-mathjax-slim': 0.23.2(markdown-it@14.1.0)(mathjax-full@3.2.2) + '@mdit/plugin-katex-slim': 0.26.1(katex@0.16.38)(markdown-it@14.1.1) + '@mdit/plugin-mathjax-slim': 0.26.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) optionalDependencies: - katex: 0.16.25 - mathjax-full: 3.2.2 + katex: 0.16.38 transitivePeerDependencies: + - '@mathjax/mathjax-newcm-font' + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-preview@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-preview@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/helper': 0.22.1(markdown-it@14.1.0) - '@mdit/plugin-demo': 0.22.3(markdown-it@14.1.0) + '@mdit/helper': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-demo': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-stylize@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-stylize@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-align': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-attrs': 0.23.3(markdown-it@14.1.0) - '@mdit/plugin-mark': 0.22.1(markdown-it@14.1.0) - '@mdit/plugin-spoiler': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-stylize': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-sub': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-sup': 0.22.2(markdown-it@14.1.0) + '@mdit/plugin-align': 0.24.1(markdown-it@14.1.1) + '@mdit/plugin-attrs': 0.25.1(markdown-it@14.1.1) + '@mdit/plugin-layout': 0.2.1(markdown-it@14.1.1) + '@mdit/plugin-mark': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-spoiler': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-stylize': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-sub': 0.24.1(markdown-it@14.1.1) + '@mdit/plugin-sup': 0.24.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-markdown-tab@2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-markdown-tab@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@mdit/plugin-tab': 0.22.3(markdown-it@14.1.0) + '@mdit/plugin-tab': 0.24.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - '@vuepress/plugin-notice@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-notice@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - chokidar: 4.0.3 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + chokidar: 5.0.0 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-nprogress@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-nprogress@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-photo-swipe@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-photo-swipe@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) photoswipe: 5.4.4 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-reading-time@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-reading-time@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-redirect@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-redirect@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - commander: 14.0.2 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + commander: 14.0.3 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-rtl@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-rtl@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-sass-palette@2.0.0-rc.112(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-sass-palette@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - chokidar: 4.0.3 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + chokidar: 5.0.0 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) optionalDependencies: - sass-embedded: 1.89.2 + sass: 1.98.0 + sass-embedded: 1.98.0 transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-search@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-search@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - chokidar: 4.0.3 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + chokidar: 5.0.0 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-seo@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-seo@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-shiki@2.0.0-rc.112(@vueuse/core@13.9.0(vue@3.5.24))(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-shiki@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(@vueuse/core@14.2.1(vue@3.5.30))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@shikijs/transformers': 3.15.0 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/highlighter-helper': 2.0.0-rc.112(@vueuse/core@13.9.0(vue@3.5.24))(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + '@shikijs/transformers': 4.0.2 + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/highlighter-helper': 2.0.0-rc.124(@vuepress/helper@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(@vueuse/core@14.2.1(vue@3.5.30))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) nanoid: 5.1.6 - shiki: 3.15.0 - synckit: 0.11.11 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + shiki: 4.0.2 + synckit: 0.11.12 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - '@vueuse/core' - typescript - '@vuepress/plugin-sitemap@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-sitemap@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - sitemap: 8.0.2 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + sitemap: 9.0.1 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - '@vuepress/plugin-theme-data@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24))': + '@vuepress/plugin-theme-data@2.0.0-rc.124(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30))': dependencies: - '@vue/devtools-api': 7.7.8 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vue/devtools-api': 8.0.7 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: - typescript - '@vuepress/shared@2.0.0-rc.24': + '@vuepress/shared@2.0.0-rc.26': dependencies: - '@mdit-vue/types': 2.1.4 + '@mdit-vue/types': 3.0.2 - '@vuepress/utils@2.0.0-rc.24': + '@vuepress/utils@2.0.0-rc.26': dependencies: '@types/debug': 4.1.12 '@types/fs-extra': 11.0.4 '@types/hash-sum': 1.0.2 - '@vuepress/shared': 2.0.0-rc.24 + '@types/picomatch': 4.0.2 + '@vuepress/shared': 2.0.0-rc.26 debug: 4.4.3 - fs-extra: 11.3.2 - globby: 14.1.0 + fs-extra: 11.3.4 hash-sum: 2.0.0 - ora: 8.2.0 + ora: 9.3.0 picocolors: 1.1.1 + picomatch: 4.0.3 + tinyglobby: 0.2.15 upath: 2.0.1 transitivePeerDependencies: - supports-color - '@vueuse/core@13.9.0(vue@3.5.24)': + '@vueuse/core@14.2.1(vue@3.5.30)': dependencies: '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 13.9.0 - '@vueuse/shared': 13.9.0(vue@3.5.24) - vue: 3.5.24 + '@vueuse/metadata': 14.2.1 + '@vueuse/shared': 14.2.1(vue@3.5.30) + vue: 3.5.30 - '@vueuse/metadata@13.9.0': {} + '@vueuse/metadata@14.2.1': {} - '@vueuse/shared@13.9.0(vue@3.5.24)': + '@vueuse/shared@14.2.1(vue@3.5.30)': dependencies: - vue: 3.5.24 + vue: 3.5.30 '@xmldom/xmldom@0.9.8': {} + acorn@8.16.0: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -3424,11 +4317,6 @@ snapshots: dependencies: color-convert: 2.0.1 - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - arg@5.0.2: {} argparse@1.0.10: @@ -3437,27 +4325,24 @@ snapshots: argparse@2.0.1: {} - autoprefixer@10.4.22(postcss@8.5.6): + autoprefixer@10.4.27(postcss@8.5.8): dependencies: - browserslist: 4.28.0 - caniuse-lite: 1.0.30001755 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001778 fraction.js: 5.3.4 - normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.5.6 + postcss: 8.5.8 postcss-value-parser: 4.2.0 bail@2.0.2: {} balloon-css@1.2.0: {} - baseline-browser-mapping@2.8.28: {} + baseline-browser-mapping@2.10.0: {} - bcrypt-ts@7.1.0: {} + bcrypt-ts@8.0.1: {} - binary-extensions@2.3.0: {} - - birpc@2.8.0: {} + birpc@2.9.0: {} boolbase@1.0.0: {} @@ -3465,21 +4350,19 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.0: + browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.8.28 - caniuse-lite: 1.0.30001755 - electron-to-chromium: 1.5.254 - node-releases: 2.0.27 - update-browserslist-db: 1.1.4(browserslist@4.28.0) - - buffer-builder@0.2.0: {} + baseline-browser-mapping: 2.10.0 + caniuse-lite: 1.0.30001778 + electron-to-chromium: 1.5.313 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.1) cac@6.7.14: {} camelcase@5.3.1: {} - caniuse-lite@1.0.30001755: {} + caniuse-lite@1.0.30001778: {} ccount@2.0.1: {} @@ -3502,41 +4385,47 @@ snapshots: domhandler: 5.0.3 domutils: 3.2.2 - cheerio@1.1.2: + cheerio@1.2.0: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 domhandler: 5.0.3 domutils: 3.2.2 encoding-sniffer: 0.2.1 - htmlparser2: 10.0.0 + htmlparser2: 10.1.0 parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.16.0 + undici: 7.22.0 whatwg-mimetype: 4.0.0 - chokidar@3.6.0: + chevrotain-allstar@0.3.1(chevrotain@11.1.2): dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + chevrotain: 11.1.2 + lodash-es: 4.17.23 + + chevrotain@11.1.2: + dependencies: + '@chevrotain/cst-dts-gen': 11.1.2 + '@chevrotain/gast': 11.1.2 + '@chevrotain/regexp-to-ast': 11.1.2 + '@chevrotain/types': 11.1.2 + '@chevrotain/utils': 11.1.2 + lodash-es: 4.17.23 chokidar@4.0.3: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 - cli-spinners@2.9.2: {} + cli-spinners@3.4.0: {} cliui@6.0.0: dependencies: @@ -3556,17 +4445,25 @@ snapshots: commander@13.1.0: {} - commander@14.0.2: {} + commander@14.0.3: {} + + commander@7.2.0: {} commander@8.3.0: {} + confbox@0.1.8: {} + connect-history-api-fallback@2.0.0: {} - copy-anything@4.0.5: + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: dependencies: - is-what: 5.5.0 + layout-base: 2.0.1 - create-codepen@2.0.0: {} + create-codepen@2.0.1: {} css-select@5.2.2: dependencies: @@ -3578,7 +4475,193 @@ snapshots: css-what@6.2.2: {} - csstype@3.2.2: {} + csstype@3.2.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.1 + + cytoscape-fcose@2.2.0(cytoscape@3.33.1): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.1 + + cytoscape@3.33.1: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.23 + + dayjs@1.11.19: {} debug@4.4.3: dependencies: @@ -3586,12 +4669,19 @@ snapshots: decamelize@1.2.0: {} - decode-named-character-reference@1.2.0: + decode-named-character-reference@1.3.0: dependencies: character-entities: 2.0.2 + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + dequal@2.0.3: {} + detect-libc@2.1.2: + optional: true + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -3610,15 +4700,17 @@ snapshots: dependencies: domelementtype: 2.3.0 + dompurify@3.3.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 domhandler: 5.0.3 - electron-to-chromium@1.5.254: {} - - emoji-regex@10.6.0: {} + electron-to-chromium@1.5.313: {} emoji-regex@8.0.0: {} @@ -3631,7 +4723,9 @@ snapshots: entities@6.0.1: {} - envinfo@7.20.0: {} + entities@7.0.1: {} + + envinfo@7.21.0: {} esbuild@0.25.12: optionalDependencies: @@ -3684,7 +4778,7 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fastq@1.19.1: + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -3705,7 +4799,7 @@ snapshots: fraction.js@5.3.4: {} - fs-extra@11.3.2: + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -3716,11 +4810,11 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} + get-east-asian-width@1.5.0: {} giscus@1.6.0: dependencies: - lit: 3.3.1 + lit: 3.3.2 glob-parent@5.1.2: dependencies: @@ -3735,15 +4829,6 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.1.0 - globby@14.1.0: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 7.0.5 - path-type: 6.0.0 - slash: 5.1.0 - unicorn-magic: 0.3.0 - graceful-fs@4.2.11: {} gray-matter@4.0.3: @@ -3753,6 +4838,8 @@ snapshots: section-matter: 1.0.0 strip-bom-string: 1.0.0 + hachure-fill@0.5.2: {} + has-flag@4.0.0: {} hash-sum@2.0.0: {} @@ -3795,7 +4882,7 @@ snapshots: comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 property-information: 7.1.0 space-separated-tokens: 2.0.2 stringify-entities: 4.0.4 @@ -3817,12 +4904,12 @@ snapshots: html-void-elements@3.0.0: {} - htmlparser2@10.0.0: + htmlparser2@10.1.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 domutils: 3.2.2 - entities: 6.0.1 + entities: 7.0.1 husky@9.1.7: {} @@ -3832,9 +4919,11 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.5: {} + immutable@5.1.5: {} + + internmap@1.0.1: {} - immutable@5.1.4: {} + internmap@2.0.3: {} is-alphabetical@2.0.1: {} @@ -3843,10 +4932,6 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - is-decimal@2.0.1: {} is-extendable@0.1.1: {} @@ -3867,12 +4952,8 @@ snapshots: is-plain-obj@4.1.0: {} - is-unicode-supported@1.3.0: {} - is-unicode-supported@2.1.0: {} - is-what@5.5.0: {} - js-yaml@3.14.2: dependencies: argparse: 1.0.10 @@ -3894,51 +4975,74 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - katex@0.16.25: + katex@0.16.38: dependencies: commander: 8.3.0 + khroma@2.1.0: {} + kind-of@6.0.3: {} + langium@4.2.1: + dependencies: + chevrotain: 11.1.2 + chevrotain-allstar: 0.3.1(chevrotain@11.1.2) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + lilconfig@3.1.3: {} linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 - lit-element@4.2.1: + lit-element@4.2.2: dependencies: - '@lit-labs/ssr-dom-shim': 1.4.0 - '@lit/reactive-element': 2.1.1 - lit-html: 3.3.1 + '@lit-labs/ssr-dom-shim': 1.5.1 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.2 - lit-html@3.3.1: + lit-html@3.3.2: dependencies: '@types/trusted-types': 2.0.7 - lit@3.3.1: + lit@3.3.2: dependencies: - '@lit/reactive-element': 2.1.1 - lit-element: 4.2.1 - lit-html: 3.3.1 + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.2 locate-path@5.0.0: dependencies: p-locate: 4.1.0 - log-symbols@6.0.0: + lodash-es@4.17.23: {} + + log-symbols@7.0.1: dependencies: - chalk: 5.6.2 - is-unicode-supported: 1.3.0 + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - markdown-it-anchor@9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0): + markdown-it-anchor@9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.1): dependencies: '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + markdown-it: 14.1.1 + + markdown-it-cjk-friendly@2.0.2(@types/markdown-it@14.1.2)(markdown-it@14.1.1): + dependencies: + get-east-asian-width: 1.5.0 + markdown-it: 14.1.1 + optionalDependencies: + '@types/markdown-it': 14.1.2 markdown-it-emoji@3.0.0: {} @@ -3951,6 +5055,15 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdownlint-cli2-formatter-default@0.0.5(markdownlint-cli2@0.17.1): dependencies: markdownlint-cli2: 0.17.1 @@ -3980,6 +5093,8 @@ snapshots: transitivePeerDependencies: - supports-color + marked@16.4.2: {} + mathjax-full@3.2.2: dependencies: esm: 3.2.25 @@ -3987,7 +5102,7 @@ snapshots: mj-context-menu: 0.6.1 speech-rule-engine: 4.1.2 - mdast-util-to-hast@13.2.0: + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -3996,18 +5111,42 @@ snapshots: micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 vfile: 6.0.3 mdurl@2.0.0: {} merge2@1.4.1: {} + mermaid@11.13.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.0 + '@mermaid-js/parser': 1.0.1 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.19 + dompurify: 3.3.3 + katex: 0.16.38 + khroma: 2.1.0 + lodash-es: 4.17.23 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + mhchemparser@4.2.1: {} micromark-core-commonmark@2.0.2: dependencies: - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-factory-destination: 2.0.1 micromark-factory-label: 2.0.1 @@ -4062,9 +5201,9 @@ snapshots: micromark-extension-math@3.1.0: dependencies: - '@types/katex': 0.16.7 + '@types/katex': 0.16.8 devlop: 1.1.0 - katex: 0.16.25 + katex: 0.16.38 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 @@ -4159,7 +5298,7 @@ snapshots: dependencies: '@types/debug': 4.1.12 debug: 4.4.3 - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.2 micromark-factory-space: 2.0.1 @@ -4184,10 +5323,15 @@ snapshots: mimic-function@5.0.1: {} - mitt@3.0.1: {} - mj-context-menu@0.6.1: {} + mlly@1.8.1: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + ms@2.1.3: {} nano-staged@0.8.0: @@ -4198,11 +5342,10 @@ snapshots: nanoid@5.1.6: {} - node-releases@2.0.27: {} - - normalize-path@3.0.0: {} + node-addon-api@7.1.1: + optional: true - normalize-range@0.1.2: {} + node-releases@2.0.36: {} nth-check@2.1.1: dependencies: @@ -4214,23 +5357,22 @@ snapshots: oniguruma-parser@0.12.1: {} - oniguruma-to-es@4.3.3: + oniguruma-to-es@4.3.4: dependencies: oniguruma-parser: 0.12.1 - regex: 6.0.1 + regex: 6.1.0 regex-recursion: 6.0.2 - ora@8.2.0: + ora@9.3.0: dependencies: chalk: 5.6.2 cli-cursor: 5.0.0 - cli-spinners: 2.9.2 + cli-spinners: 3.4.0 is-interactive: 2.0.0 is-unicode-supported: 2.1.0 - log-symbols: 6.0.0 - stdin-discarder: 0.2.2 - string-width: 7.2.0 - strip-ansi: 7.1.2 + log-symbols: 7.0.1 + stdin-discarder: 0.3.1 + string-width: 8.2.0 p-limit@2.3.0: dependencies: @@ -4242,12 +5384,14 @@ snapshots: p-try@2.2.0: {} + package-manager-detector@1.6.0: {} + parse-entities@4.0.2: dependencies: '@types/unist': 2.0.11 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 is-alphanumerical: 2.0.1 is-decimal: 2.0.1 is-hexadecimal: 2.0.1 @@ -4265,13 +5409,15 @@ snapshots: dependencies: entities: 6.0.1 + path-data-parser@0.1.0: {} + path-exists@4.0.0: {} path-type@5.0.0: {} - path-type@6.0.0: {} + pathe@2.0.3: {} - perfect-debounce@1.0.0: {} + perfect-debounce@2.1.0: {} photoswipe@5.4.4: {} @@ -4281,17 +5427,30 @@ snapshots: picomatch@4.0.3: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.1 + pathe: 2.0.3 + pngjs@5.0.0: {} - postcss-load-config@6.0.1(postcss@8.5.6): + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + postcss-load-config@6.0.1(postcss@8.5.8): dependencies: lilconfig: 3.1.3 optionalDependencies: - postcss: 8.5.6 + postcss: 8.5.8 postcss-value-parser@4.2.0: {} - postcss@8.5.6: + postcss@8.5.8: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -4311,19 +5470,17 @@ snapshots: queue-microtask@1.2.3: {} - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - readdirp@4.1.2: {} + readdirp@5.0.0: {} + regex-recursion@6.0.2: dependencies: regex-utilities: 2.3.0 regex-utilities@2.3.0: {} - regex@6.0.1: + regex@6.1.0: dependencies: regex-utilities: 2.3.0 @@ -4355,123 +5512,155 @@ snapshots: reusify@1.1.0: {} - rfdc@1.4.1: {} + robust-predicates@3.0.2: {} - rollup@4.53.2: + rollup@4.59.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.2 - '@rollup/rollup-android-arm64': 4.53.2 - '@rollup/rollup-darwin-arm64': 4.53.2 - '@rollup/rollup-darwin-x64': 4.53.2 - '@rollup/rollup-freebsd-arm64': 4.53.2 - '@rollup/rollup-freebsd-x64': 4.53.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 - '@rollup/rollup-linux-arm-musleabihf': 4.53.2 - '@rollup/rollup-linux-arm64-gnu': 4.53.2 - '@rollup/rollup-linux-arm64-musl': 4.53.2 - '@rollup/rollup-linux-loong64-gnu': 4.53.2 - '@rollup/rollup-linux-ppc64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-musl': 4.53.2 - '@rollup/rollup-linux-s390x-gnu': 4.53.2 - '@rollup/rollup-linux-x64-gnu': 4.53.2 - '@rollup/rollup-linux-x64-musl': 4.53.2 - '@rollup/rollup-openharmony-arm64': 4.53.2 - '@rollup/rollup-win32-arm64-msvc': 4.53.2 - '@rollup/rollup-win32-ia32-msvc': 4.53.2 - '@rollup/rollup-win32-x64-gnu': 4.53.2 - '@rollup/rollup-win32-x64-msvc': 4.53.2 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rw@1.3.3: {} + rxjs@7.8.2: dependencies: tslib: 2.8.1 safer-buffer@2.1.2: {} - sass-embedded-android-arm64@1.89.2: + sass-embedded-all-unknown@1.98.0: + dependencies: + sass: 1.98.0 + optional: true + + sass-embedded-android-arm64@1.98.0: + optional: true + + sass-embedded-android-arm@1.98.0: optional: true - sass-embedded-android-arm@1.89.2: + sass-embedded-android-riscv64@1.98.0: optional: true - sass-embedded-android-riscv64@1.89.2: + sass-embedded-android-x64@1.98.0: optional: true - sass-embedded-android-x64@1.89.2: + sass-embedded-darwin-arm64@1.98.0: optional: true - sass-embedded-darwin-arm64@1.89.2: + sass-embedded-darwin-x64@1.98.0: optional: true - sass-embedded-darwin-x64@1.89.2: + sass-embedded-linux-arm64@1.98.0: optional: true - sass-embedded-linux-arm64@1.89.2: + sass-embedded-linux-arm@1.98.0: optional: true - sass-embedded-linux-arm@1.89.2: + sass-embedded-linux-musl-arm64@1.98.0: optional: true - sass-embedded-linux-musl-arm64@1.89.2: + sass-embedded-linux-musl-arm@1.98.0: optional: true - sass-embedded-linux-musl-arm@1.89.2: + sass-embedded-linux-musl-riscv64@1.98.0: optional: true - sass-embedded-linux-musl-riscv64@1.89.2: + sass-embedded-linux-musl-x64@1.98.0: optional: true - sass-embedded-linux-musl-x64@1.89.2: + sass-embedded-linux-riscv64@1.98.0: optional: true - sass-embedded-linux-riscv64@1.89.2: + sass-embedded-linux-x64@1.98.0: optional: true - sass-embedded-linux-x64@1.89.2: + sass-embedded-unknown-all@1.98.0: + dependencies: + sass: 1.98.0 optional: true - sass-embedded-win32-arm64@1.89.2: + sass-embedded-win32-arm64@1.98.0: optional: true - sass-embedded-win32-x64@1.89.2: + sass-embedded-win32-x64@1.98.0: optional: true - sass-embedded@1.89.2: + sass-embedded@1.98.0: dependencies: - '@bufbuild/protobuf': 2.10.1 - buffer-builder: 0.2.0 + '@bufbuild/protobuf': 2.11.0 colorjs.io: 0.5.2 - immutable: 5.1.4 + immutable: 5.1.5 rxjs: 7.8.2 supports-color: 8.1.1 sync-child-process: 1.0.2 varint: 6.0.0 optionalDependencies: - sass-embedded-android-arm: 1.89.2 - sass-embedded-android-arm64: 1.89.2 - sass-embedded-android-riscv64: 1.89.2 - sass-embedded-android-x64: 1.89.2 - sass-embedded-darwin-arm64: 1.89.2 - sass-embedded-darwin-x64: 1.89.2 - sass-embedded-linux-arm: 1.89.2 - sass-embedded-linux-arm64: 1.89.2 - sass-embedded-linux-musl-arm: 1.89.2 - sass-embedded-linux-musl-arm64: 1.89.2 - sass-embedded-linux-musl-riscv64: 1.89.2 - sass-embedded-linux-musl-x64: 1.89.2 - sass-embedded-linux-riscv64: 1.89.2 - sass-embedded-linux-x64: 1.89.2 - sass-embedded-win32-arm64: 1.89.2 - sass-embedded-win32-x64: 1.89.2 - - sax@1.4.3: {} + sass-embedded-all-unknown: 1.98.0 + sass-embedded-android-arm: 1.98.0 + sass-embedded-android-arm64: 1.98.0 + sass-embedded-android-riscv64: 1.98.0 + sass-embedded-android-x64: 1.98.0 + sass-embedded-darwin-arm64: 1.98.0 + sass-embedded-darwin-x64: 1.98.0 + sass-embedded-linux-arm: 1.98.0 + sass-embedded-linux-arm64: 1.98.0 + sass-embedded-linux-musl-arm: 1.98.0 + sass-embedded-linux-musl-arm64: 1.98.0 + sass-embedded-linux-musl-riscv64: 1.98.0 + sass-embedded-linux-musl-x64: 1.98.0 + sass-embedded-linux-riscv64: 1.98.0 + sass-embedded-linux-x64: 1.98.0 + sass-embedded-unknown-all: 1.98.0 + sass-embedded-win32-arm64: 1.98.0 + sass-embedded-win32-x64: 1.98.0 + + sass@1.98.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + optional: true + + sax@1.5.0: {} section-matter@1.0.0: dependencies: @@ -4480,25 +5669,25 @@ snapshots: set-blocking@2.0.0: {} - shiki@3.15.0: + shiki@4.0.2: dependencies: - '@shikijs/core': 3.15.0 - '@shikijs/engine-javascript': 3.15.0 - '@shikijs/engine-oniguruma': 3.15.0 - '@shikijs/langs': 3.15.0 - '@shikijs/themes': 3.15.0 - '@shikijs/types': 3.15.0 + '@shikijs/core': 4.0.2 + '@shikijs/engine-javascript': 4.0.2 + '@shikijs/engine-oniguruma': 4.0.2 + '@shikijs/langs': 4.0.2 + '@shikijs/themes': 4.0.2 + '@shikijs/types': 4.0.2 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 signal-exit@4.1.0: {} - sitemap@8.0.2: + sitemap@9.0.1: dependencies: - '@types/node': 17.0.45 + '@types/node': 24.12.0 '@types/sax': 1.2.7 arg: 5.0.2 - sax: 1.4.3 + sax: 1.5.0 slash@5.1.0: {} @@ -4506,8 +5695,6 @@ snapshots: space-separated-tokens@2.0.2: {} - speakingurl@14.0.1: {} - speech-rule-engine@4.1.2: dependencies: '@xmldom/xmldom': 0.9.8 @@ -4516,7 +5703,7 @@ snapshots: sprintf-js@1.0.3: {} - stdin-discarder@0.2.2: {} + stdin-discarder@0.3.1: {} string-width@4.2.3: dependencies: @@ -4524,11 +5711,10 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@7.2.0: + string-width@8.2.0: dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 stringify-entities@4.0.4: dependencies: @@ -4539,15 +5725,13 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 strip-bom-string@1.0.0: {} - superjson@2.2.5: - dependencies: - copy-anything: 4.0.5 + stylis@4.3.6: {} supports-color@8.1.1: dependencies: @@ -4555,14 +5739,16 @@ snapshots: sync-child-process@1.0.2: dependencies: - sync-message-port: 1.1.3 + sync-message-port: 1.2.0 - sync-message-port@1.1.3: {} + sync-message-port@1.2.0: {} - synckit@0.11.11: + synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -4576,17 +5762,21 @@ snapshots: trough@2.2.0: {} + ts-dedent@2.2.0: {} + tslib@2.8.1: {} uc.micro@2.1.0: {} + ufo@1.6.3: {} + undici-types@7.16.0: {} - undici@7.16.0: {} + undici-types@7.18.2: {} - unicorn-magic@0.1.0: {} + undici@7.22.0: {} - unicorn-magic@0.3.0: {} + unicorn-magic@0.1.0: {} unified@11.0.5: dependencies: @@ -4615,7 +5805,7 @@ snapshots: '@types/unist': 3.0.3 unist-util-is: 6.0.1 - unist-util-visit@5.0.0: + unist-util-visit@5.1.0: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.1 @@ -4625,12 +5815,14 @@ snapshots: upath@2.0.1: {} - update-browserslist-db@1.1.4(browserslist@4.28.0): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 + uuid@11.1.0: {} + varint@6.0.0: {} vfile-location@5.0.3: @@ -4648,125 +5840,156 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.0.8(@types/node@24.10.1)(sass-embedded@1.89.2): + vite@7.1.12(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.53.2 + postcss: 8.5.8 + rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 25.4.0 fsevents: 2.3.3 - sass-embedded: 1.89.2 + sass: 1.98.0 + sass-embedded: 1.98.0 + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.1.0: {} - vue-router@4.6.3(vue@3.5.24): + vue-router@4.6.4(vue@3.5.30): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.24 + vue: 3.5.30 - vue@3.5.24: + vue@3.5.30: dependencies: - '@vue/compiler-dom': 3.5.24 - '@vue/compiler-sfc': 3.5.24 - '@vue/runtime-dom': 3.5.24 - '@vue/server-renderer': 3.5.24(vue@3.5.24) - '@vue/shared': 3.5.24 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30) + '@vue/shared': 3.5.30 - vuepress-plugin-components@2.0.0-rc.94(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)): + vuepress-plugin-components@2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)): dependencies: '@stackblitz/sdk': 1.11.0 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-sass-palette': 2.0.0-rc.112(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-sass-palette': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) balloon-css: 1.2.0 - create-codepen: 2.0.0 + create-codepen: 2.0.1 qrcode: 1.5.4 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) - vuepress-shared: 2.0.0-rc.94(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + vuepress-shared: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) optionalDependencies: - sass-embedded: 1.89.2 + sass: 1.98.0 + sass-embedded: 1.98.0 transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - vuepress-plugin-md-enhance@2.0.0-rc.94(markdown-it@14.1.0)(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)): + vuepress-plugin-md-enhance@2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)): dependencies: - '@mdit/plugin-container': 0.22.2(markdown-it@14.1.0) - '@mdit/plugin-demo': 0.22.3(markdown-it@14.1.0) + '@mdit/plugin-container': 0.23.1(markdown-it@14.1.1) + '@mdit/plugin-demo': 0.23.1(markdown-it@14.1.1) '@types/markdown-it': 14.1.2 - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-sass-palette': 2.0.0-rc.112(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-sass-palette': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) balloon-css: 1.2.0 js-yaml: 4.1.1 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) - vuepress-shared: 2.0.0-rc.94(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + vuepress-shared: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) optionalDependencies: - sass-embedded: 1.89.2 + sass: 1.98.0 + sass-embedded: 1.98.0 transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - markdown-it - typescript - vuepress-shared@2.0.0-rc.94(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)): + vuepress-shared@2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)): dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) transitivePeerDependencies: + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - typescript - vuepress-theme-hope@2.0.0-rc.94(@vuepress/plugin-feed@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)))(@vuepress/plugin-search@2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)))(katex@0.16.25)(markdown-it@14.1.0)(mathjax-full@3.2.2)(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)): - dependencies: - '@vuepress/helper': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-active-header-links': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-back-to-top': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-blog': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-catalog': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-comment': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-copy-code': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-copyright': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-git': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-icon': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-links-check': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-chart': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-ext': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-hint': 2.0.0-rc.112(markdown-it@14.1.0)(vue@3.5.24)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-image': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-include': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-math': 2.0.0-rc.112(katex@0.16.25)(markdown-it@14.1.0)(mathjax-full@3.2.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-preview': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-stylize': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-markdown-tab': 2.0.0-rc.112(markdown-it@14.1.0)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-notice': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-nprogress': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-photo-swipe': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-reading-time': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-redirect': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-rtl': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-sass-palette': 2.0.0-rc.112(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-seo': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-shiki': 2.0.0-rc.112(@vueuse/core@13.9.0(vue@3.5.24))(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-sitemap': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-theme-data': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vueuse/core': 13.9.0(vue@3.5.24) + vuepress-theme-hope@2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(@vuepress/plugin-feed@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(@vuepress/plugin-search@2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)))(katex@0.16.38)(markdown-it@14.1.1)(mermaid@11.13.0)(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)): + dependencies: + '@vuepress/helper': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-active-header-links': 2.0.0-rc.124(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-back-to-top': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-blog': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-catalog': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-comment': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-copy-code': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-copyright': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-git': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-icon': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-links-check': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-chart': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(mermaid@11.13.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-ext': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-hint': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vue@3.5.30)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-image': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-include': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-math': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(katex@0.16.38)(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-preview': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-stylize': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-markdown-tab': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-notice': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-nprogress': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-photo-swipe': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-reading-time': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-redirect': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-rtl': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-sass-palette': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-seo': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-shiki': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(@vueuse/core@14.2.1(vue@3.5.30))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-sitemap': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-theme-data': 2.0.0-rc.124(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vueuse/core': 14.2.1(vue@3.5.30) balloon-css: 1.2.0 - bcrypt-ts: 7.1.0 - chokidar: 4.0.3 - vue: 3.5.24 - vuepress: 2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24) - vuepress-plugin-components: 2.0.0-rc.94(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress-plugin-md-enhance: 2.0.0-rc.94(markdown-it@14.1.0)(sass-embedded@1.89.2)(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - vuepress-shared: 2.0.0-rc.94(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) + bcrypt-ts: 8.0.1 + chokidar: 5.0.0 + vue: 3.5.30 + vuepress: 2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30) + vuepress-plugin-components: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress-plugin-md-enhance: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(markdown-it@14.1.1)(sass-embedded@1.98.0)(sass@1.98.0)(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + vuepress-shared: 2.0.0-rc.103(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) optionalDependencies: - '@vuepress/plugin-feed': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - '@vuepress/plugin-search': 2.0.0-rc.112(vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24)) - sass-embedded: 1.89.2 + '@vuepress/plugin-feed': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + '@vuepress/plugin-search': 2.0.0-rc.124(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30)) + sass: 1.98.0 + sass-embedded: 1.98.0 transitivePeerDependencies: + - '@mathjax/mathjax-newcm-font' + - '@mathjax/src' - '@vue/repl' + - '@vuepress/bundler-vite' + - '@vuepress/bundler-webpack' - '@waline/client' - artalk - artplayer @@ -4781,7 +6004,6 @@ snapshots: - markmap-lib - markmap-toolbar - markmap-view - - mathjax-full - mermaid - mpegts.js - sandpack-vue3 @@ -4789,17 +6011,17 @@ snapshots: - typescript - vidstack - vuepress@2.0.0-rc.24(@vuepress/bundler-vite@2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2))(vue@3.5.24): + vuepress@2.0.0-rc.26(@vuepress/bundler-vite@2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0))(vue@3.5.30): dependencies: - '@vuepress/cli': 2.0.0-rc.24 - '@vuepress/client': 2.0.0-rc.24 - '@vuepress/core': 2.0.0-rc.24 - '@vuepress/markdown': 2.0.0-rc.24 - '@vuepress/shared': 2.0.0-rc.24 - '@vuepress/utils': 2.0.0-rc.24 - vue: 3.5.24 + '@vuepress/cli': 2.0.0-rc.26 + '@vuepress/client': 2.0.0-rc.26 + '@vuepress/core': 2.0.0-rc.26 + '@vuepress/markdown': 2.0.0-rc.26 + '@vuepress/shared': 2.0.0-rc.26 + '@vuepress/utils': 2.0.0-rc.26 + vue: 3.5.30 optionalDependencies: - '@vuepress/bundler-vite': 2.0.0-rc.24(@types/node@24.10.1)(sass-embedded@1.89.2) + '@vuepress/bundler-vite': 2.0.0-rc.26(@types/node@25.4.0)(sass-embedded@1.98.0)(sass@1.98.0) transitivePeerDependencies: - supports-color - typescript @@ -4824,7 +6046,7 @@ snapshots: xml-js@1.6.11: dependencies: - sax: 1.4.3 + sax: 1.5.0 y18n@4.0.3: {} @@ -4847,4 +6069,6 @@ snapshots: y18n: 4.0.3 yargs-parser: 18.1.3 + yoctocolors@2.1.2: {} + zwitch@2.0.4: {}