diff --git a/.gitattributes b/.gitattributes
index 52695f70c2..e218bbe25d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,6 +4,7 @@
 /assets/*.json linguist-generated
 /public/assets/img/svg/*.svg linguist-generated
 /templates/swagger/v1_json.tmpl linguist-generated
+/options/fileicon/** linguist-generated
 /vendor/** -text -eol linguist-vendored
 /web_src/js/vendor/** -text -eol linguist-vendored
 Dockerfile.* linguist-language=Dockerfile
diff --git a/README.md b/README.md
index 5ae65cd2ac..017ca629d0 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
 [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
 [![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
 
-[View this document in Chinese](./README_ZH.md)
+[繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
 
 ## Purpose
 
diff --git a/README.zh-cn.md b/README.zh-cn.md
new file mode 100644
index 0000000000..f34b25b945
--- /dev/null
+++ b/README.zh-cn.md
@@ -0,0 +1,206 @@
+# Gitea
+
+[![](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main)](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain "Release Nightly")
+[![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea")
+[![](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea "Go Report Card")
+[![](https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg)](https://pkg.go.dev/code.gitea.io/gitea "GoDoc")
+[![](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest "GitHub release")
+[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
+[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
+[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
+[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
+[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
+
+[English](./README.md) | [繁體中文](./README.zh-tw.md)
+
+## 目的
+
+这个项目的目标是提供最简单、最快速、最无痛的方式来设置自托管的 Git 服务。
+
+由于 Gitea 是用 Go 语言编写的,它可以在 Go 支持的所有平台和架构上运行,包括 Linux、macOS 和 Windows 的 x86、amd64、ARM 和 PowerPC 架构。这个项目自 2016 年 11 月从 [Gogs](https://gogs.io) [分叉](https://blog.gitea.com/welcome-to-gitea/) 而来,但已经有了很多变化。
+
+在线演示可以访问 [demo.gitea.com](https://demo.gitea.com)。
+
+要访问免费的 Gitea 服务(有一定数量的仓库限制),可以访问 [gitea.com](https://gitea.com/user/login)。
+
+要快速部署您自己的专用 Gitea 实例,可以在 [cloud.gitea.com](https://cloud.gitea.com) 开始免费试用。
+
+## 文件
+
+您可以在我们的官方 [文件网站](https://docs.gitea.com/) 上找到全面的文件。
+
+它包括安装、管理、使用、开发、贡献指南等,帮助您快速入门并有效地探索所有功能。
+
+如果您有任何建议或想要贡献,可以访问 [文件仓库](https://gitea.com/gitea/docs)
+
+## 构建
+
+从源代码树的根目录运行:
+
+    TAGS="bindata" make build
+
+如果需要 SQLite 支持:
+
+    TAGS="bindata sqlite sqlite_unlock_notify" make build
+
+`build` 目标分为两个子目标:
+
+- `make backend` 需要 [Go Stable](https://go.dev/dl/),所需版本在 [go.mod](/go.mod) 中定义。
+- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本。
+
+需要互联网连接来下载 go 和 npm 模块。从包含预构建前端文件的官方源代码压缩包构建时,不会触发 `frontend` 目标,因此可以在没有 Node.js 的情况下构建。
+
+更多信息:https://docs.gitea.com/installation/install-from-source
+
+## 使用
+
+构建后,默认情况下会在源代码树的根目录生成一个名为 `gitea` 的二进制文件。要运行它,请使用:
+
+    ./gitea web
+
+> [!注意]
+> 如果您对使用我们的 API 感兴趣,我们提供了实验性支持,并附有 [文件](https://docs.gitea.com/api)。
+
+## 贡献
+
+预期的工作流程是:Fork -> Patch -> Push -> Pull Request
+
+> [!注意]
+>
+> 1. **在开始进行 Pull Request 之前,您必须阅读 [贡献者指南](CONTRIBUTING.md)。**
+> 2. 如果您在项目中发现了漏洞,请私下写信给 **security@gitea.io**。谢谢!
+
+## 翻译
+
+[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com)
+
+翻译通过 [Crowdin](https://translate.gitea.com) 进行。如果您想翻译成新的语言,请在 Crowdin 项目中请求管理员添加新语言。
+
+您也可以创建一个 issue 来添加语言,或者在 discord 的 #translation 频道上询问。如果您需要上下文或发现一些翻译问题,可以在字符串上留言或在 Discord 上询问。对于一般的翻译问题,文档中有一个部分。目前有点空,但我们希望随着问题的出现而填充它。
+
+更多信息请参阅 [文件](https://docs.gitea.com/contributing/localization)。
+
+## 官方和第三方项目
+
+我们提供了一个官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一个名为 [tea](https://gitea.com/gitea/tea) 的 CLI 工具和一个 Gitea Action 的 [action runner](https://gitea.com/gitea/act_runner)。
+
+我们在 [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea) 维护了一个 Gitea 相关项目的列表,您可以在那里发现更多的第三方项目,包括 SDK、插件、主题等。
+
+## 通讯
+
+[![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea")
+
+如果您有任何文件未涵盖的问题,可以在我们的 [Discord 服务器](https://discord.gg/Gitea) 上与我们联系,或者在 [discourse 论坛](https://forum.gitea.com/) 上创建帖子。
+
+## 作者
+
+- [维护者](https://github.com/orgs/go-gitea/people)
+- [贡献者](https://github.com/go-gitea/gitea/graphs/contributors)
+- [翻译者](options/locale/TRANSLATORS)
+
+## 支持者
+
+感谢所有支持者! 🙏 [[成为支持者](https://opencollective.com/gitea#backer)]
+
+<a href="https://opencollective.com/gitea#backers" target="_blank"><img src="https://opencollective.com/gitea/backers.svg?width=890"></a>
+
+## 赞助商
+
+通过成为赞助商来支持这个项目。您的标志将显示在这里,并带有链接到您的网站。 [[成为赞助商](https://opencollective.com/gitea#sponsor)]
+
+<a href="https://opencollective.com/gitea/sponsor/0/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/0/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/1/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/1/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/2/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/2/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/3/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/3/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/4/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/4/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/5/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/5/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/6/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/6/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
+
+## 常见问题
+
+**Gitea 怎么发音?**
+
+Gitea 的发音是 [/ɡɪ’ti:/](https://youtu.be/EM71-2uDAoY),就像 "gi-tea" 一样,g 是硬音。
+
+**为什么这个项目没有托管在 Gitea 实例上?**
+
+我们正在 [努力](https://github.com/go-gitea/gitea/issues/1029)。
+
+**在哪里可以找到安全补丁?**
+
+在 [发布日志](https://github.com/go-gitea/gitea/releases) 或 [变更日志](https://github.com/go-gitea/gitea/blob/main/CHANGELOG.md) 中,搜索关键词 `SECURITY` 以找到安全补丁。
+
+## 许可证
+
+这个项目是根据 MIT 许可证授权的。
+请参阅 [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) 文件以获取完整的许可证文本。
+
+## 进一步信息
+
+<details>
+<summary>寻找界面概述?查看这里!</summary>
+
+### 登录/注册页面
+
+![Login](https://dl.gitea.com/screenshots/login.png)
+![Register](https://dl.gitea.com/screenshots/register.png)
+
+### 用户仪表板
+
+![Home](https://dl.gitea.com/screenshots/home.png)
+![Issues](https://dl.gitea.com/screenshots/issues.png)
+![Pull Requests](https://dl.gitea.com/screenshots/pull_requests.png)
+![Milestones](https://dl.gitea.com/screenshots/milestones.png)
+
+### 用户资料
+
+![Profile](https://dl.gitea.com/screenshots/user_profile.png)
+
+### 探索
+
+![Repos](https://dl.gitea.com/screenshots/explore_repos.png)
+![Users](https://dl.gitea.com/screenshots/explore_users.png)
+![Orgs](https://dl.gitea.com/screenshots/explore_orgs.png)
+
+### 仓库
+
+![Home](https://dl.gitea.com/screenshots/repo_home.png)
+![Commits](https://dl.gitea.com/screenshots/repo_commits.png)
+![Branches](https://dl.gitea.com/screenshots/repo_branches.png)
+![Labels](https://dl.gitea.com/screenshots/repo_labels.png)
+![Milestones](https://dl.gitea.com/screenshots/repo_milestones.png)
+![Releases](https://dl.gitea.com/screenshots/repo_releases.png)
+![Tags](https://dl.gitea.com/screenshots/repo_tags.png)
+
+#### 仓库问题
+
+![List](https://dl.gitea.com/screenshots/repo_issues.png)
+![Issue](https://dl.gitea.com/screenshots/repo_issue.png)
+
+#### 仓库拉取请求
+
+![List](https://dl.gitea.com/screenshots/repo_pull_requests.png)
+![Pull Request](https://dl.gitea.com/screenshots/repo_pull_request.png)
+![File](https://dl.gitea.com/screenshots/repo_pull_request_file.png)
+![Commits](https://dl.gitea.com/screenshots/repo_pull_request_commits.png)
+
+#### 仓库操作
+
+![List](https://dl.gitea.com/screenshots/repo_actions.png)
+![Details](https://dl.gitea.com/screenshots/repo_actions_run.png)
+
+#### 仓库活动
+
+![Activity](https://dl.gitea.com/screenshots/repo_activity.png)
+![Contributors](https://dl.gitea.com/screenshots/repo_contributors.png)
+![Code Frequency](https://dl.gitea.com/screenshots/repo_code_frequency.png)
+![Recent Commits](https://dl.gitea.com/screenshots/repo_recent_commits.png)
+
+### 组织
+
+![Home](https://dl.gitea.com/screenshots/org_home.png)
+
+</details>
diff --git a/README.zh-tw.md b/README.zh-tw.md
new file mode 100644
index 0000000000..9de3f85dd5
--- /dev/null
+++ b/README.zh-tw.md
@@ -0,0 +1,206 @@
+# Gitea
+
+[![](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main)](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain "Release Nightly")
+[![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea")
+[![](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea "Go Report Card")
+[![](https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg)](https://pkg.go.dev/code.gitea.io/gitea "GoDoc")
+[![](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest "GitHub release")
+[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
+[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
+[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
+[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
+[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
+
+[English](./README.md) | [简体中文](./README.zh-cn.md)
+
+## 目的
+
+這個項目的目標是提供最簡單、最快速、最無痛的方式來設置自託管的 Git 服務。
+
+由於 Gitea 是用 Go 語言編寫的,它可以在 Go 支援的所有平台和架構上運行,包括 Linux、macOS 和 Windows 的 x86、amd64、ARM 和 PowerPC 架構。這個項目自 2016 年 11 月從 [Gogs](https://gogs.io) [分叉](https://blog.gitea.com/welcome-to-gitea/) 而來,但已經有了很多變化。
+
+在線演示可以訪問 [demo.gitea.com](https://demo.gitea.com)。
+
+要訪問免費的 Gitea 服務(有一定數量的倉庫限制),可以訪問 [gitea.com](https://gitea.com/user/login)。
+
+要快速部署您自己的專用 Gitea 實例,可以在 [cloud.gitea.com](https://cloud.gitea.com) 開始免費試用。
+
+## 文件
+
+您可以在我們的官方 [文件網站](https://docs.gitea.com/) 上找到全面的文件。
+
+它包括安裝、管理、使用、開發、貢獻指南等,幫助您快速入門並有效地探索所有功能。
+
+如果您有任何建議或想要貢獻,可以訪問 [文件倉庫](https://gitea.com/gitea/docs)
+
+## 構建
+
+從源代碼樹的根目錄運行:
+
+    TAGS="bindata" make build
+
+如果需要 SQLite 支援:
+
+    TAGS="bindata sqlite sqlite_unlock_notify" make build
+
+`build` 目標分為兩個子目標:
+
+- `make backend` 需要 [Go Stable](https://go.dev/dl/),所需版本在 [go.mod](/go.mod) 中定義。
+- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本。
+
+需要互聯網連接來下載 go 和 npm 模塊。從包含預構建前端文件的官方源代碼壓縮包構建時,不會觸發 `frontend` 目標,因此可以在沒有 Node.js 的情況下構建。
+
+更多信息:https://docs.gitea.com/installation/install-from-source
+
+## 使用
+
+構建後,默認情況下會在源代碼樹的根目錄生成一個名為 `gitea` 的二進制文件。要運行它,請使用:
+
+    ./gitea web
+
+> [!注意]
+> 如果您對使用我們的 API 感興趣,我們提供了實驗性支援,並附有 [文件](https://docs.gitea.com/api)。
+
+## 貢獻
+
+預期的工作流程是:Fork -> Patch -> Push -> Pull Request
+
+> [!注意]
+>
+> 1. **在開始進行 Pull Request 之前,您必須閱讀 [貢獻者指南](CONTRIBUTING.md)。**
+> 2. 如果您在項目中發現了漏洞,請私下寫信給 **security@gitea.io**。謝謝!
+
+## 翻譯
+
+[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com)
+
+翻譯通過 [Crowdin](https://translate.gitea.com) 進行。如果您想翻譯成新的語言,請在 Crowdin 項目中請求管理員添加新語言。
+
+您也可以創建一個 issue 來添加語言,或者在 discord 的 #translation 頻道上詢問。如果您需要上下文或發現一些翻譯問題,可以在字符串上留言或在 Discord 上詢問。對於一般的翻譯問題,文檔中有一個部分。目前有點空,但我們希望隨著問題的出現而填充它。
+
+更多信息請參閱 [文件](https://docs.gitea.com/contributing/localization)。
+
+## 官方和第三方項目
+
+我們提供了一個官方的 [go-sdk](https://gitea.com/gitea/go-sdk),一個名為 [tea](https://gitea.com/gitea/tea) 的 CLI 工具和一個 Gitea Action 的 [action runner](https://gitea.com/gitea/act_runner)。
+
+我們在 [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea) 維護了一個 Gitea 相關項目的列表,您可以在那裡發現更多的第三方項目,包括 SDK、插件、主題等。
+
+## 通訊
+
+[![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea")
+
+如果您有任何文件未涵蓋的問題,可以在我們的 [Discord 服務器](https://discord.gg/Gitea) 上與我們聯繫,或者在 [discourse 論壇](https://forum.gitea.com/) 上創建帖子。
+
+## 作者
+
+- [維護者](https://github.com/orgs/go-gitea/people)
+- [貢獻者](https://github.com/go-gitea/gitea/graphs/contributors)
+- [翻譯者](options/locale/TRANSLATORS)
+
+## 支持者
+
+感謝所有支持者! 🙏 [[成為支持者](https://opencollective.com/gitea#backer)]
+
+<a href="https://opencollective.com/gitea#backers" target="_blank"><img src="https://opencollective.com/gitea/backers.svg?width=890"></a>
+
+## 贊助商
+
+通過成為贊助商來支持這個項目。您的標誌將顯示在這裡,並帶有鏈接到您的網站。 [[成為贊助商](https://opencollective.com/gitea#sponsor)]
+
+<a href="https://opencollective.com/gitea/sponsor/0/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/0/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/1/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/1/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/2/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/2/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/3/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/3/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/4/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/4/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/5/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/5/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/6/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/6/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
+<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
+
+## 常見問題
+
+**Gitea 怎麼發音?**
+
+Gitea 的發音是 [/ɡɪ’ti:/](https://youtu.be/EM71-2uDAoY),就像 "gi-tea" 一樣,g 是硬音。
+
+**為什麼這個項目沒有託管在 Gitea 實例上?**
+
+我們正在 [努力](https://github.com/go-gitea/gitea/issues/1029)。
+
+**在哪裡可以找到安全補丁?**
+
+在 [發佈日誌](https://github.com/go-gitea/gitea/releases) 或 [變更日誌](https://github.com/go-gitea/gitea/blob/main/CHANGELOG.md) 中,搜索關鍵詞 `SECURITY` 以找到安全補丁。
+
+## 許可證
+
+這個項目是根據 MIT 許可證授權的。
+請參閱 [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) 文件以獲取完整的許可證文本。
+
+## 進一步信息
+
+<details>
+<summary>尋找界面概述?查看這裡!</summary>
+
+### 登錄/註冊頁面
+
+![Login](https://dl.gitea.com/screenshots/login.png)
+![Register](https://dl.gitea.com/screenshots/register.png)
+
+### 用戶儀表板
+
+![Home](https://dl.gitea.com/screenshots/home.png)
+![Issues](https://dl.gitea.com/screenshots/issues.png)
+![Pull Requests](https://dl.gitea.com/screenshots/pull_requests.png)
+![Milestones](https://dl.gitea.com/screenshots/milestones.png)
+
+### 用戶資料
+
+![Profile](https://dl.gitea.com/screenshots/user_profile.png)
+
+### 探索
+
+![Repos](https://dl.gitea.com/screenshots/explore_repos.png)
+![Users](https://dl.gitea.com/screenshots/explore_users.png)
+![Orgs](https://dl.gitea.com/screenshots/explore_orgs.png)
+
+### 倉庫
+
+![Home](https://dl.gitea.com/screenshots/repo_home.png)
+![Commits](https://dl.gitea.com/screenshots/repo_commits.png)
+![Branches](https://dl.gitea.com/screenshots/repo_branches.png)
+![Labels](https://dl.gitea.com/screenshots/repo_labels.png)
+![Milestones](https://dl.gitea.com/screenshots/repo_milestones.png)
+![Releases](https://dl.gitea.com/screenshots/repo_releases.png)
+![Tags](https://dl.gitea.com/screenshots/repo_tags.png)
+
+#### 倉庫問題
+
+![List](https://dl.gitea.com/screenshots/repo_issues.png)
+![Issue](https://dl.gitea.com/screenshots/repo_issue.png)
+
+#### 倉庫拉取請求
+
+![List](https://dl.gitea.com/screenshots/repo_pull_requests.png)
+![Pull Request](https://dl.gitea.com/screenshots/repo_pull_request.png)
+![File](https://dl.gitea.com/screenshots/repo_pull_request_file.png)
+![Commits](https://dl.gitea.com/screenshots/repo_pull_request_commits.png)
+
+#### 倉庫操作
+
+![List](https://dl.gitea.com/screenshots/repo_actions.png)
+![Details](https://dl.gitea.com/screenshots/repo_actions_run.png)
+
+#### 倉庫活動
+
+![Activity](https://dl.gitea.com/screenshots/repo_activity.png)
+![Contributors](https://dl.gitea.com/screenshots/repo_contributors.png)
+![Code Frequency](https://dl.gitea.com/screenshots/repo_code_frequency.png)
+![Recent Commits](https://dl.gitea.com/screenshots/repo_recent_commits.png)
+
+### 組織
+
+![Home](https://dl.gitea.com/screenshots/org_home.png)
+
+</details>
diff --git a/README_ZH.md b/README_ZH.md
deleted file mode 100644
index 89c34f6b63..0000000000
--- a/README_ZH.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Gitea
-
-[![](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main)](https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain "Release Nightly")
-[![](https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/Gitea "Join the Discord chat at https://discord.gg/Gitea")
-[![](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea "Go Report Card")
-[![](https://pkg.go.dev/badge/code.gitea.io/gitea?status.svg)](https://pkg.go.dev/code.gitea.io/gitea "GoDoc")
-[![](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest "GitHub release")
-[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
-[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
-[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
-[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
-[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
-
-[View this document in English](./README.md)
-
-## 目标
-
-Gitea 的首要目标是创建一个极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。我们采用 Go 作为后端语言,这使我们只要生成一个可执行程序即可。并且他还支持跨平台,支持 Linux、macOS 和 Windows 以及各种架构,除了 x86 和 amd64,还包括 ARM 和 PowerPC。
-
-如果你想试用在线演示和报告问题,请访问 [demo.gitea.com](https://demo.gitea.com/)。
-
-如果你想使用免费的 Gitea 服务(有仓库数量限制),请访问 [gitea.com](https://gitea.com/user/login)。
-
-如果你想在 Gitea Cloud 上快速部署你自己独享的 Gitea 实例,请访问 [cloud.gitea.com](https://cloud.gitea.com) 开始免费试用。
-
-## 文档
-
-关于如何安装请访问我们的 [文档站](https://docs.gitea.com/zh-cn/category/installation),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/gitea) 和 QQ群 328432459 来和我们交流。
-
-## 编译
-
-在源代码的根目录下执行:
-
-    TAGS="bindata" make build
-
-或者如果需要SQLite支持:
-
-    TAGS="bindata sqlite sqlite_unlock_notify" make build
-
-编译过程会分成2个子任务:
-
-- `make backend`,需要 [Go Stable](https://go.dev/dl/),最低版本需求可查看 [go.mod](/go.mod)。
-- `make frontend`,需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本。
-
-你需要连接网络来下载 go 和 npm modules。当从 tar 格式的源文件编译时,其中包含了预编译的前端文件,因此 `make frontend` 将不会被执行。这允许编译时不需要 Node.js。
-
-更多信息: https://docs.gitea.com/installation/install-from-source
-
-## 使用
-
-编译之后,默认会在根目录下生成一个名为 `gitea` 的文件。你可以这样执行它:
-
-    ./gitea web
-
-> [!注意]
-> 如果你要使用API,请参见 [API 文档](https://godoc.org/code.gitea.io/sdk/gitea)。
-
-## 贡献
-
-贡献流程:Fork -> Patch -> Push -> Pull Request
-
-> [!注意]
->
-> 1. **开始贡献代码之前请确保你已经看过了 [贡献者向导(英文)](CONTRIBUTING.md)**。
-> 2. 所有的安全问题,请私下发送邮件给 **security@gitea.io**。 谢谢!
-
-## 翻译
-
-[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com)
-
-多语言翻译是基于Crowdin进行的。
-
-从 [文档](https://docs.gitea.com/contributing/localization) 中获取更多信息。
-
-## 官方和第三方项目
-
-Gitea 提供官方的 [go-sdk](https://gitea.com/gitea/go-sdk),以及名为 [tea](https://gitea.com/gitea/tea) 的 CLI 工具 和 用于 Gitea Action 的 [action runner](https://gitea.com/gitea/act_runner)。
-
-[gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea) 是一个 Gitea 相关项目的列表,你可以在这里找到更多的第三方项目,包括 SDK、插件、主题等等。
-
-## 作者
-
-- [Maintainers](https://github.com/orgs/go-gitea/people)
-- [Contributors](https://github.com/go-gitea/gitea/graphs/contributors)
-- [Translators](options/locale/TRANSLATORS)
-
-## 授权许可
-
-本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/go-gitea/gitea/blob/main/LICENSE) 文件中。
-
-## 更多信息
-
-<details>
-<summary>截图</summary>
-
-### 登录界面
-
-![登录](https://dl.gitea.com/screenshots/login.png)
-![注册](https://dl.gitea.com/screenshots/register.png)
-
-### 用户首页
-
-![首页](https://dl.gitea.com/screenshots/home.png)
-![工单列表](https://dl.gitea.com/screenshots/issues.png)
-![合并请求列表](https://dl.gitea.com/screenshots/pull_requests.png)
-![里程碑列表](https://dl.gitea.com/screenshots/milestones.png)
-
-### 用户资料
-
-![用户资料](https://dl.gitea.com/screenshots/user_profile.png)
-
-### 探索
-
-![仓库列表](https://dl.gitea.com/screenshots/explore_repos.png)
-![用户列表](https://dl.gitea.com/screenshots/explore_users.png)
-![组织列表](https://dl.gitea.com/screenshots/explore_orgs.png)
-
-### 仓库
-
-![首页](https://dl.gitea.com/screenshots/repo_home.png)
-![提交列表](https://dl.gitea.com/screenshots/repo_commits.png)
-![分支列表](https://dl.gitea.com/screenshots/repo_branches.png)
-![标签列表](https://dl.gitea.com/screenshots/repo_labels.png)
-![里程碑列表](https://dl.gitea.com/screenshots/repo_milestones.png)
-![版本发布](https://dl.gitea.com/screenshots/repo_releases.png)
-![标签列表](https://dl.gitea.com/screenshots/repo_tags.png)
-
-#### 仓库工单
-
-![列表](https://dl.gitea.com/screenshots/repo_issues.png)
-![工单](https://dl.gitea.com/screenshots/repo_issue.png)
-
-#### 仓库合并请求
-
-![列表](https://dl.gitea.com/screenshots/repo_pull_requests.png)
-![合并请求](https://dl.gitea.com/screenshots/repo_pull_request.png)
-![文件](https://dl.gitea.com/screenshots/repo_pull_request_file.png)
-![提交列表](https://dl.gitea.com/screenshots/repo_pull_request_commits.png)
-
-#### 仓库 Actions
-
-![列表](https://dl.gitea.com/screenshots/repo_actions.png)
-![Run](https://dl.gitea.com/screenshots/repo_actions_run.png)
-
-#### 仓库动态
-
-![动态](https://dl.gitea.com/screenshots/repo_activity.png)
-![贡献者](https://dl.gitea.com/screenshots/repo_contributors.png)
-![代码频率](https://dl.gitea.com/screenshots/repo_code_frequency.png)
-![最近的提交](https://dl.gitea.com/screenshots/repo_recent_commits.png)
-
-### 组织
-
-![首页](https://dl.gitea.com/screenshots/org_home.png)
-
-</details>
diff --git a/cmd/web.go b/cmd/web.go
index dc5c6de48a..e47b171455 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -213,6 +213,10 @@ func serveInstalled(ctx *cli.Context) error {
 		log.Fatal("Can not find APP_DATA_PATH %q", setting.AppDataPath)
 	}
 
+	// the AppDataTempDir is fully managed by us with a safe sub-path
+	// so it's safe to automatically remove the outdated files
+	setting.AppDataTempDir("").RemoveOutdated(3 * 24 * time.Hour)
+
 	// Override the provided port number within the configuration
 	if ctx.IsSet("port") {
 		if err := setPort(ctx.String("port")); err != nil {
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 07a6ebdcf2..8d39551168 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -197,13 +197,6 @@ RUN_USER = ; git
 ;; relative paths are made absolute relative to the APP_DATA_PATH
 ;SSH_SERVER_HOST_KEYS=ssh/gitea.rsa, ssh/gogs.rsa
 ;;
-;; Directory to create temporary files in when testing public keys using ssh-keygen,
-;; default is the system temporary directory.
-;SSH_KEY_TEST_PATH =
-;;
-;; Use `ssh-keygen` to parse public SSH keys. The value is passed to the shell. By default, Gitea does the parsing itself.
-;SSH_KEYGEN_PATH =
-;;
 ;; Enable SSH Authorized Key Backup when rewriting all keys, default is false
 ;SSH_AUTHORIZED_KEYS_BACKUP = false
 ;;
@@ -294,6 +287,9 @@ RUN_USER = ; git
 ;; Default path for App data
 ;APP_DATA_PATH = data ; relative paths will be made absolute with _`AppWorkPath`_
 ;;
+;; Base path for App's temp files, leave empty to use the managed tmp directory in APP_DATA_PATH
+;APP_TEMP_PATH =
+;;
 ;; Enable gzip compression for runtime-generated content, static resources excluded
 ;ENABLE_GZIP = false
 ;;
@@ -1069,15 +1065,6 @@ LEVEL = Info
 ;; Separate extensions with a comma. To line wrap files without an extension, just put a comma
 ;LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd,.livemd,
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;[repository.local]
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Path for local repository copy. Defaults to `tmp/local-repo` (content gets deleted on gitea restart)
-;LOCAL_COPY_PATH = tmp/local-repo
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;[repository.upload]
@@ -1087,9 +1074,6 @@ LEVEL = Info
 ;; Whether repository file uploads are enabled. Defaults to `true`
 ;ENABLED = true
 ;;
-;; Path for uploads. Defaults to `data/tmp/uploads` (content gets deleted on gitea restart)
-;TEMP_PATH = data/tmp/uploads
-;;
 ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
 ;ALLOWED_TYPES =
 ;;
@@ -2473,7 +2457,7 @@ LEVEL = Info
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Set the maximum number of characters in a mermaid source. (Set to -1 to disable limits)
-;MERMAID_MAX_SOURCE_CHARACTERS = 5000
+;MERMAID_MAX_SOURCE_CHARACTERS = 50000
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2594,9 +2578,6 @@ LEVEL = Info
 ;; Currently, only `minio` and `azureblob` is supported.
 ;SERVE_DIRECT = false
 ;;
-;; Path for chunked uploads. Defaults to APP_DATA_PATH + `tmp/package-upload`
-;CHUNKED_UPLOAD_PATH = tmp/package-upload
-;;
 ;; Maximum count of package versions a single owner can have (`-1` means no limits)
 ;LIMIT_TOTAL_OWNER_COUNT = -1
 ;; Maximum size of packages a single owner can use (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
diff --git a/docker/root/etc/s6/openssh/setup b/docker/root/etc/s6/openssh/setup
index 6fbc599cc5..48e7d4b211 100755
--- a/docker/root/etc/s6/openssh/setup
+++ b/docker/root/etc/s6/openssh/setup
@@ -31,16 +31,19 @@ if [ -e /data/ssh/ssh_host_ecdsa_cert ]; then
   SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa_cert"}
 fi
 
-if [ -e /data/ssh/ssh_host_ed25519-cert.pub ]; then
-  SSH_ED25519_CERT=${SSH_ED25519_CERT:-"/data/ssh/ssh_host_ed25519-cert.pub"}
+# In case someone wants to sign the `{keyname}.pub` key by `ssh-keygen -s ca -I identity ...` to
+# make use of the ssh-key certificate authority feature (see ssh-keygen CERTIFICATES section),
+# the generated key file name is `{keyname}-cert.pub`
+if [ -e /data/ssh/ssh_host_ed25519_key-cert.pub ]; then
+  SSH_ED25519_CERT=${SSH_ED25519_CERT:-"/data/ssh/ssh_host_ed25519_key-cert.pub"}
 fi
 
-if [ -e /data/ssh/ssh_host_rsa-cert.pub ]; then
-  SSH_RSA_CERT=${SSH_RSA_CERT:-"/data/ssh/ssh_host_rsa-cert.pub"}
+if [ -e /data/ssh/ssh_host_rsa_key-cert.pub ]; then
+  SSH_RSA_CERT=${SSH_RSA_CERT:-"/data/ssh/ssh_host_rsa_key-cert.pub"}
 fi
 
-if [ -e /data/ssh/ssh_host_ecdsa-cert.pub ]; then
-  SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa-cert.pub"}
+if [ -e /data/ssh/ssh_host_ecdsa_key-cert.pub ]; then
+  SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa_key-cert.pub"}
 fi
 
 if [ -d /etc/ssh ]; then
diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go
index 24c76f7b5c..220f46ad1d 100644
--- a/models/asymkey/gpg_key.go
+++ b/models/asymkey/gpg_key.go
@@ -240,3 +240,10 @@ func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err err
 
 	return committer.Commit()
 }
+
+func FindGPGKeyWithSubKeys(ctx context.Context, keyID string) ([]*GPGKey, error) {
+	return db.Find[GPGKey](ctx, FindGPGKeyOptions{
+		KeyID:          keyID,
+		IncludeSubKeys: true,
+	})
+}
diff --git a/models/asymkey/ssh_key_fingerprint.go b/models/asymkey/ssh_key_fingerprint.go
index 1ed3b5df2a..4dcfe1f279 100644
--- a/models/asymkey/ssh_key_fingerprint.go
+++ b/models/asymkey/ssh_key_fingerprint.go
@@ -6,27 +6,13 @@ package asymkey
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	"code.gitea.io/gitea/models/db"
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/process"
-	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/modules/util"
 
 	"golang.org/x/crypto/ssh"
 	"xorm.io/builder"
 )
 
-// ___________.__                                         .__        __
-// \_   _____/|__| ____    ____   ________________________|__| _____/  |_
-//  |    __)  |  |/    \  / ___\_/ __ \_  __ \____ \_  __ \  |/    \   __\
-//  |     \   |  |   |  \/ /_/  >  ___/|  | \/  |_> >  | \/  |   |  \  |
-//  \___  /   |__|___|  /\___  / \___  >__|  |   __/|__|  |__|___|  /__|
-//      \/            \//_____/      \/      |__|                 \/
-//
-// This file contains functions for fingerprinting SSH keys
-//
 // The database is used in checkKeyFingerprint however most of these functions probably belong in a module
 
 // checkKeyFingerprint only checks if key fingerprint has been used as public key,
@@ -41,29 +27,6 @@ func checkKeyFingerprint(ctx context.Context, fingerprint string) error {
 	return nil
 }
 
-func calcFingerprintSSHKeygen(publicKeyContent string) (string, error) {
-	// Calculate fingerprint.
-	tmpPath, err := writeTmpKeyFile(publicKeyContent)
-	if err != nil {
-		return "", err
-	}
-	defer func() {
-		if err := util.Remove(tmpPath); err != nil {
-			log.Warn("Unable to remove temporary key file: %s: Error: %v", tmpPath, err)
-		}
-	}()
-	stdout, stderr, err := process.GetManager().Exec("AddPublicKey", "ssh-keygen", "-lf", tmpPath)
-	if err != nil {
-		if strings.Contains(stderr, "is not a public key file") {
-			return "", ErrKeyUnableVerify{stderr}
-		}
-		return "", util.NewInvalidArgumentErrorf("'ssh-keygen -lf %s' failed with error '%s': %s", tmpPath, err, stderr)
-	} else if len(stdout) < 2 {
-		return "", util.NewInvalidArgumentErrorf("not enough output for calculating fingerprint: %s", stdout)
-	}
-	return strings.Split(stdout, " ")[1], nil
-}
-
 func calcFingerprintNative(publicKeyContent string) (string, error) {
 	// Calculate fingerprint.
 	pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKeyContent))
@@ -75,15 +38,12 @@ func calcFingerprintNative(publicKeyContent string) (string, error) {
 
 // CalcFingerprint calculate public key's fingerprint
 func CalcFingerprint(publicKeyContent string) (string, error) {
-	// Call the method based on configuration
-	useNative := setting.SSH.KeygenPath == ""
-	calcFn := util.Iif(useNative, calcFingerprintNative, calcFingerprintSSHKeygen)
-	fp, err := calcFn(publicKeyContent)
+	fp, err := calcFingerprintNative(publicKeyContent)
 	if err != nil {
 		if IsErrKeyUnableVerify(err) {
 			return "", err
 		}
-		return "", fmt.Errorf("CalcFingerprint(%s): %w", util.Iif(useNative, "native", "ssh-keygen"), err)
+		return "", fmt.Errorf("CalcFingerprint: %w", err)
 	}
 	return fp, nil
 }
diff --git a/models/asymkey/ssh_key_parse.go b/models/asymkey/ssh_key_parse.go
index c843525718..46dcf4d894 100644
--- a/models/asymkey/ssh_key_parse.go
+++ b/models/asymkey/ssh_key_parse.go
@@ -13,12 +13,9 @@ import (
 	"errors"
 	"fmt"
 	"math/big"
-	"os"
-	"strconv"
 	"strings"
 
 	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
@@ -175,20 +172,9 @@ func CheckPublicKeyString(content string) (_ string, err error) {
 		return content, nil
 	}
 
-	var (
-		fnName  string
-		keyType string
-		length  int
-	)
-	if len(setting.SSH.KeygenPath) == 0 {
-		fnName = "SSHNativeParsePublicKey"
-		keyType, length, err = SSHNativeParsePublicKey(content)
-	} else {
-		fnName = "SSHKeyGenParsePublicKey"
-		keyType, length, err = SSHKeyGenParsePublicKey(content)
-	}
+	keyType, length, err := SSHNativeParsePublicKey(content)
 	if err != nil {
-		return "", fmt.Errorf("%s: %w", fnName, err)
+		return "", fmt.Errorf("SSHNativeParsePublicKey: %w", err)
 	}
 	log.Trace("Key info [native: %v]: %s-%d", setting.SSH.StartBuiltinServer, keyType, length)
 
@@ -258,56 +244,3 @@ func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
 	}
 	return "", 0, fmt.Errorf("unsupported key length detection for type: %s", pkey.Type())
 }
-
-// writeTmpKeyFile writes key content to a temporary file
-// and returns the name of that file, along with any possible errors.
-func writeTmpKeyFile(content string) (string, error) {
-	tmpFile, err := os.CreateTemp(setting.SSH.KeyTestPath, "gitea_keytest")
-	if err != nil {
-		return "", fmt.Errorf("TempFile: %w", err)
-	}
-	defer tmpFile.Close()
-
-	if _, err = tmpFile.WriteString(content); err != nil {
-		return "", fmt.Errorf("WriteString: %w", err)
-	}
-	return tmpFile.Name(), nil
-}
-
-// SSHKeyGenParsePublicKey extracts key type and length using ssh-keygen.
-func SSHKeyGenParsePublicKey(key string) (string, int, error) {
-	tmpName, err := writeTmpKeyFile(key)
-	if err != nil {
-		return "", 0, fmt.Errorf("writeTmpKeyFile: %w", err)
-	}
-	defer func() {
-		if err := util.Remove(tmpName); err != nil {
-			log.Warn("Unable to remove temporary key file: %s: Error: %v", tmpName, err)
-		}
-	}()
-
-	keygenPath := setting.SSH.KeygenPath
-	if len(keygenPath) == 0 {
-		keygenPath = "ssh-keygen"
-	}
-
-	stdout, stderr, err := process.GetManager().Exec("SSHKeyGenParsePublicKey", keygenPath, "-lf", tmpName)
-	if err != nil {
-		return "", 0, fmt.Errorf("fail to parse public key: %s - %s", err, stderr)
-	}
-	if strings.Contains(stdout, "is not a public key file") {
-		return "", 0, ErrKeyUnableVerify{stdout}
-	}
-
-	fields := strings.Split(stdout, " ")
-	if len(fields) < 4 {
-		return "", 0, fmt.Errorf("invalid public key line: %s", stdout)
-	}
-
-	keyType := strings.Trim(fields[len(fields)-1], "()\r\n")
-	length, err := strconv.ParseInt(fields[0], 10, 32)
-	if err != nil {
-		return "", 0, err
-	}
-	return strings.ToLower(keyType), int(length), nil
-}
diff --git a/models/asymkey/ssh_key_test.go b/models/asymkey/ssh_key_test.go
index b33d16030d..21e4ddf62e 100644
--- a/models/asymkey/ssh_key_test.go
+++ b/models/asymkey/ssh_key_test.go
@@ -18,7 +18,6 @@ import (
 
 	"github.com/42wim/sshsig"
 	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func Test_SSHParsePublicKey(t *testing.T) {
@@ -45,27 +44,6 @@ func Test_SSHParsePublicKey(t *testing.T) {
 				assert.Equal(t, tc.keyType, keyTypeN)
 				assert.Equal(t, tc.length, lengthN)
 			})
-			if tc.skipSSHKeygen {
-				return
-			}
-			t.Run("SSHKeygen", func(t *testing.T) {
-				keyTypeK, lengthK, err := SSHKeyGenParsePublicKey(tc.content)
-				if err != nil {
-					// Some servers do not support ecdsa format.
-					if !strings.Contains(err.Error(), "line 1 too long:") {
-						require.NoError(t, err)
-					}
-				}
-				assert.Equal(t, tc.keyType, keyTypeK)
-				assert.Equal(t, tc.length, lengthK)
-			})
-			t.Run("SSHParseKeyNative", func(t *testing.T) {
-				keyTypeK, lengthK, err := SSHNativeParsePublicKey(tc.content)
-				require.NoError(t, err)
-
-				assert.Equal(t, tc.keyType, keyTypeK)
-				assert.Equal(t, tc.length, lengthK)
-			})
 		})
 	}
 }
@@ -186,14 +164,6 @@ func Test_calcFingerprint(t *testing.T) {
 				assert.NoError(t, err)
 				assert.Equal(t, tc.fp, fpN)
 			})
-			if tc.skipSSHKeygen {
-				return
-			}
-			t.Run("SSHKeygen", func(t *testing.T) {
-				fpK, err := calcFingerprintSSHKeygen(tc.content)
-				assert.NoError(t, err)
-				assert.Equal(t, tc.fp, fpK)
-			})
 		})
 	}
 }
diff --git a/models/git/branch.go b/models/git/branch.go
index 9ac6c45578..beeb7c0689 100644
--- a/models/git/branch.go
+++ b/models/git/branch.go
@@ -235,6 +235,11 @@ func GetDeletedBranchByID(ctx context.Context, repoID, branchID int64) (*Branch,
 	return &branch, nil
 }
 
+func DeleteRepoBranches(ctx context.Context, repoID int64) error {
+	_, err := db.GetEngine(ctx).Where("repo_id=?", repoID).Delete(new(Branch))
+	return err
+}
+
 func DeleteBranches(ctx context.Context, repoID, doerID int64, branchIDs []int64) error {
 	return db.WithTx(ctx, func(ctx context.Context) error {
 		branches := make([]*Branch, 0, len(branchIDs))
diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go
index 746a59c6fd..7ddf7ee901 100644
--- a/models/issues/issue_update.go
+++ b/models/issues/issue_update.go
@@ -11,7 +11,6 @@ import (
 
 	"code.gitea.io/gitea/models/db"
 	"code.gitea.io/gitea/models/organization"
-	"code.gitea.io/gitea/models/perm"
 	access_model "code.gitea.io/gitea/models/perm/access"
 	project_model "code.gitea.io/gitea/models/project"
 	repo_model "code.gitea.io/gitea/models/repo"
@@ -612,7 +611,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
 				unittype = unit.TypePullRequests
 			}
 			for _, team := range teams {
-				if team.AccessMode >= perm.AccessModeAdmin {
+				if team.HasAdminAccess() {
 					checked = append(checked, team.ID)
 					resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true
 					continue
@@ -846,6 +845,7 @@ func DeleteOrphanedIssues(ctx context.Context) error {
 
 	// Remove issue attachment files.
 	for i := range attachmentPaths {
+		// FIXME: it's not right, because the attachment might not be on local filesystem
 		system_model.RemoveAllWithNotice(ctx, "Delete issue attachment", attachmentPaths[i])
 	}
 	return nil
diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go
index fe6de9c517..7da426fef0 100644
--- a/models/migrations/base/tests.go
+++ b/models/migrations/base/tests.go
@@ -15,6 +15,7 @@ import (
 	"code.gitea.io/gitea/models/unittest"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/tempdir"
 	"code.gitea.io/gitea/modules/test"
 	"code.gitea.io/gitea/modules/testlogger"
 
@@ -114,15 +115,16 @@ func MainTest(m *testing.M) {
 		setting.CustomConf = giteaConf
 	}
 
-	tmpDataPath, err := os.MkdirTemp("", "data")
+	tmpDataPath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("data")
 	if err != nil {
 		testlogger.Fatalf("Unable to create temporary data path %v\n", err)
 	}
+	defer cleanup()
 
 	setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom")
 	setting.AppDataPath = tmpDataPath
 
-	unittest.InitSettings()
+	unittest.InitSettingsForTesting()
 	if err = git.InitFull(context.Background()); err != nil {
 		testlogger.Fatalf("Unable to InitFull: %v\n", err)
 	}
@@ -134,8 +136,5 @@ func MainTest(m *testing.M) {
 	if err := removeAllWithRetry(setting.RepoRootPath); err != nil {
 		fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
 	}
-	if err := removeAllWithRetry(tmpDataPath); err != nil {
-		fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
-	}
 	os.Exit(exitStatus)
 }
diff --git a/models/organization/org.go b/models/organization/org.go
index 3e55a36758..dc889ea17f 100644
--- a/models/organization/org.go
+++ b/models/organization/org.go
@@ -178,12 +178,6 @@ func (org *Organization) HomeLink() string {
 	return org.AsUser().HomeLink()
 }
 
-// CanCreateRepo returns if user login can create a repository
-// NOTE: functions calling this assume a failure due to repository count limit; if new checks are added, those functions should be revised
-func (org *Organization) CanCreateRepo() bool {
-	return org.AsUser().CanCreateRepo()
-}
-
 // FindOrgMembersOpts represensts find org members conditions
 type FindOrgMembersOpts struct {
 	db.ListOptions
diff --git a/models/organization/org_user.go b/models/organization/org_user.go
index 08d936d922..4d7527c15f 100644
--- a/models/organization/org_user.go
+++ b/models/organization/org_user.go
@@ -78,7 +78,7 @@ func IsOrganizationAdmin(ctx context.Context, orgID, uid int64) (bool, error) {
 		return false, err
 	}
 	for _, t := range teams {
-		if t.AccessMode >= perm.AccessModeAdmin {
+		if t.HasAdminAccess() {
 			return true, nil
 		}
 	}
diff --git a/models/organization/team.go b/models/organization/team.go
index 96666da39a..7f3a9b3829 100644
--- a/models/organization/team.go
+++ b/models/organization/team.go
@@ -113,7 +113,7 @@ func (t *Team) LoadUnits(ctx context.Context) (err error) {
 
 // GetUnitNames returns the team units names
 func (t *Team) GetUnitNames() (res []string) {
-	if t.AccessMode >= perm.AccessModeAdmin {
+	if t.HasAdminAccess() {
 		return unit.AllUnitKeyNames()
 	}
 
@@ -126,7 +126,7 @@ func (t *Team) GetUnitNames() (res []string) {
 // GetUnitsMap returns the team units permissions
 func (t *Team) GetUnitsMap() map[string]string {
 	m := make(map[string]string)
-	if t.AccessMode >= perm.AccessModeAdmin {
+	if t.HasAdminAccess() {
 		for _, u := range unit.Units {
 			m[u.NameKey] = t.AccessMode.ToString()
 		}
@@ -153,6 +153,10 @@ func (t *Team) IsMember(ctx context.Context, userID int64) bool {
 	return isMember
 }
 
+func (t *Team) HasAdminAccess() bool {
+	return t.AccessMode >= perm.AccessModeAdmin
+}
+
 // LoadMembers returns paginated members in team of organization.
 func (t *Team) LoadMembers(ctx context.Context) (err error) {
 	t.Members, err = GetTeamMembers(ctx, &SearchMembersOptions{
@@ -238,22 +242,6 @@ func GetTeamByID(ctx context.Context, teamID int64) (*Team, error) {
 	return t, nil
 }
 
-// GetTeamNamesByID returns team's lower name from a list of team ids.
-func GetTeamNamesByID(ctx context.Context, teamIDs []int64) ([]string, error) {
-	if len(teamIDs) == 0 {
-		return []string{}, nil
-	}
-
-	var teamNames []string
-	err := db.GetEngine(ctx).Table("team").
-		Select("lower_name").
-		In("id", teamIDs).
-		Asc("name").
-		Find(&teamNames)
-
-	return teamNames, err
-}
-
 // IncrTeamRepoNum increases the number of repos for the given team by 1
 func IncrTeamRepoNum(ctx context.Context, teamID int64) error {
 	_, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team))
diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go
index f42c96bbe2..9d0c9f0077 100644
--- a/models/perm/access/repo_permission.go
+++ b/models/perm/access/repo_permission.go
@@ -331,7 +331,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
 
 	// if user in an owner team
 	for _, team := range teams {
-		if team.AccessMode >= perm_model.AccessModeAdmin {
+		if team.HasAdminAccess() {
 			perm.AccessMode = perm_model.AccessModeOwner
 			perm.unitsMode = nil
 			return perm, nil
@@ -399,7 +399,7 @@ func IsUserRepoAdmin(ctx context.Context, repo *repo_model.Repository, user *use
 	}
 
 	for _, team := range teams {
-		if team.AccessMode >= perm_model.AccessModeAdmin {
+		if team.HasAdminAccess() {
 			return true, nil
 		}
 	}
diff --git a/models/repo/release.go b/models/repo/release.go
index 1c2e4a48e3..663d310bc0 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -558,3 +558,8 @@ func FindTagsByCommitIDs(ctx context.Context, repoID int64, commitIDs ...string)
 	}
 	return res, nil
 }
+
+func DeleteRepoReleases(ctx context.Context, repoID int64) error {
+	_, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Delete(new(Release))
+	return err
+}
diff --git a/models/repo/update.go b/models/repo/update.go
index fce357a1ac..15c8c48d5b 100644
--- a/models/repo/update.go
+++ b/models/repo/update.go
@@ -111,31 +111,31 @@ func (err ErrRepoFilesAlreadyExist) Unwrap() error {
 	return util.ErrAlreadyExist
 }
 
-// CheckCreateRepository check if could created a repository
-func CheckCreateRepository(ctx context.Context, doer, u *user_model.User, name string, overwriteOrAdopt bool) error {
-	if !doer.CanCreateRepo() {
-		return ErrReachLimitOfRepo{u.MaxRepoCreation}
+// CheckCreateRepository check if doer could create a repository in new owner
+func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, name string, overwriteOrAdopt bool) error {
+	if !doer.CanCreateRepoIn(owner) {
+		return ErrReachLimitOfRepo{owner.MaxRepoCreation}
 	}
 
 	if err := IsUsableRepoName(name); err != nil {
 		return err
 	}
 
-	has, err := IsRepositoryModelOrDirExist(ctx, u, name)
+	has, err := IsRepositoryModelOrDirExist(ctx, owner, name)
 	if err != nil {
 		return fmt.Errorf("IsRepositoryExist: %w", err)
 	} else if has {
-		return ErrRepoAlreadyExist{u.Name, name}
+		return ErrRepoAlreadyExist{owner.Name, name}
 	}
 
-	repoPath := RepoPath(u.Name, name)
+	repoPath := RepoPath(owner.Name, name)
 	isExist, err := util.IsExist(repoPath)
 	if err != nil {
 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
 		return err
 	}
 	if !overwriteOrAdopt && isExist {
-		return ErrRepoFilesAlreadyExist{u.Name, name}
+		return ErrRepoFilesAlreadyExist{owner.Name, name}
 	}
 	return nil
 }
diff --git a/models/repo/upload.go b/models/repo/upload.go
index cae11df96a..fb57fb6c51 100644
--- a/models/repo/upload.go
+++ b/models/repo/upload.go
@@ -51,14 +51,10 @@ func init() {
 	db.RegisterModel(new(Upload))
 }
 
-// UploadLocalPath returns where uploads is stored in local file system based on given UUID.
-func UploadLocalPath(uuid string) string {
-	return filepath.Join(setting.Repository.Upload.TempPath, uuid[0:1], uuid[1:2], uuid)
-}
-
-// LocalPath returns where uploads are temporarily stored in local file system.
+// LocalPath returns where uploads are temporarily stored in local file system based on given UUID.
 func (upload *Upload) LocalPath() string {
-	return UploadLocalPath(upload.UUID)
+	uuid := upload.UUID
+	return setting.AppDataTempDir("repo-uploads").JoinPath(uuid[0:1], uuid[1:2], uuid)
 }
 
 // NewUpload creates a new upload object.
diff --git a/models/unit/unit.go b/models/unit/unit.go
index c816fc6c68..4ca676802f 100644
--- a/models/unit/unit.go
+++ b/models/unit/unit.go
@@ -20,17 +20,21 @@ type Type int
 
 // Enumerate all the unit types
 const (
-	TypeInvalid         Type = iota // 0 invalid
-	TypeCode                        // 1 code
-	TypeIssues                      // 2 issues
-	TypePullRequests                // 3 PRs
-	TypeReleases                    // 4 Releases
-	TypeWiki                        // 5 Wiki
-	TypeExternalWiki                // 6 ExternalWiki
-	TypeExternalTracker             // 7 ExternalTracker
-	TypeProjects                    // 8 Projects
-	TypePackages                    // 9 Packages
-	TypeActions                     // 10 Actions
+	TypeInvalid Type = iota // 0 invalid
+
+	TypeCode            // 1 code
+	TypeIssues          // 2 issues
+	TypePullRequests    // 3 PRs
+	TypeReleases        // 4 Releases
+	TypeWiki            // 5 Wiki
+	TypeExternalWiki    // 6 ExternalWiki
+	TypeExternalTracker // 7 ExternalTracker
+	TypeProjects        // 8 Projects
+	TypePackages        // 9 Packages
+	TypeActions         // 10 Actions
+
+	// FIXME: TEAM-UNIT-PERMISSION: the team unit "admin" permission's design is not right, when a new unit is added in the future,
+	// admin team won't inherit the correct admin permission for the new unit, need to have a complete fix before adding any new unit.
 )
 
 // Value returns integer value for unit type (used by template)
@@ -380,20 +384,3 @@ func AllUnitKeyNames() []string {
 	}
 	return res
 }
-
-// MinUnitAccessMode returns the minial permission of the permission map
-func MinUnitAccessMode(unitsMap map[Type]perm.AccessMode) perm.AccessMode {
-	res := perm.AccessModeNone
-	for t, mode := range unitsMap {
-		// Don't allow `TypeExternal{Tracker,Wiki}` to influence this as they can only be set to READ perms.
-		if t == TypeExternalTracker || t == TypeExternalWiki {
-			continue
-		}
-
-		// get the minial permission great than AccessModeNone except all are AccessModeNone
-		if mode > perm.AccessModeNone && (res == perm.AccessModeNone || mode < res) {
-			res = mode
-		}
-	}
-	return res
-}
diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go
index 7a9ca9698d..cb60cf5f85 100644
--- a/models/unittest/testdb.go
+++ b/models/unittest/testdb.go
@@ -20,6 +20,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/setting/config"
 	"code.gitea.io/gitea/modules/storage"
+	"code.gitea.io/gitea/modules/tempdir"
 	"code.gitea.io/gitea/modules/test"
 	"code.gitea.io/gitea/modules/util"
 
@@ -35,8 +36,8 @@ func fatalTestError(fmtStr string, args ...any) {
 	os.Exit(1)
 }
 
-// InitSettings initializes config provider and load common settings for tests
-func InitSettings() {
+// InitSettingsForTesting initializes config provider and load common settings for tests
+func InitSettingsForTesting() {
 	setting.IsInTesting = true
 	log.OsExiter = func(code int) {
 		if code != 0 {
@@ -75,7 +76,7 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
 	testOpts := util.OptionalArg(testOptsArg, &TestOptions{})
 	giteaRoot = test.SetupGiteaRoot()
 	setting.CustomPath = filepath.Join(giteaRoot, "custom")
-	InitSettings()
+	InitSettingsForTesting()
 
 	fixturesOpts := FixturesOptions{Dir: filepath.Join(giteaRoot, "models", "fixtures"), Files: testOpts.FixtureFiles}
 	if err := CreateTestEngine(fixturesOpts); err != nil {
@@ -92,15 +93,19 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
 	setting.SSH.Domain = "try.gitea.io"
 	setting.Database.Type = "sqlite3"
 	setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
-	repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
+	repoRootPath, cleanup1, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("repos")
 	if err != nil {
 		fatalTestError("TempDir: %v\n", err)
 	}
+	defer cleanup1()
+
 	setting.RepoRootPath = repoRootPath
-	appDataPath, err := os.MkdirTemp(os.TempDir(), "appdata")
+	appDataPath, cleanup2, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("appdata")
 	if err != nil {
 		fatalTestError("TempDir: %v\n", err)
 	}
+	defer cleanup2()
+
 	setting.AppDataPath = appDataPath
 	setting.AppWorkPath = giteaRoot
 	setting.StaticRootPath = giteaRoot
@@ -153,13 +158,6 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
 			fatalTestError("tear down failed: %v\n", err)
 		}
 	}
-
-	if err = util.RemoveAll(repoRootPath); err != nil {
-		fatalTestError("util.RemoveAll: %v\n", err)
-	}
-	if err = util.RemoveAll(appDataPath); err != nil {
-		fatalTestError("util.RemoveAll: %v\n", err)
-	}
 	os.Exit(exitStatus)
 }
 
diff --git a/models/user/user.go b/models/user/user.go
index 3b268a6f41..100f924cc6 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -247,19 +247,20 @@ func (u *User) MaxCreationLimit() int {
 	return u.MaxRepoCreation
 }
 
-// CanCreateRepo returns if user login can create a repository
-// NOTE: functions calling this assume a failure due to repository count limit; if new checks are added, those functions should be revised
-func (u *User) CanCreateRepo() bool {
+// CanCreateRepoIn checks whether the doer(u) can create a repository in the owner
+// NOTE: functions calling this assume a failure due to repository count limit; it ONLY checks the repo number LIMIT, if new checks are added, those functions should be revised
+func (u *User) CanCreateRepoIn(owner *User) bool {
 	if u.IsAdmin {
 		return true
 	}
-	if u.MaxRepoCreation <= -1 {
-		if setting.Repository.MaxCreationLimit <= -1 {
+	const noLimit = -1
+	if owner.MaxRepoCreation == noLimit {
+		if setting.Repository.MaxCreationLimit == noLimit {
 			return true
 		}
-		return u.NumRepos < setting.Repository.MaxCreationLimit
+		return owner.NumRepos < setting.Repository.MaxCreationLimit
 	}
-	return u.NumRepos < u.MaxRepoCreation
+	return owner.NumRepos < owner.MaxRepoCreation
 }
 
 // CanCreateOrganization returns true if user can create organisation.
@@ -272,13 +273,12 @@ func (u *User) CanEditGitHook() bool {
 	return !setting.DisableGitHooks && (u.IsAdmin || u.AllowGitHook)
 }
 
-// CanForkRepo returns if user login can fork a repository
-// It checks especially that the user can create repos, and potentially more
-func (u *User) CanForkRepo() bool {
+// CanForkRepoIn ONLY checks repository count limit
+func (u *User) CanForkRepoIn(owner *User) bool {
 	if setting.Repository.AllowForkWithoutMaximumLimit {
 		return true
 	}
-	return u.CanCreateRepo()
+	return u.CanCreateRepoIn(owner)
 }
 
 // CanImportLocal returns true if user can migrate repository by local path.
@@ -1187,29 +1187,28 @@ func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, e
 	for _, email := range emailAddresses {
 		userIDs.Add(email.UID)
 	}
-	users, err := GetUsersMapByIDs(ctx, userIDs.Values())
-	if err != nil {
-		return nil, err
-	}
-
 	results := make(map[string]*User, len(emails))
-	for _, email := range emailAddresses {
-		user := users[email.UID]
-		if user != nil {
-			if user.KeepEmailPrivate {
-				results[user.LowerName+"@"+setting.Service.NoReplyAddress] = user
-			} else {
-				results[email.Email] = user
+
+	if len(userIDs) > 0 {
+		users, err := GetUsersMapByIDs(ctx, userIDs.Values())
+		if err != nil {
+			return nil, err
+		}
+
+		for _, email := range emailAddresses {
+			user := users[email.UID]
+			if user != nil {
+				results[user.GetEmail()] = user
 			}
 		}
 	}
 
-	users = make(map[int64]*User, len(needCheckUserNames))
+	users := make(map[int64]*User, len(needCheckUserNames))
 	if err := db.GetEngine(ctx).In("lower_name", needCheckUserNames.Values()).Find(&users); err != nil {
 		return nil, err
 	}
 	for _, user := range users {
-		results[user.LowerName+"@"+setting.Service.NoReplyAddress] = user
+		results[user.GetPlaceholderEmail()] = user
 	}
 	return results, nil
 }
diff --git a/models/user/user_test.go b/models/user/user_test.go
index 2d5b6a405c..90e8bf13a8 100644
--- a/models/user/user_test.go
+++ b/models/user/user_test.go
@@ -19,6 +19,7 @@ import (
 	"code.gitea.io/gitea/modules/optional"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/test"
 	"code.gitea.io/gitea/modules/timeutil"
 
 	"github.com/stretchr/testify/assert"
@@ -616,3 +617,37 @@ func TestGetInactiveUsers(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Empty(t, users)
 }
+
+func TestCanCreateRepo(t *testing.T) {
+	defer test.MockVariableValue(&setting.Repository.MaxCreationLimit)()
+	const noLimit = -1
+	doerNormal := &user_model.User{}
+	doerAdmin := &user_model.User{IsAdmin: true}
+	t.Run("NoGlobalLimit", func(t *testing.T) {
+		setting.Repository.MaxCreationLimit = noLimit
+
+		assert.True(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: noLimit}))
+		assert.False(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 0}))
+		assert.True(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 100}))
+
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: noLimit}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 0}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 100}))
+	})
+
+	t.Run("GlobalLimit50", func(t *testing.T) {
+		setting.Repository.MaxCreationLimit = 50
+
+		assert.True(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: noLimit}))
+		assert.False(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 60, MaxRepoCreation: noLimit})) // limited by global limit
+		assert.False(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 0}))
+		assert.True(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 100}))
+		assert.True(t, doerNormal.CanCreateRepoIn(&user_model.User{NumRepos: 60, MaxRepoCreation: 100}))
+
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: noLimit}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 60, MaxRepoCreation: noLimit}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 0}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 10, MaxRepoCreation: 100}))
+		assert.True(t, doerAdmin.CanCreateRepoIn(&user_model.User{NumRepos: 60, MaxRepoCreation: 100}))
+	})
+}
diff --git a/modules/cache/context.go b/modules/cache/context.go
index 484cee659a..85eb9e6790 100644
--- a/modules/cache/context.go
+++ b/modules/cache/context.go
@@ -166,15 +166,15 @@ func RemoveContextData(ctx context.Context, tp, key any) {
 }
 
 // GetWithContextCache returns the cache value of the given key in the given context.
-func GetWithContextCache[T any](ctx context.Context, cacheGroupKey string, cacheTargetID any, f func() (T, error)) (T, error) {
-	v := GetContextData(ctx, cacheGroupKey, cacheTargetID)
+func GetWithContextCache[T, K any](ctx context.Context, groupKey string, targetKey K, f func(context.Context, K) (T, error)) (T, error) {
+	v := GetContextData(ctx, groupKey, targetKey)
 	if vv, ok := v.(T); ok {
 		return vv, nil
 	}
-	t, err := f()
+	t, err := f(ctx, targetKey)
 	if err != nil {
 		return t, err
 	}
-	SetContextData(ctx, cacheGroupKey, cacheTargetID, t)
+	SetContextData(ctx, groupKey, targetKey, t)
 	return t, nil
 }
diff --git a/modules/cache/context_test.go b/modules/cache/context_test.go
index decb532937..23dd789dbc 100644
--- a/modules/cache/context_test.go
+++ b/modules/cache/context_test.go
@@ -4,6 +4,7 @@
 package cache
 
 import (
+	"context"
 	"testing"
 	"time"
 
@@ -30,7 +31,7 @@ func TestWithCacheContext(t *testing.T) {
 	v = GetContextData(ctx, field, "my_config1")
 	assert.Nil(t, v)
 
-	vInt, err := GetWithContextCache(ctx, field, "my_config1", func() (int, error) {
+	vInt, err := GetWithContextCache(ctx, field, "my_config1", func(context.Context, string) (int, error) {
 		return 1, nil
 	})
 	assert.NoError(t, err)
diff --git a/modules/cachegroup/cachegroup.go b/modules/cachegroup/cachegroup.go
new file mode 100644
index 0000000000..06085f860f
--- /dev/null
+++ b/modules/cachegroup/cachegroup.go
@@ -0,0 +1,12 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package cachegroup
+
+const (
+	User               = "user"
+	EmailAvatarLink    = "email_avatar_link"
+	UserEmailAddresses = "user_email_addresses"
+	GPGKeyWithSubKeys  = "gpg_key_with_subkeys"
+	RepoUserPermission = "repo_user_permission"
+)
diff --git a/modules/git/blame.go b/modules/git/blame.go
index d1d732c716..6eb583a6b9 100644
--- a/modules/git/blame.go
+++ b/modules/git/blame.go
@@ -11,7 +11,7 @@ import (
 	"os"
 
 	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/util"
+	"code.gitea.io/gitea/modules/setting"
 )
 
 // BlamePart represents block of blame - continuous lines with one sha
@@ -29,12 +29,13 @@ type BlameReader struct {
 	bufferedReader *bufio.Reader
 	done           chan error
 	lastSha        *string
-	ignoreRevsFile *string
+	ignoreRevsFile string
 	objectFormat   ObjectFormat
+	cleanupFuncs   []func()
 }
 
 func (r *BlameReader) UsesIgnoreRevs() bool {
-	return r.ignoreRevsFile != nil
+	return r.ignoreRevsFile != ""
 }
 
 // NextPart returns next part of blame (sequential code lines with the same commit)
@@ -122,36 +123,37 @@ func (r *BlameReader) Close() error {
 	r.bufferedReader = nil
 	_ = r.reader.Close()
 	_ = r.output.Close()
-	if r.ignoreRevsFile != nil {
-		_ = util.Remove(*r.ignoreRevsFile)
+	for _, cleanup := range r.cleanupFuncs {
+		if cleanup != nil {
+			cleanup()
+		}
 	}
 	return err
 }
 
 // CreateBlameReader creates reader for given repository, commit and file
 func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
-	var ignoreRevsFile *string
-	if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
-		ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit)
-	}
-
-	cmd := NewCommandNoGlobals("blame", "--porcelain")
-	if ignoreRevsFile != nil {
-		// Possible improvement: use --ignore-revs-file /dev/stdin on unix
-		// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
-		cmd.AddOptionValues("--ignore-revs-file", *ignoreRevsFile)
-	}
-	cmd.AddDynamicArguments(commit.ID.String()).AddDashesAndList(file)
 	reader, stdout, err := os.Pipe()
 	if err != nil {
-		if ignoreRevsFile != nil {
-			_ = util.Remove(*ignoreRevsFile)
-		}
 		return nil, err
 	}
 
-	done := make(chan error, 1)
+	cmd := NewCommandNoGlobals("blame", "--porcelain")
 
+	var ignoreRevsFileName string
+	var ignoreRevsFileCleanup func() // TODO: maybe it should check the returned err in a defer func to make sure the cleanup could always be executed correctly
+	if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
+		ignoreRevsFileName, ignoreRevsFileCleanup = tryCreateBlameIgnoreRevsFile(commit)
+		if ignoreRevsFileName != "" {
+			// Possible improvement: use --ignore-revs-file /dev/stdin on unix
+			// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
+			cmd.AddOptionValues("--ignore-revs-file", ignoreRevsFileName)
+		}
+	}
+
+	cmd.AddDynamicArguments(commit.ID.String()).AddDashesAndList(file)
+
+	done := make(chan error, 1)
 	go func() {
 		stderr := bytes.Buffer{}
 		// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
@@ -169,40 +171,44 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
 	}()
 
 	bufferedReader := bufio.NewReader(reader)
-
 	return &BlameReader{
 		output:         stdout,
 		reader:         reader,
 		bufferedReader: bufferedReader,
 		done:           done,
-		ignoreRevsFile: ignoreRevsFile,
+		ignoreRevsFile: ignoreRevsFileName,
 		objectFormat:   objectFormat,
+		cleanupFuncs:   []func(){ignoreRevsFileCleanup},
 	}, nil
 }
 
-func tryCreateBlameIgnoreRevsFile(commit *Commit) *string {
+func tryCreateBlameIgnoreRevsFile(commit *Commit) (string, func()) {
 	entry, err := commit.GetTreeEntryByPath(".git-blame-ignore-revs")
 	if err != nil {
-		return nil
+		log.Error("Unable to get .git-blame-ignore-revs file: GetTreeEntryByPath: %v", err)
+		return "", nil
 	}
 
 	r, err := entry.Blob().DataAsync()
 	if err != nil {
-		return nil
+		log.Error("Unable to get .git-blame-ignore-revs file data: DataAsync: %v", err)
+		return "", nil
 	}
 	defer r.Close()
 
-	f, err := os.CreateTemp("", "gitea_git-blame-ignore-revs")
+	f, cleanup, err := setting.AppDataTempDir("git-repo-content").CreateTempFileRandom("git-blame-ignore-revs")
 	if err != nil {
-		return nil
+		log.Error("Unable to get .git-blame-ignore-revs file data: CreateTempFileRandom: %v", err)
+		return "", nil
 	}
-
+	filename := f.Name()
 	_, err = io.Copy(f, r)
 	_ = f.Close()
 	if err != nil {
-		_ = util.Remove(f.Name())
-		return nil
+		cleanup()
+		log.Error("Unable to get .git-blame-ignore-revs file data: Copy: %v", err)
+		return "", nil
 	}
 
-	return util.ToPointer(f.Name())
+	return filename, cleanup
 }
diff --git a/modules/git/blame_sha256_test.go b/modules/git/blame_sha256_test.go
index 99c23429e2..c0a97bed3b 100644
--- a/modules/git/blame_sha256_test.go
+++ b/modules/git/blame_sha256_test.go
@@ -7,10 +7,13 @@ import (
 	"context"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 )
 
 func TestReadingBlameOutputSha256(t *testing.T) {
+	setting.AppDataPath = t.TempDir()
 	ctx, cancel := context.WithCancel(t.Context())
 	defer cancel()
 
diff --git a/modules/git/blame_test.go b/modules/git/blame_test.go
index 36b5fb9349..809d6fbcf7 100644
--- a/modules/git/blame_test.go
+++ b/modules/git/blame_test.go
@@ -7,10 +7,13 @@ import (
 	"context"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 )
 
 func TestReadingBlameOutput(t *testing.T) {
+	setting.AppDataPath = t.TempDir()
 	ctx, cancel := context.WithCancel(t.Context())
 	defer cancel()
 
diff --git a/modules/git/git_test.go b/modules/git/git_test.go
index 5472842b76..58ba01cabc 100644
--- a/modules/git/git_test.go
+++ b/modules/git/git_test.go
@@ -10,18 +10,19 @@ import (
 	"testing"
 
 	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/modules/util"
+	"code.gitea.io/gitea/modules/tempdir"
 
 	"github.com/hashicorp/go-version"
 	"github.com/stretchr/testify/assert"
 )
 
 func testRun(m *testing.M) error {
-	gitHomePath, err := os.MkdirTemp(os.TempDir(), "git-home")
+	gitHomePath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("git-home")
 	if err != nil {
 		return fmt.Errorf("unable to create temp dir: %w", err)
 	}
-	defer util.RemoveAll(gitHomePath)
+	defer cleanup()
+
 	setting.Git.HomePath = gitHomePath
 
 	if err = InitFull(context.Background()); err != nil {
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 6459adf851..45937a8d5f 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -18,6 +18,7 @@ import (
 	"time"
 
 	"code.gitea.io/gitea/modules/proxy"
+	"code.gitea.io/gitea/modules/setting"
 )
 
 // GPGSettings represents the default GPG settings for this repository
@@ -266,11 +267,11 @@ func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch
 
 // CreateBundle create bundle content to the target path
 func (repo *Repository) CreateBundle(ctx context.Context, commit string, out io.Writer) error {
-	tmp, err := os.MkdirTemp(os.TempDir(), "gitea-bundle")
+	tmp, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-bundle")
 	if err != nil {
 		return err
 	}
-	defer os.RemoveAll(tmp)
+	defer cleanup()
 
 	env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repo.Path, "objects"))
 	_, _, err = NewCommand("init", "--bare").RunStdString(ctx, &RunOpts{Dir: tmp, Env: env})
diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go
index 1c7fcc063e..443a3a20d1 100644
--- a/modules/git/repo_index.go
+++ b/modules/git/repo_index.go
@@ -10,8 +10,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/util"
+	"code.gitea.io/gitea/modules/setting"
 )
 
 // ReadTreeToIndex reads a treeish to the index
@@ -59,26 +58,18 @@ func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (tmpIndexFilena
 		}
 	}()
 
-	removeDirFn := func(dir string) func() { // it can't use the return value "tmpDir" directly because it is empty when error occurs
-		return func() {
-			if err := util.RemoveAll(dir); err != nil {
-				log.Error("failed to remove tmp index dir: %v", err)
-			}
-		}
-	}
-
-	tmpDir, err = os.MkdirTemp("", "index")
+	tmpDir, cancel, err = setting.AppDataTempDir("git-repo-content").MkdirTempRandom("index")
 	if err != nil {
 		return "", "", nil, err
 	}
 
 	tmpIndexFilename = filepath.Join(tmpDir, ".tmp-index")
-	cancel = removeDirFn(tmpDir)
+
 	err = repo.ReadTreeToIndex(treeish, tmpIndexFilename)
 	if err != nil {
 		return "", "", cancel, err
 	}
-	return tmpIndexFilename, tmpDir, cancel, err
+	return tmpIndexFilename, tmpDir, cancel, nil
 }
 
 // EmptyIndex empties the index
diff --git a/modules/git/repo_language_stats_test.go b/modules/git/repo_language_stats_test.go
index 81f130bacb..12ce958c6e 100644
--- a/modules/git/repo_language_stats_test.go
+++ b/modules/git/repo_language_stats_test.go
@@ -9,11 +9,14 @@ import (
 	"path/filepath"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestRepository_GetLanguageStats(t *testing.T) {
+	setting.AppDataPath = t.TempDir()
 	repoPath := filepath.Join(testReposDir, "language_stats_repo")
 	gitRepo, err := openRepositoryWithDefaultContext(repoPath)
 	require.NoError(t, err)
diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go
index f708457853..39861ade12 100644
--- a/modules/markup/external/external.go
+++ b/modules/markup/external/external.go
@@ -12,11 +12,9 @@ import (
 	"runtime"
 	"strings"
 
-	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/modules/util"
 )
 
 // RegisterRenderers registers all supported third part renderers according settings
@@ -88,16 +86,11 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
 
 	if p.IsInputFile {
 		// write to temp file
-		f, err := os.CreateTemp("", "gitea_input")
+		f, cleanup, err := setting.AppDataTempDir("git-repo-content").CreateTempFileRandom("gitea_input")
 		if err != nil {
 			return fmt.Errorf("%s create temp file when rendering %s failed: %w", p.Name(), p.Command, err)
 		}
-		tmpPath := f.Name()
-		defer func() {
-			if err := util.Remove(tmpPath); err != nil {
-				log.Warn("Unable to remove temporary file: %s: Error: %v", tmpPath, err)
-			}
-		}()
+		defer cleanup()
 
 		_, err = io.Copy(f, input)
 		if err != nil {
diff --git a/modules/packages/hashed_buffer.go b/modules/packages/hashed_buffer.go
index 4ab45edcec..0cd657cd44 100644
--- a/modules/packages/hashed_buffer.go
+++ b/modules/packages/hashed_buffer.go
@@ -6,6 +6,7 @@ package packages
 import (
 	"io"
 
+	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util/filebuffer"
 )
 
@@ -34,11 +35,11 @@ func NewHashedBuffer() (*HashedBuffer, error) {
 
 // NewHashedBufferWithSize creates a hashed buffer with a specific memory size
 func NewHashedBufferWithSize(maxMemorySize int) (*HashedBuffer, error) {
-	b, err := filebuffer.New(maxMemorySize)
+	tempDir, err := setting.AppDataTempDir("package-hashed-buffer").MkdirAllSub("")
 	if err != nil {
 		return nil, err
 	}
-
+	b := filebuffer.New(maxMemorySize, tempDir)
 	hash := NewMultiHasher()
 
 	combinedWriter := io.MultiWriter(b, hash)
diff --git a/modules/packages/hashed_buffer_test.go b/modules/packages/hashed_buffer_test.go
index 564e782f18..5104c1fb25 100644
--- a/modules/packages/hashed_buffer_test.go
+++ b/modules/packages/hashed_buffer_test.go
@@ -9,10 +9,13 @@ import (
 	"strings"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 )
 
 func TestHashedBuffer(t *testing.T) {
+	setting.AppDataPath = t.TempDir()
 	cases := []struct {
 		MaxMemorySize int
 		Data          string
diff --git a/modules/packages/nuget/symbol_extractor_test.go b/modules/packages/nuget/symbol_extractor_test.go
index fa1b80ee82..711ad6d096 100644
--- a/modules/packages/nuget/symbol_extractor_test.go
+++ b/modules/packages/nuget/symbol_extractor_test.go
@@ -9,6 +9,8 @@ import (
 	"encoding/base64"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 )
 
@@ -17,6 +19,7 @@ fgAA3AEAAAQAAAAjU3RyaW5ncwAAAADgAQAABAAAACNVUwDkAQAAMAAAACNHVUlEAAAAFAIAACgB
 AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`
 
 func TestExtractPortablePdb(t *testing.T) {
+	setting.AppDataPath = t.TempDir()
 	createArchive := func(name string, content []byte) []byte {
 		var buf bytes.Buffer
 		archive := zip.NewWriter(&buf)
diff --git a/modules/repository/commits.go b/modules/repository/commits.go
index 16520fb28a..878fdc1603 100644
--- a/modules/repository/commits.go
+++ b/modules/repository/commits.go
@@ -13,6 +13,7 @@ import (
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/cache"
+	"code.gitea.io/gitea/modules/cachegroup"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
@@ -131,7 +132,7 @@ func (pc *PushCommits) ToAPIPayloadCommits(ctx context.Context, repo *repo_model
 func (pc *PushCommits) AvatarLink(ctx context.Context, email string) string {
 	size := avatars.DefaultAvatarPixelSize * setting.Avatar.RenderedSizeFactor
 
-	v, _ := cache.GetWithContextCache(ctx, "push_commits", email, func() (string, error) {
+	v, _ := cache.GetWithContextCache(ctx, cachegroup.EmailAvatarLink, email, func(ctx context.Context, email string) (string, error) {
 		u, err := user_model.GetUserByEmail(ctx, email)
 		if err != nil {
 			if !user_model.IsErrUserNotExist(err) {
diff --git a/modules/repository/init.go b/modules/repository/init.go
index ace21254ba..e6331966ba 100644
--- a/modules/repository/init.go
+++ b/modules/repository/init.go
@@ -11,11 +11,7 @@ import (
 	"strings"
 
 	issues_model "code.gitea.io/gitea/models/issues"
-	repo_model "code.gitea.io/gitea/models/repo"
-	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/label"
-	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/options"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
@@ -121,29 +117,6 @@ func LoadRepoConfig() error {
 	return nil
 }
 
-func CheckInitRepository(ctx context.Context, repo *repo_model.Repository) (err error) {
-	// Somehow the directory could exist.
-	isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
-	if err != nil {
-		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
-		return err
-	}
-	if isExist {
-		return repo_model.ErrRepoFilesAlreadyExist{
-			Uname: repo.OwnerName,
-			Name:  repo.Name,
-		}
-	}
-
-	// Init git bare new repository.
-	if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil {
-		return fmt.Errorf("git.InitRepository: %w", err)
-	} else if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil {
-		return fmt.Errorf("createDelegateHooks: %w", err)
-	}
-	return nil
-}
-
 // InitializeLabels adds a label set to a repository using a template
 func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg bool) error {
 	list, err := LoadTemplateLabelsByDisplayName(labelTemplate)
diff --git a/modules/repository/temp.go b/modules/repository/temp.go
index 76b9bda4ad..d7253d9e02 100644
--- a/modules/repository/temp.go
+++ b/modules/repository/temp.go
@@ -4,41 +4,19 @@
 package repository
 
 import (
+	"context"
 	"fmt"
-	"os"
-	"path/filepath"
 
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/modules/util"
 )
 
-// LocalCopyPath returns the local repository temporary copy path.
-func LocalCopyPath() string {
-	if filepath.IsAbs(setting.Repository.Local.LocalCopyPath) {
-		return setting.Repository.Local.LocalCopyPath
-	}
-	return filepath.Join(setting.AppDataPath, setting.Repository.Local.LocalCopyPath)
-}
-
 // CreateTemporaryPath creates a temporary path
-func CreateTemporaryPath(prefix string) (string, error) {
-	if err := os.MkdirAll(LocalCopyPath(), os.ModePerm); err != nil {
-		log.Error("Unable to create localcopypath directory: %s (%v)", LocalCopyPath(), err)
-		return "", fmt.Errorf("Failed to create localcopypath directory %s: %w", LocalCopyPath(), err)
-	}
-	basePath, err := os.MkdirTemp(LocalCopyPath(), prefix+".git")
+func CreateTemporaryPath(prefix string) (string, context.CancelFunc, error) {
+	basePath, cleanup, err := setting.AppDataTempDir("local-repo").MkdirTempRandom(prefix + ".git")
 	if err != nil {
 		log.Error("Unable to create temporary directory: %s-*.git (%v)", prefix, err)
-		return "", fmt.Errorf("Failed to create dir %s-*.git: %w", prefix, err)
+		return "", nil, fmt.Errorf("failed to create dir %s-*.git: %w", prefix, err)
 	}
-	return basePath, nil
-}
-
-// RemoveTemporaryPath removes the temporary path
-func RemoveTemporaryPath(basePath string) error {
-	if _, err := os.Stat(basePath); !os.IsNotExist(err) {
-		return util.RemoveAll(basePath)
-	}
-	return nil
+	return basePath, cleanup, nil
 }
diff --git a/modules/setting/markup.go b/modules/setting/markup.go
index 3bd368f831..365af05fcf 100644
--- a/modules/setting/markup.go
+++ b/modules/setting/markup.go
@@ -127,7 +127,7 @@ func loadMarkupFrom(rootCfg ConfigProvider) {
 		}
 	}
 
-	MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(5000)
+	MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(50000)
 	ExternalMarkupRenderers = make([]*MarkupRenderer, 0, 10)
 	ExternalSanitizerRules = make([]MarkupSanitizerRule, 0, 10)
 
diff --git a/modules/setting/packages.go b/modules/setting/packages.go
index 3f618cfd64..845f6d4e12 100644
--- a/modules/setting/packages.go
+++ b/modules/setting/packages.go
@@ -6,8 +6,6 @@ package setting
 import (
 	"fmt"
 	"math"
-	"os"
-	"path/filepath"
 
 	"github.com/dustin/go-humanize"
 )
@@ -67,14 +65,10 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
 		return err
 	}
 
-	Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload"))
-	if !filepath.IsAbs(Packages.ChunkedUploadPath) {
-		Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))
-	}
-
 	if HasInstallLock(rootCfg) {
-		if err := os.MkdirAll(Packages.ChunkedUploadPath, os.ModePerm); err != nil {
-			return fmt.Errorf("unable to create chunked upload directory: %s (%v)", Packages.ChunkedUploadPath, err)
+		Packages.ChunkedUploadPath, err = AppDataTempDir("package-upload").MkdirAllSub("")
+		if err != nil {
+			return fmt.Errorf("unable to create chunked upload directory: %w", err)
 		}
 	}
 
diff --git a/modules/setting/path.go b/modules/setting/path.go
index 0fdc305aa1..f51457a620 100644
--- a/modules/setting/path.go
+++ b/modules/setting/path.go
@@ -11,6 +11,7 @@ import (
 	"strings"
 
 	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/tempdir"
 )
 
 var (
@@ -196,3 +197,18 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
 	CustomPath = tmpCustomPath.Value
 	CustomConf = tmpCustomConf.Value
 }
+
+// AppDataTempDir returns a managed temporary directory for the application data.
+// Using empty sub will get the managed base temp directory, and it's safe to delete it.
+// Gitea only creates subdirectories under it, but not the APP_TEMP_PATH directory itself.
+// * When APP_TEMP_PATH="/tmp": the managed temp directory is "/tmp/gitea-tmp"
+// * When APP_TEMP_PATH is not set: the managed temp directory is "/{APP_DATA_PATH}/tmp"
+func AppDataTempDir(sub string) *tempdir.TempDir {
+	if appTempPathInternal != "" {
+		return tempdir.New(appTempPathInternal, "gitea-tmp/"+sub)
+	}
+	if AppDataPath == "" {
+		panic("setting.AppDataPath is not set")
+	}
+	return tempdir.New(AppDataPath, "tmp/"+sub)
+}
diff --git a/modules/setting/repository.go b/modules/setting/repository.go
index 43bfb3256d..f99c854e4f 100644
--- a/modules/setting/repository.go
+++ b/modules/setting/repository.go
@@ -62,17 +62,11 @@ var (
 		// Repository upload settings
 		Upload struct {
 			Enabled      bool
-			TempPath     string
 			AllowedTypes string
 			FileMaxSize  int64
 			MaxFiles     int
 		} `ini:"-"`
 
-		// Repository local settings
-		Local struct {
-			LocalCopyPath string
-		} `ini:"-"`
-
 		// Pull request settings
 		PullRequest struct {
 			WorkInProgressPrefixes                   []string
@@ -181,25 +175,16 @@ var (
 		// Repository upload settings
 		Upload: struct {
 			Enabled      bool
-			TempPath     string
 			AllowedTypes string
 			FileMaxSize  int64
 			MaxFiles     int
 		}{
 			Enabled:      true,
-			TempPath:     "data/tmp/uploads",
 			AllowedTypes: "",
 			FileMaxSize:  50,
 			MaxFiles:     5,
 		},
 
-		// Repository local settings
-		Local: struct {
-			LocalCopyPath string
-		}{
-			LocalCopyPath: "tmp/local-repo",
-		},
-
 		// Pull request settings
 		PullRequest: struct {
 			WorkInProgressPrefixes                   []string
@@ -308,8 +293,6 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
 		log.Fatal("Failed to map Repository.Editor settings: %v", err)
 	} else if err = rootCfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
 		log.Fatal("Failed to map Repository.Upload settings: %v", err)
-	} else if err = rootCfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
-		log.Fatal("Failed to map Repository.Local settings: %v", err)
 	} else if err = rootCfg.Section("repository.pull-request").MapTo(&Repository.PullRequest); err != nil {
 		log.Fatal("Failed to map Repository.PullRequest settings: %v", err)
 	}
@@ -361,10 +344,6 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
 		}
 	}
 
-	if !filepath.IsAbs(Repository.Upload.TempPath) {
-		Repository.Upload.TempPath = filepath.Join(AppWorkPath, Repository.Upload.TempPath)
-	}
-
 	if err := loadRepoArchiveFrom(rootCfg); err != nil {
 		log.Fatal("loadRepoArchiveFrom: %v", err)
 	}
diff --git a/modules/setting/server.go b/modules/setting/server.go
index e15b790906..ca635c8abe 100644
--- a/modules/setting/server.go
+++ b/modules/setting/server.go
@@ -7,6 +7,7 @@ import (
 	"encoding/base64"
 	"net"
 	"net/url"
+	"os"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -59,6 +60,8 @@ var (
 	// AssetVersion holds a opaque value that is used for cache-busting assets
 	AssetVersion string
 
+	appTempPathInternal string // the temporary path for the app, it is only an internal variable, do not use it, always use AppDataTempDir
+
 	Protocol                   Scheme
 	UseProxyProtocol           bool // `ini:"USE_PROXY_PROTOCOL"`
 	ProxyProtocolTLSBridging   bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"`
@@ -330,6 +333,19 @@ func loadServerFrom(rootCfg ConfigProvider) {
 	if !filepath.IsAbs(AppDataPath) {
 		AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath))
 	}
+	if IsInTesting && HasInstallLock(rootCfg) {
+		// FIXME: in testing, the "app data" directory is not correctly initialized before loading settings
+		if _, err := os.Stat(AppDataPath); err != nil {
+			_ = os.MkdirAll(AppDataPath, os.ModePerm)
+		}
+	}
+
+	appTempPathInternal = sec.Key("APP_TEMP_PATH").String()
+	if appTempPathInternal != "" {
+		if _, err := os.Stat(appTempPathInternal); err != nil {
+			log.Fatal("APP_TEMP_PATH %q is not accessible: %v", appTempPathInternal, err)
+		}
+	}
 
 	EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
 	EnablePprof = sec.Key("ENABLE_PPROF").MustBool(false)
diff --git a/modules/setting/ssh.go b/modules/setting/ssh.go
index 46eb49bfd4..da8cdf58d2 100644
--- a/modules/setting/ssh.go
+++ b/modules/setting/ssh.go
@@ -4,7 +4,6 @@
 package setting
 
 import (
-	"os"
 	"path/filepath"
 	"strings"
 	"text/template"
@@ -31,8 +30,6 @@ var SSH = struct {
 	ServerKeyExchanges                    []string           `ini:"SSH_SERVER_KEY_EXCHANGES"`
 	ServerMACs                            []string           `ini:"SSH_SERVER_MACS"`
 	ServerHostKeys                        []string           `ini:"SSH_SERVER_HOST_KEYS"`
-	KeyTestPath                           string             `ini:"SSH_KEY_TEST_PATH"`
-	KeygenPath                            string             `ini:"SSH_KEYGEN_PATH"`
 	AuthorizedKeysBackup                  bool               `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
 	AuthorizedPrincipalsBackup            bool               `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
 	AuthorizedKeysCommandTemplate         string             `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
@@ -57,7 +54,6 @@ var SSH = struct {
 	ServerCiphers:                 []string{"chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"},
 	ServerKeyExchanges:            []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},
 	ServerMACs:                    []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1"},
-	KeygenPath:                    "",
 	MinimumKeySizeCheck:           true,
 	MinimumKeySizes:               map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 3071},
 	ServerHostKeys:                []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
@@ -123,7 +119,6 @@ func loadSSHFrom(rootCfg ConfigProvider) {
 	if len(serverMACs) > 0 {
 		SSH.ServerMACs = serverMACs
 	}
-	SSH.KeyTestPath = os.TempDir()
 	if err = sec.MapTo(&SSH); err != nil {
 		log.Fatal("Failed to map SSH settings: %v", err)
 	}
@@ -133,7 +128,6 @@ func loadSSHFrom(rootCfg ConfigProvider) {
 		}
 	}
 
-	SSH.KeygenPath = sec.Key("SSH_KEYGEN_PATH").String()
 	SSH.Port = sec.Key("SSH_PORT").MustInt(22)
 	SSH.ListenPort = sec.Key("SSH_LISTEN_PORT").MustInt(SSH.Port)
 	SSH.UseProxyProtocol = sec.Key("SSH_SERVER_USE_PROXY_PROTOCOL").MustBool(false)
diff --git a/modules/ssh/init.go b/modules/ssh/init.go
index 21d4f89936..fdc11632e2 100644
--- a/modules/ssh/init.go
+++ b/modules/ssh/init.go
@@ -32,11 +32,6 @@ func Init() error {
 
 	builtinUnused()
 
-	// FIXME: why 0o644 for a directory .....
-	if err := os.MkdirAll(setting.SSH.KeyTestPath, 0o644); err != nil {
-		return fmt.Errorf("failed to create directory %q for ssh key test: %w", setting.SSH.KeyTestPath, err)
-	}
-
 	if len(setting.SSH.TrustedUserCAKeys) > 0 && setting.SSH.AuthorizedPrincipalsEnabled {
 		caKeysFileName := setting.SSH.TrustedUserCAKeysFile
 		caKeysFileDir := filepath.Dir(caKeysFileName)
diff --git a/modules/tempdir/tempdir.go b/modules/tempdir/tempdir.go
new file mode 100644
index 0000000000..22c2e4ea16
--- /dev/null
+++ b/modules/tempdir/tempdir.go
@@ -0,0 +1,112 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package tempdir
+
+import (
+	"os"
+	"path/filepath"
+	"time"
+
+	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/util"
+)
+
+type TempDir struct {
+	// base is the base directory for temporary files, it must exist before accessing and won't be created automatically.
+	// for example: base="/system-tmpdir", sub="gitea-tmp"
+	base, sub string
+}
+
+func (td *TempDir) JoinPath(elems ...string) string {
+	return filepath.Join(append([]string{td.base, td.sub}, elems...)...)
+}
+
+// MkdirAllSub works like os.MkdirAll, but the base directory must exist
+func (td *TempDir) MkdirAllSub(dir string) (string, error) {
+	if _, err := os.Stat(td.base); err != nil {
+		return "", err
+	}
+	full := filepath.Join(td.base, td.sub, dir)
+	if err := os.MkdirAll(full, os.ModePerm); err != nil {
+		return "", err
+	}
+	return full, nil
+}
+
+func (td *TempDir) prepareDirWithPattern(elems ...string) (dir, pattern string, err error) {
+	if _, err = os.Stat(td.base); err != nil {
+		return "", "", err
+	}
+	dir, pattern = filepath.Split(filepath.Join(append([]string{td.base, td.sub}, elems...)...))
+	if err = os.MkdirAll(dir, os.ModePerm); err != nil {
+		return "", "", err
+	}
+	return dir, pattern, nil
+}
+
+// MkdirTempRandom works like os.MkdirTemp, the last path field is the "pattern"
+func (td *TempDir) MkdirTempRandom(elems ...string) (string, func(), error) {
+	dir, pattern, err := td.prepareDirWithPattern(elems...)
+	if err != nil {
+		return "", nil, err
+	}
+	dir, err = os.MkdirTemp(dir, pattern)
+	if err != nil {
+		return "", nil, err
+	}
+	return dir, func() {
+		if err := util.RemoveAll(dir); err != nil {
+			log.Error("Failed to remove temp directory %s: %v", dir, err)
+		}
+	}, nil
+}
+
+// CreateTempFileRandom works like os.CreateTemp, the last path field is the "pattern"
+func (td *TempDir) CreateTempFileRandom(elems ...string) (*os.File, func(), error) {
+	dir, pattern, err := td.prepareDirWithPattern(elems...)
+	if err != nil {
+		return nil, nil, err
+	}
+	f, err := os.CreateTemp(dir, pattern)
+	if err != nil {
+		return nil, nil, err
+	}
+	filename := f.Name()
+	return f, func() {
+		_ = f.Close()
+		if err := util.Remove(filename); err != nil {
+			log.Error("Unable to remove temporary file: %s: Error: %v", filename, err)
+		}
+	}, err
+}
+
+func (td *TempDir) RemoveOutdated(d time.Duration) {
+	var remove func(path string)
+	remove = func(path string) {
+		entries, _ := os.ReadDir(path)
+		for _, entry := range entries {
+			full := filepath.Join(path, entry.Name())
+			if entry.IsDir() {
+				remove(full)
+				_ = os.Remove(full)
+				continue
+			}
+			info, err := entry.Info()
+			if err == nil && time.Since(info.ModTime()) > d {
+				_ = os.Remove(full)
+			}
+		}
+	}
+	remove(td.JoinPath(""))
+}
+
+// New create a new TempDir instance, "base" must be an existing directory,
+// "sub" could be a multi-level directory and will be created if not exist
+func New(base, sub string) *TempDir {
+	return &TempDir{base: base, sub: sub}
+}
+
+func OsTempDir(sub string) *TempDir {
+	return New(os.TempDir(), sub)
+}
diff --git a/modules/tempdir/tempdir_test.go b/modules/tempdir/tempdir_test.go
new file mode 100644
index 0000000000..d6afcb7bed
--- /dev/null
+++ b/modules/tempdir/tempdir_test.go
@@ -0,0 +1,75 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package tempdir
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestTempDir(t *testing.T) {
+	base := t.TempDir()
+
+	t.Run("Create", func(t *testing.T) {
+		td := New(base, "sub1/sub2") // make sure the sub dir supports "/" in the path
+		assert.Equal(t, filepath.Join(base, "sub1", "sub2"), td.JoinPath())
+		assert.Equal(t, filepath.Join(base, "sub1", "sub2/test"), td.JoinPath("test"))
+
+		t.Run("MkdirTempRandom", func(t *testing.T) {
+			s, cleanup, err := td.MkdirTempRandom("foo")
+			assert.NoError(t, err)
+			assert.True(t, strings.HasPrefix(s, filepath.Join(base, "sub1/sub2", "foo")))
+
+			_, err = os.Stat(s)
+			assert.NoError(t, err)
+			cleanup()
+			_, err = os.Stat(s)
+			assert.ErrorIs(t, err, os.ErrNotExist)
+		})
+
+		t.Run("CreateTempFileRandom", func(t *testing.T) {
+			f, cleanup, err := td.CreateTempFileRandom("foo", "bar")
+			filename := f.Name()
+			assert.NoError(t, err)
+			assert.True(t, strings.HasPrefix(filename, filepath.Join(base, "sub1/sub2", "foo", "bar")))
+			_, err = os.Stat(filename)
+			assert.NoError(t, err)
+			cleanup()
+			_, err = os.Stat(filename)
+			assert.ErrorIs(t, err, os.ErrNotExist)
+		})
+
+		t.Run("RemoveOutDated", func(t *testing.T) {
+			fa1, _, err := td.CreateTempFileRandom("dir-a", "f1")
+			assert.NoError(t, err)
+			fa2, _, err := td.CreateTempFileRandom("dir-a", "f2")
+			assert.NoError(t, err)
+			_ = os.Chtimes(fa2.Name(), time.Now().Add(-time.Hour), time.Now().Add(-time.Hour))
+			fb1, _, err := td.CreateTempFileRandom("dir-b", "f1")
+			assert.NoError(t, err)
+			_ = os.Chtimes(fb1.Name(), time.Now().Add(-time.Hour), time.Now().Add(-time.Hour))
+			_, _, _ = fa1.Close(), fa2.Close(), fb1.Close()
+
+			td.RemoveOutdated(time.Minute)
+
+			_, err = os.Stat(fa1.Name())
+			assert.NoError(t, err)
+			_, err = os.Stat(fa2.Name())
+			assert.ErrorIs(t, err, os.ErrNotExist)
+			_, err = os.Stat(fb1.Name())
+			assert.ErrorIs(t, err, os.ErrNotExist)
+		})
+	})
+
+	t.Run("BaseNotExist", func(t *testing.T) {
+		td := New(filepath.Join(base, "not-exist"), "sub")
+		_, _, err := td.MkdirTempRandom("foo")
+		assert.ErrorIs(t, err, os.ErrNotExist)
+	})
+}
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index 26cd1eb348..460b9dc190 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -56,7 +56,7 @@ var testMetas = map[string]string{
 }
 
 func TestMain(m *testing.M) {
-	unittest.InitSettings()
+	unittest.InitSettingsForTesting()
 	if err := git.InitSimple(context.Background()); err != nil {
 		log.Fatal("git init failed, err: %v", err)
 	}
diff --git a/modules/util/filebuffer/file_backed_buffer.go b/modules/util/filebuffer/file_backed_buffer.go
index 739543e297..0731ba30c8 100644
--- a/modules/util/filebuffer/file_backed_buffer.go
+++ b/modules/util/filebuffer/file_backed_buffer.go
@@ -7,16 +7,10 @@ import (
 	"bytes"
 	"errors"
 	"io"
-	"math"
 	"os"
 )
 
-var (
-	// ErrInvalidMemorySize occurs if the memory size is not in a valid range
-	ErrInvalidMemorySize = errors.New("Memory size must be greater 0 and lower math.MaxInt32")
-	// ErrWriteAfterRead occurs if Write is called after a read operation
-	ErrWriteAfterRead = errors.New("Write is unsupported after a read operation")
-)
+var ErrWriteAfterRead = errors.New("write is unsupported after a read operation") // occurs if Write is called after a read operation
 
 type readAtSeeker interface {
 	io.ReadSeeker
@@ -30,34 +24,17 @@ type FileBackedBuffer struct {
 	maxMemorySize int64
 	size          int64
 	buffer        bytes.Buffer
+	tempDir       string
 	file          *os.File
 	reader        readAtSeeker
 }
 
 // New creates a file backed buffer with a specific maximum memory size
-func New(maxMemorySize int) (*FileBackedBuffer, error) {
-	if maxMemorySize < 0 || maxMemorySize > math.MaxInt32 {
-		return nil, ErrInvalidMemorySize
-	}
-
+func New(maxMemorySize int, tempDir string) *FileBackedBuffer {
 	return &FileBackedBuffer{
 		maxMemorySize: int64(maxMemorySize),
-	}, nil
-}
-
-// CreateFromReader creates a file backed buffer and copies the provided reader data into it.
-func CreateFromReader(r io.Reader, maxMemorySize int) (*FileBackedBuffer, error) {
-	b, err := New(maxMemorySize)
-	if err != nil {
-		return nil, err
+		tempDir:       tempDir,
 	}
-
-	_, err = io.Copy(b, r)
-	if err != nil {
-		return nil, err
-	}
-
-	return b, nil
 }
 
 // Write implements io.Writer
@@ -73,7 +50,7 @@ func (b *FileBackedBuffer) Write(p []byte) (int, error) {
 		n, err = b.file.Write(p)
 	} else {
 		if b.size+int64(len(p)) > b.maxMemorySize {
-			b.file, err = os.CreateTemp("", "gitea-buffer-")
+			b.file, err = os.CreateTemp(b.tempDir, "gitea-buffer-")
 			if err != nil {
 				return 0, err
 			}
@@ -148,7 +125,7 @@ func (b *FileBackedBuffer) Seek(offset int64, whence int) (int64, error) {
 func (b *FileBackedBuffer) Close() error {
 	if b.file != nil {
 		err := b.file.Close()
-		os.Remove(b.file.Name())
+		_ = os.Remove(b.file.Name())
 		b.file = nil
 		return err
 	}
diff --git a/modules/util/filebuffer/file_backed_buffer_test.go b/modules/util/filebuffer/file_backed_buffer_test.go
index 16d5a1965f..3f13c6ac7b 100644
--- a/modules/util/filebuffer/file_backed_buffer_test.go
+++ b/modules/util/filebuffer/file_backed_buffer_test.go
@@ -21,7 +21,8 @@ func TestFileBackedBuffer(t *testing.T) {
 	}
 
 	for _, c := range cases {
-		buf, err := CreateFromReader(strings.NewReader(c.Data), c.MaxMemorySize)
+		buf := New(c.MaxMemorySize, t.TempDir())
+		_, err := io.Copy(buf, strings.NewReader(c.Data))
 		assert.NoError(t, err)
 
 		assert.EqualValues(t, len(c.Data), buf.Size())
diff --git a/options/fileicon/material-icon-rules.json b/options/fileicon/material-icon-rules.json
index fd058c82dc..d097399252 100644
--- a/options/fileicon/material-icon-rules.json
+++ b/options/fileicon/material-icon-rules.json
@@ -1112,6 +1112,18 @@
     ".routers": "folder-routes",
     "_routers": "folder-routes",
     "__routers__": "folder-routes",
+    "navigation": "folder-routes",
+    ".navigation": "folder-routes",
+    "_navigation": "folder-routes",
+    "__navigation__": "folder-routes",
+    "navigations": "folder-routes",
+    ".navigations": "folder-routes",
+    "_navigations": "folder-routes",
+    "__navigations__": "folder-routes",
+    "routing": "folder-routes",
+    ".routing": "folder-routes",
+    "_routing": "folder-routes",
+    "__routing__": "folder-routes",
     "ci": "folder-ci",
     ".ci": "folder-ci",
     "_ci": "folder-ci",
@@ -2092,6 +2104,34 @@
     ".DS_Store": "folder-macos",
     "_DS_Store": "folder-macos",
     "__DS_Store__": "folder-macos",
+    "iPhone": "folder-macos",
+    ".iPhone": "folder-macos",
+    "_iPhone": "folder-macos",
+    "__iPhone__": "folder-macos",
+    "iPad": "folder-macos",
+    ".iPad": "folder-macos",
+    "_iPad": "folder-macos",
+    "__iPad__": "folder-macos",
+    "iPod": "folder-macos",
+    ".iPod": "folder-macos",
+    "_iPod": "folder-macos",
+    "__iPod__": "folder-macos",
+    "macbook": "folder-macos",
+    ".macbook": "folder-macos",
+    "_macbook": "folder-macos",
+    "__macbook__": "folder-macos",
+    "macbook-air": "folder-macos",
+    ".macbook-air": "folder-macos",
+    "_macbook-air": "folder-macos",
+    "__macbook-air__": "folder-macos",
+    "macosx": "folder-macos",
+    ".macosx": "folder-macos",
+    "_macosx": "folder-macos",
+    "__macosx__": "folder-macos",
+    "apple": "folder-macos",
+    ".apple": "folder-macos",
+    "_apple": "folder-macos",
+    "__apple__": "folder-macos",
     "error": "folder-error",
     ".error": "folder-error",
     "_error": "folder-error",
@@ -2428,6 +2468,34 @@
     ".firebase": "folder-firebase",
     "_firebase": "folder-firebase",
     "__firebase__": "folder-firebase",
+    "firestore": "folder-firestore",
+    ".firestore": "folder-firestore",
+    "_firestore": "folder-firestore",
+    "__firestore__": "folder-firestore",
+    "cloud-firestore": "folder-firestore",
+    ".cloud-firestore": "folder-firestore",
+    "_cloud-firestore": "folder-firestore",
+    "__cloud-firestore__": "folder-firestore",
+    "firebase-firestore": "folder-firestore",
+    ".firebase-firestore": "folder-firestore",
+    "_firebase-firestore": "folder-firestore",
+    "__firebase-firestore__": "folder-firestore",
+    "cloud-functions": "folder-cloud-functions",
+    ".cloud-functions": "folder-cloud-functions",
+    "_cloud-functions": "folder-cloud-functions",
+    "__cloud-functions__": "folder-cloud-functions",
+    "cloudfunctions": "folder-cloud-functions",
+    ".cloudfunctions": "folder-cloud-functions",
+    "_cloudfunctions": "folder-cloud-functions",
+    "__cloudfunctions__": "folder-cloud-functions",
+    "firebase-cloud-functions": "folder-cloud-functions",
+    ".firebase-cloud-functions": "folder-cloud-functions",
+    "_firebase-cloud-functions": "folder-cloud-functions",
+    "__firebase-cloud-functions__": "folder-cloud-functions",
+    "firebase-cloudfunctions": "folder-cloud-functions",
+    ".firebase-cloudfunctions": "folder-cloud-functions",
+    "_firebase-cloudfunctions": "folder-cloud-functions",
+    "__firebase-cloudfunctions__": "folder-cloud-functions",
     "svelte": "folder-svelte",
     ".svelte": "folder-svelte",
     "_svelte": "folder-svelte",
@@ -2975,6 +3043,14 @@
     ".zeabur": "folder-zeabur",
     "_zeabur": "folder-zeabur",
     "__zeabur__": "folder-zeabur",
+    "kusto": "folder-kusto",
+    ".kusto": "folder-kusto",
+    "_kusto": "folder-kusto",
+    "__kusto__": "folder-kusto",
+    "kql": "folder-kusto",
+    ".kql": "folder-kusto",
+    "_kql": "folder-kusto",
+    "__kql__": "folder-kusto",
     "meta-inf": "folder-config",
     ".meta-inf": "folder-config",
     "_meta-inf": "folder-config",
@@ -2990,7 +3066,19 @@
     "ds_store": "folder-macos",
     ".ds_store": "folder-macos",
     "_ds_store": "folder-macos",
-    "__ds_store__": "folder-macos"
+    "__ds_store__": "folder-macos",
+    "iphone": "folder-macos",
+    ".iphone": "folder-macos",
+    "_iphone": "folder-macos",
+    "__iphone__": "folder-macos",
+    "ipad": "folder-macos",
+    ".ipad": "folder-macos",
+    "_ipad": "folder-macos",
+    "__ipad__": "folder-macos",
+    "ipod": "folder-macos",
+    ".ipod": "folder-macos",
+    "_ipod": "folder-macos",
+    "__ipod__": "folder-macos"
   },
   "folderNamesExpanded": {
     "rust": "folder-rust-open",
@@ -4105,6 +4193,18 @@
     ".routers": "folder-routes-open",
     "_routers": "folder-routes-open",
     "__routers__": "folder-routes-open",
+    "navigation": "folder-routes-open",
+    ".navigation": "folder-routes-open",
+    "_navigation": "folder-routes-open",
+    "__navigation__": "folder-routes-open",
+    "navigations": "folder-routes-open",
+    ".navigations": "folder-routes-open",
+    "_navigations": "folder-routes-open",
+    "__navigations__": "folder-routes-open",
+    "routing": "folder-routes-open",
+    ".routing": "folder-routes-open",
+    "_routing": "folder-routes-open",
+    "__routing__": "folder-routes-open",
     "ci": "folder-ci-open",
     ".ci": "folder-ci-open",
     "_ci": "folder-ci-open",
@@ -5085,6 +5185,34 @@
     ".DS_Store": "folder-macos-open",
     "_DS_Store": "folder-macos-open",
     "__DS_Store__": "folder-macos-open",
+    "iPhone": "folder-macos-open",
+    ".iPhone": "folder-macos-open",
+    "_iPhone": "folder-macos-open",
+    "__iPhone__": "folder-macos-open",
+    "iPad": "folder-macos-open",
+    ".iPad": "folder-macos-open",
+    "_iPad": "folder-macos-open",
+    "__iPad__": "folder-macos-open",
+    "iPod": "folder-macos-open",
+    ".iPod": "folder-macos-open",
+    "_iPod": "folder-macos-open",
+    "__iPod__": "folder-macos-open",
+    "macbook": "folder-macos-open",
+    ".macbook": "folder-macos-open",
+    "_macbook": "folder-macos-open",
+    "__macbook__": "folder-macos-open",
+    "macbook-air": "folder-macos-open",
+    ".macbook-air": "folder-macos-open",
+    "_macbook-air": "folder-macos-open",
+    "__macbook-air__": "folder-macos-open",
+    "macosx": "folder-macos-open",
+    ".macosx": "folder-macos-open",
+    "_macosx": "folder-macos-open",
+    "__macosx__": "folder-macos-open",
+    "apple": "folder-macos-open",
+    ".apple": "folder-macos-open",
+    "_apple": "folder-macos-open",
+    "__apple__": "folder-macos-open",
     "error": "folder-error-open",
     ".error": "folder-error-open",
     "_error": "folder-error-open",
@@ -5421,6 +5549,34 @@
     ".firebase": "folder-firebase-open",
     "_firebase": "folder-firebase-open",
     "__firebase__": "folder-firebase-open",
+    "firestore": "folder-firestore-open",
+    ".firestore": "folder-firestore-open",
+    "_firestore": "folder-firestore-open",
+    "__firestore__": "folder-firestore-open",
+    "cloud-firestore": "folder-firestore-open",
+    ".cloud-firestore": "folder-firestore-open",
+    "_cloud-firestore": "folder-firestore-open",
+    "__cloud-firestore__": "folder-firestore-open",
+    "firebase-firestore": "folder-firestore-open",
+    ".firebase-firestore": "folder-firestore-open",
+    "_firebase-firestore": "folder-firestore-open",
+    "__firebase-firestore__": "folder-firestore-open",
+    "cloud-functions": "folder-cloud-functions-open",
+    ".cloud-functions": "folder-cloud-functions-open",
+    "_cloud-functions": "folder-cloud-functions-open",
+    "__cloud-functions__": "folder-cloud-functions-open",
+    "cloudfunctions": "folder-cloud-functions-open",
+    ".cloudfunctions": "folder-cloud-functions-open",
+    "_cloudfunctions": "folder-cloud-functions-open",
+    "__cloudfunctions__": "folder-cloud-functions-open",
+    "firebase-cloud-functions": "folder-cloud-functions-open",
+    ".firebase-cloud-functions": "folder-cloud-functions-open",
+    "_firebase-cloud-functions": "folder-cloud-functions-open",
+    "__firebase-cloud-functions__": "folder-cloud-functions-open",
+    "firebase-cloudfunctions": "folder-cloud-functions-open",
+    ".firebase-cloudfunctions": "folder-cloud-functions-open",
+    "_firebase-cloudfunctions": "folder-cloud-functions-open",
+    "__firebase-cloudfunctions__": "folder-cloud-functions-open",
     "svelte": "folder-svelte-open",
     ".svelte": "folder-svelte-open",
     "_svelte": "folder-svelte-open",
@@ -5967,7 +6123,15 @@
     "zeabur": "folder-zeabur-open",
     ".zeabur": "folder-zeabur-open",
     "_zeabur": "folder-zeabur-open",
-    "__zeabur__": "folder-zeabur-open"
+    "__zeabur__": "folder-zeabur-open",
+    "kusto": "folder-kusto-open",
+    ".kusto": "folder-kusto-open",
+    "_kusto": "folder-kusto-open",
+    "__kusto__": "folder-kusto-open",
+    "kql": "folder-kusto-open",
+    ".kql": "folder-kusto-open",
+    "_kql": "folder-kusto-open",
+    "__kql__": "folder-kusto-open"
   },
   "rootFolderNames": {},
   "rootFolderNamesExpanded": {},
@@ -6032,8 +6196,6 @@
     "ico": "image",
     "tif": "image",
     "tiff": "image",
-    "psd": "image",
-    "psb": "image",
     "ami": "image",
     "apx": "image",
     "avif": "image",
@@ -6128,6 +6290,10 @@
     "routing.tsx": "routing",
     "routing.js": "routing",
     "routing.jsx": "routing",
+    "route.ts": "routing",
+    "route.tsx": "routing",
+    "route.js": "routing",
+    "route.jsx": "routing",
     "routes.ts": "routing",
     "routes.tsx": "routing",
     "routes.js": "routing",
@@ -6288,6 +6454,7 @@
     "py": "python",
     "pyc": "python-misc",
     "whl": "python-misc",
+    "egg": "python-misc",
     "url": "url",
     "sh": "console",
     "ksh": "console",
@@ -6780,6 +6947,11 @@
     "gltf": "3d",
     "glb": "3d",
     "svg": "svg",
+    "ai": "adobe-illustrator",
+    "ait": "adobe-illustrator",
+    "psd": "adobe-photoshop",
+    "psb": "adobe-photoshop",
+    "psdt": "adobe-photoshop",
     "svelte": "svelte",
     "svelte.js": "svelte_js",
     "svelte.ts": "svelte_ts",
@@ -7031,6 +7203,7 @@
     "dfxp": "subtitles",
     "vtt": "subtitles",
     "sub": "subtitles",
+    "ass": "subtitles",
     "beancount": "beancount",
     "bean": "beancount",
     "epub": "epub",
@@ -7272,6 +7445,10 @@
     "router.jsx": "routing",
     "router.ts": "routing",
     "router.tsx": "routing",
+    "route.js": "routing",
+    "route.jsx": "routing",
+    "route.ts": "routing",
+    "route.tsx": "routing",
     "routes.js": "routing",
     "routes.jsx": "routing",
     "routes.ts": "routing",
@@ -7310,6 +7487,11 @@
     ".pylintrc": "python-misc",
     "pyproject.toml": "python-misc",
     "py.typed": "python-misc",
+    ".coveragerc": "python-misc",
+    ".coverage": "python-misc",
+    ".scrapy": "python-misc",
+    "celerybeat-schedule": "python-misc",
+    "celerybeat.pid": "python-misc",
     "ruff.toml": "ruff",
     ".ruff.toml": "ruff",
     "uv.toml": "uv",
@@ -9317,6 +9499,11 @@
       "drone.yml": "drone_light",
       ".wakatime-project": "wakatime_light",
       "hcl": "hcl_light",
+      "ai": "adobe-illustrator_light",
+      "ait": "adobe-illustrator_light",
+      "psd": "adobe-photoshop_light",
+      "psb": "adobe-photoshop_light",
+      "psdt": "adobe-photoshop_light",
       "iuml": "uml_light",
       "pu": "uml_light",
       "puml": "uml_light",
diff --git a/options/fileicon/material-icon-svgs.json b/options/fileicon/material-icon-svgs.json
index dbda90665b..50bc2d2b8a 100644
--- a/options/fileicon/material-icon-svgs.json
+++ b/options/fileicon/material-icon-svgs.json
@@ -4,6 +4,10 @@
   "abc": "<svg viewBox='0 0 24 24'><path fill='#ff5722' d='M13.295 11.033V7.65l2.126-2.136c.774-.763.919-1.981.377-2.929a2.38 2.38 0 0 0-2.068-1.217c-.203 0-.435.029-.619.087-1.044.28-1.749 1.246-1.749 2.33v3.13L8.327 9.98a5.75 5.75 0 0 0-1.208 6.214 5.62 5.62 0 0 0 4.243 3.432v.59a.5.5 0 0 1-.483.482h-1.45v1.934h1.45a2.43 2.43 0 0 0 2.416-2.417v-.483c1.962 0 4.02-1.856 4.02-4.591 0-2.223-1.855-4.108-4.02-4.108m0-7.249c0-.222.106-.396.31-.454a.47.47 0 0 1 .54.222.48.48 0 0 1-.077.59l-.773.83V3.785m-1.933 7.732c-.938.619-1.643 1.682-1.894 2.668l1.894.503v2.948a3.73 3.73 0 0 1-2.484-2.185 3.8 3.8 0 0 1 .802-4.098l1.682-1.769zm1.933 6.283v-4.89c1.13 0 2.107 1.062 2.107 2.232 0 1.691-1.227 2.658-2.107 2.658'/></svg>",
   "actionscript": "<svg viewBox='0 -960 960 960'><path fill='#f44336' d='M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z'/><path fill='#f44336' d='M360-600h80v40h-80zm80 240h40v-200h-40v80h-80v-80h-40v200h40v-80h80zm200-200v-40H530a10 10 0 0 0-10 10v100a10 10 0 0 0 10 10h70v80h-80v40h110a10 10 0 0 0 10-10v-140a10 10 0 0 0-10-10h-70v-40z'/></svg>",
   "ada": "<svg viewBox='0 0 24 24'><path fill='#0277bd' d='m2 12 2.9-1.07c.25-1.1.87-1.73.87-1.73a3.996 3.996 0 0 1 5.65 0l1.41 1.41 6.31-6.7c.95 3.81 0 7.62-2.33 10.69L22 19.62s-8.47 1.9-13.4-1.95c-2.63-2.06-3.22-3.26-3.59-4.52zm5.04.21c.37.37.98.37 1.35 0s.37-.97 0-1.34a.96.96 0 0 0-1.35 0c-.37.37-.37.97 0 1.34'/></svg>",
+  "adobe-illustrator": "<svg viewBox='0 0 32 32'><rect width='28' height='28' x='2' y='2' fill='#5d4037' rx='4'/><path fill='#ffb74d' d='M20.988 9.999a.96.96 0 0 1-.687-.269 1 1 0 0 1-.263-.704.9.9 0 0 1 .278-.681 1 1 0 0 1 .687-.268.93.93 0 0 1 .703.268 1.046 1.046 0 0 1-.015 1.385.9.9 0 0 1-.703.268M20 12h2v10h-2zm-5.63-1.98-.01-.02h-2.08a.12.12 0 0 0-.1.13 4.5 4.5 0 0 1-.06.74c-.05.13-.08.26-.12.37l-.27.78L8 22h2.14l.75-2h5.24l.79 2h2.16zM11.64 18l1.8-4.84.01.04.02.04L14.95 17l.39 1z'/></svg>",
+  "adobe-illustrator_light": "<svg viewBox='0 0 32 32'><rect width='28' height='28' x='2' y='2' fill='#795548' rx='4'/><path fill='#ffb74d' d='M20.988 9.999a.96.96 0 0 1-.687-.269 1 1 0 0 1-.263-.704.9.9 0 0 1 .278-.681 1 1 0 0 1 .687-.268.93.93 0 0 1 .703.268 1.046 1.046 0 0 1-.015 1.385.9.9 0 0 1-.703.268M20 12h2v10h-2zm-5.63-1.98-.01-.02h-2.08a.12.12 0 0 0-.1.13 4.5 4.5 0 0 1-.06.74c-.05.13-.08.26-.12.37l-.27.78L8 22h2.14l.75-2h5.24l.79 2h2.16zM11.64 18l1.8-4.84.01.04.02.04L14.95 17l.39 1z'/></svg>",
+  "adobe-photoshop": "<svg viewBox='0 0 32 32'><rect width='28' height='28' x='2' y='2' fill='#37474f' rx='4'/><path fill='#64b5f6' d='M23.744 14.716a3.7 3.7 0 0 0-1.066-.408 5.4 5.4 0 0 0-1.245-.157 2.1 2.1 0 0 0-.666.085.57.57 0 0 0-.345.24.7.7 0 0 0-.089.324.56.56 0 0 0 .111.313 1.3 1.3 0 0 0 .378.324q.386.217.79.397a7.8 7.8 0 0 1 1.71.877 2.7 2.7 0 0 1 .878.998 2.8 2.8 0 0 1 .256 1.238 2.96 2.96 0 0 1-.434 1.599 2.83 2.83 0 0 1-1.244 1.07 4.75 4.75 0 0 1-2.011.384 7 7 0 0 1-1.511-.156 4.2 4.2 0 0 1-1.134-.385.24.24 0 0 1-.122-.228v-2.092a.14.14 0 0 1 .044-.108c.034-.024.067-.012.1.012a4.6 4.6 0 0 0 1.378.59 4.8 4.8 0 0 0 1.311.18 2 2 0 0 0 .923-.169.56.56 0 0 0 .3-.505.65.65 0 0 0-.267-.48 4.6 4.6 0 0 0-1.089-.565 6.6 6.6 0 0 1-1.578-.866 3 3 0 0 1-.844-1.021 2.76 2.76 0 0 1-.256-1.226 3 3 0 0 1 .378-1.455 2.8 2.8 0 0 1 1.167-1.105A4 4 0 0 1 21.533 12a9 9 0 0 1 1.378.108 3.7 3.7 0 0 1 .956.277.2.2 0 0 1 .11.108.7.7 0 0 1 .023.144v1.96a.15.15 0 0 1-.056.12.28.28 0 0 1-.2 0M12.38 10H9.99v-.03h-2v12h2V18h2.39A3.62 3.62 0 0 0 16 14.38v-.76A3.62 3.62 0 0 0 12.38 10M14 14.38A1.626 1.626 0 0 1 12.38 16H9.99v-4h2.39A1.626 1.626 0 0 1 14 13.62Z'/></svg>",
+  "adobe-photoshop_light": "<svg viewBox='0 0 32 32'><rect width='28' height='28' x='2' y='2' fill='#455a64' rx='4'/><path fill='#64b5f6' d='M23.744 14.716a3.7 3.7 0 0 0-1.066-.408 5.4 5.4 0 0 0-1.245-.157 2.1 2.1 0 0 0-.666.085.57.57 0 0 0-.345.24.7.7 0 0 0-.089.324.56.56 0 0 0 .111.313 1.3 1.3 0 0 0 .378.324q.386.217.79.397a7.8 7.8 0 0 1 1.71.877 2.7 2.7 0 0 1 .878.998 2.8 2.8 0 0 1 .256 1.238 2.96 2.96 0 0 1-.434 1.599 2.83 2.83 0 0 1-1.244 1.07 4.75 4.75 0 0 1-2.011.384 7 7 0 0 1-1.511-.156 4.2 4.2 0 0 1-1.134-.385.24.24 0 0 1-.122-.228v-2.092a.14.14 0 0 1 .044-.108c.034-.024.067-.012.1.012a4.6 4.6 0 0 0 1.378.59 4.8 4.8 0 0 0 1.311.18 2 2 0 0 0 .923-.169.56.56 0 0 0 .3-.505.65.65 0 0 0-.267-.48 4.6 4.6 0 0 0-1.089-.565 6.6 6.6 0 0 1-1.578-.866 3 3 0 0 1-.844-1.021 2.76 2.76 0 0 1-.256-1.226 3 3 0 0 1 .378-1.455 2.8 2.8 0 0 1 1.167-1.105A4 4 0 0 1 21.533 12a9 9 0 0 1 1.378.108 3.7 3.7 0 0 1 .956.277.2.2 0 0 1 .11.108.7.7 0 0 1 .023.144v1.96a.15.15 0 0 1-.056.12.28.28 0 0 1-.2 0M12.38 10H9.99v-.03h-2v12h2V18h2.39A3.62 3.62 0 0 0 16 14.38v-.76A3.62 3.62 0 0 0 12.38 10M14 14.38A1.626 1.626 0 0 1 12.38 16H9.99v-4h2.39A1.626 1.626 0 0 1 14 13.62Z'/></svg>",
   "adobe-swc": "<svg viewBox='0 0 32 32'><path fill='#e53935' d='M4 5v22a1 1 0 0 0 1 1h22a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1m20 7c-2.926 0-4.21.722-5.012 2H22v4h-4.582C16.34 20.857 14.393 24 8 24v-4c4.559 0 5.14-1.744 6.103-4.632C15.139 12.258 16.559 8 24 8Z'/></svg>",
   "adonis": "<svg viewBox='0 0 180 180'><path fill='#7c4dff' d='m79.579 25.741-66.481 115.15h63.305l11.218-19.433H47.613L79.804 65.7l20.005 34.649 11.423-19.783zm42.118 50.221-45.203 78.297h90.408z' paint-order='fill markers stroke'/></svg>",
   "advpl-include.clone": "<svg viewBox='0 0 16 16'><path fill='#00BCD4' fill-rule='evenodd' d='M6.752 1.158C2.234 1.96-.271 6.943 1.758 11.09c2.537 5.185 10.047 5.142 12.511-.07C16.69 5.9 12.321.17 6.752 1.159m.587 2.335c2.576.517 5.233 1.323 5.326 1.615.26.808.256 4.849-.004 5.34-.066.125-1.209-.012-2.08-.247l-.351-.094-.001-.437c-.005-1.308-.138-2.547-.29-2.7-.176-.176-1.312-.545-3.052-.99L5.78 5.697l-.014-.267c-.033-.6.117-1.95.232-2.093.063-.079.315-.05 1.34.157M4.029 5.39c.5.066 1.083.178 1.492.289l.178.048.03.984c.058 1.844.117 2.13.475 2.29.448.2 2.083.679 3.62 1.061l.34.084-.01.653c-.012.735-.083 1.393-.175 1.617l-.062.15-.261-.03c-.976-.113-4.175-.896-5.567-1.362-.611-.205-.759-.284-.811-.435-.23-.66-.23-4.905 0-5.337.054-.1.08-.1.75-.012'/></svg>",
@@ -163,8 +167,8 @@
   "fastlane": "<svg preserveAspectRatio='xMidYMid' viewBox='0 0 300 300'><path fill='#2979FF' d='M242.745 89.48c-11.223 0-21.398 4.463-28.867 11.7l-47.366-33.917c.295-1.238.469-2.524.469-3.854 0-9.167-7.432-16.6-16.6-16.6s-16.601 7.433-16.601 16.6c0 9.169 7.433 16.6 16.6 16.6 3.21 0 6.197-.927 8.738-2.504L217.1 119.7c4.52-9.428 14.49-16.77 25.645-16.77 15.492 0 28.051 12.558 28.051 28.05 0 12.38-8.02 22.887-19.148 26.608l3.806 12.91c16.703-5.368 28.79-21.03 28.79-39.518 0-22.92-18.579-41.5-41.5-41.5'/><path fill='#E64A19' d='M109.689 49.166c-3.389 10.669-2.22 21.69 2.405 30.977l-46.546 34.784a16.6 16.6 0 0 0-3.523-1.609c-8.716-2.768-18.026 2.053-20.794 10.768s2.053 18.026 10.767 20.794c8.716 2.769 18.026-2.052 20.795-10.767a16.46 16.46 0 0 0 .257-9.062l57.623-42.379c-7.598-7.144-11.567-18.84-8.2-29.444 4.68-14.727 20.411-22.874 35.139-18.195 11.768 3.738 19.334 14.535 19.513 26.238l13.421.28c-.059-17.5-11.299-33.721-28.873-39.304-21.788-6.921-45.063 5.13-51.984 26.92'/><path fill='#00bcd4' d='M32.81 161.347a41.37 41.37 0 0 0 30.043 7.612l18.362 54.878a16.3 16.3 0 0 0-2.621 2.8c-5.338 7.316-3.686 17.611 3.692 22.994 7.377 5.383 17.685 3.815 23.023-3.501 5.34-7.316 3.687-17.61-3.69-22.994a16.53 16.53 0 0 0-8.489-3.13l-22.086-67.718c-9.128 4.87-21.425 4.875-30.402-1.674-12.465-9.097-15.258-26.492-6.237-38.855 7.21-9.88 19.78-13.556 30.9-9.993l4.456-12.536c-16.566-5.525-35.414-.121-46.179 14.631-13.346 18.291-9.214 44.029 9.229 57.486'/><path fill='#8BC34A' d='M245.283 225.838c-3.42-10.583-10.75-18.811-19.884-23.64l17.72-55.05a16.6 16.6 0 0 0 3.796-.739c8.69-2.808 13.47-12.093 10.679-20.737-2.793-8.646-12.102-13.378-20.793-10.57-8.69 2.806-13.472 12.09-10.679 20.736a16.3 16.3 0 0 0 5.036 7.472l-22.334 67.6c10.315 1.374 20.312 8.527 23.71 19.046 4.72 14.61-3.36 30.298-18.044 35.042-11.735 3.791-24.138-.554-31.055-9.908l-11.078 7.543c10.176 14.106 28.706 20.71 46.23 15.048 21.726-7.019 33.678-30.23 26.696-51.843'/><path fill='#A0F' d='M116.724 270.244c9.003-6.587 14.547-16.139 16.291-26.33l57.906-.59a16.5 16.5 0 0 0 1.887 3.366c5.382 7.355 15.706 8.955 23.061 3.574s8.955-15.705 3.575-23.06c-5.382-7.356-15.706-8.956-23.061-3.575a16.4 16.4 0 0 0-5.54 7.137l-71.283.182c1.908 10.217-1.78 21.958-10.73 28.506-12.428 9.093-29.875 6.39-38.968-6.039-7.266-9.932-6.999-23.068-.257-32.585l-10.631-8.123c-10.249 14.11-10.752 33.77.098 48.601 13.453 18.389 39.265 22.389 57.652 8.936'/></svg>",
   "favicon": "<svg viewBox='0 0 32 32'><path fill='#ffd54f' d='m16 24 10 6-4-10 8-8-10-.032L16 2l-4 10H2l8 8-4 10Z'/></svg>",
   "figma": "<svg viewBox='0 0 32 32'><path fill='#f4511e' d='M12 4h4v8h-4a4 4 0 0 1-4-4 4 4 0 0 1 4-4'/><path fill='#ff8a65' d='M20 12h-4V4h4a4 4 0 0 1 4 4 4 4 0 0 1-4 4'/><rect width='8' height='8' x='16' y='12' fill='#29b6f6' rx='4' transform='rotate(180 20 16)'/><path fill='#7c4dff' d='M12 12h4v8h-4a4 4 0 0 1-4-4 4 4 0 0 1 4-4'/><path fill='#00e676' d='M12 20h4v4a4 4 0 0 1-4 4 4 4 0 0 1-4-4 4 4 0 0 1 4-4'/></svg>",
-  "file": "<svg viewBox='0 0 24 24'><path fill='#90a4ae' d='M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m5 2H6v16h12v-9h-7z'/></svg>",
-  "firebase": "<svg viewBox='0 0 24 24'><path fill='#fbc02d' d='m19.389 18.237-6.742 3.74q-.693.36-1.386 0l-6.65-3.74L16.664 6.092 16.988 6c.277 0 .434.12.461.37zM9.553 6.277 5.35 13.248 7.105 2.212c.028-.25.185-.37.462-.37.185 0 .305.056.37.232l1.985 3.648-.37.554M13.71 7.44l-8.82 8.857 6.696-11.36c.092-.185.23-.268.415-.268s.305.083.37.268z'/></svg>",
+  "file": "<svg viewBox='0 0 16 16'><path fill='#90a4ae' d='M8.668 6h3.664L8.668 2.332zM4 1.332h5.332l4 4v8c0 .738-.594 1.336-1.332 1.336H4a1.33 1.33 0 0 1-1.332-1.336V2.668A1.33 1.33 0 0 1 4 1.332m3.332 1.336H4v10.664h8v-6H7.332z'/></svg>",
+  "firebase": "<svg viewBox='0 0 24 24'><path fill='#ff9100' d='M18.217 8.974c-.45-.623-1.482-1.904-3.07-3.808-.689-.825-1.28-1.526-1.57-1.87l-.408-.48-.173-.205-.094-.11-.018-.027-.008-.004-.4-.47-.509.407a11.1 11.1 0 0 0-3.069 3.866 9.5 9.5 0 0 0-.87 2.647q-.06.303-.1.615a9 9 0 0 0-.577-.03 6.2 6.2 0 0 0-1.901.229l-.265.074-.136.238a8 8 0 0 0-1.044 3.68 8 8 0 0 0 5.006 7.697l.197.079.06.02h.002a8 8 0 0 0 2.452.473q.143.005.286.005a7.9 7.9 0 0 0 3.076-.618l.007.003.261-.12a7.99 7.99 0 0 0 4.643-6.981 8.5 8.5 0 0 0-1.778-5.31M9.837 19.82l-.192-.074-.051-.02a6.31 6.31 0 0 1-3.897-6.048 6.2 6.2 0 0 1 .697-2.667 4.6 4.6 0 0 1 .759-.103l.065-.002a8 8 0 0 1 .378 0c.108.005.215.021.322.034a13 13 0 0 0 .918 4.007 10.1 10.1 0 0 0 2.474 3.61 6.4 6.4 0 0 1-1.473 1.263m.351-5.486a11.4 11.4 0 0 1-.767-3.125 4.6 4.6 0 0 1 .95.461 4.73 4.73 0 0 1 1.94 2.884 5 5 0 0 1 .12.649 4.2 4.2 0 0 1-.288 2.023 8.3 8.3 0 0 1-1.955-2.892m1.741 5.858a8 8 0 0 0 .553-.62c.233.177.485.332.73.495a6.3 6.3 0 0 1-1.283.125m5.432-2.97a6.34 6.34 0 0 1-2.212 2.138 12.4 12.4 0 0 1-1.851-1.15 5.84 5.84 0 0 0 .309-3.998 6.02 6.02 0 0 0-2.504-3.664 6.1 6.1 0 0 0-1.679-.74 8 8 0 0 1 .064-.496 9 9 0 0 1 .465-1.598q.117-.298.253-.584l.004-.007c.14-.282.296-.567.481-.872l.073-.12h-.002a9.2 9.2 0 0 1 1.534-1.824l.227.269c.53.628 1.03 1.222 1.483 1.765 1.02 1.223 2.342 2.828 2.852 3.536a6.8 6.8 0 0 1 1.446 4.242 6.3 6.3 0 0 1-.943 3.104'/></svg>",
   "flash": "<svg viewBox='0 0 24 24'><path fill='#e53935' d='M20.314 2c-2.957 0-5.341 1.104-7.122 3.252-1.427 1.752-2.354 3.93-3.164 6.034-1.663 4.283-2.781 6.741-6.342 6.741V22c2.958 0 5.342-1.03 7.122-3.194 1.133-1.383 1.957-3.135 2.634-4.827h4.665v-3.973h-3.061c1.207-2.575 2.546-3.973 5.268-3.973z'/></svg>",
   "flow": "<svg viewBox='0 0 300 300'><path fill='#fbc02d' fill-opacity='.976' d='m38.75 33.427 77.461 77.47H54.436l61.145 61.16H38.437l93.462 93.478v-77.158l.01-.01v-77.47h-.01V66.982h46.691l20.394 20.393H153.57v76.531h22.05l24.474 24.473h-15.806l-.01-.01v.01h-31.665l-.01-.01v.01h-.313l.313.313v77.148h109.149l-39.2-39.2v-15.806l8.465 8.466v-77.37h-15.682l.017-38.191 30.09 30.086V56.362h-64.874l-22.94-22.934H113.71z'/></svg>",
   "folder-admin-open": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#cfd8dc' d='m25 10-7 3.273v4.908c0 4.542 2.986 8.788 7 9.819 4.014-1.031 7-5.277 7-9.82v-4.907zm0 3.273a2.457 2.457 0 1 1-2.333 2.454A2.396 2.396 0 0 1 25 13.273m3.99 9.817A7.6 7.6 0 0 1 25 26.298a7.6 7.6 0 0 1-3.99-3.208 8.4 8.4 0 0 1-.677-1.25c0-1.352 2.108-2.456 4.667-2.456s4.666 1.08 4.666 2.455a8.3 8.3 0 0 1-.676 1.251'/></svg>",
@@ -223,6 +227,8 @@
   "folder-client": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M15 12a1 1 0 0 0-1 1v10.994h-4v4h12v-4h-6V14h14v-2.006Z'/><path fill='#b3e5fc' d='M31 16h-6a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V17a1 1 0 0 0-1-1m-1 8h-4v-6h4Z'/></svg>",
   "folder-cline-open": "<svg viewBox='0 0 32 32'><path fill='#42a5f5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#bbdefb' d='M23 12a2 2 0 0 0-2 2h-1c-2.216 0-4 1.784-4 4l-2 3 2 3c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4l2-3-2-3c0-2.216-1.784-4-4-4h-1a2 2 0 0 0-2-2m-2 6c.554 0 1 .446 1 1v4c0 .554-.446 1-1 1s-1-.446-1-1v-4c0-.554.446-1 1-1m4 0c.554 0 1 .446 1 1v4c0 .554-.446 1-1 1s-1-.446-1-1v-4c0-.554.446-1 1-1'/></svg>",
   "folder-cline": "<svg viewBox='0 0 32 32'><path fill='#42a5f5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#bbdefb' d='M23 12a2 2 0 0 0-2 2h-1c-2.216 0-4 1.784-4 4l-2 3 2 3c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4l2-3-2-3c0-2.216-1.784-4-4-4h-1a2 2 0 0 0-2-2m-2 6c.554 0 1 .446 1 1v4c0 .554-.446 1-1 1s-1-.446-1-1v-4c0-.554.446-1 1-1m4 0c.554 0 1 .446 1 1v4c0 .554-.446 1-1 1s-1-.446-1-1v-4c0-.554.446-1 1-1'/></svg>",
+  "folder-cloud-functions-open": "<svg xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 32 32'><defs><path id='a' fill='#bbdefb' d='m26 14 2-2 4 4-2 2z'/></defs><path fill='#2196f3' fill-rule='nonzero' d='M28.967 12H9.442c-.859 0-1.627.553-1.898 1.368L4 24V10h24c0-1.097-.903-2-2-2H15.124c-.468 0-.921-.164-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4c-1.097 0-2 .903-2 2v16c0 1.097.903 2 2 2h22l4.805-11.212c.107-.249.162-.517.162-.788 0-1.097-.903-2-2-2'/><path fill='#bbdefb' d='M21.982 17.988h2.037v1.996h-2.037zm-2.983.021h2.037v1.996h-2.037zm5.998 0h1.996v1.996h-1.996zM29 14h3v10h-3z'/><use xlink:href='#a' transform='translate(0 -2)'/><use xlink:href='#a' transform='matrix(1 0 0 -1 0 40)'/><path fill='#bbdefb' d='M14 14h3v10h-3z'/><use xlink:href='#a' transform='matrix(-1 0 0 1 46 -2)'/><use xlink:href='#a' transform='rotate(180 23 20)'/></svg>",
+  "folder-cloud-functions": "<svg xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 32 32'><defs><path id='a' fill='#bbdefb' d='m26 14 2-2 4 4-2 2z'/></defs><path fill='#2196f3' fill-rule='nonzero' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4c-1.097 0-2 .903-2 2v16c0 1.097.903 2 2 2h24c1.097 0 2-.903 2-2V10c0-1.097-.903-2-2-2H15.124c-.468 0-.921-.164-1.28-.464'/><path fill='#bbdefb' d='M21.982 17.988h2.037v1.996h-2.037zm-2.983.021h2.037v1.996h-2.037zm5.998 0h1.996v1.996h-1.996zM29 14h3v10h-3z'/><use xlink:href='#a' transform='translate(0 -2)'/><use xlink:href='#a' transform='matrix(1 0 0 -1 0 40)'/><path fill='#bbdefb' d='M14 14h3v10h-3z'/><use xlink:href='#a' transform='matrix(-1 0 0 1 46 -2)'/><use xlink:href='#a' transform='rotate(180 23 20)'/></svg>",
   "folder-cloudflare-open": "<svg viewBox='0 0 32 32'><path fill='#ff8a65' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#EFEBE9' d='M27.881 19.229a6.591 6.591 0 0 0-12.308-1.759 5.278 5.278 0 0 0 .572 10.524h11.428a4.388 4.388 0 0 0 .308-8.765'/></svg>",
   "folder-cloudflare": "<svg viewBox='0 0 32 32'><path fill='#ff8a65' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#EFEBE9' d='M27.881 19.229a6.591 6.591 0 0 0-12.308-1.759 5.278 5.278 0 0 0 .572 10.524h11.428a4.388 4.388 0 0 0 .308-8.765'/></svg>",
   "folder-cluster-open": "<svg viewBox='0 0 32 32'><path fill='#26a69a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><circle cx='21' cy='15' r='3' fill='#b2dfdb'/><circle cx='17' cy='23' r='3' fill='#b2dfdb'/><circle cx='27' cy='27' r='3' fill='#b2dfdb'/></svg>",
@@ -273,8 +279,8 @@
   "folder-delta": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#f8bbd0' d='M23 17.699 28.337 26H17.663zM23 14l-9 14h18z'/></svg>",
   "folder-desktop-open": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M30 12H14a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6v2h-2v2h8v-2h-2v-2h6a2 2 0 0 0 2-2V14a2 2 0 0 0-2-2m0 12H14V14h16Z'/></svg>",
   "folder-desktop": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M30 12H14a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6v2h-2v2h8v-2h-2v-2h6a2 2 0 0 0 2-2V14a2 2 0 0 0-2-2m0 12H14V14h16Z'/></svg>",
-  "folder-development-open.clone": "<svg viewBox='0 0 32 32'><path fill='#0288D1' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#CFD8DC' d='M18.473 30a1 1 0 0 1-.238-.028 1.137 1.137 0 0 1-.828-1.323L20.5 12.905a1.13 1.13 0 0 1 .507-.744 1.06 1.06 0 0 1 .8-.134 1.14 1.14 0 0 1 .828 1.324l-3.101 15.744a1.12 1.12 0 0 1-.504.743 1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412 1.164 1.164 0 0 1 .113-1.548l5.319-4.967-5.296-4.623a1.165 1.165 0 0 1-.162-1.544 1.08 1.08 0 0 1 .754-.437 1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .003 1.723l-6.218 5.808a1.07 1.07 0 0 1-.729.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.226-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018 6.246-5.454a1.03 1.03 0 0 1 .8-.26 1.08 1.08 0 0 1 .76.436 1.165 1.165 0 0 1-.16 1.547l-5.294 4.62 5.32 4.964a1.156 1.156 0 0 1 .112 1.548 1.07 1.07 0 0 1-.762.412Z'/></svg>",
-  "folder-development.clone": "<svg viewBox='0 0 32 32'><path fill='#0288D1' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#CFD8DC' d='M18.435 30a1 1 0 0 1-.238-.028 1.137 1.137 0 0 1-.828-1.323l3.093-15.744a1.13 1.13 0 0 1 .507-.744 1.06 1.06 0 0 1 .8-.134 1.14 1.14 0 0 1 .828 1.324l-3.1 15.744a1.12 1.12 0 0 1-.505.743 1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412 1.164 1.164 0 0 1 .113-1.548l5.32-4.967-5.297-4.623a1.165 1.165 0 0 1-.162-1.544 1.08 1.08 0 0 1 .754-.437 1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .004 1.723l-6.22 5.808a1.07 1.07 0 0 1-.728.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.225-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018 6.246-5.454a1.03 1.03 0 0 1 .8-.26 1.08 1.08 0 0 1 .758.436 1.165 1.165 0 0 1-.16 1.547l-5.293 4.62 5.32 4.964a1.156 1.156 0 0 1 .112 1.548 1.07 1.07 0 0 1-.762.412Z'/></svg>",
+  "folder-development-open.clone": "<svg viewBox='0 0 32 32'><path fill='#0288D1' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#B3E5FC' d='M18.473 30a1 1 0 0 1-.238-.028 1.137 1.137 0 0 1-.828-1.323L20.5 12.905a1.13 1.13 0 0 1 .507-.744 1.06 1.06 0 0 1 .8-.134 1.14 1.14 0 0 1 .828 1.324l-3.101 15.744a1.12 1.12 0 0 1-.504.743 1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412 1.164 1.164 0 0 1 .113-1.548l5.319-4.967-5.296-4.623a1.165 1.165 0 0 1-.162-1.544 1.08 1.08 0 0 1 .754-.437 1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .003 1.723l-6.218 5.808a1.07 1.07 0 0 1-.729.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.226-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018 6.246-5.454a1.03 1.03 0 0 1 .8-.26 1.08 1.08 0 0 1 .76.436 1.165 1.165 0 0 1-.16 1.547l-5.294 4.62 5.32 4.964a1.156 1.156 0 0 1 .112 1.548 1.07 1.07 0 0 1-.762.412Z'/></svg>",
+  "folder-development.clone": "<svg viewBox='0 0 32 32'><path fill='#0288D1' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#B3E5FC' d='M18.435 30a1 1 0 0 1-.238-.028 1.137 1.137 0 0 1-.828-1.323l3.093-15.744a1.13 1.13 0 0 1 .507-.744 1.06 1.06 0 0 1 .8-.134 1.14 1.14 0 0 1 .828 1.324l-3.1 15.744a1.12 1.12 0 0 1-.505.743 1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412 1.164 1.164 0 0 1 .113-1.548l5.32-4.967-5.297-4.623a1.165 1.165 0 0 1-.162-1.544 1.08 1.08 0 0 1 .754-.437 1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .004 1.723l-6.22 5.808a1.07 1.07 0 0 1-.728.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.225-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018 6.246-5.454a1.03 1.03 0 0 1 .8-.26 1.08 1.08 0 0 1 .758.436 1.165 1.165 0 0 1-.16 1.547l-5.293 4.62 5.32 4.964a1.156 1.156 0 0 1 .112 1.548 1.07 1.07 0 0 1-.762.412Z'/></svg>",
   "folder-directive-open": "<svg viewBox='0 0 16 16'><path fill='#f44336' d='M14.484 6H4.72a1 1 0 0 0-.949.684L2 12V5h12a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h11l2.403-5.606A1 1 0 0 0 14.483 6'/><g fill='#ffcdd2'><path d='m11.5 6.001-1.5 2h3z'/><path d='M11 7v2h1V7zm-1 3H8v1.001h2z'/><path d='m9 9-2 1.5L9 12zm2 3h1v2h-1Z'/><path d='m10 13 1.5 2 1.5-2Zm2.715-3v1.001H15v-1Z'/><path d='m14 9 2 1.5-2 1.5Z'/></g></svg>",
   "folder-directive": "<svg viewBox='0 0 16 16'><path fill='#f44336' d='m6.922 3.768-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232'/><g fill='#ffcdd2'><path d='m11.5 6.001-1.5 2h3z'/><path d='M11 7v2h1V7zm-1 3H8v1.001h2z'/><path d='m9 9-2 1.5L9 12zm2 3h1v2h-1Z'/><path d='m10 13 1.5 2 1.5-2Zm3-3v1.001h2v-1Z'/><path d='m14 9 2 1.5-2 1.5Z'/></g></svg>",
   "folder-dist-open": "<svg viewBox='0 0 32 32'><path fill='#e57373' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' d='M30 14h-4v-2l-2-2h-4l-2 2v2h-4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V16a2 2 0 0 0-2-2m-10 0v-2h4v2Z'/></svg>",
@@ -309,8 +315,10 @@
   "folder-fastlane": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#e3f2fd' d='m15.508 21.618 1.272 3.936a1.456 1.456 0 0 0-.06 1.922 1.35 1.35 0 0 0 .937.486l.1.003a1.33 1.33 0 0 0 .894-.346 1.4 1.4 0 0 0 .207-.231 1.446 1.446 0 0 0-.307-1.972 1.36 1.36 0 0 0-.597-.256l-1.586-5.037a.16.16 0 0 0-.092-.101.15.15 0 0 0-.134.007 1.92 1.92 0 0 1-2.059-.113 1.995 1.995 0 0 1-.423-2.72 1.84 1.84 0 0 1 2.088-.697.16.16 0 0 0 .199-.102l.325-.95a.17.17 0 0 0-.007-.128.16.16 0 0 0-.093-.084 3 3 0 0 0-.978-.167h-.039A3.215 3.215 0 0 0 12 18.296a3.3 3.3 0 0 0 1.321 2.698 3.08 3.08 0 0 0 2.187.624'/><path fill='#e3f2fd' d='M15.802 17.146a1.35 1.35 0 0 0-1.787.535 1.45 1.45 0 0 0-.157 1.074 1.4 1.4 0 0 0 .622.875 1.33 1.33 0 0 0 .706.203 1.36 1.36 0 0 0 1.176-.685 1.47 1.47 0 0 0 .177-.971l4.14-3.149a.17.17 0 0 0 .065-.122.17.17 0 0 0-.05-.13 2.09 2.09 0 0 1-.556-2.063 1.883 1.883 0 0 1 2.383-1.262 1.95 1.95 0 0 1 1.31 1.823.16.16 0 0 0 .155.161l.983.02a.2.2 0 0 0 .114-.047.17.17 0 0 0 .048-.117 3.34 3.34 0 0 0-.945-2.333A3.12 3.12 0 0 0 21.939 10a4 4 0 0 0-.293.014 3.14 3.14 0 0 0-2.162 1.182 3.4 3.4 0 0 0-.457 3.457Zm10.842 10.755a1.4 1.4 0 0 0 .736-.77 1.45 1.45 0 0 0-.005-1.083 1.38 1.38 0 0 0-.744-.763 1.3 1.3 0 0 0-1.047.005 1.4 1.4 0 0 0-.693.672l-5.12.014a.16.16 0 0 0-.123.06.17.17 0 0 0-.033.135 2.08 2.08 0 0 1-.724 2 1.82 1.82 0 0 1-1.4.355 1.86 1.86 0 0 1-1.233-.773 2 2 0 0 1-.016-2.286.17.17 0 0 0-.033-.226l-.778-.613a.15.15 0 0 0-.12-.032.16.16 0 0 0-.105.065 3.36 3.36 0 0 0-.575 2.45 3.3 3.3 0 0 0 1.266 2.153 3.1 3.1 0 0 0 1.874.634 3.15 3.15 0 0 0 2.572-1.349 3.4 3.4 0 0 0 .545-1.264l4.01-.04a1.35 1.35 0 0 0 1.746.656'/><path fill='#e3f2fd' d='m27.718 23.882 1.228-3.945a1.34 1.34 0 0 0 .824-.473 1.44 1.44 0 0 0 .328-1.026 1.366 1.366 0 0 0-2.729-.013 1.5 1.5 0 0 0 .06.553 1.4 1.4 0 0 0 .336.564l-1.603 5.027a.17.17 0 0 0 .016.14.16.16 0 0 0 .115.075 1.952 1.952 0 0 1 .385 3.782 1.84 1.84 0 0 1-2.097-.692.156.156 0 0 0-.217-.037l-.811.572a.16.16 0 0 0-.067.108.17.17 0 0 0 .028.124A3.15 3.15 0 0 0 26.097 30a3.1 3.1 0 0 0 1.871-.63 3.36 3.36 0 0 0 1.165-3.667 3.23 3.23 0 0 0-1.415-1.82Z'/><path fill='#e3f2fd' d='M31.845 17.545a3.15 3.15 0 0 0-5.177-1.459l-3.28-2.432a1.46 1.46 0 0 0-.193-.969 1.37 1.37 0 0 0-.857-.637 1.3 1.3 0 0 0-.308-.038h-.004a1.425 1.425 0 0 0-.003 2.847h.005a1.3 1.3 0 0 0 .631-.16l4.165 3.137a.16.16 0 0 0 .133.027.16.16 0 0 0 .104-.089 1.98 1.98 0 0 1 1.735-1.178h.001a1.933 1.933 0 0 1 1.897 1.963 1.96 1.96 0 0 1-1.296 1.863.166.166 0 0 0-.102.203l.28.98a.16.16 0 0 0 .079.098.15.15 0 0 0 .123.011 3.2 3.2 0 0 0 1.867-1.64 3.4 3.4 0 0 0 .2-2.527'/></svg>",
   "folder-favicon-open": "<svg viewBox='0 0 32 32'><path fill='#fbc02d' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124c-.468 0-.921-.164-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#fffde7' d='m24 24 6 4-2-6 4-4h-6l-1.999-6L22 18h-6l4 4-2 6z'/></svg>",
   "folder-favicon": "<svg viewBox='0 0 32 32'><path fill='#fbc02d' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#fffde7' d='m24 24 6 4-2-6 4-4h-6l-1.999-6L22 18h-6l4 4-2 6z'/></svg>",
-  "folder-firebase-open": "<svg viewBox='0 0 32 32'><path fill='#fbc02d' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#fff9c4' d='m32 24.526-6.387 3.314a1.43 1.43 0 0 1-1.313 0L18 24.526l11.419-10.76.307-.08c.261 0 .41.106.437.326zM22.68 13.93l-3.98 6.178 1.662-9.778c.026-.22.175-.327.438-.327a.32.32 0 0 1 .35.205l1.882 3.232-.35.491m3.937 1.03-8.356 7.848 6.343-10.066a.42.42 0 0 1 .395-.237.335.335 0 0 1 .35.237Z'/></svg>",
-  "folder-firebase": "<svg viewBox='0 0 32 32'><path fill='#fbc02d' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#fff9c4' d='m32 24.526-6.387 3.314a1.43 1.43 0 0 1-1.313 0L18 24.526l11.419-10.76.307-.08c.261 0 .41.106.437.326zM22.68 13.93l-3.98 6.178 1.662-9.778c.026-.22.175-.327.438-.327a.32.32 0 0 1 .35.205l1.882 3.232-.35.491m3.937 1.03-8.356 7.848 6.343-10.066a.42.42 0 0 1 .395-.237.335.335 0 0 1 .35.237Z'/></svg>",
+  "folder-firebase-open": "<svg viewBox='0 0 32 32'><path fill='#FF9100' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffe0b2' d='M24 28.014s-4.584.213-7-4.014c-.66-1.156-1.006-2.805-1-4 .012-2.264.962-3.881 1.038-4 .117-.181 2.954-.867 4.962 0s3.979 3.215 4 6-2.275 4.565-2.691 4.881.691 1.133.691 1.133M22 25.5c2.051-1.646 1.875-2.063 2-3.5s-1.007-3.071-2-4-2.934-.65-3.5-.5c-2.418 5.405 3.5 8 3.5 8'/><path fill='#ffe0b2' d='m24 28.014 2.527-.941s-1.988-1.265-2.909-2.168C21.381 22.71 20.021 20.085 20 16s4-8 4-8 8.063 6.276 8 12c-.644 8.183-8 8.014-8 8.014m4-3.023c1.044-1.135 1.95-2.042 2-4.991.075-4.381-6-9.5-6-9.5s-1.856 2.393-2 5.5c-.338 7.273 6 8.991 6 8.991'/><path fill='#ffe0b2' d='M22.34 25.64s3.453-.086 5.66-.649c3.451-.879-1.022 2.191-1.022 2.191L24 28.015l-1.313-.536z'/></svg>",
+  "folder-firebase": "<svg fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 32 32'><path fill='#ff9100' fill-rule='nonzero' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4c-1.097 0-2 .903-2 2v16c0 1.097.903 2 2 2h24c1.097 0 2-.903 2-2V10c0-1.097-.903-2-2-2H15.124c-.468 0-.921-.164-1.28-.464'/><path fill='#ffe0b2' d='M24 28.014s-4.584.213-7-4.014c-.66-1.156-1.006-2.805-1-4 .012-2.264.962-3.881 1.038-4 .117-.181 2.954-.867 4.962 0s3.979 3.215 4 6-2.275 4.565-2.691 4.881.691 1.133.691 1.133M22 25.5c2.051-1.646 1.875-2.063 2-3.5s-1.007-3.071-2-4-2.934-.65-3.5-.5c-2.418 5.405 3.5 8 3.5 8'/><path fill='#ffe0b2' d='m24 28.014 2.527-.941s-1.988-1.265-2.909-2.168C21.381 22.71 20.021 20.085 20 16s4-8 4-8 8.063 6.276 8 12c-.644 8.183-8 8.014-8 8.014m4-3.023c1.044-1.135 1.95-2.042 2-4.991.075-4.381-6-9.5-6-9.5s-1.856 2.393-2 5.5c-.338 7.273 6 8.991 6 8.991'/><path fill='#ffe0b2' d='M22.34 25.64s3.453-.086 5.66-.649c3.451-.879-1.022 2.191-1.022 2.191L24 28.015l-1.313-.536z'/></svg>",
+  "folder-firestore-open": "<svg fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 32 32'><path fill='#2196f3' fill-rule='nonzero' d='M28.967 12H9.442c-.859 0-1.627.553-1.898 1.368L4 24V10h24c0-1.097-.903-2-2-2H15.124c-.468 0-.921-.164-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4c-1.097 0-2 .903-2 2v16c0 1.097.903 2 2 2h22l4.805-11.212c.107-.249.162-.517.162-.788 0-1.097-.903-2-2-2'/><path fill='#bbdefb' d='m24 10-8 4v4l8-4 8 4v-4z'/><path fill='#bbdefb' d='M16 20v4l8-4 8 4v-4l-8-4z'/><path fill='#bbdefb' d='m24 24 3-1 4 2-7 3z'/></svg>",
+  "folder-firestore": "<svg fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 32 32'><path fill='#2196f3' fill-rule='nonzero' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4c-1.097 0-2 .903-2 2v16c0 1.097.903 2 2 2h24c1.097 0 2-.903 2-2V10c0-1.097-.903-2-2-2H15.124c-.468 0-.921-.164-1.28-.464'/><path fill='#bbdefb' d='m24 10-8 4v4l8-4 8 4v-4z'/><path fill='#bbdefb' d='M16 20v4l8-4 8 4v-4l-8-4z'/><path fill='#bbdefb' d='m24 24 3-1 4 2-7 3z'/></svg>",
   "folder-flow-open": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#fbc02d' fill-opacity='.976' d='m12 10 6.71 6h-4.725l4.672 4h-6.676L20 28.025V12h3.548l1.584 2H22v6h1.98l1.979 2h-3.984l.025.025V28h10l-4-3.033v-1.221l.657.655L28 18h-2v-2.01l4 1.997v-5.99l-6-.999L21.923 10Z'/></svg>",
   "folder-flow": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#fbc02d' fill-opacity='.976' d='m12 10 6.71 6h-4.725l4.672 4h-6.676L20 28.025V12h3.548l1.584 2H22v6h1.98l1.979 2h-3.984l.025.025V28h10l-4-3.033v-1.221l.657.655L28 18h-2v-2.01l4 1.997v-5.99l-6-.999L21.923 10Z'/></svg>",
   "folder-flutter-open": "<svg viewBox='0 0 32 32'><path fill='#03a9f4' d='M29 12H9.4a2 2 0 0 0-1.9 1.4L4 24V10h24a2 2 0 0 0-2-2H15.1a2 2 0 0 1-1.3-.5l-1.2-1a2 2 0 0 0-1.3-.5H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.8-11.2A2 2 0 0 0 29 12'/><path fill='#b3e5fc' d='m20 10-8 8 4 4 12-12zm4 8-6 6 6 6h8l-6-6 6-6z'/></svg>",
@@ -391,6 +399,8 @@
   "folder-keys": "<svg viewBox='0 0 32 32'><path fill='#26a69a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b2dfdb' d='M21.651 20a6 6 0 1 0 0 4H26v4h4v-4h2v-4ZM16 24a2 2 0 1 1 2-2 2 2 0 0 1-2 2'/></svg>",
   "folder-kubernetes-open": "<svg viewBox='0 0 32 32'><path fill='#448aff' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#bbdefb' d='M22.069 10.463a.6.6 0 0 0-.116.003.59.59 0 0 0-.517.635v.16a3.6 3.6 0 0 0 .08.543 5.2 5.2 0 0 1 .065 1.018.6.6 0 0 1-.186.305l-.013.238a7 7 0 0 0-1.031.157 7.27 7.27 0 0 0-3.706 2.117l-.196-.145a.52.52 0 0 1-.346-.039 5.4 5.4 0 0 1-.765-.69 5 5 0 0 0-.372-.395l-.12-.093a.75.75 0 0 0-.397-.158.6.6 0 0 0-.463.197.61.61 0 0 0 .148.834l.013.013c.026.027.079.067.106.093a4 4 0 0 0 .475.277 5.4 5.4 0 0 1 .848.597.6.6 0 0 1 .106.33l.183.158a7.22 7.22 0 0 0-1.137 5.121l-.25.065a.8.8 0 0 1-.254.253 4.4 4.4 0 0 1-1.018.158 2 2 0 0 0-.543.051l-.144.029h-.013v.013c-.04 0-.08.013-.106.013a.57.57 0 1 0 .339 1.086l.004-.001a1 1 0 0 0 .174-.041 2.7 2.7 0 0 0 .488-.197 7 7 0 0 1 1.018-.292.5.5 0 0 1 .305.119l.263-.039a7.43 7.43 0 0 0 3.27 4.088l-.094.238a.7.7 0 0 1 .042.33 4.2 4.2 0 0 1-.517.913c-.106.159-.199.304-.318.462a.17.17 0 0 1-.052.148c-.013.04-.04.066-.054.106a.57.57 0 0 0 1.072.382c.027-.04.051-.132.078-.132a5 5 0 0 0 .16-.53 5 5 0 0 1 .437-1.017.45.45 0 0 1 .25-.12l.132-.237a7.4 7.4 0 0 0 5.254.013l.105.212a.5.5 0 0 1 .277.183 6 6 0 0 1 .398.954c.04.172.094.344.16.542.027 0 .051.08.078.12.013.039.028.065.041.105a.568.568 0 0 0 .984-.569l-.007-.012a1 1 0 0 1-.052-.16c-.106-.146-.212-.305-.318-.45a7.4 7.4 0 0 1-.501-.9.44.44 0 0 1 .039-.343 1 1 0 0 1-.093-.225 7.44 7.44 0 0 0 3.268-4.113c.08.013.158.025.251.038a.33.33 0 0 1 .305-.106 4.7 4.7 0 0 1 1.018.28 2.6 2.6 0 0 0 .475.196.7.7 0 0 0 .187.028v.013c0 .013.053.013.093.026a.585.585 0 0 0 .635-.491.57.57 0 0 0-.483-.645l-.008-.001a.34.34 0 0 1-.157-.067h-.543a6.6 6.6 0 0 1-1.018-.186.55.55 0 0 1-.253-.238l-.251-.064a7.2 7.2 0 0 0-1.165-5.109l.211-.184a.4.4 0 0 1 .106-.317 5 5 0 0 1 .848-.597 3.3 3.3 0 0 0 .462-.277 1 1 0 0 0 .12-.093c.039-.026.08-.053.08-.08a.556.556 0 0 0-.78-.793c-.04 0-.093.054-.133.08a10 10 0 0 0-.372.395 4.8 4.8 0 0 1-.767.69.5.5 0 0 1-.344.039l-.212.158a7.37 7.37 0 0 0-4.708-2.274l-.013-.253a.45.45 0 0 1-.186-.29 5.2 5.2 0 0 1 .065-1.018 3.6 3.6 0 0 0 .08-.543v-.292a.57.57 0 0 0-.504-.506m-.778 4.408-.16 2.977h-.013a.5.5 0 0 1-.106.28.5.5 0 0 1-.687.118h-.013l-2.434-1.734a5.75 5.75 0 0 1 2.803-1.535c.212-.04.412-.08.61-.106m1.427 0a5.9 5.9 0 0 1 3.4 1.641l-2.421 1.734h-.013a.6.6 0 0 1-.277.067.494.494 0 0 1-.516-.47v-.008Zm-5.727 2.713 2.223 2.024v.013a.34.34 0 0 1 .144.253.483.483 0 0 1-.323.602l-.02.005v.013l-2.858.822a5.9 5.9 0 0 1 .834-3.732m10.013.04a6.18 6.18 0 0 1 .86 3.679l-2.87-.822-.013-.013a.47.47 0 0 1-.238-.157.49.49 0 0 1 .042-.694l.01-.01-.013-.038Zm-5.462 2.144h.912l.568.7-.199.886-.819.398-.819-.398-.212-.886Zm-2.132 2.447h.106a.55.55 0 0 1 .504.382.5.5 0 0 1-.052.28v.038l-1.127 2.74a5.84 5.84 0 0 1-2.366-2.952Zm4.87 0h.319l2.948.475a5.85 5.85 0 0 1-2.367 2.977l-1.14-2.79a.53.53 0 0 1 .24-.662m-2.327 1.199a.51.51 0 0 1 .488.256h.013l1.442 2.607a5 5 0 0 1-.569.157 5.9 5.9 0 0 1-3.214-.157l1.442-2.607h.012c.04-.093.107-.133.2-.2a.5.5 0 0 1 .186-.056'/></svg>",
   "folder-kubernetes": "<svg viewBox='0 0 32 32'><path fill='#448aff' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#bbdefb' d='M22.069 10.463a.6.6 0 0 0-.116.003.59.59 0 0 0-.517.635v.16a3.6 3.6 0 0 0 .08.543 5.2 5.2 0 0 1 .065 1.018.6.6 0 0 1-.186.305l-.013.238a7 7 0 0 0-1.031.157 7.27 7.27 0 0 0-3.706 2.117l-.196-.145a.52.52 0 0 1-.346-.039 5.4 5.4 0 0 1-.765-.69 5 5 0 0 0-.372-.395l-.12-.093a.75.75 0 0 0-.397-.158.6.6 0 0 0-.463.197.61.61 0 0 0 .148.834l.013.013c.026.027.079.067.106.093a4 4 0 0 0 .475.277 5.4 5.4 0 0 1 .848.597.6.6 0 0 1 .106.33l.183.158a7.22 7.22 0 0 0-1.137 5.121l-.25.065a.8.8 0 0 1-.254.253 4.4 4.4 0 0 1-1.018.158 2 2 0 0 0-.543.051l-.144.029h-.013v.013c-.04 0-.08.013-.106.013a.57.57 0 1 0 .339 1.086l.004-.001a1 1 0 0 0 .174-.041 2.7 2.7 0 0 0 .488-.197 7 7 0 0 1 1.018-.292.5.5 0 0 1 .305.119l.263-.039a7.43 7.43 0 0 0 3.27 4.088l-.094.238a.7.7 0 0 1 .042.33 4.2 4.2 0 0 1-.517.913c-.106.159-.199.304-.318.462a.17.17 0 0 1-.052.148c-.013.04-.04.066-.054.106a.57.57 0 0 0 1.072.382c.027-.04.051-.132.078-.132a5 5 0 0 0 .16-.53 5 5 0 0 1 .437-1.017.45.45 0 0 1 .25-.12l.132-.237a7.4 7.4 0 0 0 5.254.013l.105.212a.5.5 0 0 1 .277.183 6 6 0 0 1 .398.954c.04.172.094.344.16.542.027 0 .051.08.078.12.013.039.028.065.041.105a.568.568 0 0 0 .984-.569l-.007-.012a1 1 0 0 1-.052-.16c-.106-.146-.212-.305-.318-.45a7.4 7.4 0 0 1-.501-.9.44.44 0 0 1 .039-.343 1 1 0 0 1-.093-.225 7.44 7.44 0 0 0 3.268-4.113c.08.013.158.025.251.038a.33.33 0 0 1 .305-.106 4.7 4.7 0 0 1 1.018.28 2.6 2.6 0 0 0 .475.196.7.7 0 0 0 .187.028v.013c0 .013.053.013.093.026a.585.585 0 0 0 .635-.491.57.57 0 0 0-.483-.645l-.008-.001a.34.34 0 0 1-.157-.067h-.543a6.6 6.6 0 0 1-1.018-.186.55.55 0 0 1-.253-.238l-.251-.064a7.2 7.2 0 0 0-1.165-5.109l.211-.184a.4.4 0 0 1 .106-.317 5 5 0 0 1 .848-.597 3.3 3.3 0 0 0 .462-.277 1 1 0 0 0 .12-.093c.039-.026.08-.053.08-.08a.556.556 0 0 0-.78-.793c-.04 0-.093.054-.133.08a10 10 0 0 0-.372.395 4.8 4.8 0 0 1-.767.69.5.5 0 0 1-.344.039l-.212.158a7.37 7.37 0 0 0-4.708-2.274l-.013-.253a.45.45 0 0 1-.186-.29 5.2 5.2 0 0 1 .065-1.018 3.6 3.6 0 0 0 .08-.543v-.292a.57.57 0 0 0-.504-.506m-.778 4.408-.16 2.977h-.013a.5.5 0 0 1-.106.28.5.5 0 0 1-.687.118h-.013l-2.434-1.734a5.75 5.75 0 0 1 2.803-1.535c.212-.04.412-.08.61-.106m1.427 0a5.9 5.9 0 0 1 3.4 1.641l-2.421 1.734h-.013a.6.6 0 0 1-.277.067.494.494 0 0 1-.516-.47v-.008Zm-5.727 2.713 2.223 2.024v.013a.34.34 0 0 1 .144.253.483.483 0 0 1-.323.602l-.02.005v.013l-2.858.822a5.9 5.9 0 0 1 .834-3.732m10.013.04a6.18 6.18 0 0 1 .86 3.679l-2.87-.822-.013-.013a.47.47 0 0 1-.238-.157.49.49 0 0 1 .042-.694l.01-.01-.013-.038Zm-5.462 2.144h.912l.568.7-.199.886-.819.398-.819-.398-.212-.886Zm-2.132 2.447h.106a.55.55 0 0 1 .504.382.5.5 0 0 1-.052.28v.038l-1.127 2.74a5.84 5.84 0 0 1-2.366-2.952Zm4.87 0h.319l2.948.475a5.85 5.85 0 0 1-2.367 2.977l-1.14-2.79a.53.53 0 0 1 .24-.662m-2.327 1.199a.51.51 0 0 1 .488.256h.013l1.442 2.607a5 5 0 0 1-.569.157 5.9 5.9 0 0 1-3.214-.157l1.442-2.607h.012c.04-.093.107-.133.2-.2a.5.5 0 0 1 .186-.056'/></svg>",
+  "folder-kusto-open": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#bbdefb' d='M25 10c-3.878 0-7 3.122-7 7v7h7c3.878 0 7-3.122 7-7s-3.122-7-7-7m3 4h2v6h-2zm-8 2h2v4h-2zm4 2h2v2h-2zm-8 2-3.996.02v2.322L12 24h4zm-4 6v4h4v-4zm6 0v4h4v-4z'/></svg>",
+  "folder-kusto": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#bbdefb' d='M25 10c-3.878 0-7 3.122-7 7v7h7c3.878 0 7-3.122 7-7s-3.122-7-7-7m3 4h2v6h-2zm-8 2h2v4h-2zm4 2h2v2h-2zm-8 2-3.996.02v2.322L12 24h4zm-4 6v4h4v-4zm6 0v4h4v-4z'/></svg>",
   "folder-layout-open": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M10 16h6v14h-6zm8 8h6v6h-6zm8 0h6v6h-6zm-8-8h14v6H18z'/></svg>",
   "folder-layout": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M10 16h6v14h-6zm8 8h6v6h-6zm8 0h6v6h-6zm-8-8h14v6H18z'/></svg>",
   "folder-lefthook-open": "<svg viewBox='0 0 32 32'><path fill='#607d8b' d='M28.97 11.998H9.444a2 2 0 0 0-1.898 1.368L4.001 24V9.998h24.003a2 2 0 0 0-2-2H15.125a2 2 0 0 1-1.28-.464L12.557 6.46a2 2 0 0 0-1.28-.464H4.002a2 2 0 0 0-2.001 2V24A2 2 0 0 0 4 26h22.003l4.806-11.214a2 2 0 0 0-1.838-2.788z'/><path fill='#f44336' d='M14 20v6h-4zm4.026-5.342-2.385.795a1.494 1.494 0 0 0-.867 2.094l.534 1.068 4.696-1.624c.014-.293-.004-.602-.004-.91a1.496 1.496 0 0 0-1.974-1.423m12.886 5.502-5.546-5.18C24.272 13.999 23.85 14 22 14v3.012a3.36 3.36 0 0 1-1.301 2.787L24 24l5.876 1.676c.606-.698.85-1.005 1.38-1.595a2.583 2.583 0 0 0-.344-3.921'/><path fill='#b71c1c' d='m10 26 4-2 4 2-4 2zm10.699-6.2a20 20 0 0 1-2.463 1.314 3.5 3.5 0 0 1-2.236.302v1.339l8.98 4.888a3.22 3.22 0 0 0 4.054-1c.333-.384.505-.582.842-.967zm-5.127-1.89 3.756-1.408a.5.5 0 0 1 .675.492 1.48 1.48 0 0 1-.832 1.42l-1.83.915c-1.399.7-2.717-1.063-1.769-1.419'/></svg>",
@@ -443,10 +453,10 @@
   "folder-next": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#cfd8dc' d='M24 12a8 8 0 1 0 3.969 14.94L22 19v4.5a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .5-.5h1.232a.5.5 0 0 1 .416.223l6.736 10.103A7.993 7.993 0 0 0 24 12m4 8h-2v-3.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5Z'/></svg>",
   "folder-ngrx-actions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#E1BEE7' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
   "folder-ngrx-actions.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#E1BEE7' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
-  "folder-ngrx-effects-open.clone": "<svg viewBox='0 0 32 32'><path fill='#00BCD4' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#E0F7FA' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
-  "folder-ngrx-effects.clone": "<svg viewBox='0 0 32 32'><path fill='#00BCD4' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#E0F7FA' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
-  "folder-ngrx-entities-open.clone": "<svg viewBox='0 0 32 32'><path fill='#FBC02D' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#FFF3E0' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
-  "folder-ngrx-entities.clone": "<svg viewBox='0 0 32 32'><path fill='#FBC02D' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#FFF3E0' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
+  "folder-ngrx-effects-open.clone": "<svg viewBox='0 0 32 32'><path fill='#00BCD4' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#B2EBF2' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
+  "folder-ngrx-effects.clone": "<svg viewBox='0 0 32 32'><path fill='#00BCD4' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#B2EBF2' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
+  "folder-ngrx-entities-open.clone": "<svg viewBox='0 0 32 32'><path fill='#FBC02D' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#FFECB3' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
+  "folder-ngrx-entities.clone": "<svg viewBox='0 0 32 32'><path fill='#FBC02D' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#FFECB3' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
   "folder-ngrx-reducer-open.clone": "<svg viewBox='0 0 32 32'><path fill='#EF5350' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#FFCDD2' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
   "folder-ngrx-reducer.clone": "<svg viewBox='0 0 32 32'><path fill='#EF5350' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#FFCDD2' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
   "folder-ngrx-selectors-open.clone": "<svg viewBox='0 0 32 32'><path fill='#FF6E40' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#FFCCBC' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
@@ -461,7 +471,7 @@
   "folder-nuxt": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#00e676' d='M22.498 27.998h6.927a1.56 1.56 0 0 0 1.127-.617 1.3 1.3 0 0 0 .188-.631 1.26 1.26 0 0 0-.188-.618l-4.685-8.053a1.14 1.14 0 0 0-.443-.443 1.5 1.5 0 0 0-.67-.188 1.29 1.29 0 0 0-1.074.63l-1.182 2.054-2.376-3.986a1.3 1.3 0 0 0-.43-.497 1.52 1.52 0 0 0-1.247 0 1.5 1.5 0 0 0-.51.497l-5.799 9.986a1.2 1.2 0 0 0-.134.618 1.24 1.24 0 0 0 .134.63 1.3 1.3 0 0 0 .497.43 1.3 1.3 0 0 0 .63.188h4.363a4.26 4.26 0 0 0 3.88-2.241l2.12-3.692 1.114-1.933 3.436 5.866h-4.564Zm-4.9-2h-3.04l4.533-7.8 2.28 3.893-1.52 2.667a2.34 2.34 0 0 1-2.267 1.24Z'/></svg>",
   "folder-obsidian-open": "<svg fill-rule='evenodd' clip-rule='evenodd' image-rendering='optimizeQuality' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' viewBox='0 0 512 512'><path fill='#673AB7' d='M463.47 192H151.06c-13.77 0-26 8.82-30.35 21.89L64 384V160h384c0-17.67-14.33-32-32-32H241.98a32 32 0 0 1-20.48-7.42l-20.6-17.15c-5.75-4.8-13-7.43-20.48-7.43H64c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h352l76.88-179.39c1.7-3.98 2.59-8.28 2.59-12.61 0-17.67-14.33-32-32-32'/><g fill='#D1C4E9'><path d='M336.2 318.24c8.07-1.51 12.6-2.02 21.66-2.02-34.18-89.72 48.95-139.27 18.63-155.11-17-8.88-52.32 37.77-72.93 56.26l-10.67 37.41c19.77 16.2 36.25 39.63 43.31 63.46m75.04 128.91c13.05 3.85 26.66-5.92 28.52-19.42 1.35-9.81 3.51-20.65 8.24-30.94-2.66-7.51-25.72-71.18-104.74-56.39 7.6 31.4-4.15 64.54-22.83 91.02 33.14.31 59.29 6.45 90.81 15.73'/><path d='M478.76 346.86c7.02-12.43-16.61-22.28-28.74-50.78-10.52-24.69 4.93-53.82-8.18-66.23l-40.17-38.02c-14.09 38.27-40.29 56.91-17.12 123.38 37.13 6.98 67.48 27.2 77.55 58.42 0 0 13.67-21.49 16.66-26.77m-221.26 5.78c-8.21 18.67 17.96 36.81 43.46 63.29 29-40.73 24.17-88.95-15.12-127.91z'/></g></svg>",
   "folder-obsidian": "<svg fill-rule='evenodd' clip-rule='evenodd' image-rendering='optimizeQuality' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' viewBox='0 0 512 512'><path fill='#673AB7' d='m221.5 120.58-20.6-17.16A32 32 0 0 0 180.42 96H64c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32V160c0-17.67-14.33-32-32-32H241.98a32 32 0 0 1-20.48-7.42'/><g fill='#D1C4E9'><path d='M336.2 318.24c8.07-1.51 12.6-2.02 21.66-2.02-34.18-89.72 48.95-139.27 18.63-155.11-17-8.88-52.32 37.77-72.93 56.26l-10.67 37.41c19.77 16.2 36.25 39.63 43.31 63.46m75.04 128.91c13.05 3.85 26.66-5.92 28.52-19.42 1.35-9.81 3.51-20.65 8.24-30.94-2.66-7.51-25.72-71.18-104.74-56.39 7.6 31.4-4.15 64.54-22.83 91.02 33.14.31 59.29 6.45 90.81 15.73'/><path d='M478.76 346.86c7.02-12.43-16.61-22.28-28.74-50.78-10.52-24.69 4.93-53.82-8.18-66.23l-40.17-38.02c-14.09 38.27-40.29 56.91-17.12 123.38 37.13 6.98 67.48 27.2 77.55 58.42 0 0 13.67-21.49 16.66-26.77m-221.26 5.78c-8.21 18.67 17.96 36.81 43.46 63.29 29-40.73 24.17-88.95-15.12-127.91z'/></g></svg>",
-  "folder-open": "<svg viewBox='0 0 32 32'><path fill='#90a4ae' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/></svg>",
+  "folder-open": "<svg viewBox='0 0 16 16'><path fill='#90a4ae' d='M14.483 6H4.721a1 1 0 0 0-.949.684L2 12V5h12a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h11l2.403-5.606A1 1 0 0 0 14.483 6'/></svg>",
   "folder-other-open": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffccbc' d='M22 10a10 10 0 1 0 10 10 10 10 0 0 0-10-10m-6 12.125a2 2 0 1 1 2-2 2 2 0 0 1-2 2m6 0a2 2 0 1 1 2-2 2 2 0 0 1-2 2m6 0a2 2 0 1 1 2-2 2 2 0 0 1-2 2'/></svg>",
   "folder-other": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffccbc' d='M22 10a10 10 0 1 0 10 10 10 10 0 0 0-10-10m-6 12.125a2 2 0 1 1 2-2 2 2 0 0 1-2 2m6 0a2 2 0 1 1 2-2 2 2 0 0 1-2 2m6 0a2 2 0 1 1 2-2 2 2 0 0 1-2 2'/></svg>",
   "folder-packages-open": "<svg viewBox='0 0 32 32'><path fill='#1e88e5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#bbdefb' d='M31.2 12.933 29.6 10.8A2 2 0 0 0 28 10h-8a2 2 0 0 0-1.6.8l-1.6 2.133a4 4 0 0 0-.8 2.4V26a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V15.333a4 4 0 0 0-.8-2.4M20 12h8l1.5 2h-11Zm6 10v4h-4v-4h-4l6-6 6 6Z'/></svg>",
@@ -500,8 +510,8 @@
   "folder-queue": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M24 16v-2h-3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2h-2v-8Zm8-2v-2h-5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-2h-4V14Zm-16 2h2v8h-2z'/></svg>",
   "folder-react-components-open": "<svg viewBox='0 0 32 32'><path fill='#00bcd4' d='M24.645 27.333H4.665A2.665 2.665 0 0 1 2 24.667v-16A2.656 2.656 0 0 1 4.646 6h8.01l2.665 2.667h9.324a2.68 2.68 0 0 1 2.664 2.666H4.664v13.334L7.514 14h22.739l-3.037 11.333a2.67 2.67 0 0 1-2.571 2'/><path fill='#b2ebf2' d='M21 18.035a1.923 1.923 0 1 1-.004 0zm-4.738 10.284c.645.395 2.057-.208 3.685-1.768q-.82-.948-1.545-1.977a23 23 0 0 1-2.456-.373c-.522 2.224-.328 3.754.316 4.116m.727-5.966-.297-.532a8 8 0 0 0-.296.894c.277.062.583.116.9.168l-.307-.532m6.692-.79L24.51 20l-.83-1.559c-.305-.55-.633-1.039-.93-1.528-.554-.032-1.137-.032-1.749-.032-.614 0-1.199 0-1.75.032-.298.489-.624.978-.932 1.528L17.49 20l.83 1.56c.307.55.633 1.04.93 1.528.554.031 1.137.031 1.75.031s1.198 0 1.75-.03c.297-.49.623-.978.93-1.53M21 14.573c-.194.23-.4.467-.603.749h1.206c-.204-.282-.408-.52-.603-.75m0 10.856c.194-.228.4-.468.603-.748h-1.206c.204.282.408.519.603.748m4.728-13.746c-.635-.395-2.047.208-3.675 1.768a25 25 0 0 1 1.545 1.975 23 23 0 0 1 2.456.375c.523-2.225.328-3.753-.326-4.116m-.717 5.967.297.53a8 8 0 0 0 .296-.895 16 16 0 0 0-.9-.165zm1.483-7.33c1.505.873 1.668 3.17 1.035 5.854C30.128 16.955 32 18.245 32 20c0 1.758-1.872 3.047-4.473 3.828.635 2.682.472 4.98-1.033 5.854-1.493.873-3.53-.126-5.493-2.029-1.966 1.903-4.002 2.902-5.507 2.029-1.493-.874-1.656-3.172-1.023-5.854C11.874 23.048 10 21.758 10 20s1.874-3.045 4.473-3.825c-.635-2.683-.472-4.981 1.023-5.855 1.503-.873 3.54.125 5.504 2.029 1.964-1.904 4-2.902 5.494-2.029M26.198 20a23 23 0 0 1 .911 2.352c2.149-.656 3.355-1.592 3.355-2.352 0-.758-1.206-1.693-3.355-2.35a24 24 0 0 1-.91 2.35m-10.397 0a24 24 0 0 1-.911-2.35c-2.148.657-3.355 1.592-3.355 2.35 0 .76 1.207 1.696 3.355 2.352a24 24 0 0 1 .91-2.352m9.21 2.352-.306.53c.316-.052.624-.104.899-.168a9 9 0 0 0-.296-.894zm-2.958 4.2c1.628 1.559 3.04 2.162 3.675 1.768.655-.364.85-1.892.326-4.118a23 23 0 0 1-2.455.375 25 25 0 0 1-1.544 1.975m-5.066-8.901.306-.53a14 14 0 0 0-.899.167 9 9 0 0 0 .296.894zm2.958-4.2c-1.628-1.56-3.04-2.162-3.685-1.768-.644.364-.84 1.892-.316 4.117a23 23 0 0 1 2.455-.375 25 25 0 0 1 1.544-1.975Z'/></svg>",
   "folder-react-components": "<svg viewBox='0 0 32 32'><path fill='#00bcd4' d='M12.656 6H4.664A2.656 2.656 0 0 0 2 8.648v16.019a2.68 2.68 0 0 0 2.664 2.666h21.313a2.68 2.68 0 0 0 2.664-2.666V11.333a2.665 2.665 0 0 0-2.664-2.666H15.321Z'/><path fill='#b2ebf2' d='M21 18.035a1.923 1.923 0 1 1-.004 0zm-4.738 10.284c.645.395 2.057-.208 3.685-1.768q-.82-.948-1.545-1.977a23 23 0 0 1-2.456-.373c-.522 2.224-.328 3.754.316 4.116m.727-5.966-.297-.532a8 8 0 0 0-.296.894c.277.062.583.116.9.168l-.307-.532m6.692-.79L24.51 20l-.83-1.559c-.305-.55-.633-1.039-.93-1.528-.554-.032-1.137-.032-1.749-.032-.614 0-1.199 0-1.75.032-.298.489-.624.978-.932 1.528L17.49 20l.83 1.56c.307.55.633 1.04.93 1.528.554.031 1.137.031 1.75.031s1.198 0 1.75-.03c.297-.49.623-.978.93-1.53M21 14.573c-.194.23-.4.467-.603.749h1.206c-.204-.282-.408-.52-.603-.75m0 10.856c.194-.228.4-.468.603-.748h-1.206c.204.282.408.519.603.748m4.728-13.746c-.635-.395-2.047.208-3.675 1.768a25 25 0 0 1 1.545 1.975 23 23 0 0 1 2.456.375c.523-2.225.328-3.753-.326-4.116m-.717 5.967.297.53a8 8 0 0 0 .296-.895 16 16 0 0 0-.9-.165zm1.483-7.33c1.505.873 1.668 3.17 1.035 5.854C30.128 16.955 32 18.245 32 20c0 1.758-1.872 3.047-4.473 3.828.635 2.682.472 4.98-1.033 5.854-1.493.873-3.53-.126-5.493-2.029-1.966 1.903-4.002 2.902-5.507 2.029-1.493-.874-1.656-3.172-1.023-5.854C11.874 23.048 10 21.758 10 20s1.874-3.045 4.473-3.825c-.635-2.683-.472-4.981 1.023-5.855 1.503-.873 3.54.125 5.504 2.029 1.964-1.904 4-2.902 5.494-2.029M26.198 20a23 23 0 0 1 .911 2.352c2.149-.656 3.355-1.592 3.355-2.352 0-.758-1.206-1.693-3.355-2.35a24 24 0 0 1-.91 2.35m-10.397 0a24 24 0 0 1-.911-2.35c-2.148.657-3.355 1.592-3.355 2.35 0 .76 1.207 1.696 3.355 2.352a24 24 0 0 1 .91-2.352m9.21 2.352-.306.53c.316-.052.624-.104.899-.168a9 9 0 0 0-.296-.894zm-2.958 4.2c1.628 1.559 3.04 2.162 3.675 1.768.655-.364.85-1.892.326-4.118a23 23 0 0 1-2.455.375 25 25 0 0 1-1.544 1.975m-5.066-8.901.306-.53a14 14 0 0 0-.899.167 9 9 0 0 0 .296.894zm2.958-4.2c-1.628-1.56-3.04-2.162-3.685-1.768-.644.364-.84 1.892-.316 4.117a23 23 0 0 1 2.455-.375 25 25 0 0 1 1.544-1.975Z'/></svg>",
-  "folder-redux-actions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
-  "folder-redux-actions.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#E1BEE7' stroke='#E1BEE7' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
+  "folder-redux-actions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
+  "folder-redux-actions.clone": "<svg viewBox='0 0 32 32'><path fill='#AB47BC' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#F3E5F5' stroke='#F3E5F5' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
   "folder-redux-reducer-open": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
   "folder-redux-reducer": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#ffcdd2' stroke='#ffcdd2' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
   "folder-redux-selector-open.clone": "<svg viewBox='0 0 32 32'><path fill='#FF6E40' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#FFCCBC' stroke='#FFCCBC' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#FFCCBC' stroke='#FFCCBC' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#FFCCBC' stroke='#FFCCBC' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
@@ -518,8 +528,8 @@
   "folder-review": "<svg viewBox='0 0 32 32'><path fill='#2196f3' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><circle cx='21' cy='21' r='3' fill='#bbdefb'/><path fill='#bbdefb' d='M21 14c-4.66 0-9.35 2.91-11 7 1.65 4.09 6.34 7 11 7s9.35-2.91 11-7c-1.65-4.09-6.34-7-11-7m0 12a5 5 0 1 1 5-5 5 5 0 0 1-5 5'/></svg>",
   "folder-robot-open": "<svg viewBox='0 0 32 32'><path fill='#ff5252' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' d='M10.5 26H12v-6h-1.5a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 .5.5M30 20v6h1.5a.5.5 0 0 0 .5-.5v-5a.5.5 0 0 0-.5-.5Zm-8.5-8h-1a.5.5 0 0 0-.5.5V16h-5.5a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5H22v-3.5a.5.5 0 0 0-.5-.5M18 18a2 2 0 1 1-2 2 2 2 0 0 1 2-2m8 8H16v-2h10Zm-2-8a2 2 0 1 1-2 2 2 2 0 0 1 2-2'/></svg>",
   "folder-robot": "<svg viewBox='0 0 32 32'><path fill='#ff5252' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffcdd2' d='M10.5 26H12v-6h-1.5a.5.5 0 0 0-.5.5v5a.5.5 0 0 0 .5.5M30 20v6h1.5a.5.5 0 0 0 .5-.5v-5a.5.5 0 0 0-.5-.5Zm-8.5-8h-1a.5.5 0 0 0-.5.5V16h-5.5a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5H22v-3.5a.5.5 0 0 0-.5-.5M18 18a2 2 0 1 1-2 2 2 2 0 0 1 2-2m8 8H16v-2h10Zm-2-8a2 2 0 1 1-2 2 2 2 0 0 1 2-2'/></svg>",
-  "folder-root-open": "<svg viewBox='0 0 32 32'><path fill='#90a4ae' d='M16 5A11 11 0 1 1 5 16 11.01 11.01 0 0 1 16 5m0-3a14 14 0 1 0 14 14A14 14 0 0 0 16 2'/></svg>",
-  "folder-root": "<svg viewBox='0 0 32 32'><path fill='#90a4ae' d='M16 5A11 11 0 1 1 5 16 11.01 11.01 0 0 1 16 5m0-3a14 14 0 1 0 14 14A14 14 0 0 0 16 2m0 8a6 6 0 1 0 6 6 6 6 0 0 0-6-6'/></svg>",
+  "folder-root-open": "<svg viewBox='0 0 16 16'><circle cx='8' cy='8' r='6' fill='none' stroke='#90a4ae' stroke-width='2'/></svg>",
+  "folder-root": "<svg viewBox='0 0 16 16'><circle cx='8' cy='8' r='6' fill='none' stroke='#90a4ae' stroke-width='2'/><circle cx='8' cy='8' r='3' fill='#90a4ae'/></svg>",
   "folder-routes-open": "<svg viewBox='0 0 32 32'><path fill='#43a047' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#c8e6c9' d='M17.414 14.586 20 12h-8v8l2.586-2.586 4.91 4.91A1.7 1.7 0 0 1 20 23.541V28h4v-4.459a5.68 5.68 0 0 0-1.676-4.045ZM29.36 12l-5.61 4.93.57.57a5.6 5.6 0 0 1 1.56 2.89L32 15.01Z'/></svg>",
   "folder-routes": "<svg viewBox='0 0 32 32'><path fill='#43a047' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#c8e6c9' d='M17.414 14.586 20 12h-8v8l2.586-2.586 4.91 4.91A1.7 1.7 0 0 1 20 23.541V28h4v-4.459a5.68 5.68 0 0 0-1.676-4.045ZM29.36 12l-5.61 4.93.57.57a5.6 5.6 0 0 1 1.56 2.89L32 15.01Z'/></svg>",
   "folder-rules-open": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' d='M30 14h-2a3 3 0 0 0-6 0h-2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V16a2 2 0 0 0-2-2m-5-1a1 1 0 1 1-1 1 1.003 1.003 0 0 1 1-1m-1.547 11.597-3.093-3.093 1.09-1.09 2.003 1.995 5.096-5.096 1.091 1.099Z'/></svg>",
@@ -644,7 +654,7 @@
   "folder-yarn": "<svg viewBox='0 0 32 32'><path fill='#0288d1' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M31.445 24.006a7.2 7.2 0 0 0-2.736 1.301 16.2 16.2 0 0 1-4.038 1.886 1.1 1.1 0 0 1-.68.394 42 42 0 0 1-4.455.413c-.805.006-1.296-.212-1.434-.554a1.14 1.14 0 0 1 .58-1.474l.02-.008a2.5 2.5 0 0 1-.357-.27c-.118-.122-.243-.368-.28-.277-.156.392-.237 1.352-.654 1.784a2.04 2.04 0 0 1-2.3.052c-.704-.386.05-1.295.05-1.295a.497.497 0 0 1-.679-.23l-.007-.015a3.56 3.56 0 0 1-.46-2.106 3.92 3.92 0 0 1 1.221-2.08 6.85 6.85 0 0 1 .455-3.144 7.4 7.4 0 0 1 2.187-2.614s-1.34-1.527-.84-2.912c.322-.903.453-.895.56-.935a2.5 2.5 0 0 0 1.003-.61 3.58 3.58 0 0 1 3.046-1.213s.8-2.53 1.546-2.035a13.3 13.3 0 0 1 1.06 2.062s.885-.535.985-.336a8.35 8.35 0 0 1 .361 4.382 10.1 10.1 0 0 1-1.795 3.863 7.9 7.9 0 0 1 1.808 2.778 8.4 8.4 0 0 1 .181 3.722l.024.044a4.44 4.44 0 0 0 2.343-.934 5.77 5.77 0 0 1 2.954-1.147.75.75 0 0 1 .873.62.775.775 0 0 1-.542.888'/></svg>",
   "folder-zeabur-open": "<svg fill='none' viewBox='0 0 32 32'><path fill='#7E57C2' d='M29 12H9.4c-.9 0-1.6.6-1.9 1.4L4 24V10h24c0-1.1-.9-2-2-2H15.1c-.5 0-.9-.2-1.3-.5l-1.3-1.1c-.3-.2-.8-.4-1.2-.4H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h22l4.8-11.2c.4-1 0-2.2-1-2.6-.3-.1-.6-.2-.8-.2'/><g fill='#D1C4E9' clip-path='url(#a)'><path d='M20 24h12v6H12v-6h6l8-4H12v-6h20v6z'/><path d='M26 14H12v6h14zm6 10H20v6h12z'/></g><defs><clipPath id='a'><path d='M12 14h20v16H12z'/></clipPath></defs></svg>",
   "folder-zeabur": "<svg fill='none' viewBox='0 0 32 32'><path fill='#7E57C2' d='m13.8 7.5-1.3-1.1c-.3-.2-.8-.4-1.2-.4H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h24c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2H15.1c-.5 0-.9-.1-1.3-.5'/><g fill='#D1C4E9' clip-path='url(#a)'><path d='M20 24h12v6H12v-6h6l8-4H12v-6h20v6z'/><path d='M26 14H12v6h14zm6 10H20v6h12z'/></g><defs><clipPath id='a'><path d='M12 14h20v16H12z'/></clipPath></defs></svg>",
-  "folder": "<svg viewBox='0 0 32 32'><path fill='#90a4ae' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/></svg>",
+  "folder": "<svg viewBox='0 0 16 16'><path fill='#90a4ae' d='m6.922 3.768-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232'/></svg>",
   "font": "<svg viewBox='0 0 32 32'><path fill='#f44336' d='M24 28h4L18 4h-4L4 28h4l8-19.422'/><path fill='#f44336' d='M8 20h16v4H8z'/></svg>",
   "forth": "<svg viewBox='0 0 67.733 67.733'><path fill='#ef5350' d='M10.321 12.006c-.21 0-.38.173-.38.39v12.63c0 .215.17.389.38.389h16.925c.21 0 .38-.174.38-.39v-12.63a.384.384 0 0 0-.38-.389zm30.167 0c-.21 0-.38.173-.38.39v12.63c0 .215.17.389.38.389h16.925c.21 0 .38-.174.38-.39v-12.63a.384.384 0 0 0-.38-.389zM10.321 34.328c-.21 0-.38.173-.38.39v12.63c0 .215.17.389.38.389h16.925c.21 0 .38-.174.38-.39v-12.63a.384.384 0 0 0-.38-.389zm30.167 0c-.21 0-.38.173-.38.39v12.63c0 .215.17.389.38.389h4.053v4.351H40.51a.374.374 0 0 0-.375.375v2.89c0 .207.167.374.375.374h8.303a.373.373 0 0 0 .374-.374v-4.135h3.798a.374.374 0 0 0 .374-.375v-3.106h4.054c.21 0 .38-.174.38-.39v-12.63a.384.384 0 0 0-.38-.389z'/></svg>",
   "fortran": "<svg viewBox='0 0 32 32'><path fill='#ff7043' d='M6 4v2h3a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6v2h12v-2h-3a1 1 0 0 1-1-1v-9h4a2 2 0 0 1 2 2v2h2V10h-2v2a2 2 0 0 1-2 2h-4V6h6a4 4 0 0 1 4 4h2V4Z'/></svg>",
@@ -738,7 +748,7 @@
   "knip": "<svg viewBox='0 0 24 24'><path fill='#EF6C00' d='m18.957 2.998-5.985 5.984 1.995 1.995 6.983-6.982v-.998m-9.975 9.477a.5.5 0 1 1 0-.998.5.5 0 0 1 0 .998M5.99 19.955a1.995 1.995 0 1 1 0-3.99 1.995 1.995 0 0 1 0 3.99m0-11.97a1.995 1.995 0 1 1 0-3.99 1.995 1.995 0 0 1 0 3.99m3.63-.36a3.9 3.9 0 0 0 .36-1.635 3.99 3.99 0 1 0-3.99 3.99c.589 0 1.137-.13 1.636-.36l2.354 2.355-2.354 2.354a3.9 3.9 0 0 0-1.636-.359 3.99 3.99 0 1 0 3.99 3.99c0-.588-.13-1.137-.36-1.636l2.355-2.354 6.982 6.982h2.993v-.997z'/></svg>",
   "kotlin": "<svg viewBox='0 0 24 24'><defs><linearGradient id='a' x1='1.725' x2='22.185' y1='22.67' y2='1.982' gradientTransform='translate(1.306 1.129)scale(.89324)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#7C4DFF'/><stop offset='.5' stop-color='#D500F9'/><stop offset='1' stop-color='#EF5350'/></linearGradient></defs><path fill='url(#a)' d='M2.975 2.976v18.048h18.05v-.03l-4.478-4.511-4.48-4.515 4.48-4.515 4.443-4.477z'/></svg>",
   "kubernetes": "<svg viewBox='0 0 24 24'><path fill='#448aff' d='M12.074 1.424a.638.638 0 0 0-.686.691v.173c.015.2.044.402.087.588.058.358.085.73.07 1.102a.65.65 0 0 1-.201.33l-.014.258a7 7 0 0 0-1.117.17 7.9 7.9 0 0 0-4.012 2.292l-.213-.157a.56.56 0 0 1-.374-.042 6 6 0 0 1-.829-.747c-.129-.143-.26-.299-.403-.428l-.128-.1a.8.8 0 0 0-.431-.171c-.2 0-.372.07-.501.212-.2.301-.127.675.16.904l.013.014c.03.029.087.072.115.1q.258.172.515.3c.33.186.631.403.918.647a.63.63 0 0 1 .114.358l.2.17a7.82 7.82 0 0 0-1.232 5.546l-.271.07a.84.84 0 0 1-.275.274c-.358.086-.73.17-1.102.17-.186 0-.387 0-.588.057l-.156.03h-.014v.015c-.043 0-.086.014-.115.014a.62.62 0 0 0-.4.789.625.625 0 0 0 .772.386 1 1 0 0 0 .188-.045c.186-.057.37-.127.528-.213a7.4 7.4 0 0 1 1.103-.316c.114 0 .244.057.33.129l.285-.042a8.04 8.04 0 0 0 3.54 4.426l-.1.258a.8.8 0 0 1 .044.358c-.143.344-.33.687-.56.987-.114.172-.215.33-.344.501 0 .043.001.117-.056.16-.014.043-.044.072-.059.114a.615.615 0 0 0 .372.787.62.62 0 0 0 .79-.372c.028-.043.055-.143.083-.143.072-.2.131-.387.174-.574a5.4 5.4 0 0 1 .473-1.102.5.5 0 0 1 .271-.129l.143-.257c1.82.702 3.84.701 5.688.014l.115.23a.53.53 0 0 1 .3.198c.186.33.301.674.43 1.032.043.187.102.373.174.588.028 0 .055.086.084.129.014.043.03.071.044.114a.61.61 0 0 0 .845.216.614.614 0 0 0 .213-.845c-.014-.057-.056-.13-.056-.174-.115-.157-.23-.329-.344-.486-.215-.316-.371-.63-.543-.974a.48.48 0 0 1 .042-.372 1.2 1.2 0 0 1-.1-.244c1.661-1.002 2.951-2.577 3.539-4.454.086.014.17.028.271.042.086-.115.201-.115.33-.115.387.057.73.16 1.103.302q.235.128.514.213c.058.014.116.03.202.03v.015c0 .014.058.013.1.028.344.043.617-.202.689-.532a.617.617 0 0 0-.532-.7c-.057-.014-.127-.03-.17-.072h-.588a7 7 0 0 1-1.102-.202.6.6 0 0 1-.274-.257l-.272-.07a7.8 7.8 0 0 0-1.262-5.531l.23-.2a.44.44 0 0 1 .114-.343c.273-.244.589-.46.918-.647a3.6 3.6 0 0 0 .5-.3 1 1 0 0 0 .13-.1c.043-.028.086-.058.086-.087.258-.243.273-.63 0-.859-.214-.257-.601-.257-.845 0-.043 0-.1.059-.142.087a11 11 0 0 0-.403.428c-.244.272-.53.532-.831.747a.55.55 0 0 1-.372.042l-.23.171a7.98 7.98 0 0 0-5.098-2.462l-.014-.274a.5.5 0 0 1-.201-.314 5.6 5.6 0 0 1 .07-1.102 4 4 0 0 0 .087-.588v-.316a.62.62 0 0 0-.546-.548m-.842 4.773-.174 3.223h-.014a.56.56 0 0 1-.114.302.543.543 0 0 1-.745.13h-.014L7.536 7.973a6.23 6.23 0 0 1 3.035-1.662c.23-.043.446-.086.66-.115zm1.544 0a6.38 6.38 0 0 1 3.682 1.777L13.837 9.85h-.014a.66.66 0 0 1-.3.073.535.535 0 0 1-.56-.518zm-6.2 2.938 2.406 2.19v.015c.086.071.157.16.157.274a.523.523 0 0 1-.372.657v.014l-3.095.89a6.4 6.4 0 0 1 .904-4.04m10.842.042c.73 1.189 1.032 2.595.932 3.984l-3.109-.89-.014-.014a.5.5 0 0 1-.257-.17.53.53 0 0 1 .056-.761l-.014-.042zm-5.915 2.322h.988l.615.758-.215.96-.887.431-.887-.43-.23-.96zm-2.308 2.65h.115c.243 0 .46.17.545.414 0 .1.001.23-.056.302v.042l-1.22 2.966a6.33 6.33 0 0 1-2.563-3.195zm5.274 0h.344l3.193.515a6.34 6.34 0 0 1-2.563 3.223l-1.234-3.022c-.115-.258.002-.558.26-.716m-2.521 1.298a.55.55 0 0 1 .529.277h.014l1.561 2.823a5 5 0 0 1-.615.171 6.4 6.4 0 0 1-3.481-.17l1.561-2.824h.014c.043-.1.115-.144.216-.215a.5.5 0 0 1 .201-.062'/></svg>",
-  "kusto": "<svg viewBox='0 0 318 315'><path fill='#1e88e5' d='M39.778 280.589c-4.91-2.139-4.99-2.852-4.99-34.058v-28.118H97.36v63.364H69.876c-21.702-.08-28.118-.317-30.098-1.188m69.462-30.494v-31.682h62.573v63.364H109.24zm-.791-89.027c0-51.72.158-54.414 4.435-67.958 4.119-13.068 11.802-25.424 21.94-35.246 16.079-15.603 35.009-23.682 57.582-24.553 16.633-.634 29.702 2.217 43.959 9.504 52.117 26.93 62.968 98.531 21.306 140.272-14.653 14.653-33.187 23.128-54.572 25.03-4.753.395-28.039.791-51.642.791H108.45zm61.78-15.92v-35.246H140.13v70.492h30.098zm40.394 10.297v-24.95h-30.098v49.9h30.098zm40.395-20.198V90.102H220.92v90.293h30.098zm-216.23 40.791V143.96H97.36v64.156H34.788z'/></svg>",
+  "kusto": "<svg viewBox='0 0 16 16'><path fill='#1e88e5' d='M10 1C7.23 1 5 3.23 5 6v5h5c2.77 0 5-2.23 5-5s-2.23-5-5-5m1.5 3H13v5h-1.5zm-5 1H8v4H6.5zM9 6h1.5v3H9zM1 8v3h3V8zm0 4v2.498a.5.5 0 0 0 .502.502H4v-3zm4 0v3h3v-3z'/></svg>",
   "label": "<svg viewBox='0 0 16 16'><path fill='#ffb300' d='m14.709 8.558-7.27-7.247a1 1 0 0 0-.893-.297l-4 .731c-.399.074-.714.38-.8.777l-.732 4.024c-.055.328.057.662.297.892l7.247 7.27c.393.39 1.025.39 1.417 0l4.734-4.733a1.006 1.006 0 0 0 0-1.417m-8.981-2.8c-1.434 1.554-3.65-.764-2.117-2.214 1.411-1.378 3.467.704 2.15 2.178z'/></svg>",
   "laravel": "<svg viewBox='0 0 32 32'><path fill='#ff5252' d='M31.963 9.12c-.008-.03-.023-.056-.034-.085a1 1 0 0 0-.07-.156 2 2 0 0 0-.162-.205 1 1 0 0 0-.088-.072 1 1 0 0 0-.083-.068l-.044-.02-.035-.024-6-3a1 1 0 0 0-.894 0l-6 3-.035.024-.044.02a1 1 0 0 0-.083.068.7.7 0 0 0-.187.191 1 1 0 0 0-.064.086 1 1 0 0 0-.069.156c-.01.029-.026.055-.034.085a1 1 0 0 0-.037.265v5.382l-4 2V5.385a1 1 0 0 0-.037-.265c-.008-.03-.023-.056-.034-.085a1 1 0 0 0-.07-.156 1 1 0 0 0-.063-.086.7.7 0 0 0-.187-.191 1 1 0 0 0-.083-.068l-.044-.02-.035-.024-6-3a1 1 0 0 0-.894 0l-6 3-.035.024-.044.02a1 1 0 0 0-.083.068 1 1 0 0 0-.088.072 1 1 0 0 0-.1.119 1 1 0 0 0-.063.086 1 1 0 0 0-.069.156c-.01.029-.026.055-.034.085A1 1 0 0 0 0 5.385v19a1 1 0 0 0 .553.894l6 3 6 3c.014.007.03.005.046.011a.9.9 0 0 0 .802 0c.015-.006.032-.004.046-.01l12-6a1 1 0 0 0 .553-.895v-5.382l5.447-2.724a1 1 0 0 0 .553-.894v-6a1 1 0 0 0-.037-.265M9.236 21.385l4.211-2.106h.001L19 16.503l3.764 1.882L13 23.267ZM24 13.003v3.764l-4-2v-3.764Zm1-5.5 3.764 1.882L25 11.267l-3.764-1.882ZM8 19.767V9.003l4-2v10.764ZM7 3.503l3.764 1.882L7 7.267 3.236 5.385Zm-5 3.5 4 2v16.764l-4-2Zm6 16 4 2v3.764l-4-2Zm16 .764-10 5v-3.764l10-5Zm6-9-4 2v-3.764l4-2Z'/></svg>",
   "lefthook": "<svg viewBox='0 0 32 32'><path fill='#f44336' d='M6 16v6H2zm5.106-6.537-3.317 1.775a2.22 2.22 0 0 0-.895 2.873l.333.71L14 11.571v-.193a2.006 2.006 0 0 0-2.894-1.915m18.82 7.545a2 2 0 0 0-.393-.744l-7.89-8.883a2.76 2.76 0 0 0-3.138-.384L16 8v4.559a3.97 3.97 0 0 1-1.566 3.18L16 20l8.457 2.204 4.624-2.979a2 2 0 0 0 .845-2.217'/><path fill='#b71c1c' fill-rule='evenodd' d='m2 22 4-2 4 2-4 2zm12.434-6.262a6 6 0 0 1-1.194.695l-2.544 1.136A6.55 6.55 0 0 1 8 18v.764l9.71 4.855a4.05 4.05 0 0 0 2.343.366 7.8 7.8 0 0 0 2.667-.82 24 24 0 0 0 1.737-.96zm-6.97-1.635 5.829-2.937a.5.5 0 0 1 .712.475c.007.417-.005.871-.005 1.153a2.1 2.1 0 0 1-1.367 2.03l-2.987 1.067c-1.629.581-3.103-1.324-2.182-1.788'/></svg>",
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index af366868b1..da7aef22d5 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -3238,8 +3238,6 @@ config.ssh_domain=Doména SSH serveru
 config.ssh_port=Port
 config.ssh_listen_port=Port pro naslouchání
 config.ssh_root_path=Kořenová cesta
-config.ssh_key_test_path=Cesta testu klíčů
-config.ssh_keygen_path=Cesta ke generátoru klíčů ('ssh-keygen')
 config.ssh_minimum_key_size_check=Kontrola minimální velikosti klíčů
 config.ssh_minimum_key_sizes=Minimální velikost klíčů
 
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index 50ade526ff..57f1c01404 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -3235,8 +3235,6 @@ config.ssh_domain=SSH-Server-Domain
 config.ssh_port=Port
 config.ssh_listen_port=Listen-Port
 config.ssh_root_path=Wurzelverzeichnis
-config.ssh_key_test_path=Schlüssel-Test-Pfad
-config.ssh_keygen_path=Keygen-Pfad („ssh-keygen“)
 config.ssh_minimum_key_size_check=Prüfung der Mindestschlüssellänge
 config.ssh_minimum_key_sizes=Mindestschlüssellängen
 
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index 960e3b1581..c1e2f35abc 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -2927,8 +2927,6 @@ config.ssh_domain=Domain Διακομιστή SSH
 config.ssh_port=Θύρα
 config.ssh_listen_port=Θύρα Ακρόασης
 config.ssh_root_path=Ριζική Διαδρομή
-config.ssh_key_test_path=Διαδρομή Δοκιμής Κλειδιού
-config.ssh_keygen_path=Διαδρομή Keygen ('ssh-keygen')
 config.ssh_minimum_key_size_check=Έλεγχος Ελάχιστου Μεγέθους Κλειδιού
 config.ssh_minimum_key_sizes=Ελάχιστα Μεγέθη Κλειδιών
 
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 96c99615f5..d7da975a21 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -3287,8 +3287,6 @@ config.ssh_domain = SSH Server Domain
 config.ssh_port = Port
 config.ssh_listen_port = Listen Port
 config.ssh_root_path = Root Path
-config.ssh_key_test_path = Key Test Path
-config.ssh_keygen_path = Keygen ('ssh-keygen') Path
 config.ssh_minimum_key_size_check = Minimum Key Size Check
 config.ssh_minimum_key_sizes = Minimum Key Sizes
 
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 280c735c79..82d2e2a3b9 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -2907,8 +2907,6 @@ config.ssh_domain=Dominio del servidor SSH
 config.ssh_port=Puerto
 config.ssh_listen_port=Puerto de escucha
 config.ssh_root_path=Ruta raíz
-config.ssh_key_test_path=Ruta de la clave de prueba
-config.ssh_keygen_path=Ruta del generador de claves ('ssh-keygen')
 config.ssh_minimum_key_size_check=Tamaño mínimo de la clave de verificación
 config.ssh_minimum_key_sizes=Tamaños de clave mínimos
 
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index c7bef6e6dc..b550916fb0 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -2279,8 +2279,6 @@ config.ssh_domain=دامنه سرور SSH
 config.ssh_port=درگاه (پورت)
 config.ssh_listen_port=گوش دادن به پورت
 config.ssh_root_path=مسیر ریشه
-config.ssh_key_test_path=مسیر کلید آزمایش
-config.ssh_keygen_path=مسیر فایل ssh-keygen
 config.ssh_minimum_key_size_check=بررسی حداقل طول کلید
 config.ssh_minimum_key_sizes=حداقل اندازه‌ی کلید ها
 
diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini
index e853273375..69cee090fe 100644
--- a/options/locale/locale_fi-FI.ini
+++ b/options/locale/locale_fi-FI.ini
@@ -1538,8 +1538,6 @@ config.ssh_enabled=Käytössä
 config.ssh_port=Portti
 config.ssh_listen_port=Kuuntele porttia
 config.ssh_root_path=Juuren polku
-config.ssh_key_test_path=Polku jossa avaimet testataan
-config.ssh_keygen_path=Keygen ('ssh-keygen') polku
 config.ssh_minimum_key_size_check=Avaimen vähimmäiskoko tarkistus
 config.ssh_minimum_key_sizes=Avaimen vähimmäiskoot
 
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index db70eaf66a..6e0f0aab46 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -1707,11 +1707,11 @@ issues.start_tracking_history=`a commencé son travail %s.`
 issues.tracker_auto_close=Le minuteur sera automatiquement arrêté quand le ticket sera fermé.
 issues.tracking_already_started=`Vous avez déjà un minuteur en cours sur <a href="%s">un autre ticket</a> !`
 issues.stop_tracking=Arrêter le minuteur
-issues.stop_tracking_history=a travaillé sur <b>%[1]s</b> %[2]s
+issues.stop_tracking_history=a travaillé <b>%[1]s</b> %[2]s
 issues.cancel_tracking=Abandonner
 issues.cancel_tracking_history=`a abandonné son minuteur %s.`
 issues.del_time=Supprimer ce minuteur du journal
-issues.add_time_history=a pointé du temps de travail sur <b>%[1]s</b>, %[2]s
+issues.add_time_history=a pointé <b>%[1]s</b> de travail %[2]s.
 issues.del_time_history=`a supprimé son temps de travail %s.`
 issues.add_time_manually=Temps pointé manuellement
 issues.add_time_hours=Heures
@@ -3274,8 +3274,6 @@ config.ssh_domain=Domaine du serveur SSH
 config.ssh_port=Port
 config.ssh_listen_port=Port d'écoute
 config.ssh_root_path=Emplacement racine
-config.ssh_key_test_path=Chemin de test des clés
-config.ssh_keygen_path=Chemin vers le générateur de clés (« ssh-keygen »)
 config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale
 config.ssh_minimum_key_sizes=Tailles de clé minimales
 
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index f2e5de942a..a65ed357b1 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -3282,8 +3282,6 @@ config.ssh_domain=Fearainn Freastalaí SSH
 config.ssh_port=Calafort
 config.ssh_listen_port=Éist Calafort
 config.ssh_root_path=Cosán Fréimhe
-config.ssh_key_test_path=Cosán Tástáil Eochair
-config.ssh_keygen_path=Keygen ('ssh-keygen') Cosán
 config.ssh_minimum_key_size_check=Seiceáil Íosta Méid Eochair
 config.ssh_minimum_key_sizes=Méideanna Íosta Eochrach
 
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index a57d6960dd..9be048c42f 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -1412,8 +1412,6 @@ config.ssh_start_builtin_server=Beépített szerver használata
 config.ssh_port=Port
 config.ssh_listen_port=Figyelő port
 config.ssh_root_path=Gyökérkönyvtár
-config.ssh_key_test_path=Kulcs ellenőrzés útvonala
-config.ssh_keygen_path=Kulcsgeneráló ('ssh-keygen') elérési útja
 config.ssh_minimum_key_size_check=Kulcsok minimum méretének ellenőrzése
 config.ssh_minimum_key_sizes=Minimális kulcsok méretek
 
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index c54bfbb924..9e2244c1ab 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -1219,8 +1219,6 @@ config.ssh_enabled=Aktif
 config.ssh_port=Port
 config.ssh_listen_port=Listen Port
 config.ssh_root_path=Path Induk
-config.ssh_key_test_path=Path Key Test
-config.ssh_keygen_path=Path Keygen ('ssh-keygen')
 config.ssh_minimum_key_size_check=Periksa ukuran kunci minimum
 config.ssh_minimum_key_sizes=Ukuran kunci minimum
 
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 810f1040f5..73d1762c59 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -2464,8 +2464,6 @@ config.ssh_domain=Dominio Server Ssh
 config.ssh_port=Porta
 config.ssh_listen_port=Porta in ascolto
 config.ssh_root_path=Percorso Root
-config.ssh_key_test_path=Percorso chiave di test
-config.ssh_keygen_path=Percorso Keygen ('ssh-keygen')
 config.ssh_minimum_key_size_check=Verifica delle dimensioni minime della chiave
 config.ssh_minimum_key_sizes=Dimensioni minime della chiave
 
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 4fe3a2ef60..e98c453744 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -3272,8 +3272,6 @@ config.ssh_domain=SSHサーバーのドメイン
 config.ssh_port=ポート
 config.ssh_listen_port=待受ポート
 config.ssh_root_path=ルートパス
-config.ssh_key_test_path=キーテストパス
-config.ssh_keygen_path=キージェネレータ('ssh-keygen')パス
 config.ssh_minimum_key_size_check=最小キー長のチェック
 config.ssh_minimum_key_sizes=最小キー長
 
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index ddb80dde1d..b6b9cf373e 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -1372,8 +1372,6 @@ config.ssh_start_builtin_server=빌트-인 서버 사용
 config.ssh_port=포트
 config.ssh_listen_port=수신 대기 포트
 config.ssh_root_path=최상위 경로
-config.ssh_key_test_path=주 테스트 경로
-config.ssh_keygen_path=키 생성 ('ssh-keygen') 경로
 config.ssh_minimum_key_size_check=최소 키 사이즈 검사
 config.ssh_minimum_key_sizes=최소 키 사이즈
 
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 42c12def23..fa6736df1a 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -2930,8 +2930,6 @@ config.ssh_domain=SSH servera domēns
 config.ssh_port=Ports
 config.ssh_listen_port=Klausīšanās ports
 config.ssh_root_path=Saknes ceļš
-config.ssh_key_test_path=Atslēgu pārbaudes ceļš
-config.ssh_keygen_path=Keygen ('ssh-keygen') ceļš
 config.ssh_minimum_key_size_check=Minimālā atslēgas lieluma pārbaude
 config.ssh_minimum_key_sizes=Minimālais atslēgas lielums
 
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index 0ad14807d6..345990b532 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -2310,8 +2310,6 @@ config.ssh_start_builtin_server=Gebruik de ingebouwde server
 config.ssh_port=Poort
 config.ssh_listen_port=Luister op poort
 config.ssh_root_path=Root-pad
-config.ssh_key_test_path=Pad voor key-tests
-config.ssh_keygen_path=Pad van keygen ('ssh-keygen')
 config.ssh_minimum_key_size_check=Controleer minimale key-lengte
 config.ssh_minimum_key_sizes=Minimale key-lengtes
 
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index 9673db2a71..30c08bc6db 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -2198,8 +2198,6 @@ config.ssh_start_builtin_server=Wykorzystaj wbudowany serwer
 config.ssh_port=Port
 config.ssh_listen_port=Port nasłuchiwania
 config.ssh_root_path=Ścieżka do katalogu głównego
-config.ssh_key_test_path=Ścieżka do klucza testowego
-config.ssh_keygen_path=Ścieżka do generatora ('ssh-keygen')
 config.ssh_minimum_key_size_check=Sprawdzanie minimalnej długości klucza
 config.ssh_minimum_key_sizes=Minimalne rozmiary kluczy
 
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index 204fedc311..3dcbdf87aa 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -2878,8 +2878,6 @@ config.ssh_domain=Domínio do servidor SSH
 config.ssh_port=Porta
 config.ssh_listen_port=Porta de escuta
 config.ssh_root_path=Caminho da raiz
-config.ssh_key_test_path=Caminho da chave de teste
-config.ssh_keygen_path=Caminho do keygen ('ssh-keygen')
 config.ssh_minimum_key_size_check=Verificar tamanho mínimo da chave
 config.ssh_minimum_key_sizes=Tamanhos mínimos da chave
 
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 4beeeb5b0d..fb91a76f02 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -3286,8 +3286,6 @@ config.ssh_domain=Domínio do servidor SSH
 config.ssh_port=Porto
 config.ssh_listen_port=Porto de escuta
 config.ssh_root_path=Localização base
-config.ssh_key_test_path=Localização do teste das chaves
-config.ssh_keygen_path=Localização do gerador de chaves ('ssh-keygen')
 config.ssh_minimum_key_size_check=Verificação de tamanho mínimo da chave
 config.ssh_minimum_key_sizes=Tamanhos mínimos da chave
 
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 68246ff751..ae3c9a4ed9 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -2870,8 +2870,6 @@ config.ssh_domain=Домен SSH сервера
 config.ssh_port=Порт
 config.ssh_listen_port=Прослушиваемый порт
 config.ssh_root_path=Корневой путь
-config.ssh_key_test_path=Путь к тестовому ключу
-config.ssh_keygen_path=Путь к генератору ключей ('ssh-keygen')
 config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
 config.ssh_minimum_key_sizes=Минимальные размеры ключа
 
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index 7c95b254e8..fbeea4591c 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -2240,8 +2240,6 @@ config.ssh_domain=SSH සේවාදායකය වසම්
 config.ssh_port=වරාය
 config.ssh_listen_port=සවන් වරාය
 config.ssh_root_path=මූල මාර්ගය
-config.ssh_key_test_path=ප්රධාන ටෙස්ට් මාර්ගය
-config.ssh_keygen_path=Keygen ('ssh-keygen') මාර්ගය
 config.ssh_minimum_key_size_check=අවම කී ප්රමාණය පරීක්ෂා
 config.ssh_minimum_key_sizes=අවම යතුරෙහි ප්‍රමාණ
 
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index 92917c103a..5a3091adac 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -1794,8 +1794,6 @@ config.ssh_start_builtin_server=Använd inbyggd Server
 config.ssh_port=Port
 config.ssh_listen_port=Lyssningsport
 config.ssh_root_path=Rotsökväg
-config.ssh_key_test_path=Testsökväg för nyckel
-config.ssh_keygen_path=Sökväg för nyckelgenerator ('ssh-keygen')
 config.ssh_minimum_key_size_check=Kontroll av minsta tillåtna nyckelstorlek
 config.ssh_minimum_key_sizes=Minsta tillåtna nyckelstorlek
 
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index faf442431b..bec38b2ed1 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -3106,8 +3106,6 @@ config.ssh_domain=SSH Sunucusu Alan Adı
 config.ssh_port=Bağlantı Noktası
 config.ssh_listen_port=Port'u Dinle
 config.ssh_root_path=Kök Yol
-config.ssh_key_test_path=Anahtar Test Yolu
-config.ssh_keygen_path=Keygen ('ssh-keygen') Yolu
 config.ssh_minimum_key_size_check=Minimum Anahtar Uzunluğu Kontrolü
 config.ssh_minimum_key_sizes=Minimum Anahtar Uzunlukları
 
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index 995de50b61..2aae533e7e 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -2290,8 +2290,6 @@ config.ssh_domain=Домен SSH сервера
 config.ssh_port=Порт
 config.ssh_listen_port=Порт що прослуховується
 config.ssh_root_path=Шлях до кореню
-config.ssh_key_test_path=Шлях до тестового ключа
-config.ssh_keygen_path=Шлях до генератора ключів ('ssh-keygen')
 config.ssh_minimum_key_size_check=Мінімальний розмір ключа перевірки
 config.ssh_minimum_key_sizes=Мінімальні розміри ключів
 
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 7f15c32304..85f5b08a42 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -3221,8 +3221,6 @@ config.ssh_domain=SSH 服务器域名
 config.ssh_port=端口
 config.ssh_listen_port=监听端口
 config.ssh_root_path=根目录
-config.ssh_key_test_path=密钥测试路径
-config.ssh_keygen_path=密钥生成器('ssh-keygen')路径
 config.ssh_minimum_key_size_check=密钥最小长度检查
 config.ssh_minimum_key_sizes=密钥最小长度限制
 
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index ae6c6c3552..73602fe36a 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -816,8 +816,6 @@ config.ssh_enabled=已啟用
 config.ssh_port=埠
 config.ssh_listen_port=監聽埠
 config.ssh_root_path=根路徑
-config.ssh_key_test_path=金鑰測試路徑
-config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
 config.ssh_minimum_key_size_check=金鑰最小大小檢查
 config.ssh_minimum_key_sizes=金鑰最小大小
 
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index 374ff073f2..343fb401c8 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -3211,8 +3211,6 @@ config.ssh_domain=SSH 伺服器域名
 config.ssh_port=連接埠
 config.ssh_listen_port=監聽埠
 config.ssh_root_path=根路徑
-config.ssh_key_test_path=金鑰測試路徑
-config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
 config.ssh_minimum_key_size_check=金鑰最小大小檢查
 config.ssh_minimum_key_sizes=金鑰最小大小
 
diff --git a/package-lock.json b/package-lock.json
index c347cf5fd8..e516dcd91a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,12 +16,12 @@
         "@primer/octicons": "19.15.1",
         "@silverwind/vue3-calendar-heatmap": "2.0.6",
         "add-asset-webpack-plugin": "3.0.0",
-        "ansi_up": "6.0.2",
+        "ansi_up": "6.0.5",
         "asciinema-player": "3.9.0",
         "chart.js": "4.4.8",
         "chartjs-adapter-dayjs-4": "1.0.4",
         "chartjs-plugin-zoom": "2.2.0",
-        "clippie": "4.1.5",
+        "clippie": "4.1.6",
         "cropperjs": "1.6.2",
         "css-loader": "7.1.2",
         "dayjs": "1.11.13",
@@ -35,7 +35,7 @@
         "jquery": "3.7.1",
         "katex": "0.16.21",
         "license-checker-webpack-plugin": "0.2.1",
-        "mermaid": "11.5.0",
+        "mermaid": "11.6.0",
         "mini-css-extract-plugin": "2.9.2",
         "minimatch": "10.0.1",
         "monaco-editor": "0.52.2",
@@ -46,14 +46,14 @@
         "postcss-loader": "8.1.1",
         "postcss-nesting": "13.0.1",
         "sortablejs": "1.15.6",
-        "swagger-ui-dist": "5.20.1",
+        "swagger-ui-dist": "5.20.7",
         "tailwindcss": "3.4.17",
         "throttle-debounce": "5.0.2",
         "tinycolor2": "1.6.0",
         "tippy.js": "6.3.7",
         "toastify-js": "1.12.0",
         "tributejs": "5.1.3",
-        "typescript": "5.8.2",
+        "typescript": "5.8.3",
         "uint8-to-base64": "0.2.0",
         "vanilla-colorful": "0.7.2",
         "vue": "3.5.13",
@@ -80,15 +80,15 @@
         "@types/throttle-debounce": "5.0.2",
         "@types/tinycolor2": "1.4.6",
         "@types/toastify-js": "1.12.3",
-        "@typescript-eslint/eslint-plugin": "8.26.1",
-        "@typescript-eslint/parser": "8.26.1",
-        "@vitejs/plugin-vue": "5.2.1",
-        "@vitest/eslint-plugin": "1.1.37",
+        "@typescript-eslint/eslint-plugin": "8.29.1",
+        "@typescript-eslint/parser": "8.29.1",
+        "@vitejs/plugin-vue": "5.2.3",
+        "@vitest/eslint-plugin": "1.1.39",
         "eslint": "8.57.0",
-        "eslint-import-resolver-typescript": "3.9.0",
+        "eslint-import-resolver-typescript": "4.3.2",
         "eslint-plugin-array-func": "4.0.0",
         "eslint-plugin-github": "5.0.2",
-        "eslint-plugin-import-x": "4.7.2",
+        "eslint-plugin-import-x": "4.10.2",
         "eslint-plugin-no-jquery": "3.1.1",
         "eslint-plugin-no-use-extend-native": "0.5.0",
         "eslint-plugin-playwright": "2.2.0",
@@ -97,23 +97,23 @@
         "eslint-plugin-unicorn": "56.0.1",
         "eslint-plugin-vue": "10.0.0",
         "eslint-plugin-vue-scoped-css": "2.9.0",
-        "eslint-plugin-wc": "2.2.1",
+        "eslint-plugin-wc": "3.0.0",
         "happy-dom": "17.4.4",
         "markdownlint-cli": "0.44.0",
-        "material-icon-theme": "5.20.0",
+        "material-icon-theme": "5.21.1",
         "nolyfill": "1.0.44",
         "postcss-html": "1.8.0",
-        "stylelint": "16.16.0",
-        "stylelint-config-recommended": "15.0.0",
+        "stylelint": "16.18.0",
+        "stylelint-config-recommended": "16.0.0",
         "stylelint-declaration-block-no-ignored-properties": "2.8.0",
         "stylelint-declaration-strict-value": "1.10.11",
-        "stylelint-define-config": "16.15.0",
+        "stylelint-define-config": "16.17.0",
         "stylelint-value-no-unknown-custom-properties": "6.0.1",
         "svgo": "3.3.2",
-        "type-fest": "4.37.0",
+        "type-fest": "4.39.1",
         "updates": "16.4.2",
         "vite-string-plugin": "1.4.4",
-        "vitest": "3.0.8",
+        "vitest": "3.1.1",
         "vue-tsc": "2.2.8"
       },
       "engines": {
@@ -521,9 +521,9 @@
       }
     },
     "node_modules/@emnapi/core": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz",
-      "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.0.tgz",
+      "integrity": "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==",
       "dev": true,
       "license": "MIT",
       "optional": true,
@@ -533,9 +533,9 @@
       }
     },
     "node_modules/@emnapi/runtime": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
-      "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz",
+      "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==",
       "dev": true,
       "license": "MIT",
       "optional": true,
@@ -1540,24 +1540,24 @@
       }
     },
     "node_modules/@mermaid-js/parser": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz",
-      "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.4.0.tgz",
+      "integrity": "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==",
       "license": "MIT",
       "dependencies": {
-        "langium": "3.0.0"
+        "langium": "3.3.1"
       }
     },
     "node_modules/@napi-rs/wasm-runtime": {
-      "version": "0.2.7",
-      "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.7.tgz",
-      "integrity": "sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==",
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.8.tgz",
+      "integrity": "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==",
       "dev": true,
       "license": "MIT",
       "optional": true,
       "dependencies": {
-        "@emnapi/core": "^1.3.1",
-        "@emnapi/runtime": "^1.3.1",
+        "@emnapi/core": "^1.4.0",
+        "@emnapi/runtime": "^1.4.0",
         "@tybys/wasm-util": "^0.9.0"
       }
     },
@@ -1596,16 +1596,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/@nolyfill/is-core-module": {
-      "version": "1.0.39",
-      "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
-      "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.4.0"
-      }
-    },
     "node_modules/@nolyfill/shared": {
       "version": "1.0.44",
       "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.44.tgz",
@@ -1613,163 +1603,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/@oxc-resolver/binding-darwin-arm64": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-5.0.0.tgz",
-      "integrity": "sha512-zwHAf+owoxSWTDD4dFuwW+FkpaDzbaL30H5Ltocb+RmLyg4WKuteusRLKh5Y8b/cyu7UzhxM0haIqQjyqA1iuA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-darwin-x64": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-5.0.0.tgz",
-      "integrity": "sha512-1lS3aBNVjVQKBvZdHm13+8tSjvu2Tl1Cv4FnUyMYxqx6+rsom2YaOylS5LhDUwfZu0zAgpLMwK6kGpF/UPncNg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-freebsd-x64": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-5.0.0.tgz",
-      "integrity": "sha512-q9sRd68wC1/AJ0eu6ClhxlklVfe8gH4wrUkSyEbIYTZ8zY5yjsLY3fpqqsaCvWJUx65nW+XtnAxCGCi5AXr1Mw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-5.0.0.tgz",
-      "integrity": "sha512-catYavWsvqViYnCveQjhrK6yVYDEPFvIOgGLxnz5r2dcgrjpmquzREoyss0L2QG/J5HTTbwqwZ1kk+g56hE/1A==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-linux-arm64-gnu": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-5.0.0.tgz",
-      "integrity": "sha512-l/0pWoQM5kVmJLg4frQ1mKZOXgi0ex/hzvFt8E4WK2ifXr5JgKFUokxsb/oat7f5YzdJJh5r9p+qS/t3dA26Aw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-linux-arm64-musl": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-5.0.0.tgz",
-      "integrity": "sha512-bx0oz/oaAW4FGYqpIIxJCnmgb906YfMhTEWCJvYkxjpEI8VKLJEL3PQevYiqDq36SA0yRLJ/sQK2fqry8AFBfA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-linux-x64-gnu": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-5.0.0.tgz",
-      "integrity": "sha512-4PH++qbSIhlRsFYdN1P9neDov4OGhTGo5nbQ1D7AL6gWFLo3gdZTc00FM2y8JjeTcPWEXkViZuwpuc0w5i6qHg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-linux-x64-musl": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-5.0.0.tgz",
-      "integrity": "sha512-mLfQFpX3/5y9oWi0b+9FbWDkL2hM0Y29653beCHiHxAdGyVgb2DsJbK74WkMTwtSz9by8vyBh8jGPZcg1yLZbQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-wasm32-wasi": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-5.0.0.tgz",
-      "integrity": "sha512-uEhsAZSo65qsRi6+IfBTEUUFbjg7T2yruJeLYpFfEATpm3ory5Mgo5vx3L0c2/Cz1OUZXBgp3A8x6VMUB2jT2A==",
-      "cpu": [
-        "wasm32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@napi-rs/wasm-runtime": "^0.2.7"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@oxc-resolver/binding-win32-arm64-msvc": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-5.0.0.tgz",
-      "integrity": "sha512-8DbSso9Jp1ns8AYuZFXdRfAcdJrzZwkFm/RjPuvAPTENsm685dosBF8G6gTHQlHvULnk6o3sa9ygZaTGC/UoEw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@oxc-resolver/binding-win32-x64-msvc": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-5.0.0.tgz",
-      "integrity": "sha512-ylppfPEg63NuRXOPNsXFlgyl37JrtRn0QMO26X3K3Ytp5HtLrMreQMGVtgr30e1l2YmAWqhvmKlCryOqzGPD/g==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
     "node_modules/@pkgjs/parseargs": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -3314,17 +3147,17 @@
       }
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.1.tgz",
-      "integrity": "sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
+      "integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "8.26.1",
-        "@typescript-eslint/type-utils": "8.26.1",
-        "@typescript-eslint/utils": "8.26.1",
-        "@typescript-eslint/visitor-keys": "8.26.1",
+        "@typescript-eslint/scope-manager": "8.29.1",
+        "@typescript-eslint/type-utils": "8.29.1",
+        "@typescript-eslint/utils": "8.29.1",
+        "@typescript-eslint/visitor-keys": "8.29.1",
         "graphemer": "^1.4.0",
         "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
@@ -3344,16 +3177,16 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.1.tgz",
-      "integrity": "sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz",
+      "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/scope-manager": "8.26.1",
-        "@typescript-eslint/types": "8.26.1",
-        "@typescript-eslint/typescript-estree": "8.26.1",
-        "@typescript-eslint/visitor-keys": "8.26.1",
+        "@typescript-eslint/scope-manager": "8.29.1",
+        "@typescript-eslint/types": "8.29.1",
+        "@typescript-eslint/typescript-estree": "8.29.1",
+        "@typescript-eslint/visitor-keys": "8.29.1",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -3369,14 +3202,14 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.1.tgz",
-      "integrity": "sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz",
+      "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.26.1",
-        "@typescript-eslint/visitor-keys": "8.26.1"
+        "@typescript-eslint/types": "8.29.1",
+        "@typescript-eslint/visitor-keys": "8.29.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3387,14 +3220,14 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.1.tgz",
-      "integrity": "sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz",
+      "integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "8.26.1",
-        "@typescript-eslint/utils": "8.26.1",
+        "@typescript-eslint/typescript-estree": "8.29.1",
+        "@typescript-eslint/utils": "8.29.1",
         "debug": "^4.3.4",
         "ts-api-utils": "^2.0.1"
       },
@@ -3411,9 +3244,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.1.tgz",
-      "integrity": "sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz",
+      "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -3425,14 +3258,14 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.1.tgz",
-      "integrity": "sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz",
+      "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.26.1",
-        "@typescript-eslint/visitor-keys": "8.26.1",
+        "@typescript-eslint/types": "8.29.1",
+        "@typescript-eslint/visitor-keys": "8.29.1",
         "debug": "^4.3.4",
         "fast-glob": "^3.3.2",
         "is-glob": "^4.0.3",
@@ -3468,16 +3301,16 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.1.tgz",
-      "integrity": "sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz",
+      "integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@typescript-eslint/scope-manager": "8.26.1",
-        "@typescript-eslint/types": "8.26.1",
-        "@typescript-eslint/typescript-estree": "8.26.1"
+        "@typescript-eslint/scope-manager": "8.29.1",
+        "@typescript-eslint/types": "8.29.1",
+        "@typescript-eslint/typescript-estree": "8.29.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3492,13 +3325,13 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.26.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.1.tgz",
-      "integrity": "sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==",
+      "version": "8.29.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz",
+      "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.26.1",
+        "@typescript-eslint/types": "8.29.1",
         "eslint-visitor-keys": "^4.2.0"
       },
       "engines": {
@@ -3516,10 +3349,10 @@
       "dev": true,
       "license": "ISC"
     },
-    "node_modules/@unrs/rspack-resolver-binding-darwin-arm64": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-arm64/-/rspack-resolver-binding-darwin-arm64-1.1.0.tgz",
-      "integrity": "sha512-otdWnJrycP8Ow0rbiKKjhrW7PPeHPoIglYjBruqh75fEwQGV2EmA9oZMgD4YA6g+/hGzD0mXI26YnWL0G0SkTA==",
+    "node_modules/@unrs/resolver-binding-darwin-arm64": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.4.1.tgz",
+      "integrity": "sha512-8Tv+Bsd0BjGwfEedIyor4inw8atppRxM5BdUnIt+3mAm/QXUm7Dw74CHnXpfZKXkp07EXJGiA8hStqCINAWhdw==",
       "cpu": [
         "arm64"
       ],
@@ -3530,10 +3363,10 @@
         "darwin"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-darwin-x64": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-x64/-/rspack-resolver-binding-darwin-x64-1.1.0.tgz",
-      "integrity": "sha512-MqHyrtIw2ra0KZlniDITROq6rEiMsBnaJtQDYLNDv/y+pvPSXdB3VveZCwSldXJ9TrST2b3NnIbmehljjsMVhg==",
+    "node_modules/@unrs/resolver-binding-darwin-x64": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.4.1.tgz",
+      "integrity": "sha512-X8c3PhWziEMKAzZz+YAYWfwawi5AEgzy/hmfizAB4C70gMHLKmInJcp1270yYAOs7z07YVFI220pp50z24Jk3A==",
       "cpu": [
         "x64"
       ],
@@ -3544,10 +3377,10 @@
         "darwin"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-freebsd-x64": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-freebsd-x64/-/rspack-resolver-binding-freebsd-x64-1.1.0.tgz",
-      "integrity": "sha512-bopyOqmtWn8np1d4iN90PE1tYHopdWwei7mK8/8mf4qhc99f7WRNXtWa1MoL5sjN3DWef3jvr0+MGnMS9MTfJA==",
+    "node_modules/@unrs/resolver-binding-freebsd-x64": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.4.1.tgz",
+      "integrity": "sha512-UUr/nREy1UdtxXQnmLaaTXFGOcGxPwNIzeJdb3KXai3TKtC1UgNOB9s8KOA4TaxOUBR/qVgL5BvBwmUjD5yuVA==",
       "cpu": [
         "x64"
       ],
@@ -3558,10 +3391,10 @@
         "freebsd"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-linux-arm-gnueabihf": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm-gnueabihf/-/rspack-resolver-binding-linux-arm-gnueabihf-1.1.0.tgz",
-      "integrity": "sha512-XldXRkQurDBXCiCuIaWcqOX6UtvjFW8O3CH/kFEZxNJISOAt+ztgyRQRxYhf+T1p18R4boripKmWKEE0uBCiYw==",
+    "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.4.1.tgz",
+      "integrity": "sha512-e3pII53dEeS8inkX6A1ad2UXE0nuoWCqik4kOxaDnls0uJUq0ntdj5d9IYd+bv5TDwf9DSge/xPOvCmRYH+Tsw==",
       "cpu": [
         "arm"
       ],
@@ -3572,10 +3405,24 @@
         "linux"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-linux-arm64-gnu": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-gnu/-/rspack-resolver-binding-linux-arm64-gnu-1.1.0.tgz",
-      "integrity": "sha512-8zubI4MY3whPfLNHEiJ0TeSC5eSmNVWTEGAeMGALCUQtVD9TyZTd6wGwWrQVRN7ESIapWUSChkPLr+Bi13d9sQ==",
+    "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.4.1.tgz",
+      "integrity": "sha512-e/AKKd9gR+HNmVyDEPI/PIz2t0DrA3cyonHNhHVjrkxe8pMCiYiqhtn1+h+yIpHUtUlM6Y1FNIdivFa+r7wrEQ==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.4.1.tgz",
+      "integrity": "sha512-vtIu34luF1jRktlHtiwm2mjuE8oJCsFiFr8hT5+tFQdqFKjPhbJXn83LswKsOhy0GxAEevpXDI4xxEwkjuXIPA==",
       "cpu": [
         "arm64"
       ],
@@ -3586,10 +3433,10 @@
         "linux"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-linux-arm64-musl": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-musl/-/rspack-resolver-binding-linux-arm64-musl-1.1.0.tgz",
-      "integrity": "sha512-+GAyOhl8KPqJsILpHTB/mMc4hfOwI4INed8VAZnSvdaL0ec3Sz/6UXEeTtucW1fWhwaP3lVlpjv2xuRhOCjehA==",
+    "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.4.1.tgz",
+      "integrity": "sha512-H3PaOuGyhFXiyJd+09uPhGl4gocmhyi1BRzvsP8Lv5AQO3p3/ZY7WjV4t2NkBksm9tMjf3YbOVHyPWi2eWsNYw==",
       "cpu": [
         "arm64"
       ],
@@ -3600,10 +3447,38 @@
         "linux"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-linux-x64-gnu": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-gnu/-/rspack-resolver-binding-linux-x64-gnu-1.1.0.tgz",
-      "integrity": "sha512-0zoy6UwRFoto5boJKGjgDpA+4kv+G1kysgrAe0KVefJXOnDNJlfgcV7mOV2O9J+FqtIQsXvzmOJxDB9e1Hhbzw==",
+    "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.4.1.tgz",
+      "integrity": "sha512-4+GmJcaaFntCi1S01YByqp8wLMjV/FyQyHVGm0vedIhL1Vfx7uHkz/sZmKsidRwokBGuxi92GFmSzqT2O8KcNA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.4.1.tgz",
+      "integrity": "sha512-6RDQVCmtFYTlhy89D5ixTqo9bTQqFhvNN0Ey1wJs5r+01Dq15gPHRXv2jF2bQATtMrOfYwv+R2ZR9ew1N1N3YQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.4.1.tgz",
+      "integrity": "sha512-XpU9uzIkD86+19NjCXxlVPISMUrVXsXo5htxtuG+uJ59p5JauSRZsIxQxzzfKzkxEjdvANPM/lS1HFoX6A6QeA==",
       "cpu": [
         "x64"
       ],
@@ -3614,10 +3489,10 @@
         "linux"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-linux-x64-musl": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-musl/-/rspack-resolver-binding-linux-x64-musl-1.1.0.tgz",
-      "integrity": "sha512-XjC+aZKi+X+ma5e6yaVTvojK0v0kxfikbP1dB0klx80NjCW9KRrldiZxAo7ME8Tb4a7Fz0J6PDOVzd9tFYwkQQ==",
+    "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.4.1.tgz",
+      "integrity": "sha512-3CDjG/spbTKCSHl66QP2ekHSD+H34i7utuDIM5gzoNBcZ1gTO0Op09Wx5cikXnhORRf9+HyDWzm37vU1PLSM1A==",
       "cpu": [
         "x64"
       ],
@@ -3628,10 +3503,10 @@
         "linux"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-wasm32-wasi": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-wasm32-wasi/-/rspack-resolver-binding-wasm32-wasi-1.1.0.tgz",
-      "integrity": "sha512-eVBK4z9VN3vahAh2+bQBl+vs9JgWEF1xeccilDcerGNkmlFHB1My5++sbeZzou+DExkioVAdfK+uVyVnHS4k7Q==",
+    "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.4.1.tgz",
+      "integrity": "sha512-50tYhvbCTnuzMn7vmP8IV2UKF7ITo1oihygEYq9wW2DUb/Y+QMqBHJUSCABRngATjZ4shOK6f2+s0gQX6ElENQ==",
       "cpu": [
         "wasm32"
       ],
@@ -3639,16 +3514,16 @@
       "license": "MIT",
       "optional": true,
       "dependencies": {
-        "@napi-rs/wasm-runtime": "^0.2.7"
+        "@napi-rs/wasm-runtime": "^0.2.8"
       },
       "engines": {
         "node": ">=14.0.0"
       }
     },
-    "node_modules/@unrs/rspack-resolver-binding-win32-arm64-msvc": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-arm64-msvc/-/rspack-resolver-binding-win32-arm64-msvc-1.1.0.tgz",
-      "integrity": "sha512-ktm/CnSKOt/Wwdi2SBECLPJ+gL5oaw8LDHG4IfOQO5oT6qlIP0DaOUPrTf8g/WTlLnSp4TryDBM0B/gGla3LEw==",
+    "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.4.1.tgz",
+      "integrity": "sha512-KyJiIne/AqV4IW0wyQO34wSMuJwy3VxVQOfIXIPyQ/Up6y/zi2P/WwXb78gHsLiGRUqCA9LOoCX+6dQZde0g1g==",
       "cpu": [
         "arm64"
       ],
@@ -3659,10 +3534,24 @@
         "win32"
       ]
     },
-    "node_modules/@unrs/rspack-resolver-binding-win32-x64-msvc": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-x64-msvc/-/rspack-resolver-binding-win32-x64-msvc-1.1.0.tgz",
-      "integrity": "sha512-cdMid8RdR6XaQ5uAudzdu9Ydl3HbYjiwpsh+X01APmTZG2ph7OeaRTozW4F8ScUHkPHfrYedv9McICbHxgBvXQ==",
+    "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.4.1.tgz",
+      "integrity": "sha512-y2NUD7pygrBolN2NoXUrwVqBpKPhF8DiSNE5oB5/iFO49r2DpoYqdj5HPb3F42fPBH5qNqj6Zg63+xCEzAD2hw==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.4.1.tgz",
+      "integrity": "sha512-hVXaObGI2lGFmrtT77KSbPQ3I+zk9IU500wobjk0+oX59vg/0VqAzABNtt3YSQYgXTC2a/LYxekLfND/wlt0yQ==",
       "cpu": [
         "x64"
       ],
@@ -3674,9 +3563,9 @@
       ]
     },
     "node_modules/@vitejs/plugin-vue": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz",
-      "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==",
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.3.tgz",
+      "integrity": "sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -3688,9 +3577,9 @@
       }
     },
     "node_modules/@vitest/eslint-plugin": {
-      "version": "1.1.37",
-      "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.37.tgz",
-      "integrity": "sha512-cnlBV8zr0oaBu1Vk6ruqWzpPzFCtwY0yuwUQpNIeFOUl3UhXVwNUoOYfWkZzeToGuNBaXvIsr6/RgHrXiHXqXA==",
+      "version": "1.1.39",
+      "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.39.tgz",
+      "integrity": "sha512-l5/MUFCYI8nxwr62JHlWwXfeQNS8E7xy71lSLGQ3CrjGjBdWLs1Rtee+BvYwy2m4YVPwYqUwdcAIOaZOwPUpfg==",
       "dev": true,
       "license": "MIT",
       "peerDependencies": {
@@ -3709,14 +3598,14 @@
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz",
-      "integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz",
+      "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/spy": "3.0.8",
-        "@vitest/utils": "3.0.8",
+        "@vitest/spy": "3.1.1",
+        "@vitest/utils": "3.1.1",
         "chai": "^5.2.0",
         "tinyrainbow": "^2.0.0"
       },
@@ -3725,13 +3614,13 @@
       }
     },
     "node_modules/@vitest/mocker": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz",
-      "integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz",
+      "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/spy": "3.0.8",
+        "@vitest/spy": "3.1.1",
         "estree-walker": "^3.0.3",
         "magic-string": "^0.30.17"
       },
@@ -3752,9 +3641,9 @@
       }
     },
     "node_modules/@vitest/mocker/node_modules/@types/estree": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
-      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+      "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
       "dev": true,
       "license": "MIT"
     },
@@ -3779,9 +3668,9 @@
       }
     },
     "node_modules/@vitest/pretty-format": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz",
-      "integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz",
+      "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -3792,13 +3681,13 @@
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz",
-      "integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz",
+      "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/utils": "3.0.8",
+        "@vitest/utils": "3.1.1",
         "pathe": "^2.0.3"
       },
       "funding": {
@@ -3806,13 +3695,13 @@
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz",
-      "integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz",
+      "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/pretty-format": "3.0.8",
+        "@vitest/pretty-format": "3.1.1",
         "magic-string": "^0.30.17",
         "pathe": "^2.0.3"
       },
@@ -3831,9 +3720,9 @@
       }
     },
     "node_modules/@vitest/spy": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz",
-      "integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz",
+      "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -3844,13 +3733,13 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz",
-      "integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz",
+      "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/pretty-format": "3.0.8",
+        "@vitest/pretty-format": "3.1.1",
         "loupe": "^3.1.3",
         "tinyrainbow": "^2.0.0"
       },
@@ -4378,9 +4267,9 @@
       "license": "MIT"
     },
     "node_modules/ansi_up": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.2.tgz",
-      "integrity": "sha512-3G3vKvl1ilEp7J1u6BmULpMA0xVoW/f4Ekqhl8RTrJrhEBkonKn5k3bUc5Xt+qDayA6iDX0jyUh3AbZjB/l0tw==",
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.5.tgz",
+      "integrity": "sha512-bo4K8S5usgFivfgvgQozTC2EfusPf76o7w0LUVdAOkpISvVmQqtwCdF5c6okokrgIN13KhFIVB/0BhnNXueQeA==",
       "license": "MIT",
       "engines": {
         "node": "*"
@@ -5103,9 +4992,9 @@
       }
     },
     "node_modules/clippie": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/clippie/-/clippie-4.1.5.tgz",
-      "integrity": "sha512-ZNGL7+p8HZWM2G8fecb3N7izoagXGktTg7nSYxzBID4OAtOBU7SUFvI9EL/0IZpy9VkU8AY6Zp8AvaH4/Xj7pA==",
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/clippie/-/clippie-4.1.6.tgz",
+      "integrity": "sha512-1M3xZRNWcVwRkh3i2XcVYFjVtfC6FCLmIpk5s54uT3+jkBa25KRE3dB0Fgkt/YLoeR7AABWkVTlb0WziQYGgaw==",
       "license": "BSD-2-Clause"
     },
     "node_modules/cliui": {
@@ -6586,25 +6475,24 @@
       }
     },
     "node_modules/eslint-import-resolver-typescript": {
-      "version": "3.9.0",
-      "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.9.0.tgz",
-      "integrity": "sha512-EUcFmaz0zAa6P2C9jAb5XDymRld8S6TURvWcIW7y+czOW+K8hrjgQgbhBsNE0J/dDZ6HLfcn70LqnIil9W+ICw==",
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.3.2.tgz",
+      "integrity": "sha512-T2LqBXj87ndEC9t1LrDiPkzalSFzD4rrXr6BTzGdgMx1jdQM4T972guQvg7Ih+LNO51GURXI/qMHS5GF3h1ilw==",
       "dev": true,
       "license": "ISC",
       "dependencies": {
-        "@nolyfill/is-core-module": "1.0.39",
-        "debug": "^4.3.7",
+        "debug": "^4.4.0",
         "get-tsconfig": "^4.10.0",
-        "is-bun-module": "^1.0.2",
-        "oxc-resolver": "^5.0.0",
+        "is-bun-module": "^2.0.0",
         "stable-hash": "^0.0.5",
-        "tinyglobby": "^0.2.12"
+        "tinyglobby": "^0.2.12",
+        "unrs-resolver": "^1.4.1"
       },
       "engines": {
-        "node": "^14.18.0 || >=16.0.0"
+        "node": "^16.17.0 || >=18.6.0"
       },
       "funding": {
-        "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+        "url": "https://opencollective.com/eslint-import-resolver-typescript"
       },
       "peerDependencies": {
         "eslint": "*",
@@ -6797,24 +6685,25 @@
       }
     },
     "node_modules/eslint-plugin-import-x": {
-      "version": "4.7.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.7.2.tgz",
-      "integrity": "sha512-+GpGWKbQMK3izrwU4XoRGdAJHwvxuboiNusqU25nNXlRsmnxj8B5niQRuFK1aHEvcbIKE6D9ZfwjsLmBQbnJmw==",
+      "version": "4.10.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.10.2.tgz",
+      "integrity": "sha512-jO3Y6+zBUyTX5MVbbLSzoz6fe65t+WEBaXStRLM4EBhZWbuSwAH3cLwARtM0Yp4zRtZGp9sL2zzK7G9JkHR8LA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
+        "@pkgr/core": "^0.2.1",
         "@types/doctrine": "^0.0.9",
-        "@typescript-eslint/utils": "^8.26.1",
+        "@typescript-eslint/utils": "^8.29.0",
         "debug": "^4.4.0",
         "doctrine": "^3.0.0",
         "eslint-import-resolver-node": "^0.3.9",
         "get-tsconfig": "^4.10.0",
         "is-glob": "^4.0.3",
-        "minimatch": "^10.0.1",
-        "rspack-resolver": "^1.1.0",
+        "minimatch": "^9.0.3 || ^10.0.1",
         "semver": "^7.7.1",
         "stable-hash": "^0.0.5",
-        "tslib": "^2.8.1"
+        "tslib": "^2.8.1",
+        "unrs-resolver": "^1.4.1"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -6823,6 +6712,19 @@
         "eslint": "^8.57.0 || ^9.0.0"
       }
     },
+    "node_modules/eslint-plugin-import-x/node_modules/@pkgr/core": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.1.tgz",
+      "integrity": "sha512-VzgHzGblFmUeBmmrk55zPyrQIArQN4vujc9shWytaPdB3P7qhi0cpaiKIr7tlCmFv2lYUwnLospIqjL9ZSAhhg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/unts"
+      }
+    },
     "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -7176,14 +7078,14 @@
       }
     },
     "node_modules/eslint-plugin-wc": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.1.tgz",
-      "integrity": "sha512-KstLqGmyQz088DvFlDYHg0sHih+w2QeulreCi1D1ftr357klO2zqHdG/bbnNMmuQdVFDuNkopNIyNhmG0XCT/g==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-3.0.0.tgz",
+      "integrity": "sha512-TVbwa4ytaKoUGCCAG14+FPDF3v4nGoPcEOd4kjN2MLZ2NTo1lHUs7HsVaiwC0ReKQVivJ7+v6d7u0GYu1c6GJQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-valid-element-name": "^1.0.0",
-        "js-levenshtein-esm": "^1.2.0"
+        "js-levenshtein-esm": "^2.0.0"
       },
       "peerDependencies": {
         "eslint": ">=8.40.0"
@@ -8275,13 +8177,13 @@
       }
     },
     "node_modules/is-bun-module": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz",
-      "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz",
+      "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "semver": "^7.6.3"
+        "semver": "^7.7.1"
       }
     },
     "node_modules/is-core-module": {
@@ -8520,9 +8422,9 @@
       "license": "MIT"
     },
     "node_modules/js-levenshtein-esm": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz",
-      "integrity": "sha512-fzreKVq1eD7eGcQr7MtRpQH94f8gIfhdrc7yeih38xh684TNMK9v5aAu2wxfIRMk/GpAJRrzcirMAPIaSDaByQ==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/js-levenshtein-esm/-/js-levenshtein-esm-2.0.0.tgz",
+      "integrity": "sha512-1n4LEPOL4wRXY8rOQcuA7Iuaphe5xCMayvufCzlLAi+hRsnBRDbSS6XPuV58CBVJxj5D9ApFLyjQ7KzFToyHBw==",
       "dev": true,
       "license": "MIT"
     },
@@ -8751,9 +8653,9 @@
       "license": "MIT"
     },
     "node_modules/langium": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz",
-      "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==",
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz",
+      "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==",
       "license": "MIT",
       "dependencies": {
         "chevrotain": "~11.0.3",
@@ -9244,9 +9146,9 @@
       }
     },
     "node_modules/material-icon-theme": {
-      "version": "5.20.0",
-      "resolved": "https://registry.npmjs.org/material-icon-theme/-/material-icon-theme-5.20.0.tgz",
-      "integrity": "sha512-EAz5I2O7Hq6G8Rv0JdO6NXL+jK/mvDppcVUVbsUMpSqSmFczNdaR5WJ3lOiRz4HNBlEN2i2sVSfuqI5iNQfGLg==",
+      "version": "5.21.1",
+      "resolved": "https://registry.npmjs.org/material-icon-theme/-/material-icon-theme-5.21.1.tgz",
+      "integrity": "sha512-7gWH20MC3rvf1fBXwTpeMEAJqfuhXaciY2IN/hb74hR0XU/TnicoggblFoWtZvt0HrCzxyqX5P+u60BHWXEEHw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -9316,14 +9218,14 @@
       }
     },
     "node_modules/mermaid": {
-      "version": "11.5.0",
-      "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.5.0.tgz",
-      "integrity": "sha512-IYhyukID3zzDj1EihKiN1lp+PXNImoJ3Iyz73qeDAgnus4BNGsJV1n471P4PyeGxPVONerZxignwGxGTSwZnlg==",
+      "version": "11.6.0",
+      "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.6.0.tgz",
+      "integrity": "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg==",
       "license": "MIT",
       "dependencies": {
         "@braintree/sanitize-url": "^7.0.4",
         "@iconify/utils": "^2.1.33",
-        "@mermaid-js/parser": "^0.3.0",
+        "@mermaid-js/parser": "^0.4.0",
         "@types/d3": "^7.4.3",
         "cytoscape": "^3.29.3",
         "cytoscape-cose-bilkent": "^4.1.0",
@@ -10327,29 +10229,6 @@
         "node": ">= 0.8.0"
       }
     },
-    "node_modules/oxc-resolver": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-5.0.0.tgz",
-      "integrity": "sha512-66fopyAqCN8Mx4tzNiBXWbk8asCSuxUWN62gwTc3yfRs7JfWhX/eVJCf+fUrfbNOdQVOWn+o8pAKllp76ysMXA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/Boshen"
-      },
-      "optionalDependencies": {
-        "@oxc-resolver/binding-darwin-arm64": "5.0.0",
-        "@oxc-resolver/binding-darwin-x64": "5.0.0",
-        "@oxc-resolver/binding-freebsd-x64": "5.0.0",
-        "@oxc-resolver/binding-linux-arm-gnueabihf": "5.0.0",
-        "@oxc-resolver/binding-linux-arm64-gnu": "5.0.0",
-        "@oxc-resolver/binding-linux-arm64-musl": "5.0.0",
-        "@oxc-resolver/binding-linux-x64-gnu": "5.0.0",
-        "@oxc-resolver/binding-linux-x64-musl": "5.0.0",
-        "@oxc-resolver/binding-wasm32-wasi": "5.0.0",
-        "@oxc-resolver/binding-win32-arm64-msvc": "5.0.0",
-        "@oxc-resolver/binding-win32-x64-msvc": "5.0.0"
-      }
-    },
     "node_modules/p-limit": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -11652,29 +11531,6 @@
         "points-on-path": "^0.2.1"
       }
     },
-    "node_modules/rspack-resolver": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/rspack-resolver/-/rspack-resolver-1.1.0.tgz",
-      "integrity": "sha512-pJfTX5KuwbJc4agd2AQ9sMwrBxMAGkLt4/HHw5+L06WuzxjsEjg3oDKdbfn43QGq0Stw8wQ7VpZjWA/T03L0Pg==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/JounQin"
-      },
-      "optionalDependencies": {
-        "@unrs/rspack-resolver-binding-darwin-arm64": "1.1.0",
-        "@unrs/rspack-resolver-binding-darwin-x64": "1.1.0",
-        "@unrs/rspack-resolver-binding-freebsd-x64": "1.1.0",
-        "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": "1.1.0",
-        "@unrs/rspack-resolver-binding-linux-arm64-gnu": "1.1.0",
-        "@unrs/rspack-resolver-binding-linux-arm64-musl": "1.1.0",
-        "@unrs/rspack-resolver-binding-linux-x64-gnu": "1.1.0",
-        "@unrs/rspack-resolver-binding-linux-x64-musl": "1.1.0",
-        "@unrs/rspack-resolver-binding-wasm32-wasi": "1.1.0",
-        "@unrs/rspack-resolver-binding-win32-arm64-msvc": "1.1.0",
-        "@unrs/rspack-resolver-binding-win32-x64-msvc": "1.1.0"
-      }
-    },
     "node_modules/run-con": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz",
@@ -12258,9 +12114,9 @@
       "license": "ISC"
     },
     "node_modules/stylelint": {
-      "version": "16.16.0",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz",
-      "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==",
+      "version": "16.18.0",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.18.0.tgz",
+      "integrity": "sha512-OXb68qzesv7J70BSbFwfK3yTVLEVXiQ/ro6wUE4UrSbKCMjLLA02S8Qq3LC01DxKyVjk7z8xh35aB4JzO3/sNA==",
       "dev": true,
       "funding": [
         {
@@ -12321,9 +12177,9 @@
       }
     },
     "node_modules/stylelint-config-recommended": {
-      "version": "15.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-15.0.0.tgz",
-      "integrity": "sha512-9LejMFsat7L+NXttdHdTq94byn25TD+82bzGRiV1Pgasl99pWnwipXS5DguTpp3nP1XjvLXVnEJIuYBfsRjRkA==",
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz",
+      "integrity": "sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==",
       "dev": true,
       "funding": [
         {
@@ -12340,7 +12196,7 @@
         "node": ">=18.12.0"
       },
       "peerDependencies": {
-        "stylelint": "^16.13.0"
+        "stylelint": "^16.16.0"
       }
     },
     "node_modules/stylelint-declaration-block-no-ignored-properties": {
@@ -12370,9 +12226,9 @@
       }
     },
     "node_modules/stylelint-define-config": {
-      "version": "16.15.0",
-      "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.15.0.tgz",
-      "integrity": "sha512-nzHX9ZpI/k4A7izGYPS79xLAf2HyGvYkk/UXMgsQ7ZQEvkOZpQt4Aca4Qn5DYqNmWnqNlW5E3wK+qUmdR3vdxg==",
+      "version": "16.17.0",
+      "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.17.0.tgz",
+      "integrity": "sha512-HToy83mn05K4g72GjXfyw3PhFV9QZKVJWt6m+w7+XNqAOsegiBI+sYXq8sg0R+cedsi2KVyfmEEpKO550yMmrQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -12777,9 +12633,9 @@
       }
     },
     "node_modules/swagger-ui-dist": {
-      "version": "5.20.1",
-      "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.1.tgz",
-      "integrity": "sha512-qBPCis2w8nP4US7SvUxdJD3OwKcqiWeZmjN2VWhq2v+ESZEXOP/7n4DeiOiiZcGYTKMHAHUUrroHaTsjUWTEGw==",
+      "version": "5.20.7",
+      "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.7.tgz",
+      "integrity": "sha512-gLpb1wrWinUwMFKfSvDYsIlCyGQSryftzi6uWc9Qo98zO3mFT6oHOqmDUu5OoahvepuS6HGTe/3MsGUCVtpLig==",
       "license": "Apache-2.0",
       "dependencies": {
         "@scarf/scarf": "=1.4.0"
@@ -13181,9 +13037,9 @@
       }
     },
     "node_modules/type-fest": {
-      "version": "4.37.0",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz",
-      "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==",
+      "version": "4.39.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.1.tgz",
+      "integrity": "sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==",
       "dev": true,
       "license": "(MIT OR CC0-1.0)",
       "engines": {
@@ -13194,9 +13050,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.8.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
-      "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+      "version": "5.8.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+      "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
       "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
@@ -13247,6 +13103,33 @@
         "node": ">= 10.0.0"
       }
     },
+    "node_modules/unrs-resolver": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.4.1.tgz",
+      "integrity": "sha512-MhPB3wBI5BR8TGieTb08XuYlE8oFVEXdSAgat3psdlRyejl8ojQ8iqPcjh094qCZ1r+TnkxzP6BeCd/umfHckQ==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/JounQin"
+      },
+      "optionalDependencies": {
+        "@unrs/resolver-binding-darwin-arm64": "1.4.1",
+        "@unrs/resolver-binding-darwin-x64": "1.4.1",
+        "@unrs/resolver-binding-freebsd-x64": "1.4.1",
+        "@unrs/resolver-binding-linux-arm-gnueabihf": "1.4.1",
+        "@unrs/resolver-binding-linux-arm-musleabihf": "1.4.1",
+        "@unrs/resolver-binding-linux-arm64-gnu": "1.4.1",
+        "@unrs/resolver-binding-linux-arm64-musl": "1.4.1",
+        "@unrs/resolver-binding-linux-ppc64-gnu": "1.4.1",
+        "@unrs/resolver-binding-linux-s390x-gnu": "1.4.1",
+        "@unrs/resolver-binding-linux-x64-gnu": "1.4.1",
+        "@unrs/resolver-binding-linux-x64-musl": "1.4.1",
+        "@unrs/resolver-binding-wasm32-wasi": "1.4.1",
+        "@unrs/resolver-binding-win32-arm64-msvc": "1.4.1",
+        "@unrs/resolver-binding-win32-ia32-msvc": "1.4.1",
+        "@unrs/resolver-binding-win32-x64-msvc": "1.4.1"
+      }
+    },
     "node_modules/update-browserslist-db": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -13436,9 +13319,9 @@
       }
     },
     "node_modules/vite-node": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz",
-      "integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz",
+      "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -13527,31 +13410,31 @@
       }
     },
     "node_modules/vitest": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz",
-      "integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz",
+      "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/expect": "3.0.8",
-        "@vitest/mocker": "3.0.8",
-        "@vitest/pretty-format": "^3.0.8",
-        "@vitest/runner": "3.0.8",
-        "@vitest/snapshot": "3.0.8",
-        "@vitest/spy": "3.0.8",
-        "@vitest/utils": "3.0.8",
+        "@vitest/expect": "3.1.1",
+        "@vitest/mocker": "3.1.1",
+        "@vitest/pretty-format": "^3.1.1",
+        "@vitest/runner": "3.1.1",
+        "@vitest/snapshot": "3.1.1",
+        "@vitest/spy": "3.1.1",
+        "@vitest/utils": "3.1.1",
         "chai": "^5.2.0",
         "debug": "^4.4.0",
-        "expect-type": "^1.1.0",
+        "expect-type": "^1.2.0",
         "magic-string": "^0.30.17",
         "pathe": "^2.0.3",
-        "std-env": "^3.8.0",
+        "std-env": "^3.8.1",
         "tinybench": "^2.9.0",
         "tinyexec": "^0.3.2",
         "tinypool": "^1.0.2",
         "tinyrainbow": "^2.0.0",
         "vite": "^5.0.0 || ^6.0.0",
-        "vite-node": "3.0.8",
+        "vite-node": "3.1.1",
         "why-is-node-running": "^2.3.0"
       },
       "bin": {
@@ -13567,8 +13450,8 @@
         "@edge-runtime/vm": "*",
         "@types/debug": "^4.1.12",
         "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
-        "@vitest/browser": "3.0.8",
-        "@vitest/ui": "3.0.8",
+        "@vitest/browser": "3.1.1",
+        "@vitest/ui": "3.1.1",
         "happy-dom": "*",
         "jsdom": "*"
       },
diff --git a/package.json b/package.json
index ef1a132994..040d6b24fd 100644
--- a/package.json
+++ b/package.json
@@ -15,12 +15,12 @@
     "@primer/octicons": "19.15.1",
     "@silverwind/vue3-calendar-heatmap": "2.0.6",
     "add-asset-webpack-plugin": "3.0.0",
-    "ansi_up": "6.0.2",
+    "ansi_up": "6.0.5",
     "asciinema-player": "3.9.0",
     "chart.js": "4.4.8",
     "chartjs-adapter-dayjs-4": "1.0.4",
     "chartjs-plugin-zoom": "2.2.0",
-    "clippie": "4.1.5",
+    "clippie": "4.1.6",
     "cropperjs": "1.6.2",
     "css-loader": "7.1.2",
     "dayjs": "1.11.13",
@@ -34,7 +34,7 @@
     "jquery": "3.7.1",
     "katex": "0.16.21",
     "license-checker-webpack-plugin": "0.2.1",
-    "mermaid": "11.5.0",
+    "mermaid": "11.6.0",
     "mini-css-extract-plugin": "2.9.2",
     "minimatch": "10.0.1",
     "monaco-editor": "0.52.2",
@@ -45,14 +45,14 @@
     "postcss-loader": "8.1.1",
     "postcss-nesting": "13.0.1",
     "sortablejs": "1.15.6",
-    "swagger-ui-dist": "5.20.1",
+    "swagger-ui-dist": "5.20.7",
     "tailwindcss": "3.4.17",
     "throttle-debounce": "5.0.2",
     "tinycolor2": "1.6.0",
     "tippy.js": "6.3.7",
     "toastify-js": "1.12.0",
     "tributejs": "5.1.3",
-    "typescript": "5.8.2",
+    "typescript": "5.8.3",
     "uint8-to-base64": "0.2.0",
     "vanilla-colorful": "0.7.2",
     "vue": "3.5.13",
@@ -79,15 +79,15 @@
     "@types/throttle-debounce": "5.0.2",
     "@types/tinycolor2": "1.4.6",
     "@types/toastify-js": "1.12.3",
-    "@typescript-eslint/eslint-plugin": "8.26.1",
-    "@typescript-eslint/parser": "8.26.1",
-    "@vitejs/plugin-vue": "5.2.1",
-    "@vitest/eslint-plugin": "1.1.37",
+    "@typescript-eslint/eslint-plugin": "8.29.1",
+    "@typescript-eslint/parser": "8.29.1",
+    "@vitejs/plugin-vue": "5.2.3",
+    "@vitest/eslint-plugin": "1.1.39",
     "eslint": "8.57.0",
-    "eslint-import-resolver-typescript": "3.9.0",
+    "eslint-import-resolver-typescript": "4.3.2",
     "eslint-plugin-array-func": "4.0.0",
     "eslint-plugin-github": "5.0.2",
-    "eslint-plugin-import-x": "4.7.2",
+    "eslint-plugin-import-x": "4.10.2",
     "eslint-plugin-no-jquery": "3.1.1",
     "eslint-plugin-no-use-extend-native": "0.5.0",
     "eslint-plugin-playwright": "2.2.0",
@@ -96,23 +96,23 @@
     "eslint-plugin-unicorn": "56.0.1",
     "eslint-plugin-vue": "10.0.0",
     "eslint-plugin-vue-scoped-css": "2.9.0",
-    "eslint-plugin-wc": "2.2.1",
+    "eslint-plugin-wc": "3.0.0",
     "happy-dom": "17.4.4",
     "markdownlint-cli": "0.44.0",
-    "material-icon-theme": "5.20.0",
+    "material-icon-theme": "5.21.1",
     "nolyfill": "1.0.44",
     "postcss-html": "1.8.0",
-    "stylelint": "16.16.0",
-    "stylelint-config-recommended": "15.0.0",
+    "stylelint": "16.18.0",
+    "stylelint-config-recommended": "16.0.0",
     "stylelint-declaration-block-no-ignored-properties": "2.8.0",
     "stylelint-declaration-strict-value": "1.10.11",
-    "stylelint-define-config": "16.15.0",
+    "stylelint-define-config": "16.17.0",
     "stylelint-value-no-unknown-custom-properties": "6.0.1",
     "svgo": "3.3.2",
-    "type-fest": "4.37.0",
+    "type-fest": "4.39.1",
     "updates": "16.4.2",
     "vite-string-plugin": "1.4.4",
-    "vitest": "3.0.8",
+    "vitest": "3.1.1",
     "vue-tsc": "2.2.8"
   },
   "browserslist": [
diff --git a/poetry.lock b/poetry.lock
index ca7ae78cb8..b532bf0a3a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand.
 
 [[package]]
 name = "click"
@@ -119,18 +119,18 @@ six = ">=1.13.0"
 
 [[package]]
 name = "json5"
-version = "0.10.0"
+version = "0.12.0"
 description = "A Python implementation of the JSON5 data format."
 optional = false
 python-versions = ">=3.8.0"
 groups = ["dev"]
 files = [
-    {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"},
-    {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"},
+    {file = "json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db"},
+    {file = "json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a"},
 ]
 
 [package.extras]
-dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (==24.3.1)", "pylint (==3.2.3)", "ruff (==0.7.3)", "twine (==5.1.1)", "uv (==0.5.1)"]
+dev = ["build (==1.2.2.post1)", "coverage (==7.5.4) ; python_version < \"3.9\"", "coverage (==7.8.0) ; python_version >= \"3.9\"", "mypy (==1.14.1) ; python_version < \"3.9\"", "mypy (==1.15.0) ; python_version >= \"3.9\"", "pip (==25.0.1)", "pylint (==3.2.7) ; python_version < \"3.9\"", "pylint (==3.3.6) ; python_version >= \"3.9\"", "ruff (==0.11.2)", "twine (==6.1.0)", "uv (==0.6.11)"]
 
 [[package]]
 name = "pathspec"
@@ -330,7 +330,7 @@ description = "A lil' TOML parser"
 optional = false
 python-versions = ">=3.8"
 groups = ["dev"]
-markers = "python_version < \"3.11\""
+markers = "python_version == \"3.10\""
 files = [
     {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
     {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
@@ -390,27 +390,27 @@ telegram = ["requests"]
 
 [[package]]
 name = "typing-extensions"
-version = "4.12.2"
+version = "4.13.1"
 description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
 python-versions = ">=3.8"
 groups = ["dev"]
-markers = "python_version < \"3.11\""
+markers = "python_version == \"3.10\""
 files = [
-    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
-    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+    {file = "typing_extensions-4.13.1-py3-none-any.whl", hash = "sha256:4b6cf02909eb5495cfbc3f6e8fd49217e6cc7944e145cdda8caa3734777f9e69"},
+    {file = "typing_extensions-4.13.1.tar.gz", hash = "sha256:98795af00fb9640edec5b8e31fc647597b4691f099ad75f469a2616be1a76dff"},
 ]
 
 [[package]]
 name = "yamllint"
-version = "1.36.1"
+version = "1.37.0"
 description = "A linter for YAML files."
 optional = false
 python-versions = ">=3.9"
 groups = ["dev"]
 files = [
-    {file = "yamllint-1.36.1-py3-none-any.whl", hash = "sha256:3e2ccd47ea12449837adf6b2c56fd9e31172ce42bc1470380806be461f25df66"},
-    {file = "yamllint-1.36.1.tar.gz", hash = "sha256:a287689daaafc301a80549b2d0170452ebfdcabd826e3fe3b4c66e322d4851fa"},
+    {file = "yamllint-1.37.0-py3-none-any.whl", hash = "sha256:c03ab4e79ab4af964c8eb16ac9746880fc76a3bb0ffb14925b9a55220ae7dda0"},
+    {file = "yamllint-1.37.0.tar.gz", hash = "sha256:ead81921d4d87216b2528b7a055664708f9fb8267beb0c427cb706ac6ab93580"},
 ]
 
 [package.dependencies]
@@ -423,4 +423,4 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"]
 [metadata]
 lock-version = "2.1"
 python-versions = "^3.10"
-content-hash = "d48a461813418f7b803a7f94713d93076a009a96554e0f4c707be0cc2a95b563"
+content-hash = "d8ed1d7f88ff4be57be2c599b9d906dee25d0f6f6e46fdc9051c892c4e812a1c"
diff --git a/pyproject.toml b/pyproject.toml
index a2aedfe148..4eed5f0e74 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ python = "^3.10"
 
 [tool.poetry.group.dev.dependencies]
 djlint = "1.36.4"
-yamllint = "1.36.1"
+yamllint = "1.37.0"
 
 [tool.djlint]
 profile="golang"
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index f70e5dd235..71c21f2dde 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -141,26 +141,18 @@ func GetTeam(ctx *context.APIContext) {
 	ctx.JSON(http.StatusOK, apiTeam)
 }
 
-func attachTeamUnits(team *organization.Team, units []string) {
+func attachTeamUnits(team *organization.Team, defaultAccessMode perm.AccessMode, units []string) {
 	unitTypes, _ := unit_model.FindUnitTypes(units...)
 	team.Units = make([]*organization.TeamUnit, 0, len(units))
 	for _, tp := range unitTypes {
 		team.Units = append(team.Units, &organization.TeamUnit{
 			OrgID:      team.OrgID,
 			Type:       tp,
-			AccessMode: team.AccessMode,
+			AccessMode: defaultAccessMode,
 		})
 	}
 }
 
-func convertUnitsMap(unitsMap map[string]string) map[unit_model.Type]perm.AccessMode {
-	res := make(map[unit_model.Type]perm.AccessMode, len(unitsMap))
-	for unitKey, p := range unitsMap {
-		res[unit_model.TypeFromKey(unitKey)] = perm.ParseAccessMode(p)
-	}
-	return res
-}
-
 func attachTeamUnitsMap(team *organization.Team, unitsMap map[string]string) {
 	team.Units = make([]*organization.TeamUnit, 0, len(unitsMap))
 	for unitKey, p := range unitsMap {
@@ -214,24 +206,22 @@ func CreateTeam(ctx *context.APIContext) {
 	//   "422":
 	//     "$ref": "#/responses/validationError"
 	form := web.GetForm(ctx).(*api.CreateTeamOption)
-	p := perm.ParseAccessMode(form.Permission)
-	if p < perm.AccessModeAdmin && len(form.UnitsMap) > 0 {
-		p = unit_model.MinUnitAccessMode(convertUnitsMap(form.UnitsMap))
-	}
+	teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
 	team := &organization.Team{
 		OrgID:                   ctx.Org.Organization.ID,
 		Name:                    form.Name,
 		Description:             form.Description,
 		IncludesAllRepositories: form.IncludesAllRepositories,
 		CanCreateOrgRepo:        form.CanCreateOrgRepo,
-		AccessMode:              p,
+		AccessMode:              teamPermission,
 	}
 
 	if team.AccessMode < perm.AccessModeAdmin {
 		if len(form.UnitsMap) > 0 {
 			attachTeamUnitsMap(team, form.UnitsMap)
 		} else if len(form.Units) > 0 {
-			attachTeamUnits(team, form.Units)
+			unitPerm := perm.ParseAccessMode(form.Permission, perm.AccessModeRead, perm.AccessModeWrite)
+			attachTeamUnits(team, unitPerm, form.Units)
 		} else {
 			ctx.APIErrorInternal(errors.New("units permission should not be empty"))
 			return
@@ -304,15 +294,10 @@ func EditTeam(ctx *context.APIContext) {
 	isAuthChanged := false
 	isIncludeAllChanged := false
 	if !team.IsOwnerTeam() && len(form.Permission) != 0 {
-		// Validate permission level.
-		p := perm.ParseAccessMode(form.Permission)
-		if p < perm.AccessModeAdmin && len(form.UnitsMap) > 0 {
-			p = unit_model.MinUnitAccessMode(convertUnitsMap(form.UnitsMap))
-		}
-
-		if team.AccessMode != p {
+		teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
+		if team.AccessMode != teamPermission {
 			isAuthChanged = true
-			team.AccessMode = p
+			team.AccessMode = teamPermission
 		}
 
 		if form.IncludesAllRepositories != nil {
@@ -325,7 +310,8 @@ func EditTeam(ctx *context.APIContext) {
 		if len(form.UnitsMap) > 0 {
 			attachTeamUnitsMap(team, form.UnitsMap)
 		} else if len(form.Units) > 0 {
-			attachTeamUnits(team, form.Units)
+			unitPerm := perm.ParseAccessMode(form.Permission, perm.AccessModeRead, perm.AccessModeWrite)
+			attachTeamUnits(team, unitPerm, form.Units)
 		}
 	} else {
 		attachAdminTeamUnits(team)
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index a54225f0fd..d1652c1d51 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -181,7 +181,7 @@ func AddOrUpdateCollaborator(ctx *context.APIContext) {
 
 	p := perm.AccessModeWrite
 	if form.Permission != nil {
-		p = perm.ParseAccessMode(*form.Permission)
+		p = perm.ParseAccessMode(*form.Permission, perm.AccessModeRead, perm.AccessModeWrite, perm.AccessModeAdmin)
 	}
 
 	if err := repo_service.AddOrUpdateCollaborator(ctx, ctx.Repo.Repository, collaborator, p); err != nil {
diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go
index 442d0a76c9..8b1e849e7a 100644
--- a/routers/private/hook_post_receive.go
+++ b/routers/private/hook_post_receive.go
@@ -14,6 +14,7 @@ import (
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/cache"
+	"code.gitea.io/gitea/modules/cachegroup"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
@@ -326,9 +327,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
 }
 
 func loadContextCacheUser(ctx context.Context, id int64) (*user_model.User, error) {
-	return cache.GetWithContextCache(ctx, "hook_post_receive_user", id, func() (*user_model.User, error) {
-		return user_model.GetUserByID(ctx, id)
-	})
+	return cache.GetWithContextCache(ctx, cachegroup.User, id, user_model.GetUserByID)
 }
 
 // handlePullRequestMerging handle pull request merging, a pull request action should push at least 1 commit
diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go
index aeea3708b2..b1b0dd2c49 100644
--- a/routers/web/org/teams.go
+++ b/routers/web/org/teams.go
@@ -284,6 +284,8 @@ func NewTeam(ctx *context.Context) {
 	ctx.HTML(http.StatusOK, tplTeamNew)
 }
 
+// FIXME: TEAM-UNIT-PERMISSION: this design is not right, when a new unit is added in the future,
+// admin team won't inherit the correct admin permission for the new unit.
 func getUnitPerms(forms url.Values, teamPermission perm.AccessMode) map[unit_model.Type]perm.AccessMode {
 	unitPerms := make(map[unit_model.Type]perm.AccessMode)
 	for _, ut := range unit_model.AllRepoUnitTypes {
@@ -314,19 +316,14 @@ func getUnitPerms(forms url.Values, teamPermission perm.AccessMode) map[unit_mod
 func NewTeamPost(ctx *context.Context) {
 	form := web.GetForm(ctx).(*forms.CreateTeamForm)
 	includesAllRepositories := form.RepoAccess == "all"
-	p := perm.ParseAccessMode(form.Permission)
-	unitPerms := getUnitPerms(ctx.Req.Form, p)
-	if p < perm.AccessModeAdmin {
-		// if p is less than admin accessmode, then it should be general accessmode,
-		// so we should calculate the minial accessmode from units accessmodes.
-		p = unit_model.MinUnitAccessMode(unitPerms)
-	}
+	teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
+	unitPerms := getUnitPerms(ctx.Req.Form, teamPermission)
 
 	t := &org_model.Team{
 		OrgID:                   ctx.Org.Organization.ID,
 		Name:                    form.TeamName,
 		Description:             form.Description,
-		AccessMode:              p,
+		AccessMode:              teamPermission,
 		IncludesAllRepositories: includesAllRepositories,
 		CanCreateOrgRepo:        form.CanCreateOrgRepo,
 	}
@@ -485,13 +482,8 @@ func EditTeam(ctx *context.Context) {
 func EditTeamPost(ctx *context.Context) {
 	form := web.GetForm(ctx).(*forms.CreateTeamForm)
 	t := ctx.Org.Team
-	newAccessMode := perm.ParseAccessMode(form.Permission)
-	unitPerms := getUnitPerms(ctx.Req.Form, newAccessMode)
-	if newAccessMode < perm.AccessModeAdmin {
-		// if newAccessMode is less than admin accessmode, then it should be general accessmode,
-		// so we should calculate the minial accessmode from units accessmodes.
-		newAccessMode = unit_model.MinUnitAccessMode(unitPerms)
-	}
+	teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
+	unitPerms := getUnitPerms(ctx.Req.Form, teamPermission)
 	isAuthChanged := false
 	isIncludeAllChanged := false
 	includesAllRepositories := form.RepoAccess == "all"
@@ -503,9 +495,9 @@ func EditTeamPost(ctx *context.Context) {
 
 	if !t.IsOwnerTeam() {
 		t.Name = form.TeamName
-		if t.AccessMode != newAccessMode {
+		if t.AccessMode != teamPermission {
 			isAuthChanged = true
-			t.AccessMode = newAccessMode
+			t.AccessMode = teamPermission
 		}
 
 		if t.IncludesAllRepositories != includesAllRepositories {
diff --git a/routers/web/repo/fork.go b/routers/web/repo/fork.go
index 36e64bfee3..79f033659b 100644
--- a/routers/web/repo/fork.go
+++ b/routers/web/repo/fork.go
@@ -91,12 +91,17 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
 	ctx.Data["CanForkToUser"] = canForkToUser
 	ctx.Data["Orgs"] = orgs
 
+	// TODO: this message should only be shown for the "current doer" when it is selected, just like the "new repo" page.
+	// msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", ctx.Doer.MaxCreationLimit())
+
 	if canForkToUser {
 		ctx.Data["ContextUser"] = ctx.Doer
+		ctx.Data["CanForkRepoInNewOwner"] = true
 	} else if len(orgs) > 0 {
 		ctx.Data["ContextUser"] = orgs[0]
+		ctx.Data["CanForkRepoInNewOwner"] = true
 	} else {
-		ctx.Data["CanForkRepo"] = false
+		ctx.Data["CanForkRepoInNewOwner"] = false
 		ctx.Flash.Error(ctx.Tr("repo.fork_no_valid_owners"), true)
 		return nil
 	}
@@ -120,15 +125,6 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
 // Fork render repository fork page
 func Fork(ctx *context.Context) {
 	ctx.Data["Title"] = ctx.Tr("new_fork")
-
-	if ctx.Doer.CanForkRepo() {
-		ctx.Data["CanForkRepo"] = true
-	} else {
-		maxCreationLimit := ctx.Doer.MaxCreationLimit()
-		msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit)
-		ctx.Flash.Error(msg, true)
-	}
-
 	getForkRepository(ctx)
 	if ctx.Written() {
 		return
@@ -141,7 +137,6 @@ func Fork(ctx *context.Context) {
 func ForkPost(ctx *context.Context) {
 	form := web.GetForm(ctx).(*forms.CreateRepoForm)
 	ctx.Data["Title"] = ctx.Tr("new_fork")
-	ctx.Data["CanForkRepo"] = true
 
 	ctxUser := checkContextUser(ctx, form.UID)
 	if ctx.Written() {
diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go
index f4ac9d769b..61606f8c5f 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -29,7 +29,6 @@ import (
 	repo_module "code.gitea.io/gitea/modules/repository"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/structs"
-	"code.gitea.io/gitea/modules/util"
 	"code.gitea.io/gitea/services/context"
 	repo_service "code.gitea.io/gitea/services/repository"
 
@@ -303,17 +302,12 @@ var (
 
 func dummyInfoRefs(ctx *context.Context) {
 	infoRefsOnce.Do(func() {
-		tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-info-refs-cache")
+		tmpDir, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-info-refs-cache")
 		if err != nil {
 			log.Error("Failed to create temp dir for git-receive-pack cache: %v", err)
 			return
 		}
-
-		defer func() {
-			if err := util.RemoveAll(tmpDir); err != nil {
-				log.Error("RemoveAll: %v", err)
-			}
-		}()
+		defer cleanup()
 
 		if err := git.InitRepository(ctx, tmpDir, true, git.Sha1ObjectFormat.Name()); err != nil {
 			log.Error("Failed to init bare repo for git-receive-pack cache: %v", err)
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index e260ea36dd..ee112b83f2 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -87,17 +87,13 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User {
 		return nil
 	}
 
-	if !ctx.Doer.IsAdmin {
-		orgsAvailable := []*organization.Organization{}
-		for i := 0; i < len(orgs); i++ {
-			if orgs[i].CanCreateRepo() {
-				orgsAvailable = append(orgsAvailable, orgs[i])
-			}
+	var orgsAvailable []*organization.Organization
+	for i := 0; i < len(orgs); i++ {
+		if ctx.Doer.CanCreateRepoIn(orgs[i].AsUser()) {
+			orgsAvailable = append(orgsAvailable, orgs[i])
 		}
-		ctx.Data["Orgs"] = orgsAvailable
-	} else {
-		ctx.Data["Orgs"] = orgs
 	}
+	ctx.Data["Orgs"] = orgsAvailable
 
 	// Not equal means current user is an organization.
 	if uid == ctx.Doer.ID || uid == 0 {
@@ -154,7 +150,7 @@ func createCommon(ctx *context.Context) {
 	ctx.Data["Licenses"] = repo_module.Licenses
 	ctx.Data["Readmes"] = repo_module.Readmes
 	ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
-	ctx.Data["CanCreateRepoInDoer"] = ctx.Doer.CanCreateRepo()
+	ctx.Data["CanCreateRepoInDoer"] = ctx.Doer.CanCreateRepoIn(ctx.Doer)
 	ctx.Data["MaxCreationLimitOfDoer"] = ctx.Doer.MaxCreationLimit()
 	ctx.Data["SupportedObjectFormats"] = git.DefaultFeatures().SupportedObjectFormats
 	ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go
index 655291d25c..efda9bda58 100644
--- a/routers/web/repo/setting/lfs.go
+++ b/routers/web/repo/setting/lfs.go
@@ -109,17 +109,13 @@ func LFSLocks(ctx *context.Context) {
 	}
 
 	// Clone base repo.
-	tmpBasePath, err := repo_module.CreateTemporaryPath("locks")
+	tmpBasePath, cleanup, err := repo_module.CreateTemporaryPath("locks")
 	if err != nil {
 		log.Error("Failed to create temporary path: %v", err)
 		ctx.ServerError("LFSLocks", err)
 		return
 	}
-	defer func() {
-		if err := repo_module.RemoveTemporaryPath(tmpBasePath); err != nil {
-			log.Error("LFSLocks: RemoveTemporaryPath: %v", err)
-		}
-	}()
+	defer cleanup()
 
 	if err := git.Clone(ctx, ctx.Repo.Repository.RepoPath(), tmpBasePath, git.CloneRepoOptions{
 		Bare:   true,
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 380fec9d4a..5552a8726c 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -59,6 +59,7 @@ func SettingsCtxData(ctx *context.Context) {
 	ctx.Data["DisableNewPushMirrors"] = setting.Mirror.DisableNewPush
 	ctx.Data["DefaultMirrorInterval"] = setting.Mirror.DefaultInterval
 	ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
+	ctx.Data["CanConvertFork"] = ctx.Repo.Repository.IsFork && ctx.Doer.CanCreateRepoIn(ctx.Repo.Repository.Owner)
 
 	signing, _ := asymkey_service.SigningKey(ctx, ctx.Repo.Repository.RepoPath())
 	ctx.Data["SigningKeyAvailable"] = len(signing) > 0
@@ -786,7 +787,7 @@ func handleSettingsPostConvertFork(ctx *context.Context) {
 		return
 	}
 
-	if !ctx.Repo.Owner.CanCreateRepo() {
+	if !ctx.Doer.CanForkRepoIn(ctx.Repo.Owner) {
 		maxCreationLimit := ctx.Repo.Owner.MaxCreationLimit()
 		msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit)
 		ctx.Flash.Error(msg)
diff --git a/services/asymkey/commit.go b/services/asymkey/commit.go
index 5d85be56f1..105782a93a 100644
--- a/services/asymkey/commit.go
+++ b/services/asymkey/commit.go
@@ -11,6 +11,8 @@ import (
 	asymkey_model "code.gitea.io/gitea/models/asymkey"
 	"code.gitea.io/gitea/models/db"
 	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/cache"
+	"code.gitea.io/gitea/modules/cachegroup"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
@@ -115,7 +117,7 @@ func ParseCommitWithSignatureCommitter(ctx context.Context, c *git.Commit, commi
 			}
 		}
 
-		committerEmailAddresses, _ := user_model.GetEmailAddresses(ctx, committer.ID)
+		committerEmailAddresses, _ := cache.GetWithContextCache(ctx, cachegroup.UserEmailAddresses, committer.ID, user_model.GetEmailAddresses)
 		activated := false
 		for _, e := range committerEmailAddresses {
 			if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) {
@@ -209,10 +211,9 @@ func checkKeyEmails(ctx context.Context, email string, keys ...*asymkey_model.GP
 		}
 		if key.Verified && key.OwnerID != 0 {
 			if uid != key.OwnerID {
-				userEmails, _ = user_model.GetEmailAddresses(ctx, key.OwnerID)
+				userEmails, _ = cache.GetWithContextCache(ctx, cachegroup.UserEmailAddresses, key.OwnerID, user_model.GetEmailAddresses)
 				uid = key.OwnerID
-				user = &user_model.User{ID: uid}
-				_, _ = user_model.GetUser(ctx, user)
+				user, _ = cache.GetWithContextCache(ctx, cachegroup.User, uid, user_model.GetUserByID)
 			}
 			for _, e := range userEmails {
 				if e.IsActivated && (email == "" || strings.EqualFold(e.Email, email)) {
@@ -231,10 +232,7 @@ func HashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
 	if keyID == "" {
 		return nil
 	}
-	keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
-		KeyID:          keyID,
-		IncludeSubKeys: true,
-	})
+	keys, err := cache.GetWithContextCache(ctx, cachegroup.GPGKeyWithSubKeys, keyID, asymkey_model.FindGPGKeyWithSubKeys)
 	if err != nil {
 		log.Error("GetGPGKeysByKeyID: %v", err)
 		return &asymkey_model.CommitVerification{
@@ -249,10 +247,7 @@ func HashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
 	for _, key := range keys {
 		var primaryKeys []*asymkey_model.GPGKey
 		if key.PrimaryKeyID != "" {
-			primaryKeys, err = db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{
-				KeyID:          key.PrimaryKeyID,
-				IncludeSubKeys: true,
-			})
+			primaryKeys, err = cache.GetWithContextCache(ctx, cachegroup.GPGKeyWithSubKeys, key.PrimaryKeyID, asymkey_model.FindGPGKeyWithSubKeys)
 			if err != nil {
 				log.Error("GetGPGKeysByKeyID: %v", err)
 				return &asymkey_model.CommitVerification{
@@ -272,8 +267,8 @@ func HashAndVerifyForKeyID(ctx context.Context, sig *packet.Signature, payload s
 			Name:  name,
 			Email: email,
 		}
-		if key.OwnerID != 0 {
-			owner, err := user_model.GetUserByID(ctx, key.OwnerID)
+		if key.OwnerID > 0 {
+			owner, err := cache.GetWithContextCache(ctx, cachegroup.User, key.OwnerID, user_model.GetUserByID)
 			if err == nil {
 				signer = owner
 			} else if !user_model.IsErrUserNotExist(err) {
@@ -381,7 +376,7 @@ func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *
 			}
 		}
 
-		committerEmailAddresses, err := user_model.GetEmailAddresses(ctx, committer.ID)
+		committerEmailAddresses, err := cache.GetWithContextCache(ctx, cachegroup.UserEmailAddresses, committer.ID, user_model.GetEmailAddresses)
 		if err != nil {
 			log.Error("GetEmailAddresses: %v", err)
 		}
diff --git a/services/context/org.go b/services/context/org.go
index 992a48afa0..c8b6ed09b7 100644
--- a/services/context/org.go
+++ b/services/context/org.go
@@ -182,7 +182,7 @@ func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) {
 					return
 				}
 				for _, team := range teams {
-					if team.IncludesAllRepositories && team.AccessMode >= perm.AccessModeAdmin {
+					if team.IncludesAllRepositories && team.HasAdminAccess() {
 						shouldSeeAllTeams = true
 						break
 					}
@@ -228,7 +228,7 @@ func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) {
 				return
 			}
 
-			ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.AccessMode >= perm.AccessModeAdmin
+			ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.HasAdminAccess()
 			ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin
 			if opts.RequireTeamAdmin && !ctx.Org.IsTeamAdmin {
 				ctx.NotFound(err)
diff --git a/services/convert/pull.go b/services/convert/pull.go
index 34c3b1bf9a..7798bebb08 100644
--- a/services/convert/pull.go
+++ b/services/convert/pull.go
@@ -14,6 +14,7 @@ import (
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/cache"
+	"code.gitea.io/gitea/modules/cachegroup"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
@@ -60,14 +61,14 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
 		doerID = doer.ID
 	}
 
-	const repoDoerPermCacheKey = "repo_doer_perm_cache"
-	p, err := cache.GetWithContextCache(ctx, repoDoerPermCacheKey, fmt.Sprintf("%d_%d", pr.BaseRepoID, doerID),
-		func() (access_model.Permission, error) {
+	repoUserPerm, err := cache.GetWithContextCache(ctx, cachegroup.RepoUserPermission, fmt.Sprintf("%d-%d", pr.BaseRepoID, doerID),
+		func(ctx context.Context, _ string) (access_model.Permission, error) {
 			return access_model.GetUserRepoPermission(ctx, pr.BaseRepo, doer)
-		})
+		},
+	)
 	if err != nil {
 		log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err)
-		p.AccessMode = perm.AccessModeNone
+		repoUserPerm.AccessMode = perm.AccessModeNone
 	}
 
 	apiPullRequest := &api.PullRequest{
@@ -107,7 +108,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
 			Name:       pr.BaseBranch,
 			Ref:        pr.BaseBranch,
 			RepoID:     pr.BaseRepoID,
-			Repository: ToRepo(ctx, pr.BaseRepo, p),
+			Repository: ToRepo(ctx, pr.BaseRepo, repoUserPerm),
 		},
 		Head: &api.PRBranchInfo{
 			Name:   pr.HeadBranch,
diff --git a/services/git/commit.go b/services/git/commit.go
index 8ab8f3d369..3faef76782 100644
--- a/services/git/commit.go
+++ b/services/git/commit.go
@@ -17,7 +17,7 @@ import (
 )
 
 // ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
-func ParseCommitsWithSignature(ctx context.Context, oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isOwnerMemberCollaborator func(*user_model.User) (bool, error)) ([]*asymkey_model.SignCommit, error) {
+func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository, oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType) ([]*asymkey_model.SignCommit, error) {
 	newCommits := make([]*asymkey_model.SignCommit, 0, len(oldCommits))
 	keyMap := map[string]bool{}
 
@@ -47,6 +47,10 @@ func ParseCommitsWithSignature(ctx context.Context, oldCommits []*user_model.Use
 			Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, c.Commit, committer),
 		}
 
+		isOwnerMemberCollaborator := func(user *user_model.User) (bool, error) {
+			return repo_model.IsOwnerMemberCollaborator(ctx, repo, user.ID)
+		}
+
 		_ = asymkey_model.CalculateTrustStatus(signCommit.Verification, repoTrustModel, isOwnerMemberCollaborator, &keyMap)
 
 		newCommits = append(newCommits, signCommit)
@@ -62,11 +66,9 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo
 	}
 	signedCommits, err := ParseCommitsWithSignature(
 		ctx,
+		repo,
 		validatedCommits,
 		repo.GetTrustModel(),
-		func(user *user_model.User) (bool, error) {
-			return repo_model.IsOwnerMemberCollaborator(ctx, repo, user.ID)
-		},
 	)
 	if err != nil {
 		return nil, err
diff --git a/services/org/team.go b/services/org/team.go
index ee3bd898ea..6890dafd90 100644
--- a/services/org/team.go
+++ b/services/org/team.go
@@ -259,37 +259,6 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode
 		}
 
 		team.NumMembers++
-
-		// Give access to team repositories.
-		// update exist access if mode become bigger
-		subQuery := builder.Select("repo_id").From("team_repo").
-			Where(builder.Eq{"team_id": team.ID})
-
-		if _, err := sess.Where("user_id=?", user.ID).
-			In("repo_id", subQuery).
-			And("mode < ?", team.AccessMode).
-			SetExpr("mode", team.AccessMode).
-			Update(new(access_model.Access)); err != nil {
-			return fmt.Errorf("update user accesses: %w", err)
-		}
-
-		// for not exist access
-		var repoIDs []int64
-		accessSubQuery := builder.Select("repo_id").From("access").Where(builder.Eq{"user_id": user.ID})
-		if err := sess.SQL(subQuery.And(builder.NotIn("repo_id", accessSubQuery))).Find(&repoIDs); err != nil {
-			return fmt.Errorf("select id accesses: %w", err)
-		}
-
-		accesses := make([]*access_model.Access, 0, 100)
-		for i, repoID := range repoIDs {
-			accesses = append(accesses, &access_model.Access{RepoID: repoID, UserID: user.ID, Mode: team.AccessMode})
-			if (i%100 == 0 || i == len(repoIDs)-1) && len(accesses) > 0 {
-				if err = db.Insert(ctx, accesses); err != nil {
-					return fmt.Errorf("insert new user accesses: %w", err)
-				}
-				accesses = accesses[:0]
-			}
-		}
 		return nil
 	})
 	if err != nil {
diff --git a/services/org/team_test.go b/services/org/team_test.go
index a7070fadb0..831fe1669f 100644
--- a/services/org/team_test.go
+++ b/services/org/team_test.go
@@ -166,24 +166,6 @@ func TestRemoveTeamMember(t *testing.T) {
 	assert.True(t, organization.IsErrLastOrgOwner(err))
 }
 
-func TestRepository_RecalculateAccesses3(t *testing.T) {
-	assert.NoError(t, unittest.PrepareTestDatabase())
-	team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
-	user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
-
-	has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: user29.ID, RepoID: 23})
-	assert.NoError(t, err)
-	assert.False(t, has)
-
-	// adding user29 to team5 should add an explicit access row for repo 23
-	// even though repo 23 is public
-	assert.NoError(t, AddTeamMember(db.DefaultContext, team5, user29))
-
-	has, err = db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: user29.ID, RepoID: 23})
-	assert.NoError(t, err)
-	assert.True(t, has)
-}
-
 func TestIncludesAllRepositoriesTeams(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 
diff --git a/services/pull/patch.go b/services/pull/patch.go
index 68f3f02669..7a24237724 100644
--- a/services/pull/patch.go
+++ b/services/pull/patch.go
@@ -355,23 +355,19 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
 	}
 
 	// 3b. Create a plain patch from head to base
-	tmpPatchFile, err := os.CreateTemp("", "patch")
+	tmpPatchFile, cleanup, err := setting.AppDataTempDir("git-repo-content").CreateTempFileRandom("patch")
 	if err != nil {
 		log.Error("Unable to create temporary patch file! Error: %v", err)
 		return false, fmt.Errorf("unable to create temporary patch file! Error: %w", err)
 	}
-	defer func() {
-		_ = util.Remove(tmpPatchFile.Name())
-	}()
+	defer cleanup()
 
 	if err := gitRepo.GetDiffBinary(pr.MergeBase+"...tracking", tmpPatchFile); err != nil {
-		tmpPatchFile.Close()
 		log.Error("Unable to get patch file from %s to %s in %s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err)
 		return false, fmt.Errorf("unable to get patch file from %s to %s in %s Error: %w", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err)
 	}
 	stat, err := tmpPatchFile.Stat()
 	if err != nil {
-		tmpPatchFile.Close()
 		return false, fmt.Errorf("unable to stat patch file: %w", err)
 	}
 	patchPath := tmpPatchFile.Name()
diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go
index 3f33370798..d543e3d4a3 100644
--- a/services/pull/temp_repo.go
+++ b/services/pull/temp_repo.go
@@ -74,11 +74,13 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
 	}
 
 	// Clone base repo.
-	tmpBasePath, err := repo_module.CreateTemporaryPath("pull")
+	tmpBasePath, cleanup, err := repo_module.CreateTemporaryPath("pull")
 	if err != nil {
 		log.Error("CreateTemporaryPath[%-v]: %v", pr, err)
 		return nil, nil, err
 	}
+	cancel = cleanup
+
 	prCtx = &prContext{
 		Context:     ctx,
 		tmpBasePath: tmpBasePath,
@@ -86,11 +88,6 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
 		outbuf:      &strings.Builder{},
 		errbuf:      &strings.Builder{},
 	}
-	cancel = func() {
-		if err := repo_module.RemoveTemporaryPath(tmpBasePath); err != nil {
-			log.Error("Error whilst removing removing temporary repo for %-v: %v", pr, err)
-		}
-	}
 
 	baseRepoPath := pr.BaseRepo.RepoPath()
 	headRepoPath := pr.HeadRepo.RepoPath()
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index b7321156d9..6d5505c42c 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -16,7 +16,6 @@ import (
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/container"
-	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/optional"
@@ -28,18 +27,30 @@ import (
 	"github.com/gobwas/glob"
 )
 
+func deleteFailedAdoptRepository(repoID int64) error {
+	return db.WithTx(db.DefaultContext, func(ctx context.Context) error {
+		if err := deleteDBRepository(ctx, repoID); err != nil {
+			return fmt.Errorf("deleteDBRepository: %w", err)
+		}
+		if err := git_model.DeleteRepoBranches(ctx, repoID); err != nil {
+			return fmt.Errorf("deleteRepoBranches: %w", err)
+		}
+		return repo_model.DeleteRepoReleases(ctx, repoID)
+	})
+}
+
 // AdoptRepository adopts pre-existing repository files for the user/organization.
-func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) {
-	if !doer.IsAdmin && !u.CanCreateRepo() {
+func AdoptRepository(ctx context.Context, doer, owner *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) {
+	if !doer.CanCreateRepoIn(owner) {
 		return nil, repo_model.ErrReachLimitOfRepo{
-			Limit: u.MaxRepoCreation,
+			Limit: owner.MaxRepoCreation,
 		}
 	}
 
 	repo := &repo_model.Repository{
-		OwnerID:                         u.ID,
-		Owner:                           u,
-		OwnerName:                       u.Name,
+		OwnerID:                         owner.ID,
+		Owner:                           owner,
+		OwnerName:                       owner.Name,
 		Name:                            opts.Name,
 		LowerName:                       strings.ToLower(opts.Name),
 		Description:                     opts.Description,
@@ -48,59 +59,52 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR
 		IsPrivate:                       opts.IsPrivate,
 		IsFsckEnabled:                   !opts.IsMirror,
 		CloseIssuesViaCommitInAnyBranch: setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch,
-		Status:                          opts.Status,
+		Status:                          repo_model.RepositoryBeingMigrated,
 		IsEmpty:                         !opts.AutoInit,
 	}
 
-	if err := db.WithTx(ctx, func(ctx context.Context) error {
-		isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
+	// 1 - create the repository database operations first
+	err := db.WithTx(ctx, func(ctx context.Context) error {
+		return createRepositoryInDB(ctx, doer, owner, repo, false)
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	// last - clean up if something goes wrong
+	// WARNING: Don't override all later err with local variables
+	defer func() {
 		if err != nil {
-			log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
-			return err
-		}
-		if !isExist {
-			return repo_model.ErrRepoNotExist{
-				OwnerName: u.Name,
-				Name:      repo.Name,
+			// we can not use the ctx because it maybe canceled or timeout
+			if errDel := deleteFailedAdoptRepository(repo.ID); errDel != nil {
+				log.Error("Failed to delete repository %s that could not be adopted: %v", repo.FullName(), errDel)
 			}
 		}
+	}()
 
-		if err := CreateRepositoryByExample(ctx, doer, u, repo, true, false); err != nil {
-			return err
-		}
-
-		// Re-fetch the repository from database before updating it (else it would
-		// override changes that were done earlier with sql)
-		if repo, err = repo_model.GetRepositoryByID(ctx, repo.ID); err != nil {
-			return fmt.Errorf("getRepositoryByID: %w", err)
-		}
-		return nil
-	}); err != nil {
-		return nil, err
+	// Re-fetch the repository from database before updating it (else it would
+	// override changes that were done earlier with sql)
+	if repo, err = repo_model.GetRepositoryByID(ctx, repo.ID); err != nil {
+		return nil, fmt.Errorf("getRepositoryByID: %w", err)
 	}
 
-	if err := func() error {
-		if err := adoptRepository(ctx, repo, opts.DefaultBranch); err != nil {
-			return fmt.Errorf("adoptRepository: %w", err)
-		}
-
-		if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
-			return fmt.Errorf("checkDaemonExportOK: %w", err)
-		}
-
-		if stdout, _, err := git.NewCommand("update-server-info").
-			RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil {
-			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
-			return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
-		}
-		return nil
-	}(); err != nil {
-		if errDel := DeleteRepository(ctx, doer, repo, false /* no notify */); errDel != nil {
-			log.Error("Failed to delete repository %s that could not be adopted: %v", repo.FullName(), errDel)
-		}
-		return nil, err
+	// 2 - adopt the repository from disk
+	if err = adoptRepository(ctx, repo, opts.DefaultBranch); err != nil {
+		return nil, fmt.Errorf("adoptRepository: %w", err)
 	}
-	notify_service.AdoptRepository(ctx, doer, u, repo)
+
+	// 3 - Update the git repository
+	if err = updateGitRepoAfterCreate(ctx, repo); err != nil {
+		return nil, fmt.Errorf("updateGitRepoAfterCreate: %w", err)
+	}
+
+	// 4 - update repository status
+	repo.Status = repo_model.RepositoryReady
+	if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
+		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
+	}
+
+	notify_service.AdoptRepository(ctx, doer, owner, repo)
 
 	return repo, nil
 }
diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go
index 294185ea1f..6e1dc417b3 100644
--- a/services/repository/adopt_test.go
+++ b/services/repository/adopt_test.go
@@ -14,6 +14,7 @@ import (
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/util"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -89,10 +90,36 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
 
 func TestAdoptRepository(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
-	assert.NoError(t, unittest.SyncDirs(filepath.Join(setting.RepoRootPath, "user2", "repo1.git"), filepath.Join(setting.RepoRootPath, "user2", "test-adopt.git")))
+
 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
-	_, err := AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"})
+
+	// a successful adopt
+	destDir := filepath.Join(setting.RepoRootPath, user2.Name, "test-adopt.git")
+	assert.NoError(t, unittest.SyncDirs(filepath.Join(setting.RepoRootPath, user2.Name, "repo1.git"), destDir))
+
+	adoptedRepo, err := AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"})
 	assert.NoError(t, err)
 	repoTestAdopt := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "test-adopt"})
 	assert.Equal(t, "sha1", repoTestAdopt.ObjectFormatName)
+
+	// just delete the adopted repo's db records
+	err = deleteFailedAdoptRepository(adoptedRepo.ID)
+	assert.NoError(t, err)
+
+	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: "test-adopt"})
+
+	// a failed adopt because some mock data
+	// remove the hooks directory and create a file so that we cannot create the hooks successfully
+	_ = os.RemoveAll(filepath.Join(destDir, "hooks", "update.d"))
+	assert.NoError(t, os.WriteFile(filepath.Join(destDir, "hooks", "update.d"), []byte("tests"), os.ModePerm))
+
+	adoptedRepo, err = AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"})
+	assert.Error(t, err)
+	assert.Nil(t, adoptedRepo)
+
+	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: "test-adopt"})
+
+	exist, err := util.IsExist(repo_model.RepoPath(user2.Name, "test-adopt"))
+	assert.NoError(t, err)
+	assert.True(t, exist) // the repository should be still in the disk
 }
diff --git a/services/repository/create.go b/services/repository/create.go
index af4e897151..5a9b2ecd2a 100644
--- a/services/repository/create.go
+++ b/services/repository/create.go
@@ -17,6 +17,7 @@ import (
 	"code.gitea.io/gitea/models/perm"
 	access_model "code.gitea.io/gitea/models/perm/access"
 	repo_model "code.gitea.io/gitea/models/repo"
+	system_model "code.gitea.io/gitea/models/system"
 	"code.gitea.io/gitea/models/unit"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/models/webhook"
@@ -28,7 +29,6 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/templates/vars"
-	"code.gitea.io/gitea/modules/util"
 )
 
 // CreateRepoOptions contains the create repository options
@@ -140,21 +140,20 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir
 
 // InitRepository initializes README and .gitignore if needed.
 func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) {
-	if err = repo_module.CheckInitRepository(ctx, repo); err != nil {
-		return err
+	// Init git bare new repository.
+	if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil {
+		return fmt.Errorf("git.InitRepository: %w", err)
+	} else if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil {
+		return fmt.Errorf("createDelegateHooks: %w", err)
 	}
 
 	// Initialize repository according to user's choice.
 	if opts.AutoInit {
-		tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name)
+		tmpDir, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("repos-" + repo.Name)
 		if err != nil {
-			return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err)
+			return fmt.Errorf("failed to create temp dir for repository %s: %w", repo.FullName(), err)
 		}
-		defer func() {
-			if err := util.RemoveAll(tmpDir); err != nil {
-				log.Warn("Unable to remove temporary directory: %s: Error: %v", tmpDir, err)
-			}
-		}()
+		defer cleanup()
 
 		if err = prepareRepoCommit(ctx, repo, tmpDir, opts); err != nil {
 			return fmt.Errorf("prepareRepoCommit: %w", err)
@@ -200,10 +199,10 @@ func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Re
 }
 
 // CreateRepositoryDirectly creates a repository for the user/organization.
-func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) {
-	if !doer.IsAdmin && !u.CanCreateRepo() {
+func CreateRepositoryDirectly(ctx context.Context, doer, owner *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) {
+	if !doer.CanCreateRepoIn(owner) {
 		return nil, repo_model.ErrReachLimitOfRepo{
-			Limit: u.MaxRepoCreation,
+			Limit: owner.MaxRepoCreation,
 		}
 	}
 
@@ -223,9 +222,9 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt
 	}
 
 	repo := &repo_model.Repository{
-		OwnerID:                         u.ID,
-		Owner:                           u,
-		OwnerName:                       u.Name,
+		OwnerID:                         owner.ID,
+		Owner:                           owner,
+		OwnerName:                       owner.Name,
 		Name:                            opts.Name,
 		LowerName:                       strings.ToLower(opts.Name),
 		Description:                     opts.Description,
@@ -244,100 +243,93 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt
 		ObjectFormatName:                opts.ObjectFormatName,
 	}
 
-	var rollbackRepo *repo_model.Repository
-
-	if err := db.WithTx(ctx, func(ctx context.Context) error {
-		if err := CreateRepositoryByExample(ctx, doer, u, repo, false, false); err != nil {
-			return err
-		}
-
-		// No need for init mirror.
-		if opts.IsMirror {
-			return nil
-		}
-
-		isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
-		if err != nil {
-			log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
-			return err
-		}
-		if isExist {
-			// repo already exists - We have two or three options.
-			// 1. We fail stating that the directory exists
-			// 2. We create the db repository to go with this data and adopt the git repo
-			// 3. We delete it and start afresh
-			//
-			// Previously Gitea would just delete and start afresh - this was naughty.
-			// So we will now fail and delegate to other functionality to adopt or delete
-			log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName())
-			return repo_model.ErrRepoFilesAlreadyExist{
-				Uname: u.Name,
-				Name:  repo.Name,
-			}
-		}
-
-		if err = initRepository(ctx, doer, repo, opts); err != nil {
-			if err2 := gitrepo.DeleteRepository(ctx, repo); err2 != nil {
-				log.Error("initRepository: %v", err)
-				return fmt.Errorf(
-					"delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2)
-			}
-			return fmt.Errorf("initRepository: %w", err)
-		}
-
-		// Initialize Issue Labels if selected
-		if len(opts.IssueLabels) > 0 {
-			if err = repo_module.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil {
-				rollbackRepo = repo
-				rollbackRepo.OwnerID = u.ID
-				return fmt.Errorf("InitializeLabels: %w", err)
-			}
-		}
-
-		if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
-			return fmt.Errorf("checkDaemonExportOK: %w", err)
-		}
-
-		if stdout, _, err := git.NewCommand("update-server-info").
-			RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil {
-			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
-			rollbackRepo = repo
-			rollbackRepo.OwnerID = u.ID
-			return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
-		}
-
-		// update licenses
-		var licenses []string
-		if len(opts.License) > 0 {
-			licenses = append(licenses, opts.License)
-
-			stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
-			if err != nil {
-				log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err)
-				rollbackRepo = repo
-				rollbackRepo.OwnerID = u.ID
-				return fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err)
-			}
-			if err := repo_model.UpdateRepoLicenses(ctx, repo, stdout, licenses); err != nil {
-				return err
-			}
-		}
-		return nil
-	}); err != nil {
-		if rollbackRepo != nil {
-			if errDelete := DeleteRepositoryDirectly(ctx, doer, rollbackRepo.ID); errDelete != nil {
-				log.Error("Rollback deleteRepository: %v", errDelete)
-			}
-		}
+	needsUpdateStatus := opts.Status != repo_model.RepositoryReady
 
+	// 1 - create the repository database operations first
+	err := db.WithTx(ctx, func(ctx context.Context) error {
+		return createRepositoryInDB(ctx, doer, owner, repo, false)
+	})
+	if err != nil {
 		return nil, err
 	}
 
+	// last - clean up if something goes wrong
+	// WARNING: Don't override all later err with local variables
+	defer func() {
+		if err != nil {
+			// we can not use the ctx because it maybe canceled or timeout
+			cleanupRepository(doer, repo.ID)
+		}
+	}()
+
+	// No need for init mirror.
+	if opts.IsMirror {
+		return repo, nil
+	}
+
+	// 2 - check whether the repository with the same storage exists
+	var isExist bool
+	isExist, err = gitrepo.IsRepositoryExist(ctx, repo)
+	if err != nil {
+		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
+		return nil, err
+	}
+	if isExist {
+		log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName())
+		// Don't return directly, we need err in defer to cleanupRepository
+		err = repo_model.ErrRepoFilesAlreadyExist{
+			Uname: repo.OwnerName,
+			Name:  repo.Name,
+		}
+		return nil, err
+	}
+
+	// 3 - init git repository in storage
+	if err = initRepository(ctx, doer, repo, opts); err != nil {
+		return nil, fmt.Errorf("initRepository: %w", err)
+	}
+
+	// 4 - Initialize Issue Labels if selected
+	if len(opts.IssueLabels) > 0 {
+		if err = repo_module.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil {
+			return nil, fmt.Errorf("InitializeLabels: %w", err)
+		}
+	}
+
+	// 5 - Update the git repository
+	if err = updateGitRepoAfterCreate(ctx, repo); err != nil {
+		return nil, fmt.Errorf("updateGitRepoAfterCreate: %w", err)
+	}
+
+	// 6 - update licenses
+	var licenses []string
+	if len(opts.License) > 0 {
+		licenses = append(licenses, opts.License)
+
+		var stdout string
+		stdout, _, err = git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
+		if err != nil {
+			log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err)
+			return nil, fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err)
+		}
+		if err = repo_model.UpdateRepoLicenses(ctx, repo, stdout, licenses); err != nil {
+			return nil, err
+		}
+	}
+
+	// 7 - update repository status to be ready
+	if needsUpdateStatus {
+		repo.Status = repo_model.RepositoryReady
+		if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
+			return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
+		}
+	}
+
 	return repo, nil
 }
 
-// CreateRepositoryByExample creates a repository for the user/organization.
-func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt, isFork bool) (err error) {
+// createRepositoryInDB creates a repository for the user/organization.
+func createRepositoryInDB(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, isFork bool) (err error) {
 	if err = repo_model.IsUsableRepoName(repo.Name); err != nil {
 		return err
 	}
@@ -352,19 +344,6 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re
 		}
 	}
 
-	isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
-	if err != nil {
-		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
-		return err
-	}
-	if !overwriteOrAdopt && isExist {
-		log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName())
-		return repo_model.ErrRepoFilesAlreadyExist{
-			Uname: u.Name,
-			Name:  repo.Name,
-		}
-	}
-
 	if err = db.Insert(ctx, repo); err != nil {
 		return err
 	}
@@ -473,3 +452,26 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re
 
 	return nil
 }
+
+func cleanupRepository(doer *user_model.User, repoID int64) {
+	if errDelete := DeleteRepositoryDirectly(db.DefaultContext, doer, repoID); errDelete != nil {
+		log.Error("cleanupRepository failed: %v", errDelete)
+		// add system notice
+		if err := system_model.CreateRepositoryNotice("DeleteRepositoryDirectly failed when cleanup repository: %v", errDelete); err != nil {
+			log.Error("CreateRepositoryNotice: %v", err)
+		}
+	}
+}
+
+func updateGitRepoAfterCreate(ctx context.Context, repo *repo_model.Repository) error {
+	if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
+		return fmt.Errorf("checkDaemonExportOK: %w", err)
+	}
+
+	if stdout, _, err := git.NewCommand("update-server-info").
+		RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil {
+		log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
+		return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
+	}
+	return nil
+}
diff --git a/services/repository/create_test.go b/services/repository/create_test.go
new file mode 100644
index 0000000000..9ecf404e8b
--- /dev/null
+++ b/services/repository/create_test.go
@@ -0,0 +1,57 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repository
+
+import (
+	"os"
+	"testing"
+
+	"code.gitea.io/gitea/models/db"
+	repo_model "code.gitea.io/gitea/models/repo"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/util"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestCreateRepositoryDirectly(t *testing.T) {
+	assert.NoError(t, unittest.PrepareTestDatabase())
+
+	// a successful creating repository
+	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+	createdRepo, err := CreateRepositoryDirectly(git.DefaultContext, user2, user2, CreateRepoOptions{
+		Name: "created-repo",
+	})
+	assert.NoError(t, err)
+	assert.NotNil(t, createdRepo)
+
+	exist, err := util.IsExist(repo_model.RepoPath(user2.Name, createdRepo.Name))
+	assert.NoError(t, err)
+	assert.True(t, exist)
+
+	unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: createdRepo.Name})
+
+	err = DeleteRepositoryDirectly(db.DefaultContext, user2, createdRepo.ID)
+	assert.NoError(t, err)
+
+	// a failed creating because some mock data
+	// create the repository directory so that the creation will fail after database record created.
+	assert.NoError(t, os.MkdirAll(repo_model.RepoPath(user2.Name, createdRepo.Name), os.ModePerm))
+
+	createdRepo2, err := CreateRepositoryDirectly(db.DefaultContext, user2, user2, CreateRepoOptions{
+		Name: "created-repo",
+	})
+	assert.Nil(t, createdRepo2)
+	assert.Error(t, err)
+
+	// assert the cleanup is successful
+	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: createdRepo.Name})
+
+	exist, err = util.IsExist(repo_model.RepoPath(user2.Name, createdRepo.Name))
+	assert.NoError(t, err)
+	assert.False(t, exist)
+}
diff --git a/services/repository/delete.go b/services/repository/delete.go
index ff74a20817..cf960af8cf 100644
--- a/services/repository/delete.go
+++ b/services/repository/delete.go
@@ -32,6 +32,19 @@ import (
 	"xorm.io/builder"
 )
 
+func deleteDBRepository(ctx context.Context, repoID int64) error {
+	if cnt, err := db.GetEngine(ctx).ID(repoID).Delete(&repo_model.Repository{}); err != nil {
+		return err
+	} else if cnt != 1 {
+		return repo_model.ErrRepoNotExist{
+			ID:        repoID,
+			OwnerName: "",
+			Name:      "",
+		}
+	}
+	return nil
+}
+
 // DeleteRepository deletes a repository for a user or organization.
 // make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock)
 func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID int64, ignoreOrgTeams ...bool) error {
@@ -82,14 +95,8 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID
 	}
 	needRewriteKeysFile := deleted > 0
 
-	if cnt, err := sess.ID(repoID).Delete(&repo_model.Repository{}); err != nil {
+	if err := deleteDBRepository(ctx, repoID); err != nil {
 		return err
-	} else if cnt != 1 {
-		return repo_model.ErrRepoNotExist{
-			ID:        repoID,
-			OwnerName: "",
-			Name:      "",
-		}
 	}
 
 	if org != nil && org.IsOrganization() {
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 1969676ab4..493ff9998d 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -30,23 +30,24 @@ type TemporaryUploadRepository struct {
 	repo     *repo_model.Repository
 	gitRepo  *git.Repository
 	basePath string
+	cleanup  func()
 }
 
 // NewTemporaryUploadRepository creates a new temporary upload repository
 func NewTemporaryUploadRepository(repo *repo_model.Repository) (*TemporaryUploadRepository, error) {
-	basePath, err := repo_module.CreateTemporaryPath("upload")
+	basePath, cleanup, err := repo_module.CreateTemporaryPath("upload")
 	if err != nil {
 		return nil, err
 	}
-	t := &TemporaryUploadRepository{repo: repo, basePath: basePath}
+	t := &TemporaryUploadRepository{repo: repo, basePath: basePath, cleanup: cleanup}
 	return t, nil
 }
 
 // Close the repository cleaning up all files
 func (t *TemporaryUploadRepository) Close() {
 	defer t.gitRepo.Close()
-	if err := repo_module.RemoveTemporaryPath(t.basePath); err != nil {
-		log.Error("Failed to remove temporary path %s: %v", t.basePath, err)
+	if t.cleanup != nil {
+		t.cleanup()
 	}
 }
 
diff --git a/services/repository/fork.go b/services/repository/fork.go
index 5b1ba7a418..1794cc18ab 100644
--- a/services/repository/fork.go
+++ b/services/repository/fork.go
@@ -65,7 +65,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 	}
 
 	// Fork is prohibited, if user has reached maximum limit of repositories
-	if !owner.CanForkRepo() {
+	if !doer.CanForkRepoIn(owner) {
 		return nil, repo_model.ErrReachLimitOfRepo{
 			Limit: owner.MaxRepoCreation,
 		}
@@ -100,114 +100,106 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 		IsFork:           true,
 		ForkID:           opts.BaseRepo.ID,
 		ObjectFormatName: opts.BaseRepo.ObjectFormatName,
+		Status:           repo_model.RepositoryBeingMigrated,
 	}
 
-	oldRepoPath := opts.BaseRepo.RepoPath()
-
-	needsRollback := false
-	rollbackFn := func() {
-		if !needsRollback {
-			return
-		}
-
-		if exists, _ := gitrepo.IsRepositoryExist(ctx, repo); !exists {
-			return
-		}
-
-		// As the transaction will be failed and hence database changes will be destroyed we only need
-		// to delete the related repository on the filesystem
-		if errDelete := gitrepo.DeleteRepository(ctx, repo); errDelete != nil {
-			log.Error("Failed to remove fork repo")
-		}
-	}
-
-	needsRollbackInPanic := true
-	defer func() {
-		panicErr := recover()
-		if panicErr == nil {
-			return
-		}
-
-		if needsRollbackInPanic {
-			rollbackFn()
-		}
-		panic(panicErr)
-	}()
-
-	err = db.WithTx(ctx, func(txCtx context.Context) error {
-		if err = CreateRepositoryByExample(txCtx, doer, owner, repo, false, true); err != nil {
+	// 1 - Create the repository in the database
+	err = db.WithTx(ctx, func(ctx context.Context) error {
+		if err = createRepositoryInDB(ctx, doer, owner, repo, true); err != nil {
 			return err
 		}
-
-		if err = repo_model.IncrementRepoForkNum(txCtx, opts.BaseRepo.ID); err != nil {
+		if err = repo_model.IncrementRepoForkNum(ctx, opts.BaseRepo.ID); err != nil {
 			return err
 		}
 
 		// copy lfs files failure should not be ignored
-		if err = git_model.CopyLFS(txCtx, repo, opts.BaseRepo); err != nil {
-			return err
-		}
-
-		needsRollback = true
-
-		cloneCmd := git.NewCommand("clone", "--bare")
-		if opts.SingleBranch != "" {
-			cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch)
-		}
-		if stdout, _, err := cloneCmd.AddDynamicArguments(oldRepoPath, repo.RepoPath()).
-			RunStdBytes(txCtx, &git.RunOpts{Timeout: 10 * time.Minute}); err != nil {
-			log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
-			return fmt.Errorf("git clone: %w", err)
-		}
-
-		if err := repo_module.CheckDaemonExportOK(txCtx, repo); err != nil {
-			return fmt.Errorf("checkDaemonExportOK: %w", err)
-		}
-
-		if stdout, _, err := git.NewCommand("update-server-info").
-			RunStdString(txCtx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil {
-			log.Error("Fork Repository (git update-server-info) failed for %v:\nStdout: %s\nError: %v", repo, stdout, err)
-			return fmt.Errorf("git update-server-info: %w", err)
-		}
-
-		if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil {
-			return fmt.Errorf("createDelegateHooks: %w", err)
-		}
-
-		gitRepo, err := gitrepo.OpenRepository(txCtx, repo)
-		if err != nil {
-			return fmt.Errorf("OpenRepository: %w", err)
-		}
-		defer gitRepo.Close()
-
-		_, err = repo_module.SyncRepoBranchesWithRepo(txCtx, repo, gitRepo, doer.ID)
-		return err
+		return git_model.CopyLFS(ctx, repo, opts.BaseRepo)
 	})
-	needsRollbackInPanic = false
 	if err != nil {
-		rollbackFn()
 		return nil, err
 	}
 
-	// even if below operations failed, it could be ignored. And they will be retried
-	if err := repo_module.UpdateRepoSize(ctx, repo); err != nil {
-		log.Error("Failed to update size for repository: %v", err)
-	}
-	if err := repo_model.CopyLanguageStat(ctx, opts.BaseRepo, repo); err != nil {
-		log.Error("Copy language stat from oldRepo failed: %v", err)
-	}
-	if err := repo_model.CopyLicense(ctx, opts.BaseRepo, repo); err != nil {
-		return nil, err
-	}
-
-	gitRepo, err := gitrepo.OpenRepository(ctx, repo)
-	if err != nil {
-		log.Error("Open created git repository failed: %v", err)
-	} else {
-		defer gitRepo.Close()
-		if err := repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
-			log.Error("Sync releases from git tags failed: %v", err)
+	// last - clean up if something goes wrong
+	// WARNING: Don't override all later err with local variables
+	defer func() {
+		if err != nil {
+			// we can not use the ctx because it maybe canceled or timeout
+			cleanupRepository(doer, repo.ID)
 		}
+	}()
+
+	// 2 - check whether the repository with the same storage exists
+	var isExist bool
+	isExist, err = gitrepo.IsRepositoryExist(ctx, repo)
+	if err != nil {
+		log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err)
+		return nil, err
+	}
+	if isExist {
+		log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName())
+		// Don't return directly, we need err in defer to cleanupRepository
+		err = repo_model.ErrRepoFilesAlreadyExist{
+			Uname: repo.OwnerName,
+			Name:  repo.Name,
+		}
+		return nil, err
+	}
+
+	// 3 - Clone the repository
+	cloneCmd := git.NewCommand("clone", "--bare")
+	if opts.SingleBranch != "" {
+		cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch)
+	}
+	var stdout []byte
+	if stdout, _, err = cloneCmd.AddDynamicArguments(opts.BaseRepo.RepoPath(), repo.RepoPath()).
+		RunStdBytes(ctx, &git.RunOpts{Timeout: 10 * time.Minute}); err != nil {
+		log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
+		return nil, fmt.Errorf("git clone: %w", err)
+	}
+
+	// 4 - Update the git repository
+	if err = updateGitRepoAfterCreate(ctx, repo); err != nil {
+		return nil, fmt.Errorf("updateGitRepoAfterCreate: %w", err)
+	}
+
+	// 5 - Create hooks
+	if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil {
+		return nil, fmt.Errorf("createDelegateHooks: %w", err)
+	}
+
+	// 6 - Sync the repository branches and tags
+	var gitRepo *git.Repository
+	gitRepo, err = gitrepo.OpenRepository(ctx, repo)
+	if err != nil {
+		return nil, fmt.Errorf("OpenRepository: %w", err)
+	}
+	defer gitRepo.Close()
+
+	if _, err = repo_module.SyncRepoBranchesWithRepo(ctx, repo, gitRepo, doer.ID); err != nil {
+		return nil, fmt.Errorf("SyncRepoBranchesWithRepo: %w", err)
+	}
+	if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
+		return nil, fmt.Errorf("Sync releases from git tags failed: %v", err)
+	}
+
+	// 7 - Update the repository
+	// even if below operations failed, it could be ignored. And they will be retried
+	if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
+		log.Error("Failed to update size for repository: %v", err)
+		err = nil
+	}
+	if err = repo_model.CopyLanguageStat(ctx, opts.BaseRepo, repo); err != nil {
+		log.Error("Copy language stat from oldRepo failed: %v", err)
+		err = nil
+	}
+	if err = repo_model.CopyLicense(ctx, opts.BaseRepo, repo); err != nil {
+		return nil, err
+	}
+
+	// 8 - update repository status to be ready
+	repo.Status = repo_model.RepositoryReady
+	if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
+		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 	}
 
 	notify_service.ForkRepository(ctx, doer, opts.BaseRepo, repo)
diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go
index 452798b25b..9edc0aa39f 100644
--- a/services/repository/fork_test.go
+++ b/services/repository/fork_test.go
@@ -4,13 +4,16 @@
 package repository
 
 import (
+	"os"
 	"testing"
 
+	"code.gitea.io/gitea/models/db"
 	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/util"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -46,3 +49,43 @@ func TestForkRepository(t *testing.T) {
 	assert.Nil(t, fork2)
 	assert.True(t, repo_model.IsErrReachLimitOfRepo(err))
 }
+
+func TestForkRepositoryCleanup(t *testing.T) {
+	assert.NoError(t, unittest.PrepareTestDatabase())
+
+	// a successful fork
+	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+	repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
+
+	fork, err := ForkRepository(git.DefaultContext, user2, user2, ForkRepoOptions{
+		BaseRepo: repo10,
+		Name:     "test",
+	})
+	assert.NoError(t, err)
+	assert.NotNil(t, fork)
+
+	exist, err := util.IsExist(repo_model.RepoPath(user2.Name, "test"))
+	assert.NoError(t, err)
+	assert.True(t, exist)
+
+	err = DeleteRepositoryDirectly(db.DefaultContext, user2, fork.ID)
+	assert.NoError(t, err)
+
+	// a failed creating because some mock data
+	// create the repository directory so that the creation will fail after database record created.
+	assert.NoError(t, os.MkdirAll(repo_model.RepoPath(user2.Name, "test"), os.ModePerm))
+
+	fork2, err := ForkRepository(db.DefaultContext, user2, user2, ForkRepoOptions{
+		BaseRepo: repo10,
+		Name:     "test",
+	})
+	assert.Nil(t, fork2)
+	assert.Error(t, err)
+
+	// assert the cleanup is successful
+	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: "test"})
+
+	exist, err = util.IsExist(repo_model.RepoPath(user2.Name, "test"))
+	assert.NoError(t, err)
+	assert.False(t, exist)
+}
diff --git a/services/repository/generate.go b/services/repository/generate.go
index 9d2bbb1f7f..b02f7c9482 100644
--- a/services/repository/generate.go
+++ b/services/repository/generate.go
@@ -17,11 +17,11 @@ import (
 
 	git_model "code.gitea.io/gitea/models/git"
 	repo_model "code.gitea.io/gitea/models/repo"
-	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/gitrepo"
 	"code.gitea.io/gitea/modules/log"
 	repo_module "code.gitea.io/gitea/modules/repository"
+	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
 	"github.com/gobwas/glob"
@@ -256,16 +256,11 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
 }
 
 func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository) (err error) {
-	tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name)
+	tmpDir, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-" + repo.Name)
 	if err != nil {
-		return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err)
+		return fmt.Errorf("failed to create temp dir for repository %s: %w", repo.FullName(), err)
 	}
-
-	defer func() {
-		if err := util.RemoveAll(tmpDir); err != nil {
-			log.Error("RemoveAll: %v", err)
-		}
-	}()
+	defer cleanup()
 
 	if err = generateRepoCommit(ctx, repo, templateRepo, generateRepo, tmpDir); err != nil {
 		return fmt.Errorf("generateRepoCommit: %w", err)
@@ -328,57 +323,6 @@ func (gro GenerateRepoOptions) IsValid() bool {
 		gro.IssueLabels || gro.ProtectedBranch // or other items as they are added
 }
 
-// generateRepository generates a repository from a template
-func generateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts GenerateRepoOptions) (_ *repo_model.Repository, err error) {
-	generateRepo := &repo_model.Repository{
-		OwnerID:          owner.ID,
-		Owner:            owner,
-		OwnerName:        owner.Name,
-		Name:             opts.Name,
-		LowerName:        strings.ToLower(opts.Name),
-		Description:      opts.Description,
-		DefaultBranch:    opts.DefaultBranch,
-		IsPrivate:        opts.Private,
-		IsEmpty:          !opts.GitContent || templateRepo.IsEmpty,
-		IsFsckEnabled:    templateRepo.IsFsckEnabled,
-		TemplateID:       templateRepo.ID,
-		TrustModel:       templateRepo.TrustModel,
-		ObjectFormatName: templateRepo.ObjectFormatName,
-	}
-
-	if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false, false); err != nil {
-		return nil, err
-	}
-
-	isExist, err := gitrepo.IsRepositoryExist(ctx, generateRepo)
-	if err != nil {
-		log.Error("Unable to check if %s exists. Error: %v", generateRepo.FullName(), err)
-		return nil, err
-	}
-	if isExist {
-		return nil, repo_model.ErrRepoFilesAlreadyExist{
-			Uname: generateRepo.OwnerName,
-			Name:  generateRepo.Name,
-		}
-	}
-
-	if err = repo_module.CheckInitRepository(ctx, generateRepo); err != nil {
-		return generateRepo, err
-	}
-
-	if err = repo_module.CheckDaemonExportOK(ctx, generateRepo); err != nil {
-		return generateRepo, fmt.Errorf("checkDaemonExportOK: %w", err)
-	}
-
-	if stdout, _, err := git.NewCommand("update-server-info").
-		RunStdString(ctx, &git.RunOpts{Dir: generateRepo.RepoPath()}); err != nil {
-		log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err)
-		return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %w", err)
-	}
-
-	return generateRepo, nil
-}
-
 var fileNameSanitizeRegexp = regexp.MustCompile(`(?i)\.\.|[<>:\"/\\|?*\x{0000}-\x{001F}]|^(con|prn|aux|nul|com\d|lpt\d)$`)
 
 // Sanitize user input to valid OS filenames
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 2a17e9acd9..003be1a9ab 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -118,14 +118,8 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
 		repo.Owner = u
 	}
 
-	if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
-		return repo, fmt.Errorf("checkDaemonExportOK: %w", err)
-	}
-
-	if stdout, _, err := git.NewCommand("update-server-info").
-		RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil {
-		log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
-		return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %w", err)
+	if err := updateGitRepoAfterCreate(ctx, repo); err != nil {
+		return nil, fmt.Errorf("updateGitRepoAfterCreate: %w", err)
 	}
 
 	gitRepo, err := git.OpenRepository(ctx, repoPath)
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 10f175d989..cd56010546 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -13,7 +13,6 @@ import (
 	issues_model "code.gitea.io/gitea/models/issues"
 	"code.gitea.io/gitea/models/organization"
 	repo_model "code.gitea.io/gitea/models/repo"
-	system_model "code.gitea.io/gitea/models/system"
 	"code.gitea.io/gitea/models/unit"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/graceful"
@@ -102,8 +101,6 @@ func Init(ctx context.Context) error {
 	if err := repo_module.LoadRepoConfig(); err != nil {
 		return err
 	}
-	system_model.RemoveAllWithNotice(ctx, "Clean up temporary repository uploads", setting.Repository.Upload.TempPath)
-	system_model.RemoveAllWithNotice(ctx, "Clean up temporary repositories", repo_module.LocalCopyPath())
 	if err := initPushQueue(); err != nil {
 		return err
 	}
diff --git a/services/repository/template.go b/services/repository/template.go
index 36a680c8e2..95f585cead 100644
--- a/services/repository/template.go
+++ b/services/repository/template.go
@@ -5,12 +5,17 @@ package repository
 
 import (
 	"context"
+	"fmt"
+	"strings"
 
 	"code.gitea.io/gitea/models/db"
 	git_model "code.gitea.io/gitea/models/git"
 	issues_model "code.gitea.io/gitea/models/issues"
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/gitrepo"
+	"code.gitea.io/gitea/modules/log"
 	notify_service "code.gitea.io/gitea/services/notify"
 )
 
@@ -63,72 +68,126 @@ func GenerateProtectedBranch(ctx context.Context, templateRepo, generateRepo *re
 
 // GenerateRepository generates a repository from a template
 func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts GenerateRepoOptions) (_ *repo_model.Repository, err error) {
-	if !doer.IsAdmin && !owner.CanCreateRepo() {
+	if !doer.CanCreateRepoIn(owner) {
 		return nil, repo_model.ErrReachLimitOfRepo{
 			Limit: owner.MaxRepoCreation,
 		}
 	}
 
-	var generateRepo *repo_model.Repository
-	if err = db.WithTx(ctx, func(ctx context.Context) error {
-		generateRepo, err = generateRepository(ctx, doer, owner, templateRepo, opts)
-		if err != nil {
-			return err
-		}
+	generateRepo := &repo_model.Repository{
+		OwnerID:          owner.ID,
+		Owner:            owner,
+		OwnerName:        owner.Name,
+		Name:             opts.Name,
+		LowerName:        strings.ToLower(opts.Name),
+		Description:      opts.Description,
+		DefaultBranch:    opts.DefaultBranch,
+		IsPrivate:        opts.Private,
+		IsEmpty:          !opts.GitContent || templateRepo.IsEmpty,
+		IsFsckEnabled:    templateRepo.IsFsckEnabled,
+		TemplateID:       templateRepo.ID,
+		TrustModel:       templateRepo.TrustModel,
+		ObjectFormatName: templateRepo.ObjectFormatName,
+		Status:           repo_model.RepositoryBeingMigrated,
+	}
 
-		// Git Content
-		if opts.GitContent && !templateRepo.IsEmpty {
-			if err = GenerateGitContent(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		// Topics
-		if opts.Topics {
-			if err = repo_model.GenerateTopics(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		// Git Hooks
-		if opts.GitHooks {
-			if err = GenerateGitHooks(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		// Webhooks
-		if opts.Webhooks {
-			if err = GenerateWebhooks(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		// Avatar
-		if opts.Avatar && len(templateRepo.Avatar) > 0 {
-			if err = generateAvatar(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		// Issue Labels
-		if opts.IssueLabels {
-			if err = GenerateIssueLabels(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		if opts.ProtectedBranch {
-			if err = GenerateProtectedBranch(ctx, templateRepo, generateRepo); err != nil {
-				return err
-			}
-		}
-
-		return nil
+	// 1 - Create the repository in the database
+	if err := db.WithTx(ctx, func(ctx context.Context) error {
+		return createRepositoryInDB(ctx, doer, owner, generateRepo, false)
 	}); err != nil {
 		return nil, err
 	}
 
+	// last - clean up the repository if something goes wrong
+	defer func() {
+		if err != nil {
+			// we can not use the ctx because it maybe canceled or timeout
+			cleanupRepository(doer, generateRepo.ID)
+		}
+	}()
+
+	// 2 - check whether the repository with the same storage exists
+	isExist, err := gitrepo.IsRepositoryExist(ctx, generateRepo)
+	if err != nil {
+		log.Error("Unable to check if %s exists. Error: %v", generateRepo.FullName(), err)
+		return nil, err
+	}
+	if isExist {
+		// Don't return directly, we need err in defer to cleanupRepository
+		err = repo_model.ErrRepoFilesAlreadyExist{
+			Uname: generateRepo.OwnerName,
+			Name:  generateRepo.Name,
+		}
+		return nil, err
+	}
+
+	// 3 -Init git bare new repository.
+	if err = git.InitRepository(ctx, generateRepo.RepoPath(), true, generateRepo.ObjectFormatName); err != nil {
+		return nil, fmt.Errorf("git.InitRepository: %w", err)
+	} else if err = gitrepo.CreateDelegateHooks(ctx, generateRepo); err != nil {
+		return nil, fmt.Errorf("createDelegateHooks: %w", err)
+	}
+
+	// 4 - Update the git repository
+	if err = updateGitRepoAfterCreate(ctx, generateRepo); err != nil {
+		return nil, fmt.Errorf("updateGitRepoAfterCreate: %w", err)
+	}
+
+	// 5 - generate the repository contents according to the template
+	// Git Content
+	if opts.GitContent && !templateRepo.IsEmpty {
+		if err = GenerateGitContent(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// Topics
+	if opts.Topics {
+		if err = repo_model.GenerateTopics(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// Git Hooks
+	if opts.GitHooks {
+		if err = GenerateGitHooks(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// Webhooks
+	if opts.Webhooks {
+		if err = GenerateWebhooks(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// Avatar
+	if opts.Avatar && len(templateRepo.Avatar) > 0 {
+		if err = generateAvatar(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// Issue Labels
+	if opts.IssueLabels {
+		if err = GenerateIssueLabels(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	if opts.ProtectedBranch {
+		if err = GenerateProtectedBranch(ctx, templateRepo, generateRepo); err != nil {
+			return nil, err
+		}
+	}
+
+	// 6 - update repository status to be ready
+	generateRepo.Status = repo_model.RepositoryReady
+	if err = repo_model.UpdateRepositoryCols(ctx, generateRepo, "status"); err != nil {
+		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
+	}
+
 	notify_service.CreateRepository(ctx, doer, owner, generateRepo)
 
 	return generateRepo, nil
diff --git a/services/repository/transfer.go b/services/repository/transfer.go
index 4e44b90df2..86917ad285 100644
--- a/services/repository/transfer.go
+++ b/services/repository/transfer.go
@@ -61,7 +61,7 @@ func AcceptTransferOwnership(ctx context.Context, repo *repo_model.Repository, d
 			return err
 		}
 
-		if !doer.IsAdmin && !repoTransfer.Recipient.CanCreateRepo() {
+		if !doer.CanCreateRepoIn(repoTransfer.Recipient) {
 			limit := util.Iif(repoTransfer.Recipient.MaxRepoCreation >= 0, repoTransfer.Recipient.MaxRepoCreation, setting.Repository.MaxCreationLimit)
 			return LimitReachedError{Limit: limit}
 		}
@@ -416,7 +416,7 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
 		return err
 	}
 
-	if !doer.IsAdmin && !newOwner.CanCreateRepo() {
+	if !doer.CanForkRepoIn(newOwner) {
 		limit := util.Iif(newOwner.MaxRepoCreation >= 0, newOwner.MaxRepoCreation, setting.Repository.MaxCreationLimit)
 		return LimitReachedError{Limit: limit}
 	}
diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go
index bf71c7ca2e..80a073e9f9 100644
--- a/services/repository/transfer_test.go
+++ b/services/repository/transfer_test.go
@@ -144,7 +144,7 @@ func TestRepositoryTransferRejection(t *testing.T) {
 	require.NotNil(t, transfer)
 	require.NoError(t, transfer.LoadRecipient(db.DefaultContext))
 
-	require.True(t, transfer.Recipient.CanCreateRepo()) // admin is not subject to limits
+	require.True(t, doerAdmin.CanCreateRepoIn(transfer.Recipient)) // admin is not subject to limits
 
 	// Administrator should not be affected by the limits so transfer should be successful
 	assert.NoError(t, AcceptTransferOwnership(db.DefaultContext, repo, doerAdmin))
@@ -158,7 +158,7 @@ func TestRepositoryTransferRejection(t *testing.T) {
 	require.NotNil(t, transfer)
 	require.NoError(t, transfer.LoadRecipient(db.DefaultContext))
 
-	require.False(t, transfer.Recipient.CanCreateRepo()) // regular user is subject to limits
+	require.False(t, doer.CanCreateRepoIn(transfer.Recipient)) // regular user is subject to limits
 
 	// Cannot accept because of the limit
 	err = AcceptTransferOwnership(db.DefaultContext, repo, doer)
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index b21f46639d..45a08dc5d6 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -102,15 +102,11 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
 
 	hasDefaultBranch := gitrepo.IsBranchExist(ctx, repo.WikiStorageRepo(), repo.DefaultWikiBranch)
 
-	basePath, err := repo_module.CreateTemporaryPath("update-wiki")
+	basePath, cleanup, err := repo_module.CreateTemporaryPath("update-wiki")
 	if err != nil {
 		return err
 	}
-	defer func() {
-		if err := repo_module.RemoveTemporaryPath(basePath); err != nil {
-			log.Error("Merge: RemoveTemporaryPath: %s", err)
-		}
-	}()
+	defer cleanup()
 
 	cloneOpts := git.CloneRepoOptions{
 		Bare:   true,
@@ -264,15 +260,11 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
 		return fmt.Errorf("InitWiki: %w", err)
 	}
 
-	basePath, err := repo_module.CreateTemporaryPath("update-wiki")
+	basePath, cleanup, err := repo_module.CreateTemporaryPath("update-wiki")
 	if err != nil {
 		return err
 	}
-	defer func() {
-		if err := repo_module.RemoveTemporaryPath(basePath); err != nil {
-			log.Error("Merge: RemoveTemporaryPath: %s", err)
-		}
-	}()
+	defer cleanup()
 
 	if err := git.Clone(ctx, repo.WikiPath(), basePath, git.CloneRepoOptions{
 		Bare:   true,
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 88dadeb3ee..806347c720 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -69,10 +69,6 @@
 					{{if not .SSH.StartBuiltinServer}}
 						<dt>{{ctx.Locale.Tr "admin.config.ssh_root_path"}}</dt>
 						<dd>{{.SSH.RootPath}}</dd>
-						<dt>{{ctx.Locale.Tr "admin.config.ssh_key_test_path"}}</dt>
-						<dd>{{.SSH.KeyTestPath}}</dd>
-						<dt>{{ctx.Locale.Tr "admin.config.ssh_keygen_path"}}</dt>
-						<dd>{{.SSH.KeygenPath}}</dd>
 						<dt>{{ctx.Locale.Tr "admin.config.ssh_minimum_key_size_check"}}</dt>
 						<dd>{{svg (Iif .SSH.MinimumKeySizeCheck "octicon-check" "octicon-x")}}</dd>
 						{{if .SSH.MinimumKeySizeCheck}}
diff --git a/templates/org/team/new.tmpl b/templates/org/team/new.tmpl
index b67c18dd7d..67529ddfba 100644
--- a/templates/org/team/new.tmpl
+++ b/templates/org/team/new.tmpl
@@ -56,7 +56,7 @@
 								<br>
 								<div class="field">
 									<div class="ui radio checkbox">
-										<input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
+										<input type="radio" name="permission" value="read" {{if or .PageIsOrgTeamsNew (eq .Team.AccessMode 0) (eq .Team.AccessMode 1) (eq .Team.AccessMode 2)}}checked{{end}}>
 										<label>{{ctx.Locale.Tr "org.teams.general_access"}}</label>
 										<span class="help">{{ctx.Locale.Tr "org.teams.general_access_helper"}}</span>
 									</div>
diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl
index c4acd8da24..8390bf0acd 100644
--- a/templates/org/team/sidebar.tmpl
+++ b/templates/org/team/sidebar.tmpl
@@ -42,10 +42,12 @@
 						<li>{{ctx.Locale.Tr "org.teams.can_create_org_repo"}}</li>
 					{{end}}
 				</ul>
-				{{if (eq .Team.AccessMode 2)}}
+				{{/* the AccessMode should be either none or admin/owner, the real permissions are provided by each team unit */}}
+				{{if false}}{{/*(eq .Team.AccessMode 2)*/}}
 					<h3>{{ctx.Locale.Tr "org.settings.permission"}}</h3>
 					{{ctx.Locale.Tr "org.teams.write_permission_desc"}}
 				{{else if (eq .Team.AccessMode 3)}}
+					{{/* FIXME: here might not right, see "FIXME: TEAM-UNIT-PERMISSION", new units might not have correct admin permission*/}}
 					<h3>{{ctx.Locale.Tr "org.settings.permission"}}</h3>
 					{{ctx.Locale.Tr "org.teams.admin_permission_desc"}}
 				{{else}}
diff --git a/templates/repo/actions/status.tmpl b/templates/repo/actions/status.tmpl
index 64c2543302..f2020bc160 100644
--- a/templates/repo/actions/status.tmpl
+++ b/templates/repo/actions/status.tmpl
@@ -16,7 +16,7 @@
 {{else if eq .status "blocked"}}
 	{{svg "octicon-blocked" $size (printf "text yellow %s" $className)}}
 {{else if eq .status "running"}}
-	{{svg "octicon-meter" $size (printf "text yellow job-status-rotate %s" $className)}}
+	{{svg "octicon-meter" $size (printf "text yellow circular-spin %s" $className)}}
 {{else}}{{/*failure, unknown*/}}
 	{{svg "octicon-x-circle-fill" $size (printf "text red %s" $className)}}
 {{end}}
diff --git a/templates/repo/clone_panel.tmpl b/templates/repo/clone_panel.tmpl
index 2ed8f52fbe..0e3c13eaa2 100644
--- a/templates/repo/clone_panel.tmpl
+++ b/templates/repo/clone_panel.tmpl
@@ -1,6 +1,6 @@
 <button class="ui primary button js-btn-clone-panel">
 	{{svg "octicon-code" 16}}
-	<span>Code</span>
+	<span>{{ctx.Locale.Tr "repo.code"}}</span>
 	{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 </button>
 <div class="clone-panel-popup tippy-target">
diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl
index 9a6c44077f..adf9e250c1 100644
--- a/templates/repo/pulls/fork.tmpl
+++ b/templates/repo/pulls/fork.tmpl
@@ -75,7 +75,7 @@
 
 				<div class="inline field">
 					<label></label>
-					<button class="ui primary button{{if not .CanForkRepo}} disabled{{end}}">
+					<button class="ui primary button{{if not .CanForkRepoInNewOwner}} disabled{{end}}">
 						{{ctx.Locale.Tr "repo.fork_repo"}}
 					</button>
 				</div>
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index 202be3fce7..4d61604612 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -802,7 +802,7 @@
 						</div>
 					</div>
 				{{end}}
-				{{if and .Repository.IsFork .Repository.Owner.CanCreateRepo}}
+				{{if .CanConvertFork}}
 					<div class="flex-item">
 						<div class="flex-item-main">
 							<div class="flex-item-title">{{ctx.Locale.Tr "repo.settings.convert_fork"}}</div>
@@ -916,7 +916,7 @@
 			</div>
 		</div>
 	{{end}}
-	{{if and .Repository.IsFork .Repository.Owner.CanCreateRepo}}
+	{{if .CanConvertFork}}
 		<div class="ui small modal" id="convert-fork-repo-modal">
 			<div class="header">
 				{{ctx.Locale.Tr "repo.settings.convert_fork"}}
diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go
index a2a2f388fd..e54203ed50 100644
--- a/tests/integration/api_team_test.go
+++ b/tests/integration/api_team_test.go
@@ -78,9 +78,9 @@ func TestAPITeam(t *testing.T) {
 	apiTeam = api.Team{}
 	DecodeJSON(t, resp, &apiTeam)
 	checkTeamResponse(t, "CreateTeam1", &apiTeam, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		teamToCreate.Permission, teamToCreate.Units, nil)
+		"none", teamToCreate.Units, nil)
 	checkTeamBean(t, apiTeam.ID, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		teamToCreate.Permission, teamToCreate.Units, nil)
+		"none", teamToCreate.Units, nil)
 	teamID := apiTeam.ID
 
 	// Edit team.
@@ -149,9 +149,9 @@ func TestAPITeam(t *testing.T) {
 	apiTeam = api.Team{}
 	DecodeJSON(t, resp, &apiTeam)
 	checkTeamResponse(t, "CreateTeam2", &apiTeam, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		"read", nil, teamToCreate.UnitsMap)
+		"none", nil, teamToCreate.UnitsMap)
 	checkTeamBean(t, apiTeam.ID, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		"read", nil, teamToCreate.UnitsMap)
+		"none", nil, teamToCreate.UnitsMap)
 	teamID = apiTeam.ID
 
 	// Edit team.
@@ -171,9 +171,9 @@ func TestAPITeam(t *testing.T) {
 	apiTeam = api.Team{}
 	DecodeJSON(t, resp, &apiTeam)
 	checkTeamResponse(t, "EditTeam2", &apiTeam, teamToEdit.Name, *teamToEdit.Description, *teamToEdit.IncludesAllRepositories,
-		"read", nil, teamToEdit.UnitsMap)
+		"none", nil, teamToEdit.UnitsMap)
 	checkTeamBean(t, apiTeam.ID, teamToEdit.Name, *teamToEdit.Description, *teamToEdit.IncludesAllRepositories,
-		"read", nil, teamToEdit.UnitsMap)
+		"none", nil, teamToEdit.UnitsMap)
 
 	// Edit team Description only
 	editDescription = "second team"
@@ -184,9 +184,9 @@ func TestAPITeam(t *testing.T) {
 	apiTeam = api.Team{}
 	DecodeJSON(t, resp, &apiTeam)
 	checkTeamResponse(t, "EditTeam2_DescOnly", &apiTeam, teamToEdit.Name, *teamToEditDesc.Description, *teamToEdit.IncludesAllRepositories,
-		"read", nil, teamToEdit.UnitsMap)
+		"none", nil, teamToEdit.UnitsMap)
 	checkTeamBean(t, apiTeam.ID, teamToEdit.Name, *teamToEditDesc.Description, *teamToEdit.IncludesAllRepositories,
-		"read", nil, teamToEdit.UnitsMap)
+		"none", nil, teamToEdit.UnitsMap)
 
 	// Read team.
 	teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
diff --git a/tests/integration/migration-test/migration_test.go b/tests/integration/migration-test/migration_test.go
index ffb8afa9c5..0fc8a6e24d 100644
--- a/tests/integration/migration-test/migration_test.go
+++ b/tests/integration/migration-test/migration_test.go
@@ -52,7 +52,7 @@ func initMigrationTest(t *testing.T) func() {
 		setting.CustomConf = giteaConf
 	}
 
-	unittest.InitSettings()
+	unittest.InitSettingsForTesting()
 
 	assert.NotEmpty(t, setting.RepoRootPath)
 	assert.NoError(t, unittest.SyncDirs(filepath.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
diff --git a/tests/integration/org_test.go b/tests/integration/org_test.go
index b1376fe1bf..9a93455858 100644
--- a/tests/integration/org_test.go
+++ b/tests/integration/org_test.go
@@ -177,9 +177,9 @@ func TestOrgRestrictedUser(t *testing.T) {
 	resp := adminSession.MakeRequest(t, req, http.StatusCreated)
 	DecodeJSON(t, resp, &apiTeam)
 	checkTeamResponse(t, "CreateTeam_codereader", &apiTeam, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		teamToCreate.Permission, teamToCreate.Units, nil)
+		"none", teamToCreate.Units, nil)
 	checkTeamBean(t, apiTeam.ID, teamToCreate.Name, teamToCreate.Description, teamToCreate.IncludesAllRepositories,
-		teamToCreate.Permission, teamToCreate.Units, nil)
+		"none", teamToCreate.Units, nil)
 	// teamID := apiTeam.ID
 
 	// Now we need to add the restricted user to the team
diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go
index da5aaf3da0..c04d09af08 100644
--- a/tests/integration/repo_test.go
+++ b/tests/integration/repo_test.go
@@ -6,15 +6,23 @@ package integration
 import (
 	"fmt"
 	"net/http"
+	"os"
 	"path"
 	"strconv"
 	"strings"
 	"testing"
 	"time"
 
+	"code.gitea.io/gitea/models/db"
+	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unit"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/test"
+	"code.gitea.io/gitea/modules/util"
+	repo_service "code.gitea.io/gitea/services/repository"
 	"code.gitea.io/gitea/tests"
 
 	"github.com/PuerkitoBio/goquery"
@@ -493,3 +501,46 @@ func testViewCommit(t *testing.T) {
 	resp := MakeRequest(t, req, http.StatusNotFound)
 	assert.True(t, test.IsNormalPageCompleted(resp.Body.String()), "non-existing commit should render 404 page")
 }
+
+// TestGenerateRepository the test cannot succeed when moved as a unit test
+func TestGenerateRepository(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	// a successful generate from template
+	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+	repo44 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44})
+
+	generatedRepo, err := repo_service.GenerateRepository(git.DefaultContext, user2, user2, repo44, repo_service.GenerateRepoOptions{
+		Name:       "generated-from-template-44",
+		GitContent: true,
+	})
+	assert.NoError(t, err)
+	assert.NotNil(t, generatedRepo)
+
+	exist, err := util.IsExist(repo_model.RepoPath(user2.Name, generatedRepo.Name))
+	assert.NoError(t, err)
+	assert.True(t, exist)
+
+	unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: generatedRepo.Name})
+
+	err = repo_service.DeleteRepositoryDirectly(db.DefaultContext, user2, generatedRepo.ID)
+	assert.NoError(t, err)
+
+	// a failed creating because some mock data
+	// create the repository directory so that the creation will fail after database record created.
+	assert.NoError(t, os.MkdirAll(repo_model.RepoPath(user2.Name, "generated-from-template-44"), os.ModePerm))
+
+	generatedRepo2, err := repo_service.GenerateRepository(db.DefaultContext, user2, user2, repo44, repo_service.GenerateRepoOptions{
+		Name:       "generated-from-template-44",
+		GitContent: true,
+	})
+	assert.Nil(t, generatedRepo2)
+	assert.Error(t, err)
+
+	// assert the cleanup is successful
+	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: generatedRepo.Name})
+
+	exist, err = util.IsExist(repo_model.RepoPath(user2.Name, generatedRepo.Name))
+	assert.NoError(t, err)
+	assert.False(t, exist)
+}
diff --git a/tests/test_utils.go b/tests/test_utils.go
index 6c95716e67..4d8a8635d6 100644
--- a/tests/test_utils.go
+++ b/tests/test_utils.go
@@ -18,7 +18,6 @@ import (
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/graceful"
 	"code.gitea.io/gitea/modules/log"
-	repo_module "code.gitea.io/gitea/modules/repository"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/storage"
 	"code.gitea.io/gitea/modules/test"
@@ -67,9 +66,8 @@ func InitTest(requireGitea bool) {
 		setting.CustomConf = giteaConf
 	}
 
-	unittest.InitSettings()
+	unittest.InitSettingsForTesting()
 	setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
-	_ = util.RemoveAll(repo_module.LocalCopyPath())
 
 	if err := git.InitFull(context.Background()); err != nil {
 		log.Fatal("git.InitOnceWithSync: %v", err)
diff --git a/web_src/css/base.css b/web_src/css/base.css
index de656c0d95..5a0579f356 100644
--- a/web_src/css/base.css
+++ b/web_src/css/base.css
@@ -1181,3 +1181,15 @@ the "!important" is necessary to override Fomantic UI menu item styles, meanwhil
   flex-grow: 1;
   justify-content: space-between;
 }
+
+.svg.octicon-file-directory-fill,
+.svg.octicon-file-directory-open-fill,
+.svg.octicon-file-submodule {
+  color: var(--color-primary);
+}
+
+.svg.octicon-file,
+.svg.octicon-file-symlink-file,
+.svg.octicon-file-directory-symlink {
+  color: var(--color-secondary-dark-7);
+}
diff --git a/web_src/css/modules/animations.css b/web_src/css/modules/animations.css
index 481e997d4f..173ca73314 100644
--- a/web_src/css/modules/animations.css
+++ b/web_src/css/modules/animations.css
@@ -116,3 +116,13 @@ code.language-math.is-loading::after {
   animation-duration: 100ms;
   animation-timing-function: ease-in-out;
 }
+
+.circular-spin {
+  animation: circular-spin-keyframes 1s linear infinite;
+}
+
+@keyframes circular-spin-keyframes {
+  100% {
+    transform: rotate(-360deg);
+  }
+}
diff --git a/web_src/css/repo/home-file-list.css b/web_src/css/repo/home-file-list.css
index 46128457ed..f2ab052a54 100644
--- a/web_src/css/repo/home-file-list.css
+++ b/web_src/css/repo/home-file-list.css
@@ -14,17 +14,6 @@
   }
 }
 
-#repo-files-table .svg.octicon-file-directory-fill,
-#repo-files-table .svg.octicon-file-submodule {
-  color: var(--color-primary);
-}
-
-#repo-files-table .svg.octicon-file,
-#repo-files-table .svg.octicon-file-symlink-file,
-#repo-files-table .svg.octicon-file-directory-symlink {
-  color: var(--color-secondary-dark-7);
-}
-
 #repo-files-table .repo-file-item {
   display: contents;
 }
diff --git a/web_src/js/components/ActionRunStatus.vue b/web_src/js/components/ActionRunStatus.vue
index 487d2460cc..bc3b99ab89 100644
--- a/web_src/js/components/ActionRunStatus.vue
+++ b/web_src/js/components/ActionRunStatus.vue
@@ -24,7 +24,7 @@ withDefaults(defineProps<{
     <SvgIcon name="octicon-stop" class="text yellow" :size="size" :class="className" v-else-if="status === 'cancelled'"/>
     <SvgIcon name="octicon-clock" class="text yellow" :size="size" :class="className" v-else-if="status === 'waiting'"/>
     <SvgIcon name="octicon-blocked" class="text yellow" :size="size" :class="className" v-else-if="status === 'blocked'"/>
-    <SvgIcon name="octicon-meter" class="text yellow" :size="size" :class="'job-status-rotate ' + className" v-else-if="status === 'running'"/>
+    <SvgIcon name="octicon-meter" class="text yellow" :size="size" :class="'circular-spin ' + className" v-else-if="status === 'running'"/>
     <SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else/><!-- failure, unknown -->
   </span>
 </template>
diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue
index 640ad8341f..5a4c22bc90 100644
--- a/web_src/js/components/RepoActionView.vue
+++ b/web_src/js/components/RepoActionView.vue
@@ -574,7 +574,7 @@ export default defineComponent({
               <!-- If the job is done and the job step log is loaded for the first time, show the loading icon
                 currentJobStepsStates[i].cursor === null means the log is loaded for the first time
               -->
-              <SvgIcon v-if="isDone(run.status) && currentJobStepsStates[i].expanded && currentJobStepsStates[i].cursor === null" name="octicon-sync" class="tw-mr-2 job-status-rotate"/>
+              <SvgIcon v-if="isDone(run.status) && currentJobStepsStates[i].expanded && currentJobStepsStates[i].cursor === null" name="octicon-sync" class="tw-mr-2 circular-spin"/>
               <SvgIcon v-else :name="currentJobStepsStates[i].expanded ? 'octicon-chevron-down': 'octicon-chevron-right'" :class="['tw-mr-2', !isExpandable(jobStep.status) && 'tw-invisible']"/>
               <ActionRunStatus :status="jobStep.status" class="tw-mr-2"/>
 
@@ -896,16 +896,6 @@ export default defineComponent({
 
 <style> /* eslint-disable-line vue-scoped-css/enforce-style-type */
 /* some elements are not managed by vue, so we need to use global style */
-.job-status-rotate {
-  animation: job-status-rotate-keyframes 1s linear infinite;
-}
-
-@keyframes job-status-rotate-keyframes {
-  100% {
-    transform: rotate(-360deg);
-  }
-}
-
 .job-step-section {
   margin: 10px;
 }
diff --git a/web_src/js/components/RepoCodeFrequency.vue b/web_src/js/components/RepoCodeFrequency.vue
index 7696996cf6..f04fc065b6 100644
--- a/web_src/js/components/RepoCodeFrequency.vue
+++ b/web_src/js/components/RepoCodeFrequency.vue
@@ -150,7 +150,7 @@ const options: ChartOptions<'line'> = {
     <div class="tw-flex ui segment main-graph">
       <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto">
         <div v-if="isLoading">
-          <SvgIcon name="octicon-sync" class="tw-mr-2 job-status-rotate"/>
+          <SvgIcon name="octicon-sync" class="tw-mr-2 circular-spin"/>
           {{ locale.loadingInfo }}
         </div>
         <div v-else class="text red">
diff --git a/web_src/js/components/RepoContributors.vue b/web_src/js/components/RepoContributors.vue
index 6ad2c848b1..b725f272a7 100644
--- a/web_src/js/components/RepoContributors.vue
+++ b/web_src/js/components/RepoContributors.vue
@@ -375,7 +375,7 @@ export default defineComponent({
     <div class="tw-flex ui segment main-graph">
       <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto">
         <div v-if="isLoading">
-          <SvgIcon name="octicon-sync" class="tw-mr-2 job-status-rotate"/>
+          <SvgIcon name="octicon-sync" class="tw-mr-2 circular-spin"/>
           {{ locale.loadingInfo }}
         </div>
         <div v-else class="text red">
diff --git a/web_src/js/components/RepoRecentCommits.vue b/web_src/js/components/RepoRecentCommits.vue
index 10e1fdd70c..1b3d8fd459 100644
--- a/web_src/js/components/RepoRecentCommits.vue
+++ b/web_src/js/components/RepoRecentCommits.vue
@@ -128,7 +128,7 @@ const options: ChartOptions<'bar'> = {
     <div class="tw-flex ui segment main-graph">
       <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto">
         <div v-if="isLoading">
-          <SvgIcon name="octicon-sync" class="tw-mr-2 job-status-rotate"/>
+          <SvgIcon name="octicon-sync" class="tw-mr-2 circular-spin"/>
           {{ locale.loadingInfo }}
         </div>
         <div v-else class="text red">
diff --git a/web_src/js/components/ViewFileTreeItem.vue b/web_src/js/components/ViewFileTreeItem.vue
index 69e26dbc33..c39fa1f4ae 100644
--- a/web_src/js/components/ViewFileTreeItem.vue
+++ b/web_src/js/components/ViewFileTreeItem.vue
@@ -58,7 +58,8 @@ const doGotoSubModule = () => {
   >
     <!-- submodule -->
     <div class="item-content">
-      <SvgIcon class="text primary" name="octicon-file-submodule"/>
+      <!-- eslint-disable-next-line vue/no-v-html -->
+      <span class="tw-contents" v-html="item.entryIcon"/>
       <span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
     </div>
   </div>
@@ -70,7 +71,8 @@ const doGotoSubModule = () => {
   >
     <!-- symlink -->
     <div class="item-content">
-      <SvgIcon name="octicon-file-symlink-file"/>
+      <!-- eslint-disable-next-line vue/no-v-html -->
+      <span class="tw-contents" v-html="item.entryIcon"/>
       <span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
     </div>
   </div>
@@ -83,7 +85,7 @@ const doGotoSubModule = () => {
     <!-- file -->
     <div class="item-content">
       <!-- eslint-disable-next-line vue/no-v-html -->
-      <span v-html="item.entryIcon"/>
+      <span class="tw-contents" v-html="item.entryIcon"/>
       <span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
     </div>
   </div>
@@ -95,13 +97,12 @@ const doGotoSubModule = () => {
   >
     <!-- directory -->
     <div class="item-toggle">
-      <!-- FIXME: use a general and global class for this animation -->
-      <SvgIcon v-if="isLoading" name="octicon-sync" class="job-status-rotate"/>
+      <SvgIcon v-if="isLoading" name="octicon-sync" class="circular-spin"/>
       <SvgIcon v-else :name="collapsed ? 'octicon-chevron-right' : 'octicon-chevron-down'" @click.stop="doLoadChildren"/>
     </div>
     <div class="item-content">
       <!-- eslint-disable-next-line vue/no-v-html -->
-      <span class="text primary" v-html="(!collapsed && item.entryIconOpen) ? item.entryIconOpen : item.entryIcon"/>
+      <span class="tw-contents" v-html="(!collapsed && item.entryIconOpen) ? item.entryIconOpen : item.entryIcon"/>
       <span class="gt-ellipsis">{{ item.entryName }}</span>
     </div>
   </div>
@@ -154,7 +155,7 @@ const doGotoSubModule = () => {
   grid-area: content;
   display: flex;
   align-items: center;
-  gap: 0.25em;
+  gap: 0.5em;
   text-overflow: ellipsis;
   min-width: 0;
 }