diff --git a/docs/.gitignore b/docs/.gitignore index ff878b5dd9..8982bf978a 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,15 +1,3 @@ -node_modules -dist - -upload -data/* -tmp - -.DS_Store -.idea - -coverage -.nyc_ .vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 0000000000..c11b8ba5d8 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,85 @@ +import { defineConfig } from 'vitepress' +import { NavItemsInEnglish, SidebarItemsInEnglish } from './en.mts' +import { NavItemsInZh, SidebarItemsInZh } from './zh.mts' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + lastUpdated: true, + markdown: { + lineNumbers: true, + }, + + locales: { + root: { + label: '简体中文', + lang: 'zh-CN', + link: '/zh/', + title: "Laf 开发文档", + description: "laf 开发文档,像写博客一样写函数。", + themeConfig: { + logo: "/logo.png", + footer: { + message: "Apache License V2.0", + copyright: "Copyright © 2021-2024 labring/laf", + }, + editLink: { + pattern: "https://github.com/labring/laf/edit/main/docs/:path", + text: "我修改这一页", + }, + lastUpdated: { + text: "更新于" + }, + docFooter: { + prev: '上一篇', + next: '下一篇' + }, + socialLinks: [ + { icon: "github", link: "https://github.com/labring/laf" }, + { icon: "discord", link: "https://discord.gg/KaxHF86CcF" }, + { icon: "twitter", link: "https://twitter.com/laf_dev" }, + ], + returnToTopLabel: '返回顶部', + externalLinkIcon: true, + outline: 'deep', + + // https://vitepress.dev/reference/default-theme-config + nav: NavItemsInZh, + + sidebar: SidebarItemsInZh, + }, + }, + en: { + label: 'English', + lang: 'en', + link: '/en/', + title: "Laf Documentation", + description: "Development documentation of laf, write function like writing blog.", + themeConfig: { + logo: "/logo.png", + footer: { + message: "Apache License V2.0", + copyright: "Copyright © 2021-2024 labring/laf", + }, + editLink: { + pattern: "https://github.com/labring/laf/edit/main/docs/:path", + text: "Edit this page on GitHub", + }, + socialLinks: [ + { icon: "github", link: "https://github.com/labring/laf" }, + { icon: "discord", link: "https://discord.gg/KaxHF86CcF" }, + { icon: "twitter", link: "https://twitter.com/laf_dev" }, + ], + + outline: 'deep', + + externalLinkIcon: true, + + // https://vitepress.dev/reference/default-theme-config + nav: NavItemsInEnglish, + + sidebar: SidebarItemsInEnglish, + } + }, + }, + +}) diff --git a/docs/.vitepress/en.mts b/docs/.vitepress/en.mts new file mode 100644 index 0000000000..0868f3f651 --- /dev/null +++ b/docs/.vitepress/en.mts @@ -0,0 +1,17 @@ +import { DefaultTheme } from 'vitepress' + + +export const NavItemsInEnglish: DefaultTheme.NavItem[] = [ + // { text: 'Guides', link: '/en/' }, + // { text: 'Examples', link: './markdown-examples' } +] + +export const SidebarItemsInEnglish: DefaultTheme.SidebarItem[] = [ + { + text: 'Getting Started', + items: [ + { text: 'Overview', link: '/en/' }, + { text: 'Architecture', link: '/en/architecture' }, + ] + } +] \ No newline at end of file diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 8e037902a3..eb4452dc79 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -1,34 +1,21 @@ -:root { - --vp-c-brand: #646cff; - --vp-c-brand-light: #747bff; - --vp-c-brand-dark: #323cf7; +.VPSidebar::-webkit-scrollbar { + display: none; } -.inline img { - display: inline; +/* +.VPDocAside .outline-link { + color: rgb(6, 63, 148); } -.search { - flex-grow: 1; - padding-left: 24px; +.VPDocAside .outline-link { + font-size: 14px; } -.search button { - justify-content: flex-start; - border: 1px solid transparent; - border-radius: 8px; - padding: 0 10px 0 12px; - width: 100%; - height: 40px; - margin-right: -20px; - background-color: #f6f6f7; +.VPDocAside .outline-link.active { + color: rgb(82, 7, 234); } -.search button:hover { - border: 1px solid var(--vp-c-brand); - background-color: #f6f6f7; -} -.dark .search button { - background-color: var(--vp-c-bg); -} +.VPDocAside .outline-link:hover { + color: rgb(82, 7, 234); +} */ \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000000..508d8b4af1 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme \ No newline at end of file diff --git a/docs/.vitepress/zh.mts b/docs/.vitepress/zh.mts new file mode 100644 index 0000000000..1b7dedde4b --- /dev/null +++ b/docs/.vitepress/zh.mts @@ -0,0 +1,140 @@ +import { DefaultTheme } from 'vitepress' + + +function wrapGray(content: string) { + return `${content}` +} + +export const NavItemsInZh: DefaultTheme.NavItem[] = [ + { text: '开发指南', link: '/zh/' }, + { text: '使用实例', link: '/zh/examples/' } +] + +export const SidebarItemsInZh: DefaultTheme.SidebarItem[] = [ + { + text: '入门', + link: '/zh/', + items: [ + { + text: 'laf 介绍', + link: '/zh/', + }, + { + text: '快速开始', + link: '/zh/quick-start/login' + } + ], + }, + { + text: '云函数', + collapsed: false, + items: [ + { text: '云函数简介', link: '/zh/cloud-function/' }, + { text: '快速开始', link: '/zh/cloud-function/quick-start' }, + { + text: '处理 HTTP', + collapsed: true, + items: [ + { text: '请求', link: '/zh/cloud-function/request' }, + { text: '响应', link: '/zh/cloud-function/response' }, + { text: '认证', link: '/zh/cloud-function/auth' }, + { text: '文件上传', link: '/zh/cloud-function/files' }, + ] + }, + { text: '发起网络请求', link: '/zh/cloud-function/fetch' }, + { text: '函数引用', link: '/zh/cloud-function/import' }, + { text: '环境变量', link: '/zh/cloud-function/env' }, + { text: '依赖管理', link: '/zh/cloud-function/deps' }, + { text: '定时任务', link: '/zh/cloud-function/cron' }, + { + text: '内置云函数', + collapsed: true, + items: [ + { text: '拦截器(TBD)' }, + { text: '初始化(TBD)' }, + { text: 'NotFound(TBD)' }, + ], + }, + { text: 'WebSocket(TBD)' }, + ] + }, + { + text: '云数据库', + collapsed: false, + items: [ + { text: '云数据库简介', link: '/zh/cloud-database/' }, + { text: '快速开始', link: '/zh/cloud-database/quick-start' }, + { text: '插入文档', link: '/zh/cloud-database/insert' }, + { + text: '查询文档', + link: '/zh/cloud-database/find', + collapsed: true, + items: [ + { text: '条件查询', link: '/zh/cloud-database/query/condition' }, + { text: '排序查询', link: '/zh/cloud-database/query/sort' }, + { text: '分页查询', link: '/zh/cloud-database/query/pagination' }, + { text: '嵌套文档查询', link: '/zh/cloud-database/query/nested' }, + { text: '正则模糊查询', link: '/zh/cloud-database/query/regex' }, + { text: '数组查询', link: '/zh/cloud-database/query/array' }, + ] + }, + { text: '更新文档', link: '/zh/cloud-database/update' }, + { text: '删除文档', link: '/zh/cloud-database/delete' }, + { + text: '进阶使用', + collapsed: true, + items: [ + { text: '聚合查询(TBD)' }, + { text: '事务(TBD)' }, + { text: '组合操作(TBD)' }, + { text: '索引(TBD)' }, + { text: '时序集合(TBD)' }, + { text: '变更流(TBD)' }, + ] + }, + { + text: wrapGray('旧版语法'), + collapsed: true, + items: [ + { text: wrapGray('数据库简介'), link: '/zh/cloud-database/database-ql/' }, + { text: wrapGray('数据库入门'), link: '/zh/cloud-database/database-ql/quickstart' }, + { text: wrapGray('新增数据'), link: '/zh/cloud-database/database-ql/add' }, + { text: wrapGray('查询数据'), link: '/zh/cloud-database/database-ql/find' }, + { text: wrapGray('更新数据'), link: '/zh/cloud-database/database-ql/update' }, + { text: wrapGray('删除数据'), link: '/zh/cloud-database/database-ql/del' }, + { text: wrapGray('数据库操作符'), link: '/zh/cloud-database/database-ql/command' }, + { text: wrapGray('数据库聚合操作'), link: '/zh/cloud-database/database-ql/aggregate' }, + { text: wrapGray('数据库运算'), link: '/zh/cloud-database/database-ql/operator' }, + ] + } + ], + }, + { + text: '云存储', + collapsed: false, + items: [ + { text: '云存储简介', link: '/zh/cloud-storage/' }, + { text: '上传文件', link: '/zh/cloud-storage/upload' }, + { text: '读取文件', link: '/zh/cloud-storage/read' }, + { text: '删除文件', link: '/zh/cloud-storage/delete' }, + { text: '文件列表', link: '/zh/cloud-storage/list' }, + { text: '生成文件上传地址', link: '/zh/cloud-storage/upload-url' }, + { text: '生成文件下载地址', link: '/zh/cloud-storage/download-url' }, + { text: '网站托管', link: '/zh/cloud-storage/website-hosting' }, + { + text: '更多例子', + collapsed: true, + items: [ + { text: '微信小程序上传文件', link: '/zh/examples/wxmp-upload' }, + { text: 'GitHub Action 持续集成网站托管', link: '/zh/examples/website-hosting-ci-cd.md' }, + { text: 'Web 前端上传文件(TBD)' }, + { text: '微信小程序上传文件(TBD)' }, + ] + } + ], + }, + { + text: '工具', + items: [{ text: 'laf-cli', link: '/zh/cli/' }], + }, +] \ No newline at end of file diff --git a/docs/en/architecture.md b/docs/en/architecture.md new file mode 100644 index 0000000000..115d6fb64a --- /dev/null +++ b/docs/en/architecture.md @@ -0,0 +1,2 @@ + +> TBD \ No newline at end of file diff --git a/docs/en/ide.png b/docs/en/ide.png new file mode 100644 index 0000000000..f081131a19 Binary files /dev/null and b/docs/en/ide.png differ diff --git a/docs/en/index.md b/docs/en/index.md index bf148f1a7a..8dfd934a0f 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,37 +1,66 @@ ---- -title: laf Cloud Development Documentation -layout: home - -hero: - name: laf - text: Write code like writing a blog Go live anytime, anywhere - tagline: life is short, you need laf :) - actions: - - theme: brand - text: Get Started Quickly - link: /guide/ - - theme: alt - text: Start Using Now - link: https://laf.run/ - - theme: alt - text: GitHub Repository - link: https://github.com/labring/laf - -heroImage: https://socialify.git.ci/labring/laf/image?description=1& -tagline: Write functions like writing a blog, go live with ease -actionText: Get Started -actionLink: /guide/ -features: - - title: Cloud Functions - details: Code running in the cloud, write cloud functions using TypeScript, support WebSocket, can be directly called from the frontend. Cloud functions run on the Node.js runtime environment, no cold start required. - - title: Cloud Database - details: Ready to use, no need to create. The database can also be accessed "directly" by the client through access policies, saving more than 90% of backend APIs. Frontend developers can independently complete application development. - - title: Online IDE - details: Support AI-generated cloud functions, code with intelligence. Support intelligent autocompletion for all types, write, debug, and view logs online, code as content. Go live anytime, anywhere. - - title: Triggers - details: Cloud functions can be configured with timers and event triggers, and can listen for database change events. Data changes can trigger the execution of cloud functions (event triggers will be updated later). - - title: Cloud Storage - details: Provide a professional S3-compatible object storage service (MinIO), support Service Account open capabilities. - - title: Static Website Hosting - details: One-click deployment and hosting for frontend static websites, automatically assign subdomains that can be accessed directly. Support binding custom domains and automatically generate SSL certificates. ---- \ No newline at end of file + +# Introduction + +## 👀 What is `laf` + +`laf` is an open-source cloud development platform that offers ready-to-use application resources such as cloud functions, cloud databases, and cloud storage. It allows developers to focus on business development without the need to tinker with servers, enabling them to quickly unleash their creativity. + +![dev](./ide.png) + + +## 🖥 Online experience + +🎉 [laf.dev](https://laf.dev) Free experience `laf` cloud development. + + +## 🎉 Features of `laf` + +- Cloud Functions +- Cloud Database +- Cloud Storage +- WebIDE, Write code like writing a blog +- Website Hosting +- WebSocket support + +## 👨‍💻 Who uses `laf`? + +1. Front-end developers + `laf` = Full-stack developers, transforming front-end developers into true full-stack developers. + + - `laf` provides [laf-client-sdk](https://github.com/labring/laf/tree/main/packages/client-sdk) for front-end developers, suitable for any JavaScript runtime environment. + - `laf` allows front-end and back-end code to be developed using JavaScript/TypeScript, eliminating the barrier between them and enabling a quick learning curve. + - `laf` offers static website hosting, allowing direct deployment of front-end built web pages without the need for server configuration, nginx, domains, etc. + - `laf` will provide SDKs for various client platforms (Flutter/Android/iOS, etc.) in the future, offering backend development services and a consistent development experience for all client developers. + +2. Back-end developers can free themselves from trivial tasks and focus on the core business, enhancing development efficiency. + + - `laf` saves effort on server maintenance, multi-environment deployment, and management. + - `laf` eliminates the need for configuration and debugging of nginx. + - `laf` eliminates the repetitive work of manually deploying databases and addressing security concerns for each project. + - `laf` eliminates the tedious iterative experience of "making changes and taking half a day to publish." + - `laf` allows you to view function execution logs anytime, anywhere on the web without the need to connect to servers or spend time searching. + - `laf` enables you to "write a function like writing a blog," making it easy to publish and invoke functions effortlessly. + +3. Cloud development users, if you are a user of other cloud development platforms, `laf` not only provides a more powerful and fast development experience but also prevents vendor lock-in. + + - You can deliver source code to clients and privately deploy a `laf` + your cloud development application. Closed-source cloud development services cannot deliver independently runnable source code. + - You can deploy your own product to your servers at any time according to future needs, as `laf` is open-source and free. + - You can even modify and customize your own cloud development platform, as `laf` is open-source and highly extensible. + +4. Independent developers and startup teams can save costs, start quickly, and focus on their business. + + - Reduce the project development process, start quickly, and shorten the product validation cycle. + - Greatly improve iteration speed, adapt to changes at any time, and release updates quickly. + - Focus on the core business of the product, quickly launch Minimum Viable Products (MVP), and validate the product and market rapidly. + - One person + `laf` = a team. + +> life is short, you need laf:) + + +## 🏘️ Community Groups + +- [Discord](https://discord.gg/uWZqAwwdvy) +- [Twitter](https://twitter.com/laf_dev) + +## 🌟 Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=labring/laf&type=Date)](https://star-history.com/#labring/laf&Date) diff --git a/docs/package-lock.json b/docs/package-lock.json index 2bded8896d..dd6ce35651 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,29 +8,40 @@ "name": "laf-docs", "version": "1.0.0-beta.14", "hasInstallScript": true, - "dependencies": { - "markdown-it-custom-attrs": "^1.0.2", - "vitepress": "^1.0.0-alpha.29" - }, + "license": "ISC", "devDependencies": { - "flexsearch": "^0.7.31", - "vitepress-plugin-search": "^1.0.4-alpha.20" + "vitepress": "^1.0.0-rc.31" } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", - "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dev": true, "dependencies": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", - "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dev": true, "dependencies": { - "@algolia/autocomplete-shared": "1.7.4" + "@algolia/autocomplete-shared": "1.9.3" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -38,129 +49,149 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", - "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "dev": true, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", - "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz", + "integrity": "sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==", + "dev": true, "dependencies": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.20.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", - "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.20.0.tgz", + "integrity": "sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==", + "dev": true }, "node_modules/@algolia/cache-in-memory": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", - "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz", + "integrity": "sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==", + "dev": true, "dependencies": { - "@algolia/cache-common": "4.17.0" + "@algolia/cache-common": "4.20.0" } }, "node_modules/@algolia/client-account": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", - "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.20.0.tgz", + "integrity": "sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==", + "dev": true, "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/transporter": "4.20.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", - "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.20.0.tgz", + "integrity": "sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==", + "dev": true, "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" } }, "node_modules/@algolia/client-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", - "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.20.0.tgz", + "integrity": "sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==", + "dev": true, "dependencies": { - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", - "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.20.0.tgz", + "integrity": "sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==", + "dev": true, "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" } }, "node_modules/@algolia/client-search": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", - "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.20.0.tgz", + "integrity": "sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==", + "dev": true, "dependencies": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" + "@algolia/client-common": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" } }, "node_modules/@algolia/logger-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", - "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.20.0.tgz", + "integrity": "sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==", + "dev": true }, "node_modules/@algolia/logger-console": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", - "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.20.0.tgz", + "integrity": "sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==", + "dev": true, "dependencies": { - "@algolia/logger-common": "4.17.0" + "@algolia/logger-common": "4.20.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", - "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz", + "integrity": "sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==", + "dev": true, "dependencies": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.20.0" } }, "node_modules/@algolia/requester-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", - "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.20.0.tgz", + "integrity": "sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==", + "dev": true }, "node_modules/@algolia/requester-node-http": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", - "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz", + "integrity": "sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==", + "dev": true, "dependencies": { - "@algolia/requester-common": "4.17.0" + "@algolia/requester-common": "4.20.0" } }, "node_modules/@algolia/transporter": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", - "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.20.0.tgz", + "integrity": "sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==", + "dev": true, "dependencies": { - "@algolia/cache-common": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/requester-common": "4.17.0" + "@algolia/cache-common": "4.20.0", + "@algolia/logger-common": "4.20.0", + "@algolia/requester-common": "4.20.0" } }, "node_modules/@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -169,33 +200,37 @@ } }, "node_modules/@docsearch/css": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", - "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", + "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==", + "dev": true }, "node_modules/@docsearch/js": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", - "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.5.2.tgz", + "integrity": "sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==", + "dev": true, "dependencies": { - "@docsearch/react": "3.3.3", + "@docsearch/react": "3.5.2", "preact": "^10.0.0" } }, "node_modules/@docsearch/react": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", - "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", + "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "dev": true, "dependencies": { - "@algolia/autocomplete-core": "1.7.4", - "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.3", - "algoliasearch": "^4.0.0" + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.5.2", + "algoliasearch": "^4.19.1" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0" + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" }, "peerDependenciesMeta": { "@types/react": { @@ -206,16 +241,20 @@ }, "react-dom": { "optional": true + }, + "search-insights": { + "optional": true } } }, "node_modules/@esbuild/android-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", - "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.9.tgz", + "integrity": "sha512-jkYjjq7SdsWuNI6b5quymW0oC83NN5FdRPuCbs9HZ02mfVdAP8B8eeqLSYU3gb6OJEaY5CQabtTFbqBf26H3GA==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -225,12 +264,13 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", - "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.9.tgz", + "integrity": "sha512-q4cR+6ZD0938R19MyEW3jEsMzbb/1rulLXiNAJQADD/XYp7pT+rOS5JGxvpRW8dFDEfjW4wLgC/3FXIw4zYglQ==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -240,12 +280,13 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", - "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.9.tgz", + "integrity": "sha512-KOqoPntWAH6ZxDwx1D6mRntIgZh9KodzgNOy5Ebt9ghzffOk9X2c1sPwtM9P+0eXbefnDhqYfkh5PLP5ULtWFA==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -255,12 +296,13 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", - "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.9.tgz", + "integrity": "sha512-KBJ9S0AFyLVx2E5D8W0vExqRW01WqRtczUZ8NRu+Pi+87opZn5tL4Y0xT0mA4FtHctd0ZgwNoN639fUUGlNIWw==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -270,12 +312,13 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", - "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.9.tgz", + "integrity": "sha512-vE0VotmNTQaTdX0Q9dOHmMTao6ObjyPm58CHZr1UK7qpNleQyxlFlNCaHsHx6Uqv86VgPmR4o2wdNq3dP1qyDQ==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -285,12 +328,13 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", - "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.9.tgz", + "integrity": "sha512-uFQyd/o1IjiEk3rUHSwUKkqZwqdvuD8GevWF065eqgYfexcVkxh+IJgwTaGZVu59XczZGcN/YMh9uF1fWD8j1g==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -300,12 +344,13 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", - "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.9.tgz", + "integrity": "sha512-WMLgWAtkdTbTu1AWacY7uoj/YtHthgqrqhf1OaEWnZb7PQgpt8eaA/F3LkV0E6K/Lc0cUr/uaVP/49iE4M4asA==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -315,12 +360,13 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", - "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.9.tgz", + "integrity": "sha512-C/ChPohUYoyUaqn1h17m/6yt6OB14hbXvT8EgM1ZWaiiTYz7nWZR0SYmMnB5BzQA4GXl3BgBO1l8MYqL/He3qw==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -330,12 +376,13 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", - "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.9.tgz", + "integrity": "sha512-PiPblfe1BjK7WDAKR1Cr9O7VVPqVNpwFcPWgfn4xu0eMemzRp442hXyzF/fSwgrufI66FpHOEJk0yYdPInsmyQ==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -345,12 +392,13 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", - "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.9.tgz", + "integrity": "sha512-f37i/0zE0MjDxijkPSQw1CO/7C27Eojqb+r3BbHVxMLkj8GCa78TrBZzvPyA/FNLUMzP3eyHCVkAopkKVja+6Q==", "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -360,12 +408,13 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", - "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.9.tgz", + "integrity": "sha512-t6mN147pUIf3t6wUt3FeumoOTPfmv9Cc6DQlsVBpB7eCpLOqQDyWBP1ymXn1lDw4fNUSb/gBcKAmvTP49oIkaA==", "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -375,12 +424,13 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", - "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.9.tgz", + "integrity": "sha512-jg9fujJTNTQBuDXdmAg1eeJUL4Jds7BklOTkkH80ZgQIoCTdQrDaHYgbFZyeTq8zbY+axgptncko3v9p5hLZtw==", "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -390,12 +440,13 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", - "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.9.tgz", + "integrity": "sha512-tkV0xUX0pUUgY4ha7z5BbDS85uI7ABw3V1d0RNTii7E9lbmV8Z37Pup2tsLV46SQWzjOeyDi1Q7Wx2+QM8WaCQ==", "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -405,12 +456,13 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", - "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.9.tgz", + "integrity": "sha512-DfLp8dj91cufgPZDXr9p3FoR++m3ZJ6uIXsXrIvJdOjXVREtXuQCjfMfvmc3LScAVmLjcfloyVtpn43D56JFHg==", "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -420,12 +472,13 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", - "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.9.tgz", + "integrity": "sha512-zHbglfEdC88KMgCWpOl/zc6dDYJvWGLiUtmPRsr1OgCViu3z5GncvNVdf+6/56O2Ca8jUU+t1BW261V6kp8qdw==", "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -435,12 +488,13 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", - "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.9.tgz", + "integrity": "sha512-JUjpystGFFmNrEHQnIVG8hKwvA2DN5o7RqiO1CVX8EN/F/gkCjkUMgVn6hzScpwnJtl2mPR6I9XV1oW8k9O+0A==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -450,12 +504,13 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", - "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.9.tgz", + "integrity": "sha512-GThgZPAwOBOsheA2RUlW5UeroRfESwMq/guy8uEe3wJlAOjpOXuSevLRd70NZ37ZrpO6RHGHgEHvPg1h3S1Jug==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -465,12 +520,13 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", - "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.9.tgz", + "integrity": "sha512-Ki6PlzppaFVbLnD8PtlVQfsYw4S9n3eQl87cqgeIw+O3sRr9IghpfSKY62mggdt1yCSZ8QWvTZ9jo9fjDSg9uw==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -480,12 +536,13 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", - "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.9.tgz", + "integrity": "sha512-MLHj7k9hWh4y1ddkBpvRj2b9NCBhfgBt3VpWbHQnXRedVun/hC7sIyTGDGTfsGuXo4ebik2+3ShjcPbhtFwWDw==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -495,12 +552,13 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", - "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.9.tgz", + "integrity": "sha512-GQoa6OrQ8G08guMFgeXPH7yE/8Dt0IfOGWJSfSH4uafwdC7rWwrfE6P9N8AtPGIjUzdo2+7bN8Xo3qC578olhg==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -510,12 +568,13 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", - "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.9.tgz", + "integrity": "sha512-UOozV7Ntykvr5tSOlGCrqU3NBr3d8JqPes0QWN2WOXfvkWVGRajC+Ym0/Wj88fUgecUCLDdJPDF0Nna2UK3Qtg==", "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -525,12 +584,13 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", - "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz", + "integrity": "sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -539,176 +599,482 @@ "node": ">=12" } }, - "node_modules/@types/flexsearch": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", - "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.8.0.tgz", + "integrity": "sha512-zdTObFRoNENrdPpnTNnhOljYIcOX7aI7+7wyrSpPFFIOf/nRdedE6IYsjaBE7tjukphh1tMTojgJ7p3lKY8x6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.8.0.tgz", + "integrity": "sha512-aiItwP48BiGpMFS9Znjo/xCNQVwTQVcRKkFKsO81m8exrGjHkCBDvm9PHay2kpa8RPnZzzKcD1iQ9KaLY4fPQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.8.0.tgz", + "integrity": "sha512-zhNIS+L4ZYkYQUjIQUR6Zl0RXhbbA0huvNIWjmPc2SL0cB1h5Djkcy+RZ3/Bwszfb6vgwUvcVJYD6e6Zkpsi8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.8.0.tgz", + "integrity": "sha512-A/FAHFRNQYrELrb/JHncRWzTTXB2ticiRFztP4ggIUAfa9Up1qfW8aG2w/mN9jNiZ+HB0t0u0jpJgFXG6BfRTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.8.0.tgz", + "integrity": "sha512-JsidBnh3p2IJJA4/2xOF2puAYqbaczB3elZDT0qHxn362EIoIkq7hrR43Xa8RisgI6/WPfvb2umbGsuvf7E37A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.8.0.tgz", + "integrity": "sha512-hBNCnqw3EVCkaPB0Oqd24bv8SklETptQWcJz06kb9OtiShn9jK1VuTgi7o4zPSt6rNGWQOTDEAccbk0OqJmS+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.8.0.tgz", + "integrity": "sha512-Fw9ChYfJPdltvi9ALJ9wzdCdxGw4wtq4t1qY028b2O7GwB5qLNSGtqMsAel1lfWTZvf4b6/+4HKp0GlSYg0ahA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.8.0.tgz", + "integrity": "sha512-BH5xIh7tOzS9yBi8dFrCTG8Z6iNIGWGltd3IpTSKp6+pNWWO6qy8eKoRxOtwFbMrid5NZaidLYN6rHh9aB8bEw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.8.0.tgz", + "integrity": "sha512-PmvAj8k6EuWiyLbkNpd6BLv5XeYFpqWuRvRNRl80xVfpGXK/z6KYXmAgbI4ogz7uFiJxCnYcqyvZVD0dgFog7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.8.0.tgz", + "integrity": "sha512-mdxnlW2QUzXwY+95TuxZ+CurrhgrPAMveDWI97EQlA9bfhR8tw3Pt7SUlc/eSlCNxlWktpmT//EAA8UfCHOyXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.8.0.tgz", + "integrity": "sha512-ge7saUz38aesM4MA7Cad8CHo0Fyd1+qTaqoIo+Jtk+ipBi4ATSrHWov9/S4u5pbEQmLjgUjB7BJt+MiKG2kzmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.8.0.tgz", + "integrity": "sha512-p9E3PZlzurhlsN5h9g7zIP1DnqKXJe8ZUkFwAazqSvHuWfihlIISPxG9hCHCoA+dOOspL/c7ty1eeEVFTE0UTw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.8.0.tgz", + "integrity": "sha512-kb4/auKXkYKqlUYTE8s40FcJIj5soOyRLHKd4ugR0dCq0G2EfcF54eYcfQiGkHzjidZ40daB4ulsFdtqNKZtBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/hast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", + "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", "dev": true }, "node_modules/@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "13.0.7", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.7.tgz", + "integrity": "sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==", "dev": true, "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, + "node_modules/@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", "dev": true }, "node_modules/@types/web-bluetooth": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", - "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/@vitejs/plugin-vue": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", - "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.2.tgz", + "integrity": "sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==", + "dev": true, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.0.0", + "vite": "^4.0.0 || ^5.0.0", "vue": "^3.2.25" } }, "node_modules/@vue/compiler-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", - "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.11.tgz", + "integrity": "sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==", + "dev": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.47", + "@babel/parser": "^7.23.5", + "@vue/shared": "3.3.11", "estree-walker": "^2.0.2", - "source-map": "^0.6.1" + "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", - "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.11.tgz", + "integrity": "sha512-zoAiUIqSKqAJ81WhfPXYmFGwDRuO+loqLxvXmfUdR5fOitPoUiIeFI9cTTyv9MU5O1+ZZglJVTusWzy+wfk5hw==", + "dev": true, "dependencies": { - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", - "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.11.tgz", + "integrity": "sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==", + "dev": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-ssr": "3.2.47", - "@vue/reactivity-transform": "3.2.47", - "@vue/shared": "3.2.47", + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-ssr": "3.3.11", + "@vue/reactivity-transform": "3.3.11", + "@vue/shared": "3.3.11", "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" + "magic-string": "^0.30.5", + "postcss": "^8.4.32", + "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", - "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.11.tgz", + "integrity": "sha512-Zd66ZwMvndxRTgVPdo+muV4Rv9n9DwQ4SSgWWKWkPFebHQfVYRrVjeygmmDmPewsHyznCNvJ2P2d6iOOhdv8Qg==", + "dev": true, "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-dom": "3.3.11", + "@vue/shared": "3.3.11" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", + "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==", + "dev": true }, "node_modules/@vue/reactivity": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", - "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.11.tgz", + "integrity": "sha512-D5tcw091f0nuu+hXq5XANofD0OXnBmaRqMYl5B3fCR+mX+cXJIGNw/VNawBqkjLNWETrFW0i+xH9NvDbTPVh7g==", + "dev": true, "dependencies": { - "@vue/shared": "3.2.47" + "@vue/shared": "3.3.11" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", - "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.11.tgz", + "integrity": "sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==", + "dev": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47", + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11", "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" + "magic-string": "^0.30.5" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", - "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.11.tgz", + "integrity": "sha512-g9ztHGwEbS5RyWaOpXuyIVFTschclnwhqEbdy5AwGhYOgc7m/q3NFwr50MirZwTTzX55JY8pSkeib9BX04NIpw==", + "dev": true, "dependencies": { - "@vue/reactivity": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/reactivity": "3.3.11", + "@vue/shared": "3.3.11" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", - "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.11.tgz", + "integrity": "sha512-OlhtV1PVpbgk+I2zl+Y5rQtDNcCDs12rsRg71XwaA2/Rbllw6mBLMi57VOn8G0AjOJ4Mdb4k56V37+g8ukShpQ==", + "dev": true, "dependencies": { - "@vue/runtime-core": "3.2.47", - "@vue/shared": "3.2.47", - "csstype": "^2.6.8" + "@vue/runtime-core": "3.3.11", + "@vue/shared": "3.3.11", + "csstype": "^3.1.2" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", - "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.11.tgz", + "integrity": "sha512-AIWk0VwwxCAm4wqtJyxBylRTXSy1wCLOKbWxHaHiu14wjsNYtiRCSgVuqEPVuDpErOlRdNnuRgipQfXRLjLN5A==", + "dev": true, "dependencies": { - "@vue/compiler-ssr": "3.2.47", - "@vue/shared": "3.2.47" + "@vue/compiler-ssr": "3.3.11", + "@vue/shared": "3.3.11" }, "peerDependencies": { - "vue": "3.2.47" + "vue": "3.3.11" } }, "node_modules/@vue/shared": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", - "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.11.tgz", + "integrity": "sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw==", + "dev": true }, "node_modules/@vueuse/core": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", - "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.0.tgz", + "integrity": "sha512-4EUDESCHtwu44ZWK3Gc/hZUVhVo/ysvdtwocB5vcauSV4B7NiGY5972WnsojB3vRNdxvAt7kzJWE2h9h7C9d5w==", + "dev": true, "dependencies": { - "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "10.0.2", - "@vueuse/shared": "10.0.2", - "vue-demi": ">=0.14.0" + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.7.0", + "@vueuse/shared": "10.7.0", + "vue-demi": ">=0.14.6" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", - "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", + "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.7.0.tgz", + "integrity": "sha512-rxiMYgS+91n93qXpHZF9NbHhppWY6IJyVTDxt4acyChL0zZVx7P8FAAfpF1qVK8e4wfjerhpEiMJ0IZ1GWUZ2A==", + "dev": true, + "dependencies": { + "@vueuse/core": "10.7.0", + "@vueuse/shared": "10.7.0", + "vue-demi": ">=0.14.6" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "*", + "axios": "*", + "change-case": "*", + "drauu": "*", + "focus-trap": "*", + "fuse.js": "*", + "idb-keyval": "*", + "jwt-decode": "*", + "nprogress": "*", + "qrcode": "*", + "sortablejs": "*", + "universal-cookie": "*" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations/node_modules/vue-demi": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", + "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "dev": true, "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -731,28 +1097,31 @@ } }, "node_modules/@vueuse/metadata": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", - "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.0.tgz", + "integrity": "sha512-GlaH7tKP2iBCZ3bHNZ6b0cl9g0CJK8lttkBNUX156gWvNYhTKEtbweWLm9rxCPIiwzYcr/5xML6T8ZUEt+DkvA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", - "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.0.tgz", + "integrity": "sha512-kc00uV6CiaTdc3i1CDC4a3lBxzaBE9AgYNtFN87B5OOscqeWElj/uza8qVDmk7/U8JbqoONLbtqiLJ5LGRuqlw==", + "dev": true, "dependencies": { - "vue-demi": ">=0.14.0" + "vue-demi": ">=0.14.6" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", - "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", + "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "dev": true, "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -774,70 +1143,100 @@ } } }, - "node_modules/a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, "node_modules/algoliasearch": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", - "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.20.0.tgz", + "integrity": "sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==", + "dev": true, "dependencies": { - "@algolia/cache-browser-local-storage": "4.17.0", - "@algolia/cache-common": "4.17.0", - "@algolia/cache-in-memory": "4.17.0", - "@algolia/client-account": "4.17.0", - "@algolia/client-analytics": "4.17.0", - "@algolia/client-common": "4.17.0", - "@algolia/client-personalization": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/logger-console": "4.17.0", - "@algolia/requester-browser-xhr": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/requester-node-http": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" - }, - "node_modules/argparse": { + "@algolia/cache-browser-local-storage": "4.20.0", + "@algolia/cache-common": "4.20.0", + "@algolia/cache-in-memory": "4.20.0", + "@algolia/client-account": "4.20.0", + "@algolia/client-analytics": "4.20.0", + "@algolia/client-common": "4.20.0", + "@algolia/client-personalization": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/logger-common": "4.20.0", + "@algolia/logger-console": "4.20.0", + "@algolia/requester-browser-xhr": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/requester-node-http": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/ccount": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/body-scroll-lock": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmmirror.com/body-scroll-lock/-/body-scroll-lock-4.0.0-beta.0.tgz", - "integrity": "sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==" + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "engines": { "node": ">=0.12" @@ -847,9 +1246,10 @@ } }, "node_modules/esbuild": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", - "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.9.tgz", + "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -858,45 +1258,50 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.17", - "@esbuild/android-arm64": "0.17.17", - "@esbuild/android-x64": "0.17.17", - "@esbuild/darwin-arm64": "0.17.17", - "@esbuild/darwin-x64": "0.17.17", - "@esbuild/freebsd-arm64": "0.17.17", - "@esbuild/freebsd-x64": "0.17.17", - "@esbuild/linux-arm": "0.17.17", - "@esbuild/linux-arm64": "0.17.17", - "@esbuild/linux-ia32": "0.17.17", - "@esbuild/linux-loong64": "0.17.17", - "@esbuild/linux-mips64el": "0.17.17", - "@esbuild/linux-ppc64": "0.17.17", - "@esbuild/linux-riscv64": "0.17.17", - "@esbuild/linux-s390x": "0.17.17", - "@esbuild/linux-x64": "0.17.17", - "@esbuild/netbsd-x64": "0.17.17", - "@esbuild/openbsd-x64": "0.17.17", - "@esbuild/sunos-x64": "0.17.17", - "@esbuild/win32-arm64": "0.17.17", - "@esbuild/win32-ia32": "0.17.17", - "@esbuild/win32-x64": "0.17.17" + "@esbuild/android-arm": "0.19.9", + "@esbuild/android-arm64": "0.19.9", + "@esbuild/android-x64": "0.19.9", + "@esbuild/darwin-arm64": "0.19.9", + "@esbuild/darwin-x64": "0.19.9", + "@esbuild/freebsd-arm64": "0.19.9", + "@esbuild/freebsd-x64": "0.19.9", + "@esbuild/linux-arm": "0.19.9", + "@esbuild/linux-arm64": "0.19.9", + "@esbuild/linux-ia32": "0.19.9", + "@esbuild/linux-loong64": "0.19.9", + "@esbuild/linux-mips64el": "0.19.9", + "@esbuild/linux-ppc64": "0.19.9", + "@esbuild/linux-riscv64": "0.19.9", + "@esbuild/linux-s390x": "0.19.9", + "@esbuild/linux-x64": "0.19.9", + "@esbuild/netbsd-x64": "0.19.9", + "@esbuild/openbsd-x64": "0.19.9", + "@esbuild/sunos-x64": "0.19.9", + "@esbuild/win32-arm64": "0.19.9", + "@esbuild/win32-ia32": "0.19.9", + "@esbuild/win32-x64": "0.19.9" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/flexsearch": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", - "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dev": true, + "dependencies": { + "tabbable": "^6.2.0" + } + }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -906,93 +1311,300 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/hexo-pagination": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.1.0.tgz", - "integrity": "sha512-Ji/LYq7xP7cdBdG15CJ4YZZNA/c6Kf64rXj+Jp2bKsC2JTgcBmz+GGkHwpk6aoMHXRP2XraxGcGjXhITr7ooYg==", + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dev": true, "dependencies": { - "object-assign": "^4.1.0" + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + "node_modules/hast-util-raw": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", + "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "node_modules/hast-util-to-html": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.0.tgz", + "integrity": "sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==", "dev": true, "dependencies": { - "uc.micro": "^1.0.1" + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^9.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dev": true, "dependencies": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" } }, "node_modules/mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true }, - "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "node_modules/mdast-util-to-hast": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", + "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", "dev": true, "dependencies": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" }, - "bin": { - "markdown-it": "bin/markdown-it.js" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/markdown-it-custom-attrs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", - "integrity": "sha512-6jiuxs//DhkFe7K3z5Y3nF1E6Lk2GRKGVzk8IpusxPZL90rOOhwEAtYjOGjRBPQctK56kJreCnFmPSUW0n3YeQ==", + "node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "hexo-pagination": "^0.1.0", - "lodash.pick": "^4.4.0", - "nunjucks": "^3.0.1" + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, "node_modules/minisearch": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", - "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.3.0.tgz", + "integrity": "sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==", + "dev": true + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1000,47 +1612,29 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, "dependencies": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - }, - "bin": { - "nunjucks-precompile": "bin/precompile" + "entities": "^4.4.0" }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "chokidar": "^3.3.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1049,10 +1643,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -1061,89 +1659,265 @@ } }, "node_modules/preact": { - "version": "10.13.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", - "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", + "version": "10.19.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", + "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" } }, + "node_modules/property-information": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", + "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/rollup": { - "version": "3.20.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", - "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.8.0.tgz", + "integrity": "sha512-NpsklK2fach5CdI+PScmlE5R4Ao/FSWtF7LkoIrHDxPACY/xshNasPsbpG0VVHxUTbf74tJbVT4PrP8JsJ6ZDA==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.8.0", + "@rollup/rollup-android-arm64": "4.8.0", + "@rollup/rollup-darwin-arm64": "4.8.0", + "@rollup/rollup-darwin-x64": "4.8.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.8.0", + "@rollup/rollup-linux-arm64-gnu": "4.8.0", + "@rollup/rollup-linux-arm64-musl": "4.8.0", + "@rollup/rollup-linux-riscv64-gnu": "4.8.0", + "@rollup/rollup-linux-x64-gnu": "4.8.0", + "@rollup/rollup-linux-x64-musl": "4.8.0", + "@rollup/rollup-win32-arm64-msvc": "4.8.0", + "@rollup/rollup-win32-ia32-msvc": "4.8.0", + "@rollup/rollup-win32-x64-msvc": "4.8.0", "fsevents": "~2.3.2" } }, - "node_modules/shiki": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", - "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", + "node_modules/search-insights": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", + "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", + "dev": true, + "peer": true + }, + "node_modules/shikiji": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.7.6.tgz", + "integrity": "sha512-KzEtvSGQtBvfwVIB70kOmIfl/5rz1LC8j+tvlHXsJKAIdONNQvG1at7ivUUq3xUctqgO6fsO3AGomUSh0F+wsQ==", + "dev": true, "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "hast-util-to-html": "^9.0.0" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node_modules/shikiji-transformers": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/shikiji-transformers/-/shikiji-transformers-0.7.6.tgz", + "integrity": "sha512-yTp+7JMD/aXbV9ndn14eo9IK/UNt8iDsLNyqlOmCtcldlkqWE9T2YKAlOHOTVaeDfYWUWZa2EgSXb/CBfepBrw==", + "dev": true, + "dependencies": { + "shikiji": "0.7.6" } }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dev": true, + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "dev": true }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", - "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.7.tgz", + "integrity": "sha512-B4T4rJCDPihrQo2B+h1MbeGL/k/GMAHzhQ8S0LjQ142s6/+l3hHTT095ORvsshj4QCkoWu3Xtmob5mazvakaOw==", + "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.21", - "rollup": "^3.20.2" + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -1156,6 +1930,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -1171,881 +1948,82 @@ } }, "node_modules/vitepress": { - "version": "1.0.0-alpha.72", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", - "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", + "version": "1.0.0-rc.31", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-rc.31.tgz", + "integrity": "sha512-ikH9pIjOOAbyoYAGBVfTz8TzuXp+UoWaIRMU4bw/oiTg8R65SbAaGKY84xx6TuL+f4VqUJ8lhzW82YyxSLvstA==", + "dev": true, "dependencies": { - "@docsearch/css": "^3.3.3", - "@docsearch/js": "^3.3.3", - "@vitejs/plugin-vue": "^4.1.0", - "@vue/devtools-api": "^6.5.0", - "@vueuse/core": "^10.0.2", - "body-scroll-lock": "4.0.0-beta.0", - "mark.js": "^8.11.1", - "minisearch": "^6.0.1", - "shiki": "^0.14.1", - "vite": "^4.2.1", - "vue": "^3.2.47" + "@docsearch/css": "^3.5.2", + "@docsearch/js": "^3.5.2", + "@types/markdown-it": "^13.0.7", + "@vitejs/plugin-vue": "^4.5.0", + "@vue/devtools-api": "^6.5.1", + "@vueuse/core": "^10.6.1", + "@vueuse/integrations": "^10.6.1", + "focus-trap": "^7.5.4", + "mark.js": "8.11.1", + "minisearch": "^6.3.0", + "mrmime": "^1.0.1", + "shikiji": "^0.7.4", + "shikiji-transformers": "^0.7.4", + "vite": "^5.0.2", + "vue": "^3.3.8" }, "bin": { "vitepress": "bin/vitepress.js" - } - }, - "node_modules/vitepress-plugin-search": { - "version": "1.0.4-alpha.20", - "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", - "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", - "dev": true, - "dependencies": { - "@types/flexsearch": "^0.7.3", - "@types/markdown-it": "^12.2.3", - "glob-to-regexp": "^0.4.1", - "markdown-it": "^13.0.1" - }, - "engines": { - "node": "^14.13.1 || ^16.7.0 || >=18" }, "peerDependencies": { - "flexsearch": "^0.7.31", - "vitepress": "^1.0.0-alpha.65", - "vue": "3" + "markdown-it-mathjax3": "^4.3.2", + "postcss": "^8.4.31" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } } }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" - }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" - }, "node_modules/vue": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", - "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", - "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-sfc": "3.2.47", - "@vue/runtime-dom": "3.2.47", - "@vue/server-renderer": "3.2.47", - "@vue/shared": "3.2.47" - } - } - }, - "dependencies": { - "@algolia/autocomplete-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", - "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", - "requires": { - "@algolia/autocomplete-shared": "1.7.4" - } - }, - "@algolia/autocomplete-preset-algolia": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", - "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", - "requires": { - "@algolia/autocomplete-shared": "1.7.4" - } - }, - "@algolia/autocomplete-shared": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", - "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" - }, - "@algolia/cache-browser-local-storage": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", - "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", - "requires": { - "@algolia/cache-common": "4.17.0" - } - }, - "@algolia/cache-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", - "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" - }, - "@algolia/cache-in-memory": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", - "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", - "requires": { - "@algolia/cache-common": "4.17.0" - } - }, - "@algolia/client-account": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", - "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", - "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "@algolia/client-analytics": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", - "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", - "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "@algolia/client-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", - "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", - "requires": { - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "@algolia/client-personalization": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", - "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", - "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "@algolia/client-search": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", - "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", - "requires": { - "@algolia/client-common": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "@algolia/logger-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", - "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" - }, - "@algolia/logger-console": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", - "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", - "requires": { - "@algolia/logger-common": "4.17.0" - } - }, - "@algolia/requester-browser-xhr": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", - "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", - "requires": { - "@algolia/requester-common": "4.17.0" - } - }, - "@algolia/requester-common": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", - "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" - }, - "@algolia/requester-node-http": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", - "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", - "requires": { - "@algolia/requester-common": "4.17.0" - } - }, - "@algolia/transporter": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", - "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", - "requires": { - "@algolia/cache-common": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/requester-common": "4.17.0" - } - }, - "@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==" - }, - "@docsearch/css": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", - "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" - }, - "@docsearch/js": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", - "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", - "requires": { - "@docsearch/react": "3.3.3", - "preact": "^10.0.0" - } - }, - "@docsearch/react": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", - "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", - "requires": { - "@algolia/autocomplete-core": "1.7.4", - "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.3", - "algoliasearch": "^4.0.0" - } - }, - "@esbuild/android-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", - "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", - "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", - "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", - "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", - "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", - "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", - "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", - "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", - "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", - "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", - "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", - "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", - "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", - "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", - "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", - "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", - "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", - "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", - "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", - "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", - "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", - "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", - "optional": true - }, - "@types/flexsearch": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", - "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", - "dev": true - }, - "@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", - "dev": true - }, - "@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz", + "integrity": "sha512-d4oBctG92CRO1cQfVBZp6WJAs0n8AK4Xf5fNjQCBeKCvMI1efGQ5E3Alt1slFJS9fZuPcFoiAiqFvQlv1X7t/w==", "dev": true, - "requires": { - "@types/linkify-it": "*", - "@types/mdurl": "*" - } - }, - "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", - "dev": true - }, - "@types/web-bluetooth": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", - "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" - }, - "@vitejs/plugin-vue": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", - "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", - "requires": {} - }, - "@vue/compiler-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", - "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - } - }, - "@vue/compiler-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", - "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", - "requires": { - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "@vue/compiler-sfc": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", - "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-ssr": "3.2.47", - "@vue/reactivity-transform": "3.2.47", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - } - }, - "@vue/compiler-ssr": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", - "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", - "requires": { - "@vue/compiler-dom": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "@vue/devtools-api": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", - "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" - }, - "@vue/reactivity": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", - "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", - "requires": { - "@vue/shared": "3.2.47" - } - }, - "@vue/reactivity-transform": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", - "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" - } - }, - "@vue/runtime-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", - "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", - "requires": { - "@vue/reactivity": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "@vue/runtime-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", - "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", - "requires": { - "@vue/runtime-core": "3.2.47", - "@vue/shared": "3.2.47", - "csstype": "^2.6.8" - } - }, - "@vue/server-renderer": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", - "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", - "requires": { - "@vue/compiler-ssr": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "@vue/shared": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", - "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" - }, - "@vueuse/core": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", - "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", - "requires": { - "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "10.0.2", - "@vueuse/shared": "10.0.2", - "vue-demi": ">=0.14.0" - }, "dependencies": { - "vue-demi": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", - "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", - "requires": {} - } - } - }, - "@vueuse/metadata": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", - "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==" - }, - "@vueuse/shared": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", - "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", - "requires": { - "vue-demi": ">=0.14.0" + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-sfc": "3.3.11", + "@vue/runtime-dom": "3.3.11", + "@vue/server-renderer": "3.3.11", + "@vue/shared": "3.3.11" }, - "dependencies": { - "vue-demi": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", - "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", - "requires": {} + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true } } }, - "a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "algoliasearch": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", - "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", - "requires": { - "@algolia/cache-browser-local-storage": "4.17.0", - "@algolia/cache-common": "4.17.0", - "@algolia/cache-in-memory": "4.17.0", - "@algolia/client-account": "4.17.0", - "@algolia/client-analytics": "4.17.0", - "@algolia/client-common": "4.17.0", - "@algolia/client-personalization": "4.17.0", - "@algolia/client-search": "4.17.0", - "@algolia/logger-common": "4.17.0", - "@algolia/logger-console": "4.17.0", - "@algolia/requester-browser-xhr": "4.17.0", - "@algolia/requester-common": "4.17.0", - "@algolia/requester-node-http": "4.17.0", - "@algolia/transporter": "4.17.0" - } - }, - "ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" - }, - "argparse": { + "node_modules/web-namespaces": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "body-scroll-lock": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmmirror.com/body-scroll-lock/-/body-scroll-lock-4.0.0-beta.0.tgz", - "integrity": "sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - }, - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true - }, - "esbuild": { - "version": "0.17.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", - "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", - "requires": { - "@esbuild/android-arm": "0.17.17", - "@esbuild/android-arm64": "0.17.17", - "@esbuild/android-x64": "0.17.17", - "@esbuild/darwin-arm64": "0.17.17", - "@esbuild/darwin-x64": "0.17.17", - "@esbuild/freebsd-arm64": "0.17.17", - "@esbuild/freebsd-x64": "0.17.17", - "@esbuild/linux-arm": "0.17.17", - "@esbuild/linux-arm64": "0.17.17", - "@esbuild/linux-ia32": "0.17.17", - "@esbuild/linux-loong64": "0.17.17", - "@esbuild/linux-mips64el": "0.17.17", - "@esbuild/linux-ppc64": "0.17.17", - "@esbuild/linux-riscv64": "0.17.17", - "@esbuild/linux-s390x": "0.17.17", - "@esbuild/linux-x64": "0.17.17", - "@esbuild/netbsd-x64": "0.17.17", - "@esbuild/openbsd-x64": "0.17.17", - "@esbuild/sunos-x64": "0.17.17", - "@esbuild/win32-arm64": "0.17.17", - "@esbuild/win32-ia32": "0.17.17", - "@esbuild/win32-x64": "0.17.17" - } - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "flexsearch": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", - "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "hexo-pagination": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.1.0.tgz", - "integrity": "sha512-Ji/LYq7xP7cdBdG15CJ4YZZNA/c6Kf64rXj+Jp2bKsC2JTgcBmz+GGkHwpk6aoMHXRP2XraxGcGjXhITr7ooYg==", - "requires": { - "object-assign": "^4.1.0" - } - }, - "jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" - }, - "linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "requires": { - "sourcemap-codec": "^1.4.8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" - }, - "markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-custom-attrs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", - "integrity": "sha512-6jiuxs//DhkFe7K3z5Y3nF1E6Lk2GRKGVzk8IpusxPZL90rOOhwEAtYjOGjRBPQctK56kJreCnFmPSUW0n3YeQ==", - "requires": { - "hexo-pagination": "^0.1.0", - "lodash.pick": "^4.4.0", - "nunjucks": "^3.0.1" - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "minisearch": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", - "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "nunjucks": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", - "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", - "requires": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "preact": { - "version": "10.13.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", - "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==" - }, - "rollup": { - "version": "3.20.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", - "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", - "requires": { - "fsevents": "~2.3.2" - } - }, - "shiki": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", - "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", - "requires": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "vite": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", - "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", - "requires": { - "esbuild": "^0.17.5", - "fsevents": "~2.3.2", - "postcss": "^8.4.21", - "rollup": "^3.20.2" - } - }, - "vitepress": { - "version": "1.0.0-alpha.72", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", - "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", - "requires": { - "@docsearch/css": "^3.3.3", - "@docsearch/js": "^3.3.3", - "@vitejs/plugin-vue": "^4.1.0", - "@vue/devtools-api": "^6.5.0", - "@vueuse/core": "^10.0.2", - "body-scroll-lock": "4.0.0-beta.0", - "mark.js": "^8.11.1", - "minisearch": "^6.0.1", - "shiki": "^0.14.1", - "vite": "^4.2.1", - "vue": "^3.2.47" - } - }, - "vitepress-plugin-search": { - "version": "1.0.4-alpha.20", - "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", - "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", - "dev": true, - "requires": { - "@types/flexsearch": "^0.7.3", - "@types/markdown-it": "^12.2.3", - "glob-to-regexp": "^0.4.1", - "markdown-it": "^13.0.1" - } - }, - "vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" - }, - "vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" - }, - "vue": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", - "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", - "requires": { - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-sfc": "3.2.47", - "@vue/runtime-dom": "3.2.47", - "@vue/server-renderer": "3.2.47", - "@vue/shared": "3.2.47" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } } } diff --git a/docs/package.json b/docs/package.json index 1c71b4c803..22a67751e2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,15 +11,25 @@ "after-build": "sed -i -e \"s@@
粤ICP备2023048773号
@g\" ./.vitepress/dist/index.html", "docs:deploy": "npm run build && sh ./deploy.sh", "docker-build": "docker build --platform linux/amd64 -t lafyun/docs:latest .", - "lint": "eslint . --fix --ext .ts --ext .js" - }, - "dependencies": { - "markdown-it-custom-attrs": "^1.0.2", - "vitepress": "^1.0.0-alpha.29" + "lint": "eslint . --fix --ext .ts --ext .js", + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" }, + "main": "index.js", + "keywords": [ + "laf", + "lafyun", + "laf.run", + "laf.dev", + "sealos", + "laf.js" + ], + "author": "", + "license": "ISC", + "dependencies": {}, "devDependencies": { - "flexsearch": "^0.7.31", - "vitepress-plugin-search": "^1.0.4-alpha.20" + "vitepress": "^1.0.0-rc.31" }, "lint-staged": { "*.{ts,js}": "eslint --fix" diff --git a/docs/scripts/check-version.js b/docs/scripts/check-version.js index e9ee7fc13e..a287b0df17 100644 --- a/docs/scripts/check-version.js +++ b/docs/scripts/check-version.js @@ -1,7 +1,7 @@ // Lock lockFileVersion to version 2 And resolve import error when import xxx from 'node:xxx' -if (process.version && +process.version.slice(1).split('.')[0] < 16) { +if (process.version && +process.version.slice(1).split('.')[0] < 18) { console.log( - `Required node version >= 16 not satisfied with current version ${process.version}.` + `Required node version >= 18 not satisfied with current version ${process.version}.` ) process.exit(1) } diff --git a/docs/zh/cli/index.md b/docs/zh/cli/index.md new file mode 100644 index 0000000000..745e404d5f --- /dev/null +++ b/docs/zh/cli/index.md @@ -0,0 +1,201 @@ +--- +title: laf-cli 命令行工具 +--- + +# {{ $frontmatter.title }} + +## 简介 + +`laf-cli` 可以让你实现本地开发同步 Web 端,用你最熟悉的开发工具,更加高效。 + +## 安装 + +```shell +# 要求 node 版本 >= 16 +npm i laf-cli -g +``` + +cli 的主要功能就是把在 laf web 上的操作集成到命令行里,下面我们根据 web 端的操作来一个个演示。 + +## 登录 + +想要执行登录操作我们需要先拿到我们的 PAT(访问凭证)。 + +![](../doc-images/creat-token.png) + +默认登录 `laf.run`,如果要登录 `laf.dev` 或私有部署的 laf 或其他`laf.run`账号可通过 添加 user: + +```shell +laf user add dev -r https://laf.dev +laf user switch dev +laf user list +laf login [pat] +``` + +### 退出登录 + +```shell +laf logout +``` + +## App + +在 web 端登录之后我们会看到我们的 app 列表,那么在 cli 中想查看 app 列表只需要执行。 + +```shell +laf app list +``` + +### 初始化 app + +初始化需要用到 appid,我们可以在 web 端首页拿到。 +这里稍微解释一下,初始化 app 是指在你运行这个命令的目录下生成模版文件,默认是空的,如果想把 web 端的东西同步过来需要加上 -s。 +::: tip +建议在一个空的目录下尝试此命令。 +::: + +```shell +laf app init [appid] +``` + +## 依赖 + +我们可以通过 pull 命令把 web 端的依赖拉到本地,然后 npm i 即可。 + +```shell +laf dep pull +``` + +如果我们想添加依赖可以使用 add,注意这里的 add 是在 web 端和本地同时添加这个依赖,添加之后 npm i 即可使用。 + +```shell +laf dep add [dependencyName] +``` + +如果我们的依赖文件,或者说整个本地文件都是从其他地方拷贝过来的,可以通过 push 命令把 dependency.yaml 文件中的所有依赖都安装到 web 端。 + +```shell +laf dep push +``` + +## 云函数 + +新建云函数,此命令是在本地和 web 同时创建云函数。 + +```shell + laf func create [funcName] +``` + +删除云函数,同新建一样本地和 web 同时删除。 + +```shell +laf func del [funcName] +``` + +查看云函数列表。 + +```shell +laf func list +``` + +更新 web 端云函数代码到本地。 + +```shell +laf func pull [funcName] +``` + +推送本地云函数代码到 web。 + +```shell +laf func push [funcName] +``` + +执行云函数,执行结果会打印在命令行,日志需要在 web 上查看。 + +```shell +laf func exec [funcName] +``` + +## 存储 + +查看 bucket 列表。 + +```shell +laf storage list +``` + +新建 bucket。 + +```shell +laf storage create [bucketName] +``` + +删除 bucket。 + +```shell +laf storage del [bucketName] +``` + +更新 bucket 权限。 + +```shell +laf storage update [bucketName] +``` + +下载 bucket 文件到本地。 + +```shell +laf storage pull [bucketName] [outPath] +``` + +上传本地文件到 bucket。 + +```shell +laf storage push [bucketName] [inPath] +``` + +## 访问策略 + +查看所有访问策略。 + +```shell +laf policy list +``` + +拉取访问策略到本地,参数 policyName 是可选,不填代表拉取全部。 + +```shell +laf policy pull [policyName] +``` + +推送访问策略到 web,参数 policyName 是可选,不填代表推送全部。 + +```shell +laf policy push [policyName] +``` + +## 网站托管 + +查看托管列表。 + +```shell +laf website list +``` + +开启网站托管,此命令是开启 [bucketName] 的网站托管。 + +```shell +laf website create [bucketName] +``` + +关闭网站托管,此命令是关闭 [bucketName] 的网站托管。 + +```shell +laf website del [bucketName] +``` + +自定义域名,此命令是为已开启网站托管的 [bucketName] 设置自定义域名。 + +```shell +laf website custom [bucketName] [domain] +``` diff --git a/docs/zh/client-sdk/index.md b/docs/zh/client-sdk/index.md new file mode 100644 index 0000000000..4ae2b69987 --- /dev/null +++ b/docs/zh/client-sdk/index.md @@ -0,0 +1,161 @@ +--- +title: laf-client-sdk +--- + +# {{ $frontmatter.title }} + +## 介绍 + +laf 为前端提供了 `laf-client-sdk` 适用于前端 js 运行环境。 + +:::warning +优先推荐使用 HTTP 的方式请求云函数 +::: + +## 安装 + +```bash + npm install laf-client-sdk +``` + +## 使用示例 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + // 这里 APPID 需要换成对应的 APPID + baseUrl: "https://APPID.laf.run", + // 这里是访问策略的入口地址,如果没有访问策略可不填 + dbProxyUrl: "/proxy/app", + // 请求时带的 token,可空 + getAccessToken: () => localStorage.getItem("access_token"), +}); +``` + +## 参数 + +`baseUrl` Laf 应用链接,格式为 `https://APPID.laf.run`,APPID 为你的 Laf 应用的 appid + +`dbProxyUrl` 数据库访问策略入口,格式为 `/proxy/` 开头加上你新建策略名,如果不需要操作数据库,可不填此参数 + +`getAccessToken` 请求时带的 token,token 为 JWT token,如果不涉及权限可空 + +`environment` 目前兼容三种环境 `wxmp` `uniapp` `h5`,`wxmp` 为微信小程序 + +## 微信小程序中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => wx.getStorageSync('access_token'), + environment: "wxmp", +}); +``` + +::: warning +微信小程序中使用 NPM 依赖,需要 `构建NPM` +::: + +### `Typescript` 版微信小程序构建方法 + +1、终端 npm 初始化,在小程序项目文件夹中执行 `npm init -y` + +2、安装客户端 SDK,在小程序项目文件夹中执行 `npm i laf-client-sdk` + +3、修改 project.config.json + +setting 下新增: + +```typescript +"packNpmManually": true, +"packNpmRelationList": [ + { + "packageJsonPath": "./package.json", + "miniprogramNpmDistDir": "miniprogram/" + } +] +``` + +4、构建 NPM,微信开发者工具中,点击"工具"-"构建 npm" + +5、页面中调用 SDK 的功能 + +### `Javascript` 版微信小程序构建方法 + +1、终端 npm 初始化,在小程序项目文件夹中执行 `npm init -y` + +2、安装客户端 SDK,在小程序项目文件夹中执行 `npm i laf-client-sdk` + +3、构建 NPM,微信开发者工具中,点击"工具"-"构建 npm" + +6、页面中调用 SDK 的功能 + +## UNI-APP 中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => uni.getStorageSync("access_token"), + environment: "uniapp", +}); +``` + +## H5 中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => localStorage.getItem("access_token"), + environment: "h5", +}); +``` + +## 调用云函数 + +::: tip +`laf-client-sdk` 调用云函数只支持 POST 请求云函数 +::: + +```typescript +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => localStorage.getItem("access_token"), +}); + +// 调用 getCode 云函数,并且传入参数 +const res = await cloud.invoke("getCode", { phone: phone.value }); +``` + +## 操作数据库 + +:::tip +通过 `laf-client-sdk` 我们可以像在云函数中一样操作数据库。 +还有就是需要配合相对应的访问策略。 +::: + +```typescript +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", //数据库访问策略 + getAccessToken: () => localStorage.getItem("access_token"), +}); +const db = cloud.database() + +// 获取用户表中的数据。 +const res = await db.collection('user').get() +``` diff --git a/docs/zh/cloud-database/collection.png b/docs/zh/cloud-database/collection.png new file mode 100644 index 0000000000..309516287b Binary files /dev/null and b/docs/zh/cloud-database/collection.png differ diff --git a/docs/guide/db/add.md b/docs/zh/cloud-database/database-ql/add.md similarity index 100% rename from docs/guide/db/add.md rename to docs/zh/cloud-database/database-ql/add.md diff --git a/docs/guide/db/aggregate.md b/docs/zh/cloud-database/database-ql/aggregate.md similarity index 100% rename from docs/guide/db/aggregate.md rename to docs/zh/cloud-database/database-ql/aggregate.md diff --git a/docs/guide/db/command.md b/docs/zh/cloud-database/database-ql/command.md similarity index 100% rename from docs/guide/db/command.md rename to docs/zh/cloud-database/database-ql/command.md diff --git a/docs/doc-images/dblist.jpg b/docs/zh/cloud-database/database-ql/dblist.jpg similarity index 100% rename from docs/doc-images/dblist.jpg rename to docs/zh/cloud-database/database-ql/dblist.jpg diff --git a/docs/guide/db/del.md b/docs/zh/cloud-database/database-ql/del.md similarity index 100% rename from docs/guide/db/del.md rename to docs/zh/cloud-database/database-ql/del.md diff --git a/docs/zh/cloud-database/database-ql/find.md b/docs/zh/cloud-database/database-ql/find.md new file mode 100644 index 0000000000..149ec4225c --- /dev/null +++ b/docs/zh/cloud-database/database-ql/find.md @@ -0,0 +1,599 @@ +--- +title: 查询数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库支持传入不同的条件来查询数据,并且对查询结果进行处理。本文档将通过示例说明如何通过 `cloud.database()` 在云函数中执行查询。 + +查询数据操作主要支持 `where()` `limit()` `skip()` `orderBy()` `field()` `get()` `getOne()` `count()` 等 + +包括: + +[[toc]] + +## 获取所有记录 + +::: tip +可通过 `where` 设置查询条件,以及通过 `limit` 设置显示数量等 +::: + +```typescript +import cloud from '@lafjs/cloud' +// 获取数据库引用 +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // get 方法发起查询请求,不带 where 就是直接查询全部数据,默认最多查询 100 条数据 + const result1 = await db.collection('user').get() + console.log(result1) + + // get 方法发起查询请求,配置 where 条件 + const result2 = await db.collection('user').where({ + name: 'laf' + }).get() + console.log(result2) + + // get 方法发起查询请求,想一次获取更多数据,最多一次获取 1000 条数据 + const result3 = await db.collection('user').limit(1000).get() + console.log(result3) +} +``` + +`get()` 前面支持 `where()`、`limit()`、`skip()`、`orderBy()`、`field()` 等操作。下面会逐一讲解。 + +## 获取一条记录 + +如果我们查询的数据只有一条,我们也可以使用 getOne 方法,它和 get 方法不同的是它只能获取一条数据,并且 data 的格式为对象。 + +```typescript +import cloud from '@lafjs/cloud' +// 获取数据库引用 +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').getOne() + console.log(res) +// getOne 获取的结果: +// { +// ok: true, +// data: { _id: '641d21992de2b789c963e5e0', name: 'jack' }, +// requestId: undefined +// } + + const res = await db.collection('user').get() + console.log(res) +// get 获取的结果: +// { +// data: [ { _id: '641d22292de2b789c963e5fd', name: 'jack' } ], +// requestId: undefined, +// ok: true +// } +} +``` + +`getOne()` 前面支持 `where()`、`limit()`、`skip()`、`orderBy()`、`field()` 等操作。下面会逐一讲解。 + +## 添加查询条件 + +`collection.where()` + +设置查询条件条件 +where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。支持多个条件同时筛选。 + +比如筛选出所有名字叫 jack 的用户: + +```typescript +// 查询 user 集合中 name 字段等于 jack 的记录 +await db.collection("user").where({ + name:"jack" +}); +``` + +:::tip +这里注意,`where` 并不会去查询数据,需参考我们上面的栗子加上 `get()` 或者 `getOne()` +::: + +## 根据 ID 查询数据 + +`collection.doc()` + +跟 `where` 的区别是,`doc` 只根据_id 筛选 + +::: warning +如果是用 cloud.database() 新增的文档,_id 类型为字符串 +如果是用 cloud.mongo.db 新增的文档,_id 类型一般为 ObjectId +::: + +```typescript +// 查询 user 集合中 _id 为 '644148fd1eeb2b524dba499e' 的文档 +await db.collection("user").doc('644148fd1eeb2b524dba499e').get(); + +// 其实等同于 where 的筛选条件只有 _id +await db.collection("user").where({ + _id: '644148fd1eeb2b524dba499e' +}).getOne(); +``` + +```typescript +// _id 的类型为 ObjectId 的情况 +import { ObjectId } from 'mongodb' // 需要在云函数顶部引入 ObjectId 类型 + +await db.collection("user").doc(ObjectId('644148fd1eeb2b524dba499e')); +``` + +## 高级查询指令 + +::: tip +`where` 结尾不会直接查询,需要后面加 `get` 或 `getOne` +::: + +### gt 字段大于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +此例子筛选出所有年龄大于 18 的用户: + +```typescript +const db = cloud.database() +const _ = db.command; // 这里拿到指令 +await db.collection("user").where({ + age: _.gt(18) // 表示大于 18 + }, +); +``` + +### gte 字段大于或等于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +```typescript +const db = cloud.database() +const _ = db.command; // 这里拿到指令 +await db.collection("user").where({ + age: _.gte(18) // 表示大于或等于 18 + }, +); +``` + +### lt 字段小于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +### lte 字段小于或等于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +### eq 表示字段等于某个值 + +`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 + +比如筛选出所有自己发表的文章,除了用传对象的方式: + +```typescript +const myOpenID = "xxx"; +await db.collection("articles").where({ + _openid: myOpenID, +}); +``` + +还可以用指令: + +```typescript +const db = cloud.database() +const _ = db.command; +const myOpenID = "xxx"; +await db.collection("articles").where({ + _openid: _.eq(myOpenID), +}); +``` + +注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如: + +```typescript +// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN' +await db.collection("articles").where({ + stat: { + publishYear: 2018, + language: "zh-CN", + }, +}); + +// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' } +const _ = db.command; +await db.collection("articles").where({ + stat: _.eq({ + publishYear: 2018, + language: "zh-CN", + }), +}); +``` + +### neq 表示字段不等于某个值 + +字段不等于。`neq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 + +如筛选出品牌不为 X 的计算机: + +```typescript +const _ = db.command; +await db.collection("goods").where({ + category: "computer", + type: { + brand: _.neq("X"), + }, +}); +``` + +### in 字段值在给定的数组中 + +如:筛选出年龄为 18 或 20 岁的用户: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.in([18, 20]), +}); +``` + +### nin 字段值不在给定的数组中 + +筛选出年龄不是 18 或 20 岁的用户: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.nin([8, 20]), +}); +``` + +### and 表示需同时满足指定的两个或以上的条件 + +如筛选出年龄大于 18 小于 60 的用户: + +流式写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.gt(18).and(_.lt(60)), +}); +``` + +前置写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.and(_.gt(18), _.lt(60)), +}); +``` + +### or 表示需满足所有指定条件中的至少一个 + +如筛选出用户年龄等于 18 或等于 60 的用户: + +流式写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.eq(18).or(_.eq(60)), +}); +``` + +前置写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.or(_.eq(18),_.eq(60)), +}); +``` + +如果要跨字段“或”操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机) + +```typescript +const _ = db.command; +await db.collection("goods").where( + _.or( + { + type: { + memory: _.gt(8), + }, + }, + { + type: { + cpu: 3.2, + }, + } + ) +); +``` + +### exists 判断字段是否存在 + +```typescript +const _ = db.command; +await db.collection("users").where( + name: _.exists(true), // name 字段存在 + age: _.exists(false), // age 字段不存在 +); +``` + +## 正则表达式查询 + +`new RegExp` 根据正则表达式进行筛选 + +例如下面可以筛选出 `version` 字段开头是 "数字+s" 的记录,并且忽略大小写: + +```typescript +// 可以直接使用正则表达式 +await db.collection('articles').where({ + version: /^\ds/i +}) + +// 或者 +await db.collection('articles').where({ + version: new RegExp('^\\ds','i') +}) +``` + +## 获取查询数量 + +collection.count() 查询符合条件的数量 + +参数 + +```typescript +await db.collection("goods").where({ + category: "computer", + type: { + memory: 8, + }, +}).count() +``` + +响应参数 + +| 字段 | 类型 | 必填 | 说明 | +| --------- | ------- | ---- | ------------------------ | +| code | string | 否 | 状态码,操作成功则不返回 | +| message | string | 否 | 错误描述 | +| total | Integer | 否 | 计数结果 | +| requestId | string | 否 | 请求序列号,用于错误排查 | + +## 设置记录数量 + +collection.limit() 限制展示数量,最大 1000 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ----- | ------- | ---- | -------------- | +| value | Integer | 是 | 限制展示的数值 | + +使用示例 + +```typescript +await db.collection("user").limit(1).get() +``` + +## 设置起始位置 + +collection.skip() 跳过展示的数据 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ----- | ------- | ---- | -------------- | +| value | Integer | 是 | 跳过展示的数据 | + +使用示例 + +```typescript +await db.collection("user").skip(4).get() +``` + +## 分页查询 + +`skip()` 和 `limit()` 组合可做分页查询,这里不能用 `getOne()` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 每页显示数量 + const pageSize = 3; + // 第几页 + const page = 2; + const res = await db.collection('user') + .skip((page - 1) * pageSize) + .limit(pageSize) + .get() +} +``` + +## 嵌套查询 + +如果是对象或数组中的某个字段进行查询 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 userInfo.name = 'Jack' 且 userInfo.age = 10 的数据 + // 写法 1 + const result1 = await db.collection('user') + .where({ + userInfo: { + name: "Jack", + age: 10 + } + }).get() + // 写法 2 + const result2 = await db.collection('user') + .where({ + 'userInfo.name': 'Jack', + 'userInfo.age': 10 + }).get() +} +``` + +如数据库中 `test` 集合中有如下数据 + +```json +[ + { + "arr":[{ + "name": "item-1" + },{ + "name": "item-2" + }] + }, + { + "arr":[{ + "name": "item-3" + },{ + "name": "item-4" + }] + } +] +``` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 arr[0].name = 'item-1' 的数据 + const result = await db.collection('test') + .where({ + 'arr.0.name': "item-1" + }).get() +} +``` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 arr 内某个元素的 name 为 'item-2' 的文档 + const result = await db.collection('test') + .where({ + 'arr.name': "item-2" + }).get() +} +``` + +## 对结果排序 + +collection.orderBy() 对数据排序后再展示 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| --------- | ------ | ---- | ----------------------------------- | +| field | string | 是 | 排序的字段 | +| orderType | string | 是 | 排序的顺序,升序 (asc) 或 降序 (desc) | + +使用示例 + +```typescript +// 按照创建时间 createAt 的升序排序 +await db.collection("user").orderBy("createAt", "asc").get() +``` + +## 指定返回字段 + +collection.field() 只返回指定字段 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ---- | ------ | ---- | ----------------------------------------- | +| - | object | 是 | 要过滤的字段,不返回传 0,返回传 1 | + +::: tip +备注:只能指定要返回的字段或者不要返回的字段,即 `{'a': 1, 'b': 0}` 是一种错误的参数格式。默认会显示 id。 +::: + +使用示例 + +```typescript +await db.collection("user").field({ age: 1 }); +``` + +同样的后面也要加上 `get()` 或 `getOne()` ,才可以查询到结果 + +## with 关联查询 + +with / withOne 联表查询,可以实现查询一个集合时,连同某个字段的相关联记录一同查出(可跨表),比如查询“班级”时连同班级内的“学生”一起查询出来,又比如查询“文章”时连同它的“作者”一并查出等等。 + +:::info +with / withOne 联表查询在 sdk 内部是先查询了主表后,再查询子表,然后在本地(云函数或客户端)完成拼接后再传回业务开发者;如果你还没有使用 with 联表查询,推荐使用聚合操作的 [lookup 联表查询](#lookup-关联查询)。 +::: + +### 一对多关系查询 + +主要用于「一对多」关系的子查询,可跨表查询,要求用户拥有子表的查询权限 + +```typescript +await const { data } = await db + .collection("article") + .with({ + query: db.collection("tag"), + localField: "id", // 主表连接键,即 article.id + foreignField: "article_id", // 子表连接键,即 tag.article_id + as: "tags", // 查询结果中字段重命名,缺省为子表名 + }) + .get(); +console.log(data); +// [ { id: 1, name: xxx, tags: [...] } ] +``` + +### 一对一关系查询 + +> 类似 sql left join 查询 + +```typescript +const { data } = await db + .collection("article") + .withOne({ + query: db.collection("user"), + localField: "author_id", // 主表连接键,即 article.id + foreignField: "id", // 子表连接键,即 tag.article_id + as: "author", // 查询结果中字段重命名,缺省为子表名 + }) + .get(); + +console.log(data); +// [ { id: 1, name: xxx, author: {...} } ] +``` + +## lookup 关联查询 + +:::info +lookup 联表查询并非 `collection` 下的方法! + +事实上其为聚合 `aggregate` 下的方法,然而前文提到了 `with 联表查询` 用途与此一致,故在此先做说明,以避免开发者以为 lookup 不得使用,导致额外适配成 with 联表查询的成本。 +::: + +用途与 `with 联表查询` 基本一致,同 with 联表查询的示例:查询 article 集合时,把各记录的 tag 标签一同查出。 + +```typescript +const { data } = await db + .collection("article") + .aggregate() + .lookup({ + from: "tag", + localField: "id", // 主表连接键,即 article.id + foreignField: "article_id", // 子表连接键,即 tag.article_id + as: "tags", // 查询结果中字段重命名,缺省为子表名 + }) + .end(); +console.log(data); +``` diff --git a/docs/guide/db/geo.md b/docs/zh/cloud-database/database-ql/geo.md similarity index 100% rename from docs/guide/db/geo.md rename to docs/zh/cloud-database/database-ql/geo.md diff --git a/docs/zh/cloud-database/database-ql/index.md b/docs/zh/cloud-database/database-ql/index.md new file mode 100644 index 0000000000..53f74a54a9 --- /dev/null +++ b/docs/zh/cloud-database/database-ql/index.md @@ -0,0 +1,85 @@ +--- +title: 云数据库介绍 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库提供了开箱即用的数据库,无需复杂配置和连接。在云函数中可通过 `cloud.database()` 新建 DB 实例去操作数据库。 + +Laf 云数据库是使用的 `MongoDB` ,既保留了 `MongoDB` 原生查询数据库操作方法,也封装了更方便的操作方法。 + +Laf 云数据库是一个 JSON 格式的文档型数据库,数据库中的每条记录都是一个 JSON 格式的文档。因此在 Laf 数据库中,集合对应 MySQL 的数据表,文档对应 MySQL 的行,字段对应 MySQL 的列。 + +## 基本概念 + +### 文档 + +数据库的每条记录都是一个 JSON 格式的文档,如: + +```typescript +{ + "username": "hello", + "password": "123456", + "extraInfo": { + "mobile": "15912345678" + } +} +``` + +### 集合 + +集合是一组文档的集合,每个文档都在一个集合里面。如所有的用户放在 `users` 集合里。 + +```typescript +[ + { + "username": "name1", + "password": "123456", + "extraInfo": { + "mobile": "15912345678" + } + }, + { + "username": "name2", + "password": "12345678", + "extraInfo": { + "mobile": "15912345679" + } + } + ... +] +``` + +### 数据库 + +每个 Laf 应用有且仅有一个数据库,但是一个数据库可以创建多个集合。 + +![dblist](./dblist.jpg) + +上图代表当前 laf 应用下有 2 个集合,分别是 `test` 集合和 `messages` 集合 + +同时在 laf 的 `Web IDE` 中可以很方便的看到全部的集合列表,以及简单的管理。 + +## 数据类型 + +云数据库提供了以下类型: + +### 常用数据类型 + +- `String` 字符串类型,存储任意长度的 UTF-8 编码的字符串 +- `Number` 数字类型,包括整数和浮点数 +- `Boolean` 布尔类型,包括 true 和 false +- `Date` 日期类型,存储日期和时间 +- `ObjectId` 对象 ID 类型,用于存储文档的唯一标识符 +- `Array` 数组类型,可以包含任意数量的值,包括其他数据类型和嵌套数组 +- `Object` 对象类型,可以包含任意数量的键值对,其中值可以是任何数据类型,包括其他对象和嵌套数组 + +### 其他数据类型 + +- `Null` 相当于一个占位符,表示一个字段存在但是值为空 +- `GeoPoint` 地理位置点 +- `GeoLineStringLine` 地理路径 +- `GeoPolygon` 地理多边形 +- `GeoMultiPoint` 多个地理位置点 +- `GeoMultiLineString` 多个地理路径 +- `GeoMultiPolygon` 多个地理多边形 diff --git a/docs/guide/db/operator.md b/docs/zh/cloud-database/database-ql/operator.md similarity index 100% rename from docs/guide/db/operator.md rename to docs/zh/cloud-database/database-ql/operator.md diff --git a/docs/guide/db/policy.md b/docs/zh/cloud-database/database-ql/policy.md similarity index 100% rename from docs/guide/db/policy.md rename to docs/zh/cloud-database/database-ql/policy.md diff --git a/docs/guide/db/quickstart.md b/docs/zh/cloud-database/database-ql/quickstart.md similarity index 100% rename from docs/guide/db/quickstart.md rename to docs/zh/cloud-database/database-ql/quickstart.md diff --git a/docs/zh/cloud-database/database-ql/update.md b/docs/zh/cloud-database/database-ql/update.md new file mode 100644 index 0000000000..fd6a25ad5f --- /dev/null +++ b/docs/zh/cloud-database/database-ql/update.md @@ -0,0 +1,128 @@ +--- +title: 更新数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库更新数据,实际上就是针对集合中的文档进行修改,通过 `where` 等操作符设置查询条件,然后通过 `update` 或 `set` 等更新操作符进行修改。 + +## 更新文档 + +### 更新指定文档 + +我们这里把 jack 的名字改为 Tom。 + +```typescript +await db.collection('user') +.where({ name: 'jack' }) +.update({ name: "Tom" }) +``` + +同样我们也可以一次更新同一个文档的多个属性,比如:更改名字的同时也更改年龄。 + +```typescript +await db.collection('user') +.where({ name: 'jack' }) +.update({ name: "Tom", age: "18" }) +``` + +### 批量更新文档 + +这里我们没有加条件限制,直接把 `user` 表中的所有 `name` 都改成了 `Tom` ,操作和之前一样只需要多传入一个对像 `{multi:true}` 即可。 + +```typescript +await db.collection('user') +.update({ name: "Tom" },{ multi:true }) +``` + +## 更新指令 + +### set + +更新指令。如果数据不存在,则会新增一个文档。 + +::: warning +注意:使用 `set` 需要使用 `doc` 去根据 ID 查询文档,然后进行更新,如果查询不到文档,则会新增一个文档。 +::: + +```typescript +await collection.doc('644148fd1eeb2b524dba499e').set({ + name: "Hey" +}) +``` + +### inc + +更新指令。用于指示字段自增某个值,需要是正整数或者负整数。这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是: + +1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况 +2. 减少一次网络请求:不需先读再写 + +之后的 mul 指令同理。 + +如给收藏的商品数量加一: + +```typescript +const _ = db.command; +await db.collection("user") + .where({ + _openid: "my-open-id", + }) + .update({ + count: { + favorites: _.inc(1), + }, + }) +``` + +### mul + +更新指令。用于指示字段自乘某个值。需要是正整数或者负整数或者 0。 + +### remove + +更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分: + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + rating: _.remove(), + }) +``` + +### push + +向数组尾部追加元素,支持传入单个元素或数组 + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + // users: _.push('aaa') + users: _.push(["aaa", "bbb"]), + }) +``` + +### pop + +删除数组尾部元素 + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + users: _.pop(), + }) +``` + +### unshift + +向数组头部添加元素,支持传入单个元素或数组。使用同 push + +### shift + +删除数组头部元素。使用同 pop diff --git a/docs/zh/cloud-database/delete.md b/docs/zh/cloud-database/delete.md new file mode 100644 index 0000000000..1a89dd9c6d --- /dev/null +++ b/docs/zh/cloud-database/delete.md @@ -0,0 +1,80 @@ + +# 云数据库 - 删除文档 + +本节将介绍如何从云数据库中删除集合中的文档。 + +::: info 本节目录 +[[toc]] +::: + +## 删除单条文档 + +如果您想从集合中删除现有文档,可以使用 `deleteOne()` 删除一个文档,该方法接受一个查询条件,匹配您想要删除的文档。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').deleteOne({ + name: 'laf' + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + deletedCount: 1 +} +``` +::: + +::: info 更多参考 +- [db.collection.deleteOne() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteOne/) +- [API: Collection.deleteOne()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#deleteOne) +::: + + +## 删除多条文档 + +如果您想从集合中删除多个文档,可以使用 `deleteMany()` 删除多个文档,该方法接受一个查询条件,匹配您想要删除的文档。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + // 删除 age 小于 10 的文档 + const ret = await db.collection('users').deleteMany({ + age: { $lt: 10 } + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + deletedCount: 2 +} +``` +::: + +::: info 更多参考 +- [db.collection.deleteMany() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteMany/) +- [API: Collection.deleteMany()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#deleteMany) +::: + + +## 下一步 +::: tip +- [插入文档](./insert.md) +- [查询文档](./find.md) +- [更新文档](./update.md) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/find.md b/docs/zh/cloud-database/find.md new file mode 100644 index 0000000000..9344d78b30 --- /dev/null +++ b/docs/zh/cloud-database/find.md @@ -0,0 +1,121 @@ + +# 云数据库 - 查询文档 + +本节介绍在云数据库中查询文档的用法。 + +::: info 本节目录 +[[toc]] +::: + + +## 概述 + +你可以执行查找操作以从云数据库检索数据。通过调用 `find()` 或 `findOne()` 方法来执行查找操作,以获取匹配查询条件的文档。 + +Node.js 驱动程序提供了以下方法来查找文档: + +- `find()` +- `findOne()` +- `countDocuments` + +## 查找单个文档 + +`findOne()` 方法返回集合中第一个匹配查询条件的文档。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const doc = await db.collection('users').findOne({ + name: '王小波' + }) + + console.log(doc) +} +``` + +::: details 查看输出 +```js +{ + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '王小波', + age: 44, + books: [ '黄金时代', '白银时代', '青铜时代' ] +} +``` +::: + +::: info 更多参考 +- [db.collection.findOne() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.findOne/) +- [API: Collection.findOne()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#findOne) +::: + +## 查找多个文档 + +`find()` 方法返回集合中所有匹配查询条件的文档。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ age: 44 }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '王小波', + age: 44, + books: [ '黄金时代', '白银时代', '青铜时代' ] + }, + { + _id: new ObjectId("65797a86f313010ca6017f70"), + name: '张小柱', + age: 44, + books: [] + } +] +``` +::: + +::: info 更多参考 +- [db.collection.find() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.find/) +- [API: Collection.find()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#find) +::: + + +## 查询文档数量 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const count = await db.collection('users') + .countDocuments({ age: 44 }) + + console.log(count) +} +``` + +::: info 更多参考 +- [db.collection.countDocuments() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.count/) +- [API: Collection.countDocuments()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#countDocuments) +::: + +## 下一步 +::: tip +- [插入文档](./insert.md) +- [更新文档](./update.md) +- [删除文档](./delete.md) + +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/index.md b/docs/zh/cloud-database/index.md new file mode 100644 index 0000000000..958d34673c --- /dev/null +++ b/docs/zh/cloud-database/index.md @@ -0,0 +1,52 @@ + +# 云数据库介绍 + +Laf 云数据库提供了开箱即用的数据库服务,无需自行搭建和配置数据库,即可快速使用数据库服务。 + +::: info 本节目录 +[[toc]] +::: + +## 基本概念 + +### 文档(Document) + +文档是云数据库中数据的基本单元,类似于关系型数据库中的行。文档是一个键值对的有序集合,文档中的键值对是有序的,文档中的键是字符串,值可以是各种复杂的数据类型。 + +```json +{ + "_id": "5f7b6b6b6b6b6b6b6b6b6b6b", + "name": "张三", + "age": 18, + "hobbies": ["篮球", "足球", "游泳"], + "address": { + "province": "广东省", + "city": "珠海市", + "district": "香洲区" + } +} +``` +::: info +在云数据库中,每个文档都有一个 `_id` 字段,用于唯一标识一个文档。如果插入文档时没有指定 `_id` 字段,会自动生成一个唯一的 `_id` 字段。 +::: + +### 集合(Collection) + +集合是一组文档的集合,类似于关系型数据库中的表。集合中的文档可以是不同的结构,但是通常情况下,集合中的文档都有着相同的结构。 +![MongoDb Collection](collection.png) + +### 数据库(Database) + +数据库是一组集合的集合,类似于关系型数据库中的数据库。 + + +## 下一步 +::: tip +- [快速开始](./quick-start.md) +- [插入文档](./insert.md) +- [查询文档](./find.md) +- [更新文档](./update.md) +- [删除文档](./delete.md) + +> _Laf 云数据库底层是 [MongoDB](https://www.mongodb.com/),可以直接使用原生 MongoDB 的语法进行操作。_ +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/insert.md b/docs/zh/cloud-database/insert.md new file mode 100644 index 0000000000..a9d2af1a97 --- /dev/null +++ b/docs/zh/cloud-database/insert.md @@ -0,0 +1,112 @@ + +# 云数据库 - 插入文档 + +本节介绍云数据库中插入文档的用法。 + +::: info 本节目录 +[[toc]] +::: + + +## 概述 + +插入操作将一个或多个文档插入到集合中。Node.js 驱动程序提供了以下方法来执行插入操作: + +- `insertOne()` +- `insertMany()` + + +## 插入单个文档 + +`insertOne()` 方法将一个文档插入到集合中。 + +如果集合不存在,`insertOne()` 方法会自动创建集合并插入文档。 + +执行成功后,该方法返回一个 `InsertOneResult` 实例,该实例表示新文档的 `_id`。 + + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').insertOne({ + name: '王小波', + age: 44, + books: ['黄金时代', '白银时代', '青铜时代'] + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + insertedId: new ObjectId("65798555f313010ca6017f72") +} +``` +::: + +::: info 更多参考 +- [db.collection.insertOne() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.insertOne/) +- [API: Collection.insertOne()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#insertOne) +::: + + +## 插入多个文档 + +`insertMany()` 方法将一个或多个文档插入到集合中。 + +如果集合不存在,`insertMany()` 方法会自动创建集合并插入文档。 + +执行成功后,该方法返回一个 `InsertManyResult` 实例,该实例表示新文档的 `_id`。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').insertMany([ + { + name: '王小波', + age: 44, + books: ['黄金时代', '白银时代', '青铜时代'] + }, + { + name: '孙连城', + age: 33, + books: ['无边的宇宙'] + } + ]) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + insertedCount: 2, + insertedIds: { + '0': new ObjectId("6579853af313010ca6017f70"), + '1': new ObjectId("6579853af313010ca6017f71") + } +} +``` +::: + +::: info 更多参考 +- [db.collection.insertMany() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.insertMany/) +- [API: Collection.insertMany()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#insertMany) +::: + + +## 下一步 +::: tip +- [查询文档](./find.md) +- [更新文档](./update.md) +- [删除文档](./delete.md) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/array.md b/docs/zh/cloud-database/query/array.md new file mode 100644 index 0000000000..a6187af670 --- /dev/null +++ b/docs/zh/cloud-database/query/array.md @@ -0,0 +1,108 @@ + + +# 查询数组类型字段 + +本节介绍如何查询文档中的数组类型字段。 + +假设我们有如下文档: + +```json +[ + { + "name": "张三", + "age": 18, + "hobbies": ["乒乓球", "足球"], + "serviceYears": [2009, 2010, 2011, 2012] + }, + { + "name": "李四", + "age": 20, + "hobbies": ["乒乓球", "羽毛球"], + "serviceYears": [2011, 2012, 2013, 2014] + } +] +``` + +## 查询数组中包含某个元素的文档 + +下面的示例查询所有喜欢打乒乓球的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + hobbies: '乒乓球' + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '张三', + age: 18, + hobbies: ['乒乓球', '足球'] + }, + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '李四', + age: 20, + hobbies: ['乒乓球', '羽毛球'] + } +] +``` +::: + +## 配合条件操作符查询数组中的元素 + +下面的示例查询服役年份大于等于 2011 年的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + serviceYears: { $gte: 2011 } + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '张三', + age: 18, + serviceYears: [2009, 2010, 2011, 2012] + }, + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '李四', + age: 20, + serviceYears: [2011, 2012, 2013, 2014] + } +] +``` +::: + + +## 更多用法 + +::: info 引用链接 +- [查询数组](https://www.mongodb.com/docs/manual/tutorial/query-arrays/#query-an-array) +- [查询数组中的嵌套文档](https://www.mongodb.com/docs/manual/tutorial/query-array-of-documents/) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/condition.md b/docs/zh/cloud-database/query/condition.md new file mode 100644 index 0000000000..6a724b21a8 --- /dev/null +++ b/docs/zh/cloud-database/query/condition.md @@ -0,0 +1,110 @@ + +# 条件查询 + +## 概述 + +大多数 CRUD 操作允许你指定查询条件来缩小匹配文档的范围。查询条件包含一个或多个查询操作符,应用于特定字段,用于确定哪些文档包含在结果集中。 + +在查询条件中,您可以将字段与字面值进行匹配,例如 `{ title: 'The Room' }`,也可以组合查询操作符来表达更复杂的匹配条件。 + +在本节中,我们将介绍以下类别的查询操作符,并展示如何使用它们: + +- 比较操作符 +- 逻辑操作符 + + +## 比较操作符 + +| 名称 | 描述 | +| --- | --- | +| `$eq` | 匹配字段值等于指定值的文档。 | +| `$gt` | 匹配字段值大于指定值的文档。 | +| `$gte` | 匹配字段值大于或等于指定值的文档。 | +| `$in` | 匹配字段值等于指定数组中任意值的文档。 | +| `$lt` | 匹配字段值小于指定值的文档。 | +| `$lte` | 匹配字段值小于或等于指定值的文档。 | +| `$ne` | 匹配字段值不等于指定值的文档。 | +| `$nin` | 匹配字段值不等于指定数组中任意值的文档。 | + + +### `$gt` `$lt` 示例 + +你可以使用多个查询操作符来组合查询条件。例如,以下查询条件将匹配年龄大于 40 且小于 50 的用户: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + // 查询年龄大于 40 且小于 50 的用户 + const docs = await db.collection('users') + .find({ + age: { $gt: 40, $lt: 50 } + }) + .toArray() + + console.log(docs) +} +``` + + +### `$in` 示例 + +以下示例将匹配年龄为 12、24 或 36 的用户: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + age: { $in: [12, 24, 36] } + }) + .toArray() + + console.log(docs) +} +``` + +## 逻辑操作符 + +| 名称 | 描述 | +| --- | --- | +| `$and` | 匹配同时满足所有查询条件的文档。 | +| `$not` | 匹配不满足查询条件的文档。 | +| `$nor` | 匹配不满足所有查询条件的文档。 | +| `$or` | 匹配满足任意查询条件的文档。 | + +### `$or` 示例 + +以下示例将查询满足法定婚龄的用户: +- 男性年龄大于等于 22 岁 +- 女性年龄大于等于 20 岁 + + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users').find({ + $or: [ + { gender: '男', age: { $gte: 22 }}, + { gender: '女', age: { $gte: 20}} + ] + }).toArray() + + console.log(docs) +} +``` + +## 更多用法 + +::: info 引用链接 +- [查询条件](https://www.mongodb.com/docs/drivers/node/v5.0/fundamentals/crud/query-document/) +- [逻辑操作符](https://www.mongodb.com/docs/manual/reference/operator/query-logical/) +- [比较操作符](https://www.mongodb.com/docs/manual/reference/operator/query-comparison/) +- [元素操作符](https://www.mongodb.com/docs/manual/reference/operator/query-element/) +- [数组操作符](https://www.mongodb.com/docs/manual/reference/operator/query-array/) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/nested.md b/docs/zh/cloud-database/query/nested.md new file mode 100644 index 0000000000..5fecd50556 --- /dev/null +++ b/docs/zh/cloud-database/query/nested.md @@ -0,0 +1,91 @@ + + +# 嵌套文档查询 + +本节介绍如何查询嵌套文档。 + +嵌套文档是指文档中包含文档的情况,例如: + +```json +[ + { + "name": "张三", + "age": 18, + "address": { + "city": "北京", + "street": "中关村" + } + }, + { + "name": "李四", + "age": 20, + "address": { + "city": "上海", + "street": "浦东" + } + } +] +``` + + +## 使用 `.` 表示法对嵌套字段进行查询 + +下面的示例使用 `.` 表示法查询所有居住在北京的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + 'address.city': '北京' + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '张三', + age: 18, + address: { + city: '北京', + street: '中关村' + } + } +] +``` +::: + +## $in 操作符示例 + +以下示例将查询居住在北京或上海的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + 'address.city': { $in: ['北京', '上海'] } + }) + .toArray() + + console.log(docs) +} +``` + +## 更多用法 + +::: info 引用链接 +- [嵌套文档查询](https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/) +- [查询条件](https://www.mongodb.com/docs/drivers/node/v5.0/fundamentals/crud/query-document/) +- [$in 用法](https://www.mongodb.com/docs/manual/reference/operator/query/in/#mongodb-query-op.-in) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/pagination.md b/docs/zh/cloud-database/query/pagination.md new file mode 100644 index 0000000000..3abd7b2833 --- /dev/null +++ b/docs/zh/cloud-database/query/pagination.md @@ -0,0 +1,69 @@ + + +# 对文档进行分页查询 + +## 概述 + +分页查询是指将查询结果分页返回,以便于客户端进行分页展示。在云数据库中,分页查询可以通过 `limit` 和 `skip` 来实现。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({}) + .skip(0) + .limit(10) + .toArray() + + console.log(docs) +} +``` + +其中 `skip` 用于指定跳过的文档数量,`limit` 用于指定返回的文档数量,即每页的文档数量。 +上述代码中,我们指定跳过 0 个文档,返回 10 个文档,即返回第 1 页的文档。 + + +## 分页查询示例 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function (ctx: FunctionContext) { + // 每页的文档数量,默认为 10 + const pageSize = ctx.query.pageSize || 10 + + // 当前页码,默认为第一页 + const pageIndex = ctx.query.pageIndex || 1 + + // 计算查询的起始位置,即跳过的文档数量 + const skip = pageSize * (pageIndex - 1) + + // 查询文档 + const docs = await db.collection('users') + .find({}) + .skip(skip) + .limit(pageSize) + .toArray() + + // 查询总数 + const total = await db.collection('users').countDocuments() + + return { + list: docs, + total, + pageSize, + pageIndex, + total + } +} +``` + +::: info 更多参考 +- [skip() 完整说明](https://www.mongodb.com/docs/manual/reference/method/cursor.skip/) +- [limit() 完整说明](https://www.mongodb.com/docs/manual/reference/method/cursor.limit/) +- [API: skip()](https://mongodb.github.io/node-mongodb-native/5.0/classes/FindCursor.html#skip) +- [API: limit()](https://mongodb.github.io/node-mongodb-native/5.0/classes/FindCursor.html#limit) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/regex.md b/docs/zh/cloud-database/query/regex.md new file mode 100644 index 0000000000..306b77257b --- /dev/null +++ b/docs/zh/cloud-database/query/regex.md @@ -0,0 +1,127 @@ + + +# 使用正则进行模糊查询 + +## 概述 + +本节介绍如何使用正则表达式对文本字段进行模糊查询。 + + +## 正则表达式查询 + +下面的示例使用正则表达式查询所有名字中包含`王`的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + name: { $regex: /王/ } + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '王小波', + age: 1000 + }, + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '兰陵王', + age: 30 + } +] +``` +::: + +## 在 `$in` 操作符中使用正则表达式 + +下面的示例使用正则表达式查询所有姓`王`或`陈`的用户,即首字为`王`或`陈`的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + name: { $in: [/^王/, /^陈/] } + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '王小波', + age: 1000 + }, + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '陈奕迅', + age: 40 + } +] +``` +::: + + +## $regex 和 $not 操作符组合使用 + +下面的示例使用 `$regex` 和 `$not` 操作符查询所有**不姓**`王`的用户。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({ + name: { $not: { $regex: /^王/ } } + }) + .toArray() + + console.log(docs) +} +``` + +::: details 查看输出 +```js +[ + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '陈奕迅', + age: 40 + }, + { + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '兰陵王', + age: 30 + } +] +``` +::: + + +## 更多用法 + +::: info 引用链接 +- [正则表达式](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions) +- [$regex 用法](https://docs.mongodb.com/manual/reference/operator/query/regex/) +- [$not 用法](https://docs.mongodb.com/manual/reference/operator/query/not/) +- [$in 用法](https://docs.mongodb.com/manual/reference/operator/query/in/) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/query/sort.md b/docs/zh/cloud-database/query/sort.md new file mode 100644 index 0000000000..d138519933 --- /dev/null +++ b/docs/zh/cloud-database/query/sort.md @@ -0,0 +1,48 @@ + +# 对查询进行排序 + +你可以使用 `sort()` 方法对查询结果进行排序,其用法如下: + +```typescript +sort({ field: 1 }) +``` + +其中 `field` 为排序字段,`1` 表示升序,`-1` 表示降序。 + +## 升序查询 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({}) + .sort({ age: 1}) + .toArray() + + console.log(docs) +} +``` + +## 降序查询 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const docs = await db.collection('users') + .find({}) + .sort({ age: -1}) + .toArray() + + console.log(docs) +} +``` + + +::: info 更多参考 +- [sort() 完整说明](https://www.mongodb.com/docs/manual/reference/method/cursor.sort/) +- [API: sort()](https://mongodb.github.io/node-mongodb-native/5.0/classes/FindCursor.html#sort) +::: \ No newline at end of file diff --git a/docs/zh/cloud-database/quick-start.md b/docs/zh/cloud-database/quick-start.md new file mode 100644 index 0000000000..2cdeb7bdbe --- /dev/null +++ b/docs/zh/cloud-database/quick-start.md @@ -0,0 +1,136 @@ + +# 云数据库快速入门 + +本文通过 3 分钟,快速介绍如何操作云数据库。 + +::: info 本节目录 +[[toc]] +::: + +## 获取数据库实例 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db +``` + +## 插入文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').insertOne({ + name: '王小波', + age: 44, + books: ['黄金时代', '白银时代', '青铜时代'] + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + insertedId: new ObjectId("65797a86f313010ca6017f6f") +} +``` +::: + + +## 查询文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const doc = await db.collection('users').findOne({ + name: '王小波' + }) + + console.log(doc) +} + +``` + +::: details 查看输出 +```js +{ + _id: new ObjectId("65797a86f313010ca6017f6f"), + name: '王小波', + age: 44, + books: [ '黄金时代', '白银时代', '青铜时代' ] +} +``` +::: + + +## 更新文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').updateOne({ + name: '王小波' + }, { + $set: { + age: 1000 + } + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + modifiedCount: 1, + upsertedId: null, + upsertedCount: 0, + matchedCount: 1 +} +``` +::: + +## 删除文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').deleteOne({ + name: '张小柱' + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + deletedCount: 0 // 由于没有找到张小柱,所以删除数量为 0 +} +``` +::: + +## 下一步 + +::: tip +- [插入文档](./insert.md) +- [查询文档](./find.md) +- [更新文档](./update.md) +- [删除文档](./delete.md) + +>_Laf 使用的数据库 API 是 [MongoDb 官方 Node.js SDK](https://www.mongodb.com/docs/drivers/node/v5.0/quick-reference/),你也可以直接参考官方文档。_ +::: diff --git a/docs/zh/cloud-database/update.md b/docs/zh/cloud-database/update.md new file mode 100644 index 0000000000..f8d4c820e6 --- /dev/null +++ b/docs/zh/cloud-database/update.md @@ -0,0 +1,137 @@ + +# 云数据库 - 更新文档 +本节介绍在云数据库中更新文档的用法。 + +::: info 本节目录 +[[toc]] +::: + +## 概述 + +你可以使用更新和替换操作修改集合中的文档。 + +更新文档时,你可以使用更新操作或替换操作: + +- 更新操作修改文档的字段和值,同时保持其他字段和值不变。 +- 替换操作将现有文档中的所有字段和值替换为指定的字段和值,同时保持 _id 字段值不变。 + +Node.js 驱动程序提供了以下方法来更改文档: + +- `updateOne()` +- `updateMany()` +- `replaceOne()` + +## 更新单个文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').updateOne({ + name: '王小波' + }, { + $set: { age: 1000 } + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + modifiedCount: 1, + upsertedId: null, + upsertedCount: 0, + matchedCount: 1 +} +``` +::: + +::: info 更多参考 +- [db.collection.updateOne() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/) +- [API: Collection.updateOne()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#updateOne) +::: + + +## 更新多条文档 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').updateMany({ + createdAt: { $exists: false } + }, { + $set: { createdAt: new Date() } + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + modifiedCount: 2, + upsertedId: null, + upsertedCount: 0, + matchedCount: 2 +} +``` +::: + +::: info 更多参考 +- [db.collection.updateMany() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.updateMany/) +- [API: Collection.updateMany()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#updateMany) +::: + + +## 替换单个文档 + +`replaceOne()` 方法替换集合中的单个文档。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function () { + const ret = await db.collection('users').replaceOne( + { name: '王小波' }, + { + name: '王小波', + age: 1000, + createdAt: new Date() + }) + + console.log(ret) +} +``` + +::: details 查看输出 +```js +{ + acknowledged: true, + modifiedCount: 1, + upsertedId: null, + upsertedCount: 0, + matchedCount: 1 +} +``` +::: + +::: info 更多参考 +- [db.collection.replaceOne() 完整说明](https://www.mongodb.com/docs/manual/reference/method/db.collection.replaceOne/) +- [API: Collection.replaceOne()](https://mongodb.github.io/node-mongodb-native/5.0/classes/Collection.html#replaceOne) +::: + +## 下一步 +::: tip +- [插入文档](./insert.md) +- [查询文档](./find.md) +- [删除文档](./delete.md) +::: \ No newline at end of file diff --git a/docs/zh/cloud-function/auth.md b/docs/zh/cloud-function/auth.md new file mode 100644 index 0000000000..0071a83fd0 --- /dev/null +++ b/docs/zh/cloud-function/auth.md @@ -0,0 +1,88 @@ + + +# 基于 JWT 的身份验证 + +关于 JWT 的介绍,可以参考文末参考链接,本节不在赘述。 + +::: info 本节目录 +[[toc]] +::: + + +## 生成 JWT + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const payload = { + user_id: 123, + exp: 60 * 60 * 24 * 7, // 有效期为 7 天 + } + const token = cloud.getToken(payload) + + return token +} +``` + +## 验证 JWT + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const token = ctx.headers.token + const payload = cloud.parseToken(token) + + if(payload.uid === 123) { + return 'success' + } else { + return 'fail' + } +} +``` + +## 开箱即用的 `Bearer Token` + +::: info +Laf 云函数内置了 `Bearer Token` 的身份验证,即 `Authorization` 请求头的值为 `Bearer ${jwt}`,可直接使用。 +关于 `Bearer Token` 的介绍不再赘述,需要你需要自行了解其含义用法。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const payload = ctx.user + + if(payload.uid === 123) { + return 'success' + } else { + return 'fail' + } +} +``` + +::: info +客户端请求时,只需在请求头中添加 `Authorization: Bearer ${jwt}` 即可,Laf 云函数会自动验证身份,并将解析后的 `payload` 存储在 `ctx.user` 中。 + +如果请求未携带 `Authorization` 请求头,或者 `Authorization` 请求头的值不是 `Bearer ${jwt}`,则 `ctx.user` 为 `null`。 + +如果 token 验证不通过, `ctx.user` 为 `null`。 +::: + + +## 参考链接 + +- [JWT 中文详解](https://zhuanlan.zhihu.com/p/651660344) +- [JWT 官网](https://jwt.io/) + + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +- [云数据库](../cloud-database/index.md) +::: diff --git a/docs/zh/cloud-function/cron.md b/docs/zh/cloud-function/cron.md new file mode 100644 index 0000000000..849399d341 --- /dev/null +++ b/docs/zh/cloud-function/cron.md @@ -0,0 +1,8 @@ + +# 定时任务 + +本节介绍使用触发器,定时触发云函数的执行。 + +![Cron Trigger](cron.png) + +如图,在「应用开发控制台」中,云函数编辑器页面左上触,可打开触发器管理面板,按界面操作即可新建定时触发器来实现定时任务。 \ No newline at end of file diff --git a/docs/zh/cloud-function/cron.png b/docs/zh/cloud-function/cron.png new file mode 100644 index 0000000000..acb5cfc0dd Binary files /dev/null and b/docs/zh/cloud-function/cron.png differ diff --git a/docs/zh/cloud-function/deps.md b/docs/zh/cloud-function/deps.md new file mode 100644 index 0000000000..39a2d0f2a4 --- /dev/null +++ b/docs/zh/cloud-function/deps.md @@ -0,0 +1,88 @@ + + +# 依赖包管理 + +本节介绍应用的依赖包管理,laf 应用支持添加三方的 npm packages。 + +::: info 本节目录 +[[toc]] +::: + +应用的依赖分为两种: +- 自定义依赖,是开发者为应用主动添加的依赖 +- 内置依赖,是运行时中自带的依赖,无需安装 + +## 自定义依赖 + +应用添加的`自定义依赖`包在运行时内部,会存储在一个单独的目录下, 与`内置依赖`不在同一目录。 + +`自定义依赖` 的加载优先级会高于 `内置依赖`,即你可以添加一个`内置依赖`中已存在的依赖包,云函数会优先加载你添加的依赖版本。 + +自定义依赖的添加和管理,在「laf 应用开发控制台」中云函数列表的下方,可根据页面对应的操作来完成自定义依赖的管理,不再赘述。 + +## 内置依赖 + + +**此表中依赖项及其版本,可能并不会随着迭代及时更新,知悉。** + +```json +{ + "@aws-sdk/client-s3": "^3.468.0", + "@aws-sdk/client-sts": "^3.468.0", + "@aws-sdk/s3-request-presigner": "^3.468.0", + "@kubernetes/client-node": "^0.18.0", + "@lafjs/cloud": "^1.0.0-beta.14", + "@types/pako": "^2.0.2", + "axios": "^1.4.0", + "chalk": "^4.1.2", + "chatgpt": "^5.2.5", + "cors": "^2.8.5", + "database-proxy": "^1.0.0-beta.14", + "dayjs": "^1.11.7", + "dotenv": "^8.2.0", + "ejs": "^3.1.8", + "express": "^4.18.2", + "express-http-proxy": "^2.0.0", + "express-xml-bodyparser": "^0.3.0", + "jsonwebtoken": "^9.0.0", + "lodash": "^4.17.21", + "minio": "^7.0.32", + "mongodb": "^5.9.2", + "mongodb-uri": "^0.9.7", + "multer": "^1.4.5-lts.1", + "node-modules-utils": "^1.0.0-beta.14", + "nodemailer": "^6.6.3", + "pako": "^2.1.0", + "validator": "^13.7.0", + "ws": "^8.11.0" +} +``` + +## 依赖缓存 + +在应用启动时,运行时会自动运行 `npm install` 指令安装依赖,在首次安装成功后,会将已安装的依赖目录打包缓存到云存储中。 + +后续再重启/启动应用时,会自动使用缓存,从而大大减少启动时间。 + +Laf 会自动为每个应用自动创建一个 `cloud-bin` 的文件桶,依赖缓存文件会自动上传到该文件桶中,文件名为 `node_modules.tar`。 + +开发者如果主动删除 `node_modules.tar` 文件,则下次启动的时候会重新安装依赖并缓存。 + +开发者如果主动删除 `cloud-bin` 文件桶,则下次启动时 laf 会自动创建该文件桶。 + +## 离线使用 + +如果开发者需要在完全离线的环境下,无法使用在线的 npm registry 服务,即无法执行 `npm install` 进行依赖安装,可通过以下方式完成离线使用: + +- 在有网环境中将要使用的依赖打包为 `node_modules.tar`,并上传到 `cloud-bin` 文件中,以缓存的方式提供给运行时 +- 给应用添加 `LF_NODE_MODULES_CACHE=always` 环境变量,以控制运行时跳过执行 `npm install` 操作 + + +## 下一步 +::: tip +- [发起网络请求](./fetch.md) +- [环境变量](./env.md) +- [云数据库](../cloud-database/index.md) +- [云存储](../cloud-storage/index.md) +- [函数引用](./import.md) +::: \ No newline at end of file diff --git a/docs/zh/cloud-function/env.md b/docs/zh/cloud-function/env.md new file mode 100644 index 0000000000..f03dc2083b --- /dev/null +++ b/docs/zh/cloud-function/env.md @@ -0,0 +1,130 @@ + + +# 环境变量 + +在 laf「开发控制台」,点击左下角的「设置」按钮,可打开「应用设置」面板,在「环境变量」可修改/添加环境变量。 + + +![Environment Variables](env.png) + +## 访问环境变量 + +可通过 `process.env` 访问应用环境变量。 + +```typescript +export default async function (ctx: FunctionContext) { + const appid = process.env.APPID + console.log(appid) +} +``` + +## 内置的环境变量 + +::: warning 提示 +通常不需要手动修改应用的内置环境变量,可能会对应用产生不可预期的影响,除非你很清楚其用法用途。 +::: + +### `APPID` + +`process.env.APPID` 可获取当前应用的 `appid`,请勿修改此项。 + +### `NPM_INSTALL_FLAGS` + +`process.env.NPM_INSTALL_FLAGS` 可用于配置应用安装依赖时的额外参数,默认为空。 + +如果你需要指定应用执行 `npm install` 指令的镜像源,可添加此环境变量覆盖默认配置,如: + +```sh +NPM_INSTALL_FLAGS="--registry=https://registry.npmjs.org" +``` + +::: tip +在 [laf.run](https://laf.run) 公有云上,为了加速中国大陆地区的应用初始化速度,使用了加速镜像,该值默认为 `--registry=https://registry.npmmirror.com --canvas_binary_host_mirror=https://npmmirror.com/mirrors/canvas --sharp_binary_host=https://npmmirror.com/mirrors/sharp --sharp_libvips_binary_host=https://npm.taobao.org/mirrors/sharp-libvips` +::: + + +### `SERVER_SECRET` + +`process.env.SERVER_SECRET` 是应用运行时默认的服务端密钥,默认用于内置的 JWT 令牌的生成和验签,通常不需要修改此项。 + +**⚠️ 此项环境变量不可为空,不可被删除。** + +> 相关内容 [云函数认证](./auth.md)。 + +### `DB_URI` + +`process.env.DB_URI` 用于获取云数据库的连接地址,请勿修改此项。 + +### `LOG_LEVEL` + +`process.env.LOG_LEVEL` 用于控制日志输出的级别,默认值为 `debug`,可选值有: +- `debug` 输出所有日志。 +- `info` 输出除 `console.debug()` 以外的所有日志。 +- `warn` 仅输出 `console.warn()` 和 `console.error()`的日志。 +- `error` 仅输出 `console.error()` 日志。 + + +### `LOG_DEPTH` + +`process.env.LOG_DEPTH` 用于控制打印 Javascript 对象的嵌套深度,默认值为 `1`,最大可用值为 `5`。 + + +### `REQUEST_LIMIT_SIZE` + +`process.env.REQUEST_LIMIT_SIZE` 用于配置 HTTP 请求体大小的上限,默认值为 `10mb`,开发者可根据业务需要调整此值。 + + +### `OSS_EXTERNAL_ENDPOINT` + +`process.env.OSS_EXTERNAL_ENDPOINT` 用于获取云存储的外网访问入口地址,在公有云中其值为 `https://oss.laf.run`,请勿修改此项。 + +### `OSS_INTERNAL_ENDPOINT` + +`process.env.OSS_INTERNAL_ENDPOINT` 用于获取云存储的内网访问入口地址,请勿修改此项。 + +### `OSS_REGION` + +`process.env.OSS_REGION` 用于获取云存储的区域信息,请勿修改此项。 + +### `OSS_ACCESS_KEY` + +`process.env.OSS_ACCESS_KEY` 用于获取云存储的用户名,请勿修改此项。 + +### `OSS_ACCESS_SECRET` + +`process.env.OSS_ACCESS_SECRET` 用于获取云存储的密码,请勿修改此项。 + +### `NODE_VERSION` + +`process.env.NODE_VERSION` 用于获取应用运行时的 `Node.js` 版本。 + +### `NODE_MODULES_PUSH_URL` + +`process.env.NODE_MODULES_PUSH_URL` 用于配置 `node_modules.tar` 缓存文件的下载地址,通常不需要修改。 + +默认应用的 `node_modules` 文件会缓存在应用自身的 `cloud-bin` 文件桶中,此环境变量的值为该文件桶的访问地址。 + +### `NODE_MODULES_PULL_URL` + +`process.env.NODE_MODULES_PULL_URL` 用于配置 `node_modules.tar` 缓存文件的上传地址,通常不需要修改。 + +默认应用的 `node_modules` 文件会缓存到应用自身的 `cloud-bin` 文件桶中,此环境变量的值为该文件桶的上传地址。 + + +### `RESTART_AT` + +`process.env.RESTART_AT` 用于获取应用上一次重启的时间戳,其值形式如: `1703158202968`。 + + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +- [云数据库](../cloud-database/index.md) +- [云存储](../cloud-storage/index.md) +- [函数引用](./import.md) +- [依赖管理](./deps.md) +::: diff --git a/docs/zh/cloud-function/env.png b/docs/zh/cloud-function/env.png new file mode 100644 index 0000000000..e4c57c00ba Binary files /dev/null and b/docs/zh/cloud-function/env.png differ diff --git a/docs/zh/cloud-function/fetch.md b/docs/zh/cloud-function/fetch.md new file mode 100644 index 0000000000..7305bddfc4 --- /dev/null +++ b/docs/zh/cloud-function/fetch.md @@ -0,0 +1,105 @@ + + +# 在云函数中发起网络请求 + +本节介绍在云函数中发起 HTTP 请求。 + +::: info 本节目录 +[[toc]] +::: + +[Fetch API](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API) 提供了一个全局 fetch() 方法,该方法提供了一种简单的方式来跨网络异步获取资源。 + + +## 发起 GET 请求 + +### 获取 JSON 数据 + +```typescript +export default async function (ctx: FunctionContext) { + const res = await fetch('https://api.github.com/users/maslow') + const obj = await res.json() + return obj +} +``` + +### 获取文本类型数据 + +```typescript +export default async function (ctx: FunctionContext) { + const res = await fetch('http://www.baidu.com/') + const html = await res.text() + return html +} +``` + +### 下载文件并上传到云存储 +::: tip +本例演示使用 `fetch()` 方法下载网络图片,并保存到云存储中,需要你提前在 laf 控制台创建一个文件桶,本例中文件桶名假定为 `data`。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 下载图片 + const imgUrl = 'https://laf.run/logo_text.png' + const res = await fetch(imgUrl) + const imageBuffer = Buffer.from(await res.arrayBuffer()) + + // 上传到云存储 + const bucket = cloud.storage.bucket('data') + await bucket.writeFile('test.png', imageBuffer, { + ContentType: res.headers.get('content-type') + }) + + return 'ok' +} +``` + +::: info 更多参考 +操作云存储的详细用法,请参考[云存储上传文件](../cloud-storage/upload.md)。 +::: + + +## 发起 POST 请求 + +### 提交 JSON 数据 + +```typescript +export default async function (ctx: FunctionContext) { + const url = 'https://laf.run/v1/auth/passwd/signin' + const user = { + username: 'laf-user', + password: 'your-laf-run-password' + } + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json;charset=utf-8' + }, + body: JSON.stringify(user) + }) + + const token = await res.json() + return token +} +``` + + +::: tip 更多参考 + +可查看 Fetch API 中文详细教程 [《阮一峰的网络日志 - Fetch API 教程》](https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html)。 +::: + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [函数引用](./import.md) +- [云存储](../cloud-storage/index.md) +::: + diff --git a/docs/zh/cloud-function/files.md b/docs/zh/cloud-function/files.md new file mode 100644 index 0000000000..dc24c95c6e --- /dev/null +++ b/docs/zh/cloud-function/files.md @@ -0,0 +1,103 @@ + + +# 处理客户端上传的文件 + +本节介绍如何使用云函数处理客户端上传的文件。 + +::: info 本节目录 +[[toc]] +::: + +## 获取上传的文件对象 + +::: info +在客户端上传到云函数的文件,可以通过 `ctx.files` 获取到,其值是一个数组,支持上传多个文件。 +::: + +```typescript +export default async function (ctx: FunctionContext) { + console.log(ctx.files) +} +``` + + +::: info 输出结果 +```typescript +[ + { + fieldname: 'file', + originalname: 'WWcBsfDKw45X965dd934f04a7b0a405467b91800d7ce.jpg', + encoding: '7bit', + mimetype: 'image/jpeg', + destination: '/tmp', + filename: 'e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', + path: '/tmp/e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', + size: 219043 + } +] +``` +::: + + + +## 读取客户端上传的文件 + +::: info +本例演示读取用户上传的文件内容。 +::: + +```typescript +import { readFile } from 'node:fs/promises' + +export default async function (ctx: FunctionContext) { + if (ctx.files.length === 0) { + return 'no file found' + } + + const file = ctx.files[0] + const data = await readFile(file.path, 'utf8') + console.log(data) +} +``` + +## 将客户端上传的文件保存到云存储 + +::: info +本例演示将客户端上传的文件保存到云存储中,需要你提前在 laf 控制台创建一个文件桶,本例中文件桶名假定为 `data`。 +::: + +```typescript +import cloud from '@lafjs/cloud' +import { createReadStream } from 'node:fs' + +export default async function (ctx: FunctionContext) { + if (ctx.files.length === 0) { + return 'no file found' + } + + const file = ctx.files[0] + const stream = createReadStream(file.path) + + const bucket = cloud.storage.bucket('test') + const res = await bucket.writeFile(file.originalname, stream, { + ContentType: file.mimetype + }) + + return res +} +``` + +::: info 更多参考 +操作云存储的详细用法,请参考[云存储上传文件](../cloud-storage/upload.md)。 +::: + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [云存储](../cloud-storage/index.md) +- [发起网络请求](./fetch.md) +- [函数引用](./import.md) +::: + diff --git a/docs/zh/cloud-function/import.md b/docs/zh/cloud-function/import.md new file mode 100644 index 0000000000..86dcd06463 --- /dev/null +++ b/docs/zh/cloud-function/import.md @@ -0,0 +1,119 @@ + + +# 函数引用 + +本节介绍云函数之间的引用,主要用于复用代码逻辑。 + +::: info 本节目录 +[[toc]] +::: + +## import + +本例创建一个工具模块 `utils`,可供其它云函数引入调用。 + +::: tip 创建一个云函数名为 `utils`,做为工具模块使用 +```typescript +import { createHash, randomUUID } from 'crypto' + +export function md5(data: any) { + return createHash('md5').update(data).digest('hex') +} + +export function sha256(data: any) { + return createHash('sha256').update(data).digest('hex') +} + +export function uuid() { + return randomUUID() +} +``` +::: + +::: warning 在云函数中引用 `utils` 工具函数 +```typescript +import { uuid, md5 } from '@/utils' + +export default async function (ctx: FunctionContext) { + console.log('生成一个 UUID: ', uuid()) + console.log('计算 md5 值: ', md5('123456')) +} +``` +::: + +::: details 查看输出结果 +```text +生成一个 UUID: 25fdca90-9211-4bf2-952a-900356b05eb4 +计算 md5 值: e10adc3949ba59abbe56e057f20f883e +``` +::: + +## 实现一个内存缓存 + +每个云函数模块,可当成一个 Node.js module 使用,我们使用函数模块来实现一个简单的缓存模块 + +::: tip 创建一个云函数名为 `memcache`,实现一个缓存模块 +```typescript +const cached = new Map() + +function get(key: string) { + return cached.get(key) +} + +function set(key: string, value: any) { + cached.set(key, value) +} + +function keys() { + return cached.keys() +} + +function size() { + return cached.size +} + +function remove (key: string) { + return cached.delete(key) +} + +function clear() { + cached.clear() +} + + +export default { get, set, keys, size, remove, clear } +``` +::: + +::: warning 在云函数中使用 `memcache` 缓存 +```typescript +import cache from '@/memcache' + +export default async function (ctx: FunctionContext) { + cache.set('name', 'maslow') + console.log(cache.get('name')) + + cache.clear() + console.log(cache.size()) +} +``` +::: + +::: details 查看输出结果 +```text +maslow +0 +``` +::: + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +- [环境变量](./env.md) +- [云存储](../cloud-storage/index.md) +::: + diff --git a/docs/zh/cloud-function/index.md b/docs/zh/cloud-function/index.md new file mode 100644 index 0000000000..01a9a17018 --- /dev/null +++ b/docs/zh/cloud-function/index.md @@ -0,0 +1,62 @@ + +# 云函数简介 + +云函数为应用提供计算能力,是 laf 最核心的应用资源之一。 + +::: tip +Laf 云函数并不是传统意义上的函数计算服务,Laf 应用是常驻的进程实例。 +::: + +::: info 本节目录 +[[toc]] +::: + +## 能力 + +- 处理 HTTP 请求 +- 操作数据库 +- 操作云存储 +- 调用三方服务 +- 定时任务 +- 处理 WebSocket + + +## 特点 + +### 毫秒级发布 + +Laf 云函数可实现像写博客一样写代码,在线编写、一键发布、毫秒级生效,无需在改动代码后漫长的等待构建与发布过程。 + +### 无冷启动 + +Laf 应用是常驻内存的实例,天然没有冷启动时延问题,云函数的调用时延通常小于 10ms。 + +### 性能优异 + +同一个 Laf 应用的所有云函数由一个 Node.js Runtime 常驻进程来提供服务,可以充分利用 Node.js 异步 IO 模型提供强大的网络并发处理能力。 + +### 成本低廉 + +由于 Laf 应用是常驻实例,单实例可以处理数千数万的并发请求,调用成本极低。 +传统的函数计算一个请求一个实例,一千个请求就需要上千个实例来处理,其成本极其昂贵,两者调用成本相差数十甚至百倍。 + +### 长连接 + +Laf 云函数天然支持标准的 WebSocket 长连接处理, 实测单实例即可处理 `100K WebSocket` 连接。 +传统的函数计算一般不支持 WebSocket 长连接,或通过网关间接支持非标准的、成本极其昂贵的长连接方案。 + +### 弹性伸缩 + +Laf 应用支持以实例为单位的自动水平伸缩,基于 Kubernetes HPA 实现。可根据业务负载情况自动伸缩实例数量,自动应对峰谷时段负载。 + +## 下一步 +::: tip +- [快速开始](./quick-start.md) +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +- [函数引用](./import.md) +::: + diff --git a/docs/zh/cloud-function/quick-start.md b/docs/zh/cloud-function/quick-start.md new file mode 100644 index 0000000000..1ab2104244 --- /dev/null +++ b/docs/zh/cloud-function/quick-start.md @@ -0,0 +1,108 @@ + + +# 云函数快速入门 + +本节通过给出几个简单的云函数示例,快速展示云函数的能力和用法。 + +::: tip +你可以在 `https://laf.run` 上创建一个应用,然后创建函数来调试这些云函数代码。 +::: + +::: info 本节目录 +[[toc]] +::: + +## Hello World + +```typescript +export default async function (ctx: FunctionContext) { + console.log('Hello World') + return 'hi, laf' +} +``` + +这个最简单的云函数,打印一条日志 `Hello World`,并返回 `hi, laf` 做为其响应内容。 +通过浏览器访问其地址即可看到 `hi, laf`。 + +## 获取请求参数 + +```typescript +export default async function (ctx: FunctionContext) { + // 获取请求参数 + console.log(ctx.query) + + // 获取客户端的 IP 地址 + const ip = ctx.headers['x-real-ip'] + + return `你的 IP 地址是:${ip}` +} +``` + +## 响应 JSON 对象 + +```typescript +export default async function (ctx: FunctionContext) { + // ... + + return { + code: 'success', + message: '操作成功', + data: [] + } +} +``` + +## 访问数据库 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export default async function (ctx: FunctionContext) { + // 新增数据 + await db.collection('users').insertOne({ + username: 'laf', + created_at: new Date() + }) + + // 查询数据 + const users = await db.collection('users') + .find() + .toArray() + + return users +} +``` + +## 发起 HTTP 请求 + +```typescript +export default async function (ctx: FunctionContext) { + const res = await fetch('https://laf.run/v1/regions') + const obj = await res.json() + return obj +} +``` + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +- [云数据库](../cloud-database/index.md) +- [云存储](../cloud-storage/index.md) +- [函数引用](./import.md) +- [环境变量](./env.md) +::: + + + + + + + + + + diff --git a/docs/zh/cloud-function/request.md b/docs/zh/cloud-function/request.md new file mode 100644 index 0000000000..e18d81a7d7 --- /dev/null +++ b/docs/zh/cloud-function/request.md @@ -0,0 +1,79 @@ + + + +# HTTP 请求 + +本节介绍云函数处理 HTTP 请求相关的用法。 + +::: info 本节目录 +[[toc]] +::: + +## 获取查询参数 + +```typescript +export default async function (ctx: FunctionContext) { + const id = ctx.query.id + console.log(id) +} +``` + +::: info +`ctx.query` 为 `Object` 类型,可直接获取到查询参数,详见 [req.query](https://expressjs.com/en/api.html#req.query)。 +::: + +## 获取请求体 + +```typescript +export default async function (ctx: FunctionContext) { + const body = ctx.body + console.log(body) +} +``` + +::: info +`ctx.body` 为 `Object` 类型,可直接获取到请求体,详见 [req.body](https://expressjs.com/en/api.html#req.body)。 +::: + + +## 获取客户端 IP 地址 + +```typescript +export default async function (ctx: FunctionContext) { + const ip = ctx.headers['x-real-ip'] + return `你的 IP 是:${ip}` +} + +``` + +## 获取请求对象 + +```typescript +export default async function (ctx: FunctionContext) { + const req = ctx.request + + console.log(req.url) // 获取请求的 url + console.log(req.path) // 获取请求 path + console.log(req.hostname) // 获取请求 hostname +} +``` + +::: details 查看输出 +```text +/test?id=1 +/test +c07iol.laf.dev +``` +::: + +`ctx.request` 请求对象,是一个 `express.js` 的 `Request` 对象,详见 [Express.js 文档](https://expressjs.com/en/api.html#req)。 + +## 下一步 +::: tip +- [HTTP 响应](./response.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +::: + + diff --git a/docs/zh/cloud-function/response.md b/docs/zh/cloud-function/response.md new file mode 100644 index 0000000000..62d3ade3b9 --- /dev/null +++ b/docs/zh/cloud-function/response.md @@ -0,0 +1,95 @@ + + +# HTTP 响应 + +本节介绍云函数处理 HTTP 响应相关的用法。 + +::: info 本节目录 +[[toc]] +::: + +## 返回文本 + +```typescript +export default async function (ctx: FunctionContext) { + return 'hello world' +} +``` + +## 返回 JSON + +```typescript +export default async function (ctx: FunctionContext) { + return { + code: 0, + message: 'success' + } +} +``` + +## 返回 HTML + +```typescript +export default async function (ctx: FunctionContext) { + ctx.response.setHeader('Content-Type', 'text/html') + return '

hello world

' +} +``` + +## 返回状态码 + +```typescript +export default async function (ctx: FunctionContext) { + ctx.response.status(404) + return 'Not Found' +} +``` + +## 返回重定向 + +```typescript +export default async function (ctx: FunctionContext) { + ctx.response.redirect('https://laf.run') +} +``` + + +## 流式响应 + +```typescript +import { createReadStream } from 'node:fs' + +export default async function (ctx: FunctionContext) { + const response = ctx.response + response.chunkedEncoding = true + + const stream = createReadStream('package.json') + stream.on('data', chunk => { + response.write(chunk) + }) + + stream.on('end', () => { + response.end() + }) +} +``` + + +## 返回 Cookie + +```typescript +export default async function (ctx: FunctionContext) { + ctx.response.cookie('session_id', 'abc123') + return 'hello world' +} +``` + +## 下一步 +::: tip +- [HTTP 请求](./request.md) +- [HTTP 认证](./auth.md) +- [处理文件上传](./files.md) +- [发起网络请求](./fetch.md) +::: + + diff --git a/docs/zh/cloud-storage/delete.md b/docs/zh/cloud-storage/delete.md new file mode 100644 index 0000000000..ce7b75bc47 --- /dev/null +++ b/docs/zh/cloud-storage/delete.md @@ -0,0 +1,24 @@ + +# 在云函数中删除文件 + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +## 删除文件 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 删除文件 + await bucket.deleteFile('index.html') +} +``` + +::: tip +注意:如果文件不存在,也会正常返回,不会抛出异常。 +::: diff --git a/docs/zh/cloud-storage/download-url.md b/docs/zh/cloud-storage/download-url.md new file mode 100644 index 0000000000..cbd6688aa3 --- /dev/null +++ b/docs/zh/cloud-storage/download-url.md @@ -0,0 +1,75 @@ + +# 使用云函数生成文件下载地址 + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +获取文件的访问地址有两种情况: +1. 若存储桶的访问权限为 `public` 或 `readonly`,则可直接使用文件的公共访问地址。 +2. 若存储桶的访问权限为 `private`,则需要生成一个带签名的临时访问地址。 + + +## 获取文件永久访问地址 +::: tip +仅当存储桶的访问权限为 `public` 或 `readonly`,则可直接使用文件的公共访问地址。 +且该地址永久有效,除非存储桶的访问权限被修改。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const bucket = cloud.storage.bucket('data') + const url = bucket.externalUrl('index.html') + return url +} +``` + + +## 获取文件临时访问地址(带签名) + +使用云函数生成一个临时的下载地址,客户端可直接使用该地址下载文件。 + +::: tip +当存储桶的访问权限为 `private`,则需要生成一个带签名的临时访问地址。 +且该地址默认有效期为 3600 秒,即 1 小时。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const bucket = cloud.storage.bucket('data') + const url = await bucket.getDownloadUrl('index.html') + return url +} + +``` + +::: details 使用 curl 测试下载地址 + +```bash +# 下载文件,请将 YOUR_DOWNLOAD_URL 替换为上一步获取的下载地址 +curl -X GET YOUR_DOWNLOAD_URL +``` +::: + +## 设置文件下载地址的有效期 + +::: info +- 地址默认有效期为 3600 秒,即 1 小时。 +- 最大有效期为 3600 * 24 * 7 秒,即 7 天。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const bucket = cloud.storage.bucket('data') + + // 第二个参数为上传地址有效期,单位为秒 + const url = bucket.getUploadUrl('index.html', 3600 * 24 * 7) + return url +} +``` \ No newline at end of file diff --git a/docs/zh/cloud-storage/index.md b/docs/zh/cloud-storage/index.md new file mode 100644 index 0000000000..e4cfb29e85 --- /dev/null +++ b/docs/zh/cloud-storage/index.md @@ -0,0 +1,43 @@ + +# 云存储简介 + +`laf` 云存储是兼容 S3 API 的对象存储服务,支持多种存储桶权限,包括公有读、私有读、公有读写,支持通过 HTTP/HTTPS 访问,支持自定义文件元数据,支持文件上传、下载、删除、获取文件列表等操作。 + + +## 存储桶(Bucket) + +在云存储中,存储桶是存储文件的容器,所有的文件都必须存储在存储桶中,每个存储桶都有一个唯一的名称。 + + +::: info +云存储支持创建多个存储桶,每一个存储桶都是一个独立的存储空间,文件桶的名称必须是全局唯一的,且只能包含小写字母、数字和 `-` 字符,且长度不能超过 63 个字符。 + +在 laf 应用中,文件桶的名称是由应用的 `appid` 作为前缀,然后加上存储桶的名称,例如:`{appid}-bucket`,这样可以保证每个应用的文件桶名称都是唯一的。 +::: + + +## 存储桶权限 + +云存储支持多种存储桶权限,包括公有读、私有读、公有读写。 + +在创建存储桶时,可以指定存储桶的权限: +- `public` 公有读写权限,无需凭证即可对存储桶中的文件进行读写操作。 +- `readonly` 公有读权限,无需凭证即可对存储桶中的文件进行读操作,但是需要凭证才能对存储桶中的文件进行写操作。 +- `private` 私有读写权限,需要使用凭证才能对存储桶中的文件进行读写操作。 + +::: tip +通常不建议使用 `public` 权限,因为这样会导致存储桶中的文件可以被任何人访问。 +::: + +## 网站托管 + +`laf` 云存储支持将存储桶中的文件作为静态网站进行托管: + +1. 将存储桶的权限设置为 `readonly`,只有 `readonly` 权限的存储桶才能作为静态网站进行托管。 +2. 在 `laf 控制台` 中开启存储桶的网站托管功能。 +3. 在存储桶中创建一个名为 `index.html` 的文件,作为默认首页。 + + +## Cloud Bin Bucket + +Laf 会为每个应用自动创建一个名为 `{appid}-cloud-bin` 的存储桶,用于存储应用的缓存和备份文件,默认该存储桶的权限为 `private`,建议不要修改该存储桶的权限。 diff --git a/docs/zh/cloud-storage/list.md b/docs/zh/cloud-storage/list.md new file mode 100644 index 0000000000..a6e88c0be2 --- /dev/null +++ b/docs/zh/cloud-storage/list.md @@ -0,0 +1,122 @@ + +# 在云函数中获取文件列表 + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +## 获取文件列表 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 获取文件列表 + const res = await bucket.listFiles() + return res +} +``` + +返回结果 `res.Contents` 格式如下: + +```json + [ + { + "Key": "laf.jpg", + "LastModified": "2023-12-12T12:03:36.154Z", + "ETag": "f0ce41411bdec6212f0836ebfbc56375", + "Size": 49425 + }, + { + "Key": "test.html", + "LastModified": "2023-12-12T11:38:53.117Z", + "ETag": "08ba5fadaac344913c216bcd26348263", + "Size": 10 + } +] +``` + + +## 只获取当前目录下的文件列表 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 获取文件列表 + const res = await bucket.listFiles({ Delimiter: '/' }) + return res +} +``` + +::: info +`Delimiter` 是一个分隔符,用于对存储桶中的对象名称进行分组。如果您希望获取当前目录下的文件列表,可以使用 `Delimiter` 参数。 +若不指定 `Delimiter` 参数,则返回存储桶中所有文件的列表,包括子目录下的文件。 +::: + + +## 获取子目录下的文件列表 + + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 获取 `images/` 目录下的文件列表 + const res = await bucket.listFiles({ Prefix: 'images/', Delimiter: '/' }) + return res +} +``` + +::: tip +`Prefix` 是一个前缀,用于对存储桶中的对象名称进行筛选。如果您希望获取子目录下的文件列表,可以使用 `Prefix` 参数。 +::: + + +## 获取指定数量的文件列表 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 获取前 10 个文件 + const res = await bucket.listFiles({ MaxKeys: 10 }) + return res +} +``` + +::: tip +`MaxKeys` 用于对存储桶中的对象数量进行限定。如果您希望获取指定数量的文件列表,可以使用 `MaxKeys` 参数,默认值为 1000。 +::: + +## 分页获取文件列表 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const marker = ctx.query.marker + const bucket = cloud.storage.bucket('data') + const res = await bucket.listFiles({ MaxKeys: 10, Marker: marker }) + return res +} +``` + +::: tip +`listFiles` 返回的 res 对象中包含 `NextMarker` 和 `IsTruncated` 两个属性,用于分页获取下一页文件列表: + +- `IsTruncated` 用于判断是否还有下一页文件列表,如果为 `true`,则表示还有下一页文件列表,否则表示已经是最后一页文件列表。 +- `NextMarker` 用于指定下一页文件列表的起始位置,如果 `IsTruncated` 为 `true`,则可以使用 `NextMarker` 作为 `Marker` 参数,获取下一页文件列表。 +::: \ No newline at end of file diff --git a/docs/zh/cloud-storage/read.md b/docs/zh/cloud-storage/read.md new file mode 100644 index 0000000000..bdfc4f7a4a --- /dev/null +++ b/docs/zh/cloud-storage/read.md @@ -0,0 +1,45 @@ + +# 在云函数中读文件 + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +## 读文件 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 读文件 + const res = await bucket.readFile('index.html') + + // 转换为字符串 + const data = await res.Body.transformToString() + + console.log(data) +} +``` + +## 读文件为 Buffer + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 读文件 + const res = await bucket.readFile('index.html') + + // 转换为 Buffer + const bytes = await res.Body.transformToByteArray() + const buffer = Buffer.from(bytes) + + console.log(buffer) +} +``` diff --git a/docs/zh/cloud-storage/upload-url.md b/docs/zh/cloud-storage/upload-url.md new file mode 100644 index 0000000000..3fda12ea59 --- /dev/null +++ b/docs/zh/cloud-storage/upload-url.md @@ -0,0 +1,53 @@ + + +# 使用云函数生成文件上传地址 + + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +## 生成上传地址 + +使用云函数生成一个临时的上传地址,客户端可直接使用该地址上传文件。 + + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const bucket = cloud.storage.bucket('data') + const url = bucket.getUploadUrl('index.html') + return url +} +``` + + +::: details 使用 curl 测试上传地址 + +```bash +#请将 YOUR_UPLOAD_URL 替换为上一步获取的上传地址 + +curl -X PUT -H "Content-Type: text/html" -d 'hi, laf' YOUR_UPLOAD_URL +``` +::: + +## 设置上传地址有效期 + +::: info +- 生成的地址默认有效期为 3600 秒,即 1 小时。 +- 可设置的最大有效期为 3600 * 24 * 7 秒,即 7 天。 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + const bucket = cloud.storage.bucket('data') + + // 第二个参数为上传地址有效期,单位为秒。 + const url = bucket.getUploadUrl('index.html', 3600 * 24 * 7) + return url +} +``` + diff --git a/docs/zh/cloud-storage/upload.md b/docs/zh/cloud-storage/upload.md new file mode 100644 index 0000000000..00c9651f79 --- /dev/null +++ b/docs/zh/cloud-storage/upload.md @@ -0,0 +1,88 @@ + +# 在云函数中上传文件 + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + + +## 上传文件 + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 写文件 + const content = 'hello, laf' + await bucket.writeFile('laf.html', content) +} +``` + + +## 指定文件类型(MIME) + +在上面的示例中,文件类型默认为 `application/octet-stream`,如果需要指定文件类型,可以在 `writeFile` 方法中传入 `options.ContentType` 参数: + +```ts +import cloud from '@lafjs/cloud' + +export default async function (ctx: FunctionContext) { + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 写文件并指定文件类型为 text/html + const content = 'hello, laf' + await bucket.writeFile('index.html', content, { + ContentType: 'text/html' + }) +} +``` + +更多文件类型请参考 [MIME Types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)。 + + + +## 上传文件流 + +```ts +import cloud from '@lafjs/cloud' +import { createReadStream } from 'node:fs' + +export default async function (ctx: FunctionContext) { + + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 读文件流 + const stream = createReadStream('./package.json') + + // 写文件 + await bucket.writeFile('laf.json', stream, { + ContentType: 'application/json' + }) +} +``` + +## 上传文件 Buffer + +```ts +import cloud from '@lafjs/cloud' +import { readFile } from 'node:fs/promises' + +export default async function (ctx: FunctionContext) { + + // 获取存储桶 + const bucket = cloud.storage.bucket('data') + + // 读文件 Buffer + const buffer = await readFile('./package.json') + + // 写文件 + await bucket.writeFile('laf.json', buffer, { + ContentType: 'application/json' + }) +} +``` diff --git a/docs/zh/cloud-storage/website-hosting-0.png b/docs/zh/cloud-storage/website-hosting-0.png new file mode 100644 index 0000000000..3685b11e9e Binary files /dev/null and b/docs/zh/cloud-storage/website-hosting-0.png differ diff --git a/docs/zh/cloud-storage/website-hosting-domain.png b/docs/zh/cloud-storage/website-hosting-domain.png new file mode 100644 index 0000000000..bf34413394 Binary files /dev/null and b/docs/zh/cloud-storage/website-hosting-domain.png differ diff --git a/docs/zh/cloud-storage/website-hosting.md b/docs/zh/cloud-storage/website-hosting.md new file mode 100644 index 0000000000..c726310d8a --- /dev/null +++ b/docs/zh/cloud-storage/website-hosting.md @@ -0,0 +1,37 @@ + +# 网站托管 + +在 laf 云存储中,可以选择一个存储桶开启网站托管服务。 + +网站托管会为你的网站自动提供一个独立的域名,也可以绑定自定义域名。 + +在存储桶中上传一个 `index.html` 的文件,作为默认首页。 + + +## 开启网站托管 + +1. 创建一个存储桶,并设置其权限策略为 `readonly`,只有此权限的存储桶才能开启网站托管。 +2. 将你的网站文件上传到该存储桶即可。 +3. 在 `laf 控制台` 云存储页面,点击右上角「开启网站托管」,即可通过生成的地址访问你的网站。 + +![Website-hosting](website-hosting-0.png) + + +## 绑定自定义域名 + +网站托管支持绑定自己的域名,并会自动为其生成 HTTPS 证书,支持 `https` 和 `http` 访问。 + +按页面上操作提示,完成域名的 `CNAME` 解析,等待解析生效后,可继续绑定操作。 + +![bind custom domain](website-hosting-domain.png) + +::: tip 提示 +- 域名解析生效时间:1~10分钟不等,待解析生效后才可继续绑定操作。 +- 绑定自己的域名后,laf 将会自动为您的域名配置 `SSL` 证书,这个过程可能会有 1~2 分钟,之后即可通过 `https` 进行访问 +::: + + + +## 更多 + +[用 GitHub Action 自动构建前端并发布到网站托管](/zh/examples/website-hosting-ci-cd.md) \ No newline at end of file diff --git a/docs/doc-images/AppID.png b/docs/zh/doc-images/AppID.png similarity index 100% rename from docs/doc-images/AppID.png rename to docs/zh/doc-images/AppID.png diff --git a/docs/doc-images/Laf-Pilot.png b/docs/zh/doc-images/Laf-Pilot.png similarity index 100% rename from docs/doc-images/Laf-Pilot.png rename to docs/zh/doc-images/Laf-Pilot.png diff --git a/docs/doc-images/Laf-Pilot2.png b/docs/zh/doc-images/Laf-Pilot2.png similarity index 100% rename from docs/doc-images/Laf-Pilot2.png rename to docs/zh/doc-images/Laf-Pilot2.png diff --git a/docs/doc-images/MediaPlatformBaseSetting.png b/docs/zh/doc-images/MediaPlatformBaseSetting.png similarity index 100% rename from docs/doc-images/MediaPlatformBaseSetting.png rename to docs/zh/doc-images/MediaPlatformBaseSetting.png diff --git a/docs/doc-images/MediaPlatformBaseSetting2.png b/docs/zh/doc-images/MediaPlatformBaseSetting2.png similarity index 100% rename from docs/doc-images/MediaPlatformBaseSetting2.png rename to docs/zh/doc-images/MediaPlatformBaseSetting2.png diff --git a/docs/doc-images/SALAI_TOKEN.jpg b/docs/zh/doc-images/SALAI_TOKEN.jpg similarity index 100% rename from docs/doc-images/SALAI_TOKEN.jpg rename to docs/zh/doc-images/SALAI_TOKEN.jpg diff --git a/docs/doc-images/add-env-step1.png b/docs/zh/doc-images/add-env-step1.png similarity index 100% rename from docs/doc-images/add-env-step1.png rename to docs/zh/doc-images/add-env-step1.png diff --git a/docs/doc-images/add-env-step2.png b/docs/zh/doc-images/add-env-step2.png similarity index 100% rename from docs/doc-images/add-env-step2.png rename to docs/zh/doc-images/add-env-step2.png diff --git a/docs/doc-images/add-env-step3.png b/docs/zh/doc-images/add-env-step3.png similarity index 100% rename from docs/doc-images/add-env-step3.png rename to docs/zh/doc-images/add-env-step3.png diff --git a/docs/doc-images/add-env.png b/docs/zh/doc-images/add-env.png similarity index 100% rename from docs/doc-images/add-env.png rename to docs/zh/doc-images/add-env.png diff --git a/docs/doc-images/add-packages.png b/docs/zh/doc-images/add-packages.png similarity index 100% rename from docs/doc-images/add-packages.png rename to docs/zh/doc-images/add-packages.png diff --git a/docs/doc-images/add-polocy.png b/docs/zh/doc-images/add-polocy.png similarity index 100% rename from docs/doc-images/add-polocy.png rename to docs/zh/doc-images/add-polocy.png diff --git a/docs/doc-images/app-list.png b/docs/zh/doc-images/app-list.png similarity index 100% rename from docs/doc-images/app-list.png rename to docs/zh/doc-images/app-list.png diff --git a/docs/doc-images/appList.png b/docs/zh/doc-images/appList.png similarity index 100% rename from docs/doc-images/appList.png rename to docs/zh/doc-images/appList.png diff --git a/docs/doc-images/application-list.png b/docs/zh/doc-images/application-list.png similarity index 100% rename from docs/doc-images/application-list.png rename to docs/zh/doc-images/application-list.png diff --git a/docs/doc-images/auto-build1.png b/docs/zh/doc-images/auto-build1.png similarity index 100% rename from docs/doc-images/auto-build1.png rename to docs/zh/doc-images/auto-build1.png diff --git a/docs/doc-images/auto-build2.png b/docs/zh/doc-images/auto-build2.png similarity index 100% rename from docs/doc-images/auto-build2.png rename to docs/zh/doc-images/auto-build2.png diff --git a/docs/doc-images/bind-pay.png b/docs/zh/doc-images/bind-pay.png similarity index 100% rename from docs/doc-images/bind-pay.png rename to docs/zh/doc-images/bind-pay.png diff --git a/docs/doc-images/bind-pay2.png b/docs/zh/doc-images/bind-pay2.png similarity index 100% rename from docs/doc-images/bind-pay2.png rename to docs/zh/doc-images/bind-pay2.png diff --git a/docs/doc-images/change-package-version.png b/docs/zh/doc-images/change-package-version.png similarity index 100% rename from docs/doc-images/change-package-version.png rename to docs/zh/doc-images/change-package-version.png diff --git a/docs/doc-images/cli-mind.png b/docs/zh/doc-images/cli-mind.png similarity index 100% rename from docs/doc-images/cli-mind.png rename to docs/zh/doc-images/cli-mind.png diff --git a/docs/doc-images/creat-polocy.png b/docs/zh/doc-images/creat-polocy.png similarity index 100% rename from docs/doc-images/creat-polocy.png rename to docs/zh/doc-images/creat-polocy.png diff --git a/docs/doc-images/creat-token.png b/docs/zh/doc-images/creat-token.png similarity index 100% rename from docs/doc-images/creat-token.png rename to docs/zh/doc-images/creat-token.png diff --git a/docs/doc-images/create-application.png b/docs/zh/doc-images/create-application.png similarity index 100% rename from docs/doc-images/create-application.png rename to docs/zh/doc-images/create-application.png diff --git a/docs/doc-images/create-bucket-1.png b/docs/zh/doc-images/create-bucket-1.png similarity index 100% rename from docs/doc-images/create-bucket-1.png rename to docs/zh/doc-images/create-bucket-1.png diff --git a/docs/doc-images/create-bucket.png b/docs/zh/doc-images/create-bucket.png similarity index 100% rename from docs/doc-images/create-bucket.png rename to docs/zh/doc-images/create-bucket.png diff --git a/docs/doc-images/create-cloudfunction.png b/docs/zh/doc-images/create-cloudfunction.png similarity index 100% rename from docs/doc-images/create-cloudfunction.png rename to docs/zh/doc-images/create-cloudfunction.png diff --git a/docs/doc-images/create-function.jpg b/docs/zh/doc-images/create-function.jpg similarity index 100% rename from docs/doc-images/create-function.jpg rename to docs/zh/doc-images/create-function.jpg diff --git a/docs/doc-images/create-function.png b/docs/zh/doc-images/create-function.png similarity index 100% rename from docs/doc-images/create-function.png rename to docs/zh/doc-images/create-function.png diff --git a/docs/doc-images/create-gather.png b/docs/zh/doc-images/create-gather.png similarity index 100% rename from docs/doc-images/create-gather.png rename to docs/zh/doc-images/create-gather.png diff --git a/docs/doc-images/create-injector.png b/docs/zh/doc-images/create-injector.png similarity index 100% rename from docs/doc-images/create-injector.png rename to docs/zh/doc-images/create-injector.png diff --git a/docs/doc-images/create-laf-app.jpg b/docs/zh/doc-images/create-laf-app.jpg similarity index 100% rename from docs/doc-images/create-laf-app.jpg rename to docs/zh/doc-images/create-laf-app.jpg diff --git a/docs/doc-images/db.png b/docs/zh/doc-images/db.png similarity index 100% rename from docs/doc-images/db.png rename to docs/zh/doc-images/db.png diff --git a/docs/en/doc-images/dblist.jpg b/docs/zh/doc-images/dblist.jpg similarity index 100% rename from docs/en/doc-images/dblist.jpg rename to docs/zh/doc-images/dblist.jpg diff --git a/docs/doc-images/delete-package.png b/docs/zh/doc-images/delete-package.png similarity index 100% rename from docs/doc-images/delete-package.png rename to docs/zh/doc-images/delete-package.png diff --git a/docs/doc-images/doc-app-list.png b/docs/zh/doc-images/doc-app-list.png similarity index 100% rename from docs/doc-images/doc-app-list.png rename to docs/zh/doc-images/doc-app-list.png diff --git a/docs/doc-images/doc-db.png b/docs/zh/doc-images/doc-db.png similarity index 100% rename from docs/doc-images/doc-db.png rename to docs/zh/doc-images/doc-db.png diff --git a/docs/doc-images/doc-function-list.png b/docs/zh/doc-images/doc-function-list.png similarity index 100% rename from docs/doc-images/doc-function-list.png rename to docs/zh/doc-images/doc-function-list.png diff --git a/docs/doc-images/doc-policy.png b/docs/zh/doc-images/doc-policy.png similarity index 100% rename from docs/doc-images/doc-policy.png rename to docs/zh/doc-images/doc-policy.png diff --git a/docs/doc-images/doc-storage.png b/docs/zh/doc-images/doc-storage.png similarity index 100% rename from docs/doc-images/doc-storage.png rename to docs/zh/doc-images/doc-storage.png diff --git a/docs/doc-images/edit-cloudfunction.png b/docs/zh/doc-images/edit-cloudfunction.png similarity index 100% rename from docs/doc-images/edit-cloudfunction.png rename to docs/zh/doc-images/edit-cloudfunction.png diff --git a/docs/doc-images/file.png b/docs/zh/doc-images/file.png similarity index 100% rename from docs/doc-images/file.png rename to docs/zh/doc-images/file.png diff --git a/docs/doc-images/function-body.png b/docs/zh/doc-images/function-body.png similarity index 100% rename from docs/doc-images/function-body.png rename to docs/zh/doc-images/function-body.png diff --git a/docs/doc-images/function-log.png b/docs/zh/doc-images/function-log.png similarity index 100% rename from docs/doc-images/function-log.png rename to docs/zh/doc-images/function-log.png diff --git a/docs/doc-images/function-market.png b/docs/zh/doc-images/function-market.png similarity index 100% rename from docs/doc-images/function-market.png rename to docs/zh/doc-images/function-market.png diff --git a/docs/doc-images/function-query.png b/docs/zh/doc-images/function-query.png similarity index 100% rename from docs/doc-images/function-query.png rename to docs/zh/doc-images/function-query.png diff --git a/docs/doc-images/function-template.png b/docs/zh/doc-images/function-template.png similarity index 100% rename from docs/doc-images/function-template.png rename to docs/zh/doc-images/function-template.png diff --git a/docs/doc-images/function-url.png b/docs/zh/doc-images/function-url.png similarity index 100% rename from docs/doc-images/function-url.png rename to docs/zh/doc-images/function-url.png diff --git a/docs/doc-images/function.png b/docs/zh/doc-images/function.png similarity index 100% rename from docs/doc-images/function.png rename to docs/zh/doc-images/function.png diff --git a/docs/doc-images/getToken-parseToken.png b/docs/zh/doc-images/getToken-parseToken.png similarity index 100% rename from docs/doc-images/getToken-parseToken.png rename to docs/zh/doc-images/getToken-parseToken.png diff --git a/docs/doc-images/index.png b/docs/zh/doc-images/index.png similarity index 100% rename from docs/doc-images/index.png rename to docs/zh/doc-images/index.png diff --git a/docs/doc-images/mj-id.png b/docs/zh/doc-images/mj-id.png similarity index 100% rename from docs/doc-images/mj-id.png rename to docs/zh/doc-images/mj-id.png diff --git a/docs/doc-images/my-template.png b/docs/zh/doc-images/my-template.png similarity index 100% rename from docs/doc-images/my-template.png rename to docs/zh/doc-images/my-template.png diff --git a/docs/doc-images/new-logs-1.jpg b/docs/zh/doc-images/new-logs-1.jpg similarity index 100% rename from docs/doc-images/new-logs-1.jpg rename to docs/zh/doc-images/new-logs-1.jpg diff --git a/docs/doc-images/old-logs.jpg b/docs/zh/doc-images/old-logs.jpg similarity index 100% rename from docs/doc-images/old-logs.jpg rename to docs/zh/doc-images/old-logs.jpg diff --git a/docs/doc-images/open-website.png b/docs/zh/doc-images/open-website.png similarity index 100% rename from docs/doc-images/open-website.png rename to docs/zh/doc-images/open-website.png diff --git a/docs/doc-images/oss-get-sts.png b/docs/zh/doc-images/oss-get-sts.png similarity index 100% rename from docs/doc-images/oss-get-sts.png rename to docs/zh/doc-images/oss-get-sts.png diff --git a/docs/doc-images/package-list.png b/docs/zh/doc-images/package-list.png similarity index 100% rename from docs/doc-images/package-list.png rename to docs/zh/doc-images/package-list.png diff --git a/docs/doc-images/pakcage-list.jpg b/docs/zh/doc-images/pakcage-list.jpg similarity index 100% rename from docs/doc-images/pakcage-list.jpg rename to docs/zh/doc-images/pakcage-list.jpg diff --git a/docs/doc-images/polocy-db-data.png b/docs/zh/doc-images/polocy-db-data.png similarity index 100% rename from docs/doc-images/polocy-db-data.png rename to docs/zh/doc-images/polocy-db-data.png diff --git a/docs/doc-images/publish-cloudfunction.png b/docs/zh/doc-images/publish-cloudfunction.png similarity index 100% rename from docs/doc-images/publish-cloudfunction.png rename to docs/zh/doc-images/publish-cloudfunction.png diff --git a/docs/doc-images/register.png b/docs/zh/doc-images/register.png similarity index 100% rename from docs/doc-images/register.png rename to docs/zh/doc-images/register.png diff --git a/docs/doc-images/run-cloudfunction.png b/docs/zh/doc-images/run-cloudfunction.png similarity index 100% rename from docs/doc-images/run-cloudfunction.png rename to docs/zh/doc-images/run-cloudfunction.png diff --git a/docs/doc-images/select-package-version.png b/docs/zh/doc-images/select-package-version.png similarity index 100% rename from docs/doc-images/select-package-version.png rename to docs/zh/doc-images/select-package-version.png diff --git a/docs/doc-images/set-wechat-pay.png b/docs/zh/doc-images/set-wechat-pay.png similarity index 100% rename from docs/doc-images/set-wechat-pay.png rename to docs/zh/doc-images/set-wechat-pay.png diff --git a/docs/doc-images/slack-connect-create-1.jpg b/docs/zh/doc-images/slack-connect-create-1.jpg similarity index 100% rename from docs/doc-images/slack-connect-create-1.jpg rename to docs/zh/doc-images/slack-connect-create-1.jpg diff --git a/docs/doc-images/slack-connect-create.jpg b/docs/zh/doc-images/slack-connect-create.jpg similarity index 100% rename from docs/doc-images/slack-connect-create.jpg rename to docs/zh/doc-images/slack-connect-create.jpg diff --git a/docs/doc-images/slack-connect.jpg b/docs/zh/doc-images/slack-connect.jpg similarity index 100% rename from docs/doc-images/slack-connect.jpg rename to docs/zh/doc-images/slack-connect.jpg diff --git a/docs/doc-images/slack-create-app-bot.jpg b/docs/zh/doc-images/slack-create-app-bot.jpg similarity index 100% rename from docs/doc-images/slack-create-app-bot.jpg rename to docs/zh/doc-images/slack-create-app-bot.jpg diff --git a/docs/doc-images/slack-create-app.jpg b/docs/zh/doc-images/slack-create-app.jpg similarity index 100% rename from docs/doc-images/slack-create-app.jpg rename to docs/zh/doc-images/slack-create-app.jpg diff --git a/docs/doc-images/slack-install-bot.jpg b/docs/zh/doc-images/slack-install-bot.jpg similarity index 100% rename from docs/doc-images/slack-install-bot.jpg rename to docs/zh/doc-images/slack-install-bot.jpg diff --git a/docs/doc-images/specification.jpg b/docs/zh/doc-images/specification.jpg similarity index 100% rename from docs/doc-images/specification.jpg rename to docs/zh/doc-images/specification.jpg diff --git a/docs/doc-images/todo-demo.png b/docs/zh/doc-images/todo-demo.png similarity index 100% rename from docs/doc-images/todo-demo.png rename to docs/zh/doc-images/todo-demo.png diff --git a/docs/doc-images/upload.png b/docs/zh/doc-images/upload.png similarity index 100% rename from docs/doc-images/upload.png rename to docs/zh/doc-images/upload.png diff --git a/docs/doc-images/use-injector.png b/docs/zh/doc-images/use-injector.png similarity index 100% rename from docs/doc-images/use-injector.png rename to docs/zh/doc-images/use-injector.png diff --git a/docs/doc-images/web-ide-index.png b/docs/zh/doc-images/web-ide-index.png similarity index 100% rename from docs/doc-images/web-ide-index.png rename to docs/zh/doc-images/web-ide-index.png diff --git a/docs/doc-images/website-hosting.png b/docs/zh/doc-images/website-hosting.png similarity index 100% rename from docs/doc-images/website-hosting.png rename to docs/zh/doc-images/website-hosting.png diff --git a/docs/zh/examples/index.md b/docs/zh/examples/index.md new file mode 100644 index 0000000000..88508014f4 --- /dev/null +++ b/docs/zh/examples/index.md @@ -0,0 +1,12 @@ + +# laf 使用实例 + + + + + + + +## 云存储 +- [微信小程序上传文件](/zh/examples/wxmp-upload.md) +- [用 GitHub Action 自动构建前端并发布到网站托管](/zh/examples/website-hosting-ci-cd.md) \ No newline at end of file diff --git a/docs/zh/examples/website-hosting-ci-cd.md b/docs/zh/examples/website-hosting-ci-cd.md new file mode 100644 index 0000000000..6f1b8a6a01 --- /dev/null +++ b/docs/zh/examples/website-hosting-ci-cd.md @@ -0,0 +1,68 @@ + +# 用 GitHub Action 自动构建前端并发布到网站托管 + +使用 `Github Actions` 即可实现自动化构建前端并推送到 laf 云存储中。 + + +## 实现 + +1、在自己的前端项目的主分支中,新建 Actions,下面是一个基础模板 + +本模板效果是,如果有新代码推送到主分支,会自动触发 Actions + +- `API_URL` 为你当前的 Laf 应用的 API 地址,如: `https://api.laf.run` + +- `WEB_PATH` 为你前端在当前项目的哪个路径,如果前端项目在根目录,则无需修改。如果在 web 目录下,则改成 `'web'` 即可。 + +- `DIST_PATH` 为编译后的目录名称,绝大部分项目编译后的目录名均为 dist + +```yaml +name: Build +on: + push: + branches: + - main + +env: + BUCKET_NAME: ${{ secrets.DOC_BUCKET_NAME }} + LAF_APPID: ${{ secrets.LAF_APPID }} + LAF_PAT: ${{ secrets.LAF_PAT }} + API_URL: 'https://api.laf.run' + WEB_PATH: . + DIST_PATH: 'dist' +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '16.x' + # 安装项目依赖 + - name: Install Dependencies + working-directory: ${{ env.WEB_PATH }} + run: npm install + # 编译项目 + - name: Build + working-directory: ${{ env.WEB_PATH }} + run: npm run build + # 安装 laf-cli + - name: Install Laf-CLI + run: npm i laf-cli -g + # 登录 laf api + - name: Login laf-cli + working-directory: ${{ env.WEB_PATH }} + run: | + laf user add ${{ env.LAF_APPID }} -r ${{ env.API_URL }} + laf user switch ${{ env.LAF_APPID }} + laf login $LAF_PAT + # 初始化 Laf 应用然后将编译好的代码推送到云存储 + - name: Init appid and push + working-directory: ${{ env.WEB_PATH }} + env: + LAF_APPID: ${{ env.LAF_APPID }} + run: | + laf app init ${{ env.LAF_APPID }} + laf storage push -f ${{ env.BUCKET_NAME }} ${{ env.DIST_PATH }}/ +``` diff --git a/docs/zh/examples/wxmp-upload.md b/docs/zh/examples/wxmp-upload.md new file mode 100644 index 0000000000..6d9e48878b --- /dev/null +++ b/docs/zh/examples/wxmp-upload.md @@ -0,0 +1,52 @@ + +# 微信小程序中上传文件 + + +::: tip +在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 +::: + +## 接受上传文件的云函数 + +```typescript +import cloud from "@lafjs/cloud" +import { readFile } from 'fs/promises' + +export default async function (ctx: FunctionContext) { + const file = ctx.files[0] + const data = await readFile(file.path) + + const bucket = cloud.storage.bucket('data') + await bucket.writeFile(file.filename, data, { + ContentType: file.mimetype + }) + + const url = bucket.externalUrl(file.filename) + return url +} +``` + + +## 小程序中上传文件到云函数 + +以微信小程序为例 + +```js +// 微信聊天回话选择文件 +wx.chooseMessageFile({ + count: 1, + type: 'all', + success(res) { + // 选择的文件临时路径 + const tempFilePaths = res.tempFiles[0].path + wx.uploadFile({ + url: '云函数地址', + filePath: tempFilePaths, + name: 'file', + success(res) { + console.log(res.data) + } + }) + } +}) +``` diff --git a/docs/zh/index.md b/docs/zh/index.md new file mode 100644 index 0000000000..57db8c1b4a --- /dev/null +++ b/docs/zh/index.md @@ -0,0 +1,74 @@ +# laf 概览 + +## 👀 `laf` 是什么 + +`laf` 是开源的云开发平台,提供云函数、云数据库、云存储等开箱即用的应用资源。 + +让开发者专注于业务开发,无需折腾服务器,快速释放创意。 + +![](./overview-ide.png) + +## 🖥 在线体验 + +🎉 [laf.run](https://laf.run) (国内版)
+🎉 [laf.dev](https://laf.dev) (海外版) + +## 🎉 `laf` 有什么 + +- 云函数 +- 云数据库 +- 云存储 +- 网站托管 +- WebSocket 支持 +- WebIDE,像写博客一样写代码 + + +## 👨‍💻 谁适合使用 `laf` ? + +1. 前端开发者 + `laf` = 全栈开发者,前端秒变全栈 + + - `laf` 云函数使用 js/ts 开发,前后端代码无隔裂,无门槛快速上手 + - `laf` 提供了静态网站托管,可将前端构建的网页直接同步部署上来,无需再配置服务器、nginx、域名等 + +2. 后端开发者,可以从琐事中解放出来,专注于业务本身,提升开发效率 + + - 节约服务器运维、多环境部署和多应用管理的成本 + - 告别域名、证书、调试 nginx 等配置 + - 不必手动部署数据库、安全防护等重复工作 + - 告别「修改一次、发布半天」的重复繁琐的迭代体验 + - 「像写博客一样写一个函数」,招之即来,挥之即去,随手发布! + +3. 不被云厂商锁定 + + - 可以为客户提供源码交付,为客户私有部署一套 `laf` ,而使用闭源的云开发服务,无法交付可独立运行的源码 + - 可以根据未来的需要,随时将迁移到自己的服务器上,`laf` 是开源免费的 + - 可以修改、订制自己的云开发平台,`laf` 是开源的、高度可扩展的 + +4. 独立开发者、创业团队,节约成本,快速开始,专注业务 + - 减少启动项目开发的流程,快速启动,缩短产品验证周期 + - 极大程度提高迭代速度,随时应对变化,随时发布 + - 专注于产品业务本身,快速推出最小可用产品 (MVP),快速进行产品、市场验证 + - 一个人 + `laf` = 团队 + +> life is short, you need laf:) + +## 🎉 私有化部署? + +> 快速部署:[Sealos](https://sealos.io) 提供开箱即用的域名、证书、网关、数据库、监控、备份等,无需配置,一键部署。 + +[![](https://cdn.jsdelivr.us/gh/labring-actions/templates@main/Deploy-on-Sealos.svg)](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dlaf) + + +## 🏘️ 社群 + +- [论坛](https://forum.laf.run/) +- [微信群](https://cdn.jsdelivr.net/gh/yangchuansheng/imghosting3@main/uPic/2022-04-22-14-21-MRJH9o.png) +- QQ 群:`603059673` +- 官方公众号:`laf-dev` + + +## 下一步 + +::: tip +- [快速开始](/zh/quick-start/login) +::: \ No newline at end of file diff --git a/docs/zh/overview-ide.png b/docs/zh/overview-ide.png new file mode 100644 index 0000000000..5fab76e84f Binary files /dev/null and b/docs/zh/overview-ide.png differ diff --git a/docs/zh/quick-start/Todo.md b/docs/zh/quick-start/Todo.md new file mode 100644 index 0000000000..fcd7c8c579 --- /dev/null +++ b/docs/zh/quick-start/Todo.md @@ -0,0 +1,168 @@ +--- +title: 快速开始 +--- + +# {{ $frontmatter.title }} + +我们将在 [laf.run](https://laf.run) 上,通过开发一个简单的「Todo」的功能,快速体验 `laf` 云开发。 + +![todo-demo](../doc-images/todo-demo.png) + +## 准备工作 + +1. 你需要在 [laf.run](https://laf.run) 上注册一个账户。 +2. 登录到 [laf.run](https://laf.run),点击 `新建` 按钮,创建一个空应用。 +3. 待应用成功启动后,点击右侧「开发」按钮,进入应用的「开发控制台」,接下来,我们将在「开发控制台」进行第一个 `laf` 应用的功能开发。 + +## 编写云函数 + +首先需要创建一个云函数。 + +![create-function](../doc-images/create-function.png) + +然后在`get-list`云函数中写上以下代码,写完以后记得在右上角找到`发布`两个字,点一下发布。 + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + // 从 list 集合中查询数据 + const res = await db.collection('list').get() + // 返回给前端 + return res +} +``` + +按照刚刚的方式我们再创建 `add-todo` `del-todo` `update-todo`,三个云函数,并分别写入代码。 + +`add-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + // ctx.body 是前端传入的参数 + const data = ctx.body + const res = await db.collection('list').add(data) + + return res +} +``` + +`del-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + + const { id } = ctx.body + // 根据 id 删除数据 + const res = db.collection("list").where({ _id: id }).remove() + + return res +} +``` + +`update-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + + const { id, data } = ctx.body + // _id 是唯一主键,不能修改,所以我们这里删掉 + delete data._id + // 根据 id 来修改数据 + const res = await db.collection('list').where({ _id: id }).update(data) + + return res +} + +``` + +:::tip +再次提醒,更改过的每一个云函数都需要`发布`才能生效哦! +::: + +## 创建集合 + +这里的集合,对应着传统数据库的表,用来存储数据。 + +![create-gather](../doc-images/create-gather.png) + +## 前端 + +前端这里我们用的是 Vue 项目来演示,React/Angular/小程序,操作都是相同的。 + +你也可以使用我们提供的[前端模板](https://github.com/labring/laf-examples/tree/main/laf-todo-demo)。 + +首先需要在前端项目中安装 `laf-client-sdk`。 + +```shell +npm install laf-client-sdk +``` + +这里我们需要用到``,可以在控制台找到。 + +![AppID](../doc-images/AppID.png) + +引入并创建 cloud 对象,这里需要注意的是``需要换成自己的。 + +```js +import { Cloud } from "laf-client-sdk"; // 引入 + +// 创建 cloud 对象 +const cloud = new Cloud({ + baseUrl: "https://.laf.run", // 这里的 需要换成自己的 AppID + getAccessToken: () => '', // 这里先为空 +}); +``` + +然后我们在前端需要的地方调用我们的云函数。 + +```js +async function getList() { + // 调用 get-list 云函数不传参 + const res = await cloud.invoke("get-list"); + list.value = res.data; +} + +async function submit() { + if (!newTodo.value) return; + + const obj = { + name: newTodo.value, + complete: false, + }; + // 调用 add-todo 传入参数 obj + await cloud.invoke("add-todo", obj); + newTodo.value = ""; + + getList(); +} + + +async function complete(index, id) { + list.value[index].complete = !list.value[index].complete; + // 调用 update-todo 传入参数 + await cloud.invoke("update-todo", { + id, + data: list.value[index], + }); +} + + +async function del(id) { + // 调用 del-todo 传入参数 + await cloud.invoke("del-todo", { id }); + getList(); +} +``` + +以上就是一个 Todo List 所需要的所有功能啦。 \ No newline at end of file diff --git a/docs/zh/quick-start/login.md b/docs/zh/quick-start/login.md new file mode 100644 index 0000000000..2dd6f8f5fc --- /dev/null +++ b/docs/zh/quick-start/login.md @@ -0,0 +1,164 @@ + +# 快速开始 + +本文将指引你开发一个简单的「用户登录/注册」的功能,快速体验 `laf` 云开发,预计完成时间 5 分钟。 + + +## 创建应用 + +1. 你需要在 [laf.run](https://laf.run) 上注册一个账户 +2. 在 [laf 控制台](https://laf.run),点击左上角的 `新建` 按钮,创建一个新应用 +3. 待应用成功启动后,点击右侧「开发」按钮,进入应用的「开发控制台」,接下来,我们将在「开发控制台」进行第一个 `laf` 应用的功能开发 + +## 编写云函数 + +本教程会编写两个云函数: + +- `register` 处理注册请求 +- `login` 处理登录请求。 + +### 用户注册云函数 + +在「云函数」管理页面,点击「新建函数」,创建注册云函数 `register`, + +点击 `register` 函数,进入 WebIDE,编写以下代码: + +```typescript +import cloud from "@lafjs/cloud"; +import { createHash } from "crypto"; + +export default async function (ctx: FunctionContext) { + const username = ctx.body?.username || ""; + const password = ctx.body?.password || ""; + + // check param + if (!/^[a-zA-Z0-9]{3,16}$/.test(username)) + return { error: "invalid username" }; + if (!/^[a-zA-Z0-9]{3,16}$/.test(password)) + return { error: "invalid password" }; + + // check username existed + const db = cloud.database(); + const exists = await db + .collection("users") + .where({ username: username }) + .count(); + + if (exists.total > 0) return { error: "username already existed" }; + + // add user + const { id } = await db.collection("users").add({ + username: username, + password: createHash("sha256").update(password).digest("hex"), + created_at: new Date(), + }); + + console.log("user registered: ", id); + return { data: id }; +}; +``` + +点击右上角的「发布」函数即发布上线! + +### 用户登录云函数 + +同上,创建 `login` 云函数,编写以下代码: + +```typescript +import cloud from "@lafjs/cloud"; +import { createHash } from "crypto"; + +export default async function (ctx: FunctionContext) { + const username = ctx.body?.username || ""; + const password = ctx.body?.password || ""; + + // check user login + const db = cloud.database(); + const res = await db + .collection("users") + .where({ + username: username, + password: createHash("sha256").update(password).digest("hex"), + }) + .getOne(); + + if (!res.data) return { error: "invalid username or password" }; + + // generate jwt token + const user_id = res.data._id; + const payload = { + uid: user_id, + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, + }; + + const access_token = cloud.getToken(payload); + + return { + uid: res.data._id, + access_token: access_token, + }; +}; +``` + +点击右上角的「发布」函数即发布上线! + +::: details 使用 curl 调用云函数 + +你可以在右上方复制云函数的调用地址, +或将以下 curl 命令中的 `APPID` 替换成你的 APPID 后执行: + +```bash +# 注册用户 +curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.laf.run/register + +# 用户登录 +curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.laf.run/login + +``` +::: + + +::: details 在前端项目中用 HTTP 请求调用云函数 + +```js +import axios from 'axios' + +const baseUrl = 'https://APPID.laf.run' + +// register +async function register(username, password) { + try { + const response = await axios.post(baseUrl + "/register", { + username: username, + password: password + }); + console.log(response); + } catch (error) { + console.error(error); + } +} + +// login +async function register(username, password) { + try { + const response = await axios.post(baseUrl + "/login", { + username: username, + password: password + }) + console.log(response) + } catch (error) { + console.error(error) + } +} +``` + +可以在你的 Vue/React/Angular/小程序 页面中调用这两个云函数完成具体的登录注册功能! +::: + +## 下一步 + +::: tip +- [云函数](/zh/cloud-function/) +- [云数据库](/zh/cloud-database/) +- [云存储](/zh/cloud-storage/) +::: \ No newline at end of file diff --git a/docs_deprecated/.eslintignore b/docs_deprecated/.eslintignore new file mode 100644 index 0000000000..d70ebaa1da --- /dev/null +++ b/docs_deprecated/.eslintignore @@ -0,0 +1 @@ +public \ No newline at end of file diff --git a/docs_deprecated/.eslintrc b/docs_deprecated/.eslintrc new file mode 100644 index 0000000000..d315baa3c5 --- /dev/null +++ b/docs_deprecated/.eslintrc @@ -0,0 +1,4 @@ +{ + "root": true, + "extends": "laf/docs" +} \ No newline at end of file diff --git a/docs_deprecated/.gitignore b/docs_deprecated/.gitignore new file mode 100644 index 0000000000..ff878b5dd9 --- /dev/null +++ b/docs_deprecated/.gitignore @@ -0,0 +1,15 @@ + +node_modules +dist + +upload +data/* +tmp + +.DS_Store +.idea + +coverage +.nyc_ + +.vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/config.js b/docs_deprecated/.vitepress/config.js similarity index 100% rename from docs/.vitepress/config.js rename to docs_deprecated/.vitepress/config.js diff --git a/docs/.vitepress/en.js b/docs_deprecated/.vitepress/en.js similarity index 100% rename from docs/.vitepress/en.js rename to docs_deprecated/.vitepress/en.js diff --git a/docs_deprecated/.vitepress/theme/custom.css b/docs_deprecated/.vitepress/theme/custom.css new file mode 100644 index 0000000000..8e037902a3 --- /dev/null +++ b/docs_deprecated/.vitepress/theme/custom.css @@ -0,0 +1,34 @@ +:root { + --vp-c-brand: #646cff; + --vp-c-brand-light: #747bff; + --vp-c-brand-dark: #323cf7; +} + +.inline img { + display: inline; +} + +.search { + flex-grow: 1; + padding-left: 24px; +} + +.search button { + justify-content: flex-start; + border: 1px solid transparent; + border-radius: 8px; + padding: 0 10px 0 12px; + width: 100%; + height: 40px; + margin-right: -20px; + background-color: #f6f6f7; +} + +.search button:hover { + border: 1px solid var(--vp-c-brand); + background-color: #f6f6f7; +} + +.dark .search button { + background-color: var(--vp-c-bg); +} diff --git a/docs/.vitepress/theme/index.js b/docs_deprecated/.vitepress/theme/index.js similarity index 100% rename from docs/.vitepress/theme/index.js rename to docs_deprecated/.vitepress/theme/index.js diff --git a/docs/3min/chatgpt/index.md b/docs_deprecated/3min/chatgpt/index.md similarity index 100% rename from docs/3min/chatgpt/index.md rename to docs_deprecated/3min/chatgpt/index.md diff --git a/docs/3min/claude/index.md b/docs_deprecated/3min/claude/index.md similarity index 100% rename from docs/3min/claude/index.md rename to docs_deprecated/3min/claude/index.md diff --git a/docs/3min/index.md b/docs_deprecated/3min/index.md similarity index 100% rename from docs/3min/index.md rename to docs_deprecated/3min/index.md diff --git a/docs/3min/midjourney/index.md b/docs_deprecated/3min/midjourney/index.md similarity index 100% rename from docs/3min/midjourney/index.md rename to docs_deprecated/3min/midjourney/index.md diff --git a/docs/3min/wechat/CorporateWeChat/index.md b/docs_deprecated/3min/wechat/CorporateWeChat/index.md similarity index 100% rename from docs/3min/wechat/CorporateWeChat/index.md rename to docs_deprecated/3min/wechat/CorporateWeChat/index.md diff --git a/docs/3min/wechat/MediaPlatform/H5.md b/docs_deprecated/3min/wechat/MediaPlatform/H5.md similarity index 100% rename from docs/3min/wechat/MediaPlatform/H5.md rename to docs_deprecated/3min/wechat/MediaPlatform/H5.md diff --git a/docs/3min/wechat/MediaPlatform/Menu.md b/docs_deprecated/3min/wechat/MediaPlatform/Menu.md similarity index 100% rename from docs/3min/wechat/MediaPlatform/Menu.md rename to docs_deprecated/3min/wechat/MediaPlatform/Menu.md diff --git a/docs/3min/wechat/MediaPlatform/ServerDocking.md b/docs_deprecated/3min/wechat/MediaPlatform/ServerDocking.md similarity index 100% rename from docs/3min/wechat/MediaPlatform/ServerDocking.md rename to docs_deprecated/3min/wechat/MediaPlatform/ServerDocking.md diff --git a/docs/3min/wechat/MediaPlatform/index.md b/docs_deprecated/3min/wechat/MediaPlatform/index.md similarity index 100% rename from docs/3min/wechat/MediaPlatform/index.md rename to docs_deprecated/3min/wechat/MediaPlatform/index.md diff --git a/docs/3min/wechat/MiniProgram/index.md b/docs_deprecated/3min/wechat/MiniProgram/index.md similarity index 100% rename from docs/3min/wechat/MiniProgram/index.md rename to docs_deprecated/3min/wechat/MiniProgram/index.md diff --git a/docs/3min/wechat/index.md b/docs_deprecated/3min/wechat/index.md similarity index 100% rename from docs/3min/wechat/index.md rename to docs_deprecated/3min/wechat/index.md diff --git a/docs_deprecated/Dockerfile b/docs_deprecated/Dockerfile new file mode 100644 index 0000000000..a7475bd490 --- /dev/null +++ b/docs_deprecated/Dockerfile @@ -0,0 +1,6 @@ +FROM bitnami/openresty:latest + +WORKDIR /app +EXPOSE 8080 + +ADD ./.vitepress/dist /app/ diff --git a/docs/LICENSE b/docs_deprecated/LICENSE similarity index 100% rename from docs/LICENSE rename to docs_deprecated/LICENSE diff --git a/docs/README.md b/docs_deprecated/README.md similarity index 100% rename from docs/README.md rename to docs_deprecated/README.md diff --git a/docs/deploy.sh b/docs_deprecated/deploy.sh similarity index 100% rename from docs/deploy.sh rename to docs_deprecated/deploy.sh diff --git a/docs/diagrams/laf-arch-full.excalidraw b/docs_deprecated/diagrams/laf-arch-full.excalidraw similarity index 100% rename from docs/diagrams/laf-arch-full.excalidraw rename to docs_deprecated/diagrams/laf-arch-full.excalidraw diff --git a/docs/diagrams/laf-arch-simple.excalidraw b/docs_deprecated/diagrams/laf-arch-simple.excalidraw similarity index 100% rename from docs/diagrams/laf-arch-simple.excalidraw rename to docs_deprecated/diagrams/laf-arch-simple.excalidraw diff --git a/docs/en/doc-images/AppID.png b/docs_deprecated/doc-images/AppID.png similarity index 100% rename from docs/en/doc-images/AppID.png rename to docs_deprecated/doc-images/AppID.png diff --git a/docs_deprecated/doc-images/Laf-Pilot.png b/docs_deprecated/doc-images/Laf-Pilot.png new file mode 100644 index 0000000000..51780e5af4 Binary files /dev/null and b/docs_deprecated/doc-images/Laf-Pilot.png differ diff --git a/docs_deprecated/doc-images/Laf-Pilot2.png b/docs_deprecated/doc-images/Laf-Pilot2.png new file mode 100644 index 0000000000..c24fcf55c5 Binary files /dev/null and b/docs_deprecated/doc-images/Laf-Pilot2.png differ diff --git a/docs/en/doc-images/MediaPlatformBaseSetting.png b/docs_deprecated/doc-images/MediaPlatformBaseSetting.png similarity index 100% rename from docs/en/doc-images/MediaPlatformBaseSetting.png rename to docs_deprecated/doc-images/MediaPlatformBaseSetting.png diff --git a/docs/en/doc-images/MediaPlatformBaseSetting2.png b/docs_deprecated/doc-images/MediaPlatformBaseSetting2.png similarity index 100% rename from docs/en/doc-images/MediaPlatformBaseSetting2.png rename to docs_deprecated/doc-images/MediaPlatformBaseSetting2.png diff --git a/docs/en/doc-images/SALAI_TOKEN.jpg b/docs_deprecated/doc-images/SALAI_TOKEN.jpg similarity index 100% rename from docs/en/doc-images/SALAI_TOKEN.jpg rename to docs_deprecated/doc-images/SALAI_TOKEN.jpg diff --git a/docs/en/doc-images/add-env-step1.png b/docs_deprecated/doc-images/add-env-step1.png similarity index 100% rename from docs/en/doc-images/add-env-step1.png rename to docs_deprecated/doc-images/add-env-step1.png diff --git a/docs/en/doc-images/add-env-step2.png b/docs_deprecated/doc-images/add-env-step2.png similarity index 100% rename from docs/en/doc-images/add-env-step2.png rename to docs_deprecated/doc-images/add-env-step2.png diff --git a/docs/en/doc-images/add-env-step3.png b/docs_deprecated/doc-images/add-env-step3.png similarity index 100% rename from docs/en/doc-images/add-env-step3.png rename to docs_deprecated/doc-images/add-env-step3.png diff --git a/docs/en/doc-images/add-env.png b/docs_deprecated/doc-images/add-env.png similarity index 100% rename from docs/en/doc-images/add-env.png rename to docs_deprecated/doc-images/add-env.png diff --git a/docs/en/doc-images/add-packages.png b/docs_deprecated/doc-images/add-packages.png similarity index 100% rename from docs/en/doc-images/add-packages.png rename to docs_deprecated/doc-images/add-packages.png diff --git a/docs/en/doc-images/add-polocy.png b/docs_deprecated/doc-images/add-polocy.png similarity index 100% rename from docs/en/doc-images/add-polocy.png rename to docs_deprecated/doc-images/add-polocy.png diff --git a/docs/en/doc-images/app-list.png b/docs_deprecated/doc-images/app-list.png similarity index 100% rename from docs/en/doc-images/app-list.png rename to docs_deprecated/doc-images/app-list.png diff --git a/docs/en/doc-images/appList.png b/docs_deprecated/doc-images/appList.png similarity index 100% rename from docs/en/doc-images/appList.png rename to docs_deprecated/doc-images/appList.png diff --git a/docs/en/doc-images/application-list.png b/docs_deprecated/doc-images/application-list.png similarity index 100% rename from docs/en/doc-images/application-list.png rename to docs_deprecated/doc-images/application-list.png diff --git a/docs/en/doc-images/auto-build1.png b/docs_deprecated/doc-images/auto-build1.png similarity index 100% rename from docs/en/doc-images/auto-build1.png rename to docs_deprecated/doc-images/auto-build1.png diff --git a/docs/en/doc-images/auto-build2.png b/docs_deprecated/doc-images/auto-build2.png similarity index 100% rename from docs/en/doc-images/auto-build2.png rename to docs_deprecated/doc-images/auto-build2.png diff --git a/docs/en/doc-images/bind-pay.png b/docs_deprecated/doc-images/bind-pay.png similarity index 100% rename from docs/en/doc-images/bind-pay.png rename to docs_deprecated/doc-images/bind-pay.png diff --git a/docs/en/doc-images/bind-pay2.png b/docs_deprecated/doc-images/bind-pay2.png similarity index 100% rename from docs/en/doc-images/bind-pay2.png rename to docs_deprecated/doc-images/bind-pay2.png diff --git a/docs/en/doc-images/change-package-version.png b/docs_deprecated/doc-images/change-package-version.png similarity index 100% rename from docs/en/doc-images/change-package-version.png rename to docs_deprecated/doc-images/change-package-version.png diff --git a/docs/en/doc-images/cli-mind.png b/docs_deprecated/doc-images/cli-mind.png similarity index 100% rename from docs/en/doc-images/cli-mind.png rename to docs_deprecated/doc-images/cli-mind.png diff --git a/docs/en/doc-images/creat-polocy.png b/docs_deprecated/doc-images/creat-polocy.png similarity index 100% rename from docs/en/doc-images/creat-polocy.png rename to docs_deprecated/doc-images/creat-polocy.png diff --git a/docs/en/doc-images/creat-token.png b/docs_deprecated/doc-images/creat-token.png similarity index 100% rename from docs/en/doc-images/creat-token.png rename to docs_deprecated/doc-images/creat-token.png diff --git a/docs/en/doc-images/create-application.png b/docs_deprecated/doc-images/create-application.png similarity index 100% rename from docs/en/doc-images/create-application.png rename to docs_deprecated/doc-images/create-application.png diff --git a/docs/en/doc-images/create-bucket-1.png b/docs_deprecated/doc-images/create-bucket-1.png similarity index 100% rename from docs/en/doc-images/create-bucket-1.png rename to docs_deprecated/doc-images/create-bucket-1.png diff --git a/docs/en/doc-images/create-bucket.png b/docs_deprecated/doc-images/create-bucket.png similarity index 100% rename from docs/en/doc-images/create-bucket.png rename to docs_deprecated/doc-images/create-bucket.png diff --git a/docs/en/doc-images/create-cloudfunction.png b/docs_deprecated/doc-images/create-cloudfunction.png similarity index 100% rename from docs/en/doc-images/create-cloudfunction.png rename to docs_deprecated/doc-images/create-cloudfunction.png diff --git a/docs/en/doc-images/create-function.jpg b/docs_deprecated/doc-images/create-function.jpg similarity index 100% rename from docs/en/doc-images/create-function.jpg rename to docs_deprecated/doc-images/create-function.jpg diff --git a/docs/en/doc-images/create-function.png b/docs_deprecated/doc-images/create-function.png similarity index 100% rename from docs/en/doc-images/create-function.png rename to docs_deprecated/doc-images/create-function.png diff --git a/docs/en/doc-images/create-gather.png b/docs_deprecated/doc-images/create-gather.png similarity index 100% rename from docs/en/doc-images/create-gather.png rename to docs_deprecated/doc-images/create-gather.png diff --git a/docs/en/doc-images/create-injector.png b/docs_deprecated/doc-images/create-injector.png similarity index 100% rename from docs/en/doc-images/create-injector.png rename to docs_deprecated/doc-images/create-injector.png diff --git a/docs/en/doc-images/create-laf-app.jpg b/docs_deprecated/doc-images/create-laf-app.jpg similarity index 100% rename from docs/en/doc-images/create-laf-app.jpg rename to docs_deprecated/doc-images/create-laf-app.jpg diff --git a/docs/en/doc-images/db.png b/docs_deprecated/doc-images/db.png similarity index 100% rename from docs/en/doc-images/db.png rename to docs_deprecated/doc-images/db.png diff --git a/docs_deprecated/doc-images/dblist.jpg b/docs_deprecated/doc-images/dblist.jpg new file mode 100644 index 0000000000..845cebe2db Binary files /dev/null and b/docs_deprecated/doc-images/dblist.jpg differ diff --git a/docs/en/doc-images/delete-package.png b/docs_deprecated/doc-images/delete-package.png similarity index 100% rename from docs/en/doc-images/delete-package.png rename to docs_deprecated/doc-images/delete-package.png diff --git a/docs/en/doc-images/doc-app-list.png b/docs_deprecated/doc-images/doc-app-list.png similarity index 100% rename from docs/en/doc-images/doc-app-list.png rename to docs_deprecated/doc-images/doc-app-list.png diff --git a/docs/en/doc-images/doc-db.png b/docs_deprecated/doc-images/doc-db.png similarity index 100% rename from docs/en/doc-images/doc-db.png rename to docs_deprecated/doc-images/doc-db.png diff --git a/docs/en/doc-images/doc-function-list.png b/docs_deprecated/doc-images/doc-function-list.png similarity index 100% rename from docs/en/doc-images/doc-function-list.png rename to docs_deprecated/doc-images/doc-function-list.png diff --git a/docs/en/doc-images/doc-policy.png b/docs_deprecated/doc-images/doc-policy.png similarity index 100% rename from docs/en/doc-images/doc-policy.png rename to docs_deprecated/doc-images/doc-policy.png diff --git a/docs/en/doc-images/doc-storage.png b/docs_deprecated/doc-images/doc-storage.png similarity index 100% rename from docs/en/doc-images/doc-storage.png rename to docs_deprecated/doc-images/doc-storage.png diff --git a/docs/en/doc-images/edit-cloudfunction.png b/docs_deprecated/doc-images/edit-cloudfunction.png similarity index 100% rename from docs/en/doc-images/edit-cloudfunction.png rename to docs_deprecated/doc-images/edit-cloudfunction.png diff --git a/docs/en/doc-images/file.png b/docs_deprecated/doc-images/file.png similarity index 100% rename from docs/en/doc-images/file.png rename to docs_deprecated/doc-images/file.png diff --git a/docs/en/doc-images/function-body.png b/docs_deprecated/doc-images/function-body.png similarity index 100% rename from docs/en/doc-images/function-body.png rename to docs_deprecated/doc-images/function-body.png diff --git a/docs/en/doc-images/function-log.png b/docs_deprecated/doc-images/function-log.png similarity index 100% rename from docs/en/doc-images/function-log.png rename to docs_deprecated/doc-images/function-log.png diff --git a/docs_deprecated/doc-images/function-market.png b/docs_deprecated/doc-images/function-market.png new file mode 100644 index 0000000000..eaebef9491 Binary files /dev/null and b/docs_deprecated/doc-images/function-market.png differ diff --git a/docs/en/doc-images/function-query.png b/docs_deprecated/doc-images/function-query.png similarity index 100% rename from docs/en/doc-images/function-query.png rename to docs_deprecated/doc-images/function-query.png diff --git a/docs_deprecated/doc-images/function-template.png b/docs_deprecated/doc-images/function-template.png new file mode 100644 index 0000000000..99bc819934 Binary files /dev/null and b/docs_deprecated/doc-images/function-template.png differ diff --git a/docs/en/doc-images/function-url.png b/docs_deprecated/doc-images/function-url.png similarity index 100% rename from docs/en/doc-images/function-url.png rename to docs_deprecated/doc-images/function-url.png diff --git a/docs/en/doc-images/function.png b/docs_deprecated/doc-images/function.png similarity index 100% rename from docs/en/doc-images/function.png rename to docs_deprecated/doc-images/function.png diff --git a/docs/en/doc-images/getToken-parseToken.png b/docs_deprecated/doc-images/getToken-parseToken.png similarity index 100% rename from docs/en/doc-images/getToken-parseToken.png rename to docs_deprecated/doc-images/getToken-parseToken.png diff --git a/docs/en/doc-images/index.png b/docs_deprecated/doc-images/index.png similarity index 100% rename from docs/en/doc-images/index.png rename to docs_deprecated/doc-images/index.png diff --git a/docs/en/doc-images/mj-id.png b/docs_deprecated/doc-images/mj-id.png similarity index 100% rename from docs/en/doc-images/mj-id.png rename to docs_deprecated/doc-images/mj-id.png diff --git a/docs_deprecated/doc-images/my-template.png b/docs_deprecated/doc-images/my-template.png new file mode 100644 index 0000000000..a92c59a5ee Binary files /dev/null and b/docs_deprecated/doc-images/my-template.png differ diff --git a/docs_deprecated/doc-images/new-logs-1.jpg b/docs_deprecated/doc-images/new-logs-1.jpg new file mode 100644 index 0000000000..5ff910ae9e Binary files /dev/null and b/docs_deprecated/doc-images/new-logs-1.jpg differ diff --git a/docs_deprecated/doc-images/old-logs.jpg b/docs_deprecated/doc-images/old-logs.jpg new file mode 100644 index 0000000000..15d4ff2e1e Binary files /dev/null and b/docs_deprecated/doc-images/old-logs.jpg differ diff --git a/docs/en/doc-images/open-website.png b/docs_deprecated/doc-images/open-website.png similarity index 100% rename from docs/en/doc-images/open-website.png rename to docs_deprecated/doc-images/open-website.png diff --git a/docs_deprecated/doc-images/oss-get-sts.png b/docs_deprecated/doc-images/oss-get-sts.png new file mode 100644 index 0000000000..26433d3797 Binary files /dev/null and b/docs_deprecated/doc-images/oss-get-sts.png differ diff --git a/docs/en/doc-images/package-list.png b/docs_deprecated/doc-images/package-list.png similarity index 100% rename from docs/en/doc-images/package-list.png rename to docs_deprecated/doc-images/package-list.png diff --git a/docs/en/doc-images/pakcage-list.jpg b/docs_deprecated/doc-images/pakcage-list.jpg similarity index 100% rename from docs/en/doc-images/pakcage-list.jpg rename to docs_deprecated/doc-images/pakcage-list.jpg diff --git a/docs/en/doc-images/polocy-db-data.png b/docs_deprecated/doc-images/polocy-db-data.png similarity index 100% rename from docs/en/doc-images/polocy-db-data.png rename to docs_deprecated/doc-images/polocy-db-data.png diff --git a/docs/en/doc-images/publish-cloudfunction.png b/docs_deprecated/doc-images/publish-cloudfunction.png similarity index 100% rename from docs/en/doc-images/publish-cloudfunction.png rename to docs_deprecated/doc-images/publish-cloudfunction.png diff --git a/docs/en/doc-images/register.png b/docs_deprecated/doc-images/register.png similarity index 100% rename from docs/en/doc-images/register.png rename to docs_deprecated/doc-images/register.png diff --git a/docs/en/doc-images/run-cloudfunction.png b/docs_deprecated/doc-images/run-cloudfunction.png similarity index 100% rename from docs/en/doc-images/run-cloudfunction.png rename to docs_deprecated/doc-images/run-cloudfunction.png diff --git a/docs/en/doc-images/select-package-version.png b/docs_deprecated/doc-images/select-package-version.png similarity index 100% rename from docs/en/doc-images/select-package-version.png rename to docs_deprecated/doc-images/select-package-version.png diff --git a/docs/en/doc-images/set-wechat-pay.png b/docs_deprecated/doc-images/set-wechat-pay.png similarity index 100% rename from docs/en/doc-images/set-wechat-pay.png rename to docs_deprecated/doc-images/set-wechat-pay.png diff --git a/docs/en/doc-images/slack-connect-create-1.jpg b/docs_deprecated/doc-images/slack-connect-create-1.jpg similarity index 100% rename from docs/en/doc-images/slack-connect-create-1.jpg rename to docs_deprecated/doc-images/slack-connect-create-1.jpg diff --git a/docs/en/doc-images/slack-connect-create.jpg b/docs_deprecated/doc-images/slack-connect-create.jpg similarity index 100% rename from docs/en/doc-images/slack-connect-create.jpg rename to docs_deprecated/doc-images/slack-connect-create.jpg diff --git a/docs/en/doc-images/slack-connect.jpg b/docs_deprecated/doc-images/slack-connect.jpg similarity index 100% rename from docs/en/doc-images/slack-connect.jpg rename to docs_deprecated/doc-images/slack-connect.jpg diff --git a/docs/en/doc-images/slack-create-app-bot.jpg b/docs_deprecated/doc-images/slack-create-app-bot.jpg similarity index 100% rename from docs/en/doc-images/slack-create-app-bot.jpg rename to docs_deprecated/doc-images/slack-create-app-bot.jpg diff --git a/docs/en/doc-images/slack-create-app.jpg b/docs_deprecated/doc-images/slack-create-app.jpg similarity index 100% rename from docs/en/doc-images/slack-create-app.jpg rename to docs_deprecated/doc-images/slack-create-app.jpg diff --git a/docs/en/doc-images/slack-install-bot.jpg b/docs_deprecated/doc-images/slack-install-bot.jpg similarity index 100% rename from docs/en/doc-images/slack-install-bot.jpg rename to docs_deprecated/doc-images/slack-install-bot.jpg diff --git a/docs/en/doc-images/specification.jpg b/docs_deprecated/doc-images/specification.jpg similarity index 100% rename from docs/en/doc-images/specification.jpg rename to docs_deprecated/doc-images/specification.jpg diff --git a/docs/en/doc-images/todo-demo.png b/docs_deprecated/doc-images/todo-demo.png similarity index 100% rename from docs/en/doc-images/todo-demo.png rename to docs_deprecated/doc-images/todo-demo.png diff --git a/docs/en/doc-images/upload.png b/docs_deprecated/doc-images/upload.png similarity index 100% rename from docs/en/doc-images/upload.png rename to docs_deprecated/doc-images/upload.png diff --git a/docs/en/doc-images/use-injector.png b/docs_deprecated/doc-images/use-injector.png similarity index 100% rename from docs/en/doc-images/use-injector.png rename to docs_deprecated/doc-images/use-injector.png diff --git a/docs/en/doc-images/web-ide-index.png b/docs_deprecated/doc-images/web-ide-index.png similarity index 100% rename from docs/en/doc-images/web-ide-index.png rename to docs_deprecated/doc-images/web-ide-index.png diff --git a/docs/en/doc-images/website-hosting.png b/docs_deprecated/doc-images/website-hosting.png similarity index 100% rename from docs/en/doc-images/website-hosting.png rename to docs_deprecated/doc-images/website-hosting.png diff --git a/docs/en/3min/chatgpt/index.md b/docs_deprecated/en/3min/chatgpt/index.md similarity index 100% rename from docs/en/3min/chatgpt/index.md rename to docs_deprecated/en/3min/chatgpt/index.md diff --git a/docs/en/3min/claude/index.md b/docs_deprecated/en/3min/claude/index.md similarity index 100% rename from docs/en/3min/claude/index.md rename to docs_deprecated/en/3min/claude/index.md diff --git a/docs/en/3min/index.md b/docs_deprecated/en/3min/index.md similarity index 100% rename from docs/en/3min/index.md rename to docs_deprecated/en/3min/index.md diff --git a/docs/en/3min/midjourney/index.md b/docs_deprecated/en/3min/midjourney/index.md similarity index 100% rename from docs/en/3min/midjourney/index.md rename to docs_deprecated/en/3min/midjourney/index.md diff --git a/docs/en/3min/wechat/CorporateWeChat/index.md b/docs_deprecated/en/3min/wechat/CorporateWeChat/index.md similarity index 100% rename from docs/en/3min/wechat/CorporateWeChat/index.md rename to docs_deprecated/en/3min/wechat/CorporateWeChat/index.md diff --git a/docs/en/3min/wechat/MediaPlatform/H5.md b/docs_deprecated/en/3min/wechat/MediaPlatform/H5.md similarity index 100% rename from docs/en/3min/wechat/MediaPlatform/H5.md rename to docs_deprecated/en/3min/wechat/MediaPlatform/H5.md diff --git a/docs/en/3min/wechat/MediaPlatform/Menu.md b/docs_deprecated/en/3min/wechat/MediaPlatform/Menu.md similarity index 100% rename from docs/en/3min/wechat/MediaPlatform/Menu.md rename to docs_deprecated/en/3min/wechat/MediaPlatform/Menu.md diff --git a/docs/en/3min/wechat/MediaPlatform/ServerDocking.md b/docs_deprecated/en/3min/wechat/MediaPlatform/ServerDocking.md similarity index 100% rename from docs/en/3min/wechat/MediaPlatform/ServerDocking.md rename to docs_deprecated/en/3min/wechat/MediaPlatform/ServerDocking.md diff --git a/docs/en/3min/wechat/MediaPlatform/index.md b/docs_deprecated/en/3min/wechat/MediaPlatform/index.md similarity index 100% rename from docs/en/3min/wechat/MediaPlatform/index.md rename to docs_deprecated/en/3min/wechat/MediaPlatform/index.md diff --git a/docs/en/3min/wechat/MiniProgram/index.md b/docs_deprecated/en/3min/wechat/MiniProgram/index.md similarity index 100% rename from docs/en/3min/wechat/MiniProgram/index.md rename to docs_deprecated/en/3min/wechat/MiniProgram/index.md diff --git a/docs/en/3min/wechat/index.md b/docs_deprecated/en/3min/wechat/index.md similarity index 100% rename from docs/en/3min/wechat/index.md rename to docs_deprecated/en/3min/wechat/index.md diff --git a/docs/en/README.md b/docs_deprecated/en/README.md similarity index 100% rename from docs/en/README.md rename to docs_deprecated/en/README.md diff --git a/docs_deprecated/en/doc-images/AppID.png b/docs_deprecated/en/doc-images/AppID.png new file mode 100644 index 0000000000..6b4cd6af08 Binary files /dev/null and b/docs_deprecated/en/doc-images/AppID.png differ diff --git a/docs_deprecated/en/doc-images/MediaPlatformBaseSetting.png b/docs_deprecated/en/doc-images/MediaPlatformBaseSetting.png new file mode 100644 index 0000000000..5ffb08c11a Binary files /dev/null and b/docs_deprecated/en/doc-images/MediaPlatformBaseSetting.png differ diff --git a/docs_deprecated/en/doc-images/MediaPlatformBaseSetting2.png b/docs_deprecated/en/doc-images/MediaPlatformBaseSetting2.png new file mode 100644 index 0000000000..b58a559817 Binary files /dev/null and b/docs_deprecated/en/doc-images/MediaPlatformBaseSetting2.png differ diff --git a/docs_deprecated/en/doc-images/SALAI_TOKEN.jpg b/docs_deprecated/en/doc-images/SALAI_TOKEN.jpg new file mode 100644 index 0000000000..518b6a6c0d Binary files /dev/null and b/docs_deprecated/en/doc-images/SALAI_TOKEN.jpg differ diff --git a/docs_deprecated/en/doc-images/add-env-step1.png b/docs_deprecated/en/doc-images/add-env-step1.png new file mode 100644 index 0000000000..e59bcbf11d Binary files /dev/null and b/docs_deprecated/en/doc-images/add-env-step1.png differ diff --git a/docs_deprecated/en/doc-images/add-env-step2.png b/docs_deprecated/en/doc-images/add-env-step2.png new file mode 100644 index 0000000000..415f061139 Binary files /dev/null and b/docs_deprecated/en/doc-images/add-env-step2.png differ diff --git a/docs_deprecated/en/doc-images/add-env-step3.png b/docs_deprecated/en/doc-images/add-env-step3.png new file mode 100644 index 0000000000..daf0c3691e Binary files /dev/null and b/docs_deprecated/en/doc-images/add-env-step3.png differ diff --git a/docs_deprecated/en/doc-images/add-env.png b/docs_deprecated/en/doc-images/add-env.png new file mode 100644 index 0000000000..9af5525e5d Binary files /dev/null and b/docs_deprecated/en/doc-images/add-env.png differ diff --git a/docs_deprecated/en/doc-images/add-packages.png b/docs_deprecated/en/doc-images/add-packages.png new file mode 100644 index 0000000000..2247b12cb3 Binary files /dev/null and b/docs_deprecated/en/doc-images/add-packages.png differ diff --git a/docs_deprecated/en/doc-images/add-polocy.png b/docs_deprecated/en/doc-images/add-polocy.png new file mode 100644 index 0000000000..6bde41e193 Binary files /dev/null and b/docs_deprecated/en/doc-images/add-polocy.png differ diff --git a/docs_deprecated/en/doc-images/app-list.png b/docs_deprecated/en/doc-images/app-list.png new file mode 100644 index 0000000000..c66eb249d9 Binary files /dev/null and b/docs_deprecated/en/doc-images/app-list.png differ diff --git a/docs_deprecated/en/doc-images/appList.png b/docs_deprecated/en/doc-images/appList.png new file mode 100644 index 0000000000..489052d5ba Binary files /dev/null and b/docs_deprecated/en/doc-images/appList.png differ diff --git a/docs_deprecated/en/doc-images/application-list.png b/docs_deprecated/en/doc-images/application-list.png new file mode 100644 index 0000000000..d0545ce98e Binary files /dev/null and b/docs_deprecated/en/doc-images/application-list.png differ diff --git a/docs_deprecated/en/doc-images/auto-build1.png b/docs_deprecated/en/doc-images/auto-build1.png new file mode 100644 index 0000000000..314aeb2b42 Binary files /dev/null and b/docs_deprecated/en/doc-images/auto-build1.png differ diff --git a/docs_deprecated/en/doc-images/auto-build2.png b/docs_deprecated/en/doc-images/auto-build2.png new file mode 100644 index 0000000000..39cd3a9f92 Binary files /dev/null and b/docs_deprecated/en/doc-images/auto-build2.png differ diff --git a/docs_deprecated/en/doc-images/bind-pay.png b/docs_deprecated/en/doc-images/bind-pay.png new file mode 100644 index 0000000000..194ed24530 Binary files /dev/null and b/docs_deprecated/en/doc-images/bind-pay.png differ diff --git a/docs_deprecated/en/doc-images/bind-pay2.png b/docs_deprecated/en/doc-images/bind-pay2.png new file mode 100644 index 0000000000..629b6bbd03 Binary files /dev/null and b/docs_deprecated/en/doc-images/bind-pay2.png differ diff --git a/docs_deprecated/en/doc-images/change-package-version.png b/docs_deprecated/en/doc-images/change-package-version.png new file mode 100644 index 0000000000..c6537d2ff0 Binary files /dev/null and b/docs_deprecated/en/doc-images/change-package-version.png differ diff --git a/docs_deprecated/en/doc-images/cli-mind.png b/docs_deprecated/en/doc-images/cli-mind.png new file mode 100644 index 0000000000..8ea6005479 Binary files /dev/null and b/docs_deprecated/en/doc-images/cli-mind.png differ diff --git a/docs_deprecated/en/doc-images/creat-polocy.png b/docs_deprecated/en/doc-images/creat-polocy.png new file mode 100644 index 0000000000..3094797579 Binary files /dev/null and b/docs_deprecated/en/doc-images/creat-polocy.png differ diff --git a/docs_deprecated/en/doc-images/creat-token.png b/docs_deprecated/en/doc-images/creat-token.png new file mode 100644 index 0000000000..f0b14fe98f Binary files /dev/null and b/docs_deprecated/en/doc-images/creat-token.png differ diff --git a/docs_deprecated/en/doc-images/create-application.png b/docs_deprecated/en/doc-images/create-application.png new file mode 100644 index 0000000000..33637995fb Binary files /dev/null and b/docs_deprecated/en/doc-images/create-application.png differ diff --git a/docs_deprecated/en/doc-images/create-bucket-1.png b/docs_deprecated/en/doc-images/create-bucket-1.png new file mode 100644 index 0000000000..dad0aa04c3 Binary files /dev/null and b/docs_deprecated/en/doc-images/create-bucket-1.png differ diff --git a/docs_deprecated/en/doc-images/create-bucket.png b/docs_deprecated/en/doc-images/create-bucket.png new file mode 100644 index 0000000000..f7eb407840 Binary files /dev/null and b/docs_deprecated/en/doc-images/create-bucket.png differ diff --git a/docs_deprecated/en/doc-images/create-cloudfunction.png b/docs_deprecated/en/doc-images/create-cloudfunction.png new file mode 100644 index 0000000000..096a68d8d0 Binary files /dev/null and b/docs_deprecated/en/doc-images/create-cloudfunction.png differ diff --git a/docs_deprecated/en/doc-images/create-function.jpg b/docs_deprecated/en/doc-images/create-function.jpg new file mode 100644 index 0000000000..43e487b9bf Binary files /dev/null and b/docs_deprecated/en/doc-images/create-function.jpg differ diff --git a/docs_deprecated/en/doc-images/create-function.png b/docs_deprecated/en/doc-images/create-function.png new file mode 100644 index 0000000000..ed777e388e Binary files /dev/null and b/docs_deprecated/en/doc-images/create-function.png differ diff --git a/docs_deprecated/en/doc-images/create-gather.png b/docs_deprecated/en/doc-images/create-gather.png new file mode 100644 index 0000000000..e6b7e0666b Binary files /dev/null and b/docs_deprecated/en/doc-images/create-gather.png differ diff --git a/docs_deprecated/en/doc-images/create-injector.png b/docs_deprecated/en/doc-images/create-injector.png new file mode 100644 index 0000000000..43b42d2226 Binary files /dev/null and b/docs_deprecated/en/doc-images/create-injector.png differ diff --git a/docs_deprecated/en/doc-images/create-laf-app.jpg b/docs_deprecated/en/doc-images/create-laf-app.jpg new file mode 100644 index 0000000000..a4a547070f Binary files /dev/null and b/docs_deprecated/en/doc-images/create-laf-app.jpg differ diff --git a/docs_deprecated/en/doc-images/db.png b/docs_deprecated/en/doc-images/db.png new file mode 100644 index 0000000000..1c2c3580bd Binary files /dev/null and b/docs_deprecated/en/doc-images/db.png differ diff --git a/docs_deprecated/en/doc-images/dblist.jpg b/docs_deprecated/en/doc-images/dblist.jpg new file mode 100644 index 0000000000..845cebe2db Binary files /dev/null and b/docs_deprecated/en/doc-images/dblist.jpg differ diff --git a/docs_deprecated/en/doc-images/delete-package.png b/docs_deprecated/en/doc-images/delete-package.png new file mode 100644 index 0000000000..ff69f50d25 Binary files /dev/null and b/docs_deprecated/en/doc-images/delete-package.png differ diff --git a/docs_deprecated/en/doc-images/doc-app-list.png b/docs_deprecated/en/doc-images/doc-app-list.png new file mode 100644 index 0000000000..4e8c522b90 Binary files /dev/null and b/docs_deprecated/en/doc-images/doc-app-list.png differ diff --git a/docs_deprecated/en/doc-images/doc-db.png b/docs_deprecated/en/doc-images/doc-db.png new file mode 100644 index 0000000000..5124dbb058 Binary files /dev/null and b/docs_deprecated/en/doc-images/doc-db.png differ diff --git a/docs_deprecated/en/doc-images/doc-function-list.png b/docs_deprecated/en/doc-images/doc-function-list.png new file mode 100644 index 0000000000..38e0cf9b60 Binary files /dev/null and b/docs_deprecated/en/doc-images/doc-function-list.png differ diff --git a/docs_deprecated/en/doc-images/doc-policy.png b/docs_deprecated/en/doc-images/doc-policy.png new file mode 100644 index 0000000000..edcc5a67a8 Binary files /dev/null and b/docs_deprecated/en/doc-images/doc-policy.png differ diff --git a/docs_deprecated/en/doc-images/doc-storage.png b/docs_deprecated/en/doc-images/doc-storage.png new file mode 100644 index 0000000000..8173a586c5 Binary files /dev/null and b/docs_deprecated/en/doc-images/doc-storage.png differ diff --git a/docs_deprecated/en/doc-images/edit-cloudfunction.png b/docs_deprecated/en/doc-images/edit-cloudfunction.png new file mode 100644 index 0000000000..478cb69027 Binary files /dev/null and b/docs_deprecated/en/doc-images/edit-cloudfunction.png differ diff --git a/docs_deprecated/en/doc-images/file.png b/docs_deprecated/en/doc-images/file.png new file mode 100644 index 0000000000..aa88488627 Binary files /dev/null and b/docs_deprecated/en/doc-images/file.png differ diff --git a/docs_deprecated/en/doc-images/function-body.png b/docs_deprecated/en/doc-images/function-body.png new file mode 100644 index 0000000000..f29ce9cafe Binary files /dev/null and b/docs_deprecated/en/doc-images/function-body.png differ diff --git a/docs_deprecated/en/doc-images/function-log.png b/docs_deprecated/en/doc-images/function-log.png new file mode 100644 index 0000000000..b10595c90f Binary files /dev/null and b/docs_deprecated/en/doc-images/function-log.png differ diff --git a/docs_deprecated/en/doc-images/function-query.png b/docs_deprecated/en/doc-images/function-query.png new file mode 100644 index 0000000000..46197ae91c Binary files /dev/null and b/docs_deprecated/en/doc-images/function-query.png differ diff --git a/docs_deprecated/en/doc-images/function-url.png b/docs_deprecated/en/doc-images/function-url.png new file mode 100644 index 0000000000..afbcde73f0 Binary files /dev/null and b/docs_deprecated/en/doc-images/function-url.png differ diff --git a/docs_deprecated/en/doc-images/function.png b/docs_deprecated/en/doc-images/function.png new file mode 100644 index 0000000000..c21904e868 Binary files /dev/null and b/docs_deprecated/en/doc-images/function.png differ diff --git a/docs_deprecated/en/doc-images/getToken-parseToken.png b/docs_deprecated/en/doc-images/getToken-parseToken.png new file mode 100644 index 0000000000..a39fd68dec Binary files /dev/null and b/docs_deprecated/en/doc-images/getToken-parseToken.png differ diff --git a/docs_deprecated/en/doc-images/index.png b/docs_deprecated/en/doc-images/index.png new file mode 100644 index 0000000000..e5852130f2 Binary files /dev/null and b/docs_deprecated/en/doc-images/index.png differ diff --git a/docs_deprecated/en/doc-images/mj-id.png b/docs_deprecated/en/doc-images/mj-id.png new file mode 100644 index 0000000000..bd9709f248 Binary files /dev/null and b/docs_deprecated/en/doc-images/mj-id.png differ diff --git a/docs_deprecated/en/doc-images/open-website.png b/docs_deprecated/en/doc-images/open-website.png new file mode 100644 index 0000000000..f2272520bb Binary files /dev/null and b/docs_deprecated/en/doc-images/open-website.png differ diff --git a/docs_deprecated/en/doc-images/package-list.png b/docs_deprecated/en/doc-images/package-list.png new file mode 100644 index 0000000000..63b68e72c6 Binary files /dev/null and b/docs_deprecated/en/doc-images/package-list.png differ diff --git a/docs_deprecated/en/doc-images/pakcage-list.jpg b/docs_deprecated/en/doc-images/pakcage-list.jpg new file mode 100644 index 0000000000..348f7b075d Binary files /dev/null and b/docs_deprecated/en/doc-images/pakcage-list.jpg differ diff --git a/docs_deprecated/en/doc-images/polocy-db-data.png b/docs_deprecated/en/doc-images/polocy-db-data.png new file mode 100644 index 0000000000..95e647c6f0 Binary files /dev/null and b/docs_deprecated/en/doc-images/polocy-db-data.png differ diff --git a/docs_deprecated/en/doc-images/publish-cloudfunction.png b/docs_deprecated/en/doc-images/publish-cloudfunction.png new file mode 100644 index 0000000000..ac1499c251 Binary files /dev/null and b/docs_deprecated/en/doc-images/publish-cloudfunction.png differ diff --git a/docs_deprecated/en/doc-images/register.png b/docs_deprecated/en/doc-images/register.png new file mode 100644 index 0000000000..cf9ab88694 Binary files /dev/null and b/docs_deprecated/en/doc-images/register.png differ diff --git a/docs_deprecated/en/doc-images/run-cloudfunction.png b/docs_deprecated/en/doc-images/run-cloudfunction.png new file mode 100644 index 0000000000..9adf18e682 Binary files /dev/null and b/docs_deprecated/en/doc-images/run-cloudfunction.png differ diff --git a/docs_deprecated/en/doc-images/select-package-version.png b/docs_deprecated/en/doc-images/select-package-version.png new file mode 100644 index 0000000000..9c9bfe0c6c Binary files /dev/null and b/docs_deprecated/en/doc-images/select-package-version.png differ diff --git a/docs_deprecated/en/doc-images/set-wechat-pay.png b/docs_deprecated/en/doc-images/set-wechat-pay.png new file mode 100644 index 0000000000..2de73ca956 Binary files /dev/null and b/docs_deprecated/en/doc-images/set-wechat-pay.png differ diff --git a/docs_deprecated/en/doc-images/slack-connect-create-1.jpg b/docs_deprecated/en/doc-images/slack-connect-create-1.jpg new file mode 100644 index 0000000000..07350e22ef Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-connect-create-1.jpg differ diff --git a/docs_deprecated/en/doc-images/slack-connect-create.jpg b/docs_deprecated/en/doc-images/slack-connect-create.jpg new file mode 100644 index 0000000000..bf725acfc8 Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-connect-create.jpg differ diff --git a/docs_deprecated/en/doc-images/slack-connect.jpg b/docs_deprecated/en/doc-images/slack-connect.jpg new file mode 100644 index 0000000000..02c7c73003 Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-connect.jpg differ diff --git a/docs_deprecated/en/doc-images/slack-create-app-bot.jpg b/docs_deprecated/en/doc-images/slack-create-app-bot.jpg new file mode 100644 index 0000000000..802b4febf6 Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-create-app-bot.jpg differ diff --git a/docs_deprecated/en/doc-images/slack-create-app.jpg b/docs_deprecated/en/doc-images/slack-create-app.jpg new file mode 100644 index 0000000000..ef12d6b29b Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-create-app.jpg differ diff --git a/docs_deprecated/en/doc-images/slack-install-bot.jpg b/docs_deprecated/en/doc-images/slack-install-bot.jpg new file mode 100644 index 0000000000..9597cd1be3 Binary files /dev/null and b/docs_deprecated/en/doc-images/slack-install-bot.jpg differ diff --git a/docs_deprecated/en/doc-images/specification.jpg b/docs_deprecated/en/doc-images/specification.jpg new file mode 100644 index 0000000000..12e8680d97 Binary files /dev/null and b/docs_deprecated/en/doc-images/specification.jpg differ diff --git a/docs_deprecated/en/doc-images/todo-demo.png b/docs_deprecated/en/doc-images/todo-demo.png new file mode 100644 index 0000000000..8d38230e7a Binary files /dev/null and b/docs_deprecated/en/doc-images/todo-demo.png differ diff --git a/docs_deprecated/en/doc-images/upload.png b/docs_deprecated/en/doc-images/upload.png new file mode 100644 index 0000000000..2a5ba2b4ec Binary files /dev/null and b/docs_deprecated/en/doc-images/upload.png differ diff --git a/docs_deprecated/en/doc-images/use-injector.png b/docs_deprecated/en/doc-images/use-injector.png new file mode 100644 index 0000000000..b5c3e2576c Binary files /dev/null and b/docs_deprecated/en/doc-images/use-injector.png differ diff --git a/docs_deprecated/en/doc-images/web-ide-index.png b/docs_deprecated/en/doc-images/web-ide-index.png new file mode 100644 index 0000000000..29ec5c0f65 Binary files /dev/null and b/docs_deprecated/en/doc-images/web-ide-index.png differ diff --git a/docs_deprecated/en/doc-images/website-hosting.png b/docs_deprecated/en/doc-images/website-hosting.png new file mode 100644 index 0000000000..a462ba28dd Binary files /dev/null and b/docs_deprecated/en/doc-images/website-hosting.png differ diff --git a/docs/en/guide/cases/index.md b/docs_deprecated/en/guide/cases/index.md similarity index 100% rename from docs/en/guide/cases/index.md rename to docs_deprecated/en/guide/cases/index.md diff --git a/docs/en/guide/cli/index.md b/docs_deprecated/en/guide/cli/index.md similarity index 100% rename from docs/en/guide/cli/index.md rename to docs_deprecated/en/guide/cli/index.md diff --git a/docs/en/guide/client-sdk/index.md b/docs_deprecated/en/guide/client-sdk/index.md similarity index 100% rename from docs/en/guide/client-sdk/index.md rename to docs_deprecated/en/guide/client-sdk/index.md diff --git a/docs/en/guide/db/add.md b/docs_deprecated/en/guide/db/add.md similarity index 100% rename from docs/en/guide/db/add.md rename to docs_deprecated/en/guide/db/add.md diff --git a/docs/en/guide/db/command.md b/docs_deprecated/en/guide/db/command.md similarity index 100% rename from docs/en/guide/db/command.md rename to docs_deprecated/en/guide/db/command.md diff --git a/docs/en/guide/db/del.md b/docs_deprecated/en/guide/db/del.md similarity index 100% rename from docs/en/guide/db/del.md rename to docs_deprecated/en/guide/db/del.md diff --git a/docs/en/guide/db/find.md b/docs_deprecated/en/guide/db/find.md similarity index 100% rename from docs/en/guide/db/find.md rename to docs_deprecated/en/guide/db/find.md diff --git a/docs/en/guide/db/geo.md b/docs_deprecated/en/guide/db/geo.md similarity index 100% rename from docs/en/guide/db/geo.md rename to docs_deprecated/en/guide/db/geo.md diff --git a/docs/en/guide/db/index.md b/docs_deprecated/en/guide/db/index.md similarity index 100% rename from docs/en/guide/db/index.md rename to docs_deprecated/en/guide/db/index.md diff --git a/docs/en/guide/db/policy.md b/docs_deprecated/en/guide/db/policy.md similarity index 100% rename from docs/en/guide/db/policy.md rename to docs_deprecated/en/guide/db/policy.md diff --git a/docs/en/guide/db/quickstart.md b/docs_deprecated/en/guide/db/quickstart.md similarity index 100% rename from docs/en/guide/db/quickstart.md rename to docs_deprecated/en/guide/db/quickstart.md diff --git a/docs/en/guide/db/update.md b/docs_deprecated/en/guide/db/update.md similarity index 100% rename from docs/en/guide/db/update.md rename to docs_deprecated/en/guide/db/update.md diff --git a/docs/en/guide/function/call-function-in-client.md b/docs_deprecated/en/guide/function/call-function-in-client.md similarity index 100% rename from docs/en/guide/function/call-function-in-client.md rename to docs_deprecated/en/guide/function/call-function-in-client.md diff --git a/docs/en/guide/function/call-function-in-http.md b/docs_deprecated/en/guide/function/call-function-in-http.md similarity index 100% rename from docs/en/guide/function/call-function-in-http.md rename to docs_deprecated/en/guide/function/call-function-in-http.md diff --git a/docs/en/guide/function/call-function.md b/docs_deprecated/en/guide/function/call-function.md similarity index 100% rename from docs/en/guide/function/call-function.md rename to docs_deprecated/en/guide/function/call-function.md diff --git a/docs/en/guide/function/depend.md b/docs_deprecated/en/guide/function/depend.md similarity index 100% rename from docs/en/guide/function/depend.md rename to docs_deprecated/en/guide/function/depend.md diff --git a/docs/en/guide/function/env.md b/docs_deprecated/en/guide/function/env.md similarity index 100% rename from docs/en/guide/function/env.md rename to docs_deprecated/en/guide/function/env.md diff --git a/docs/en/guide/function/faq.md b/docs_deprecated/en/guide/function/faq.md similarity index 100% rename from docs/en/guide/function/faq.md rename to docs_deprecated/en/guide/function/faq.md diff --git a/docs/en/guide/function/function-param.md b/docs_deprecated/en/guide/function/function-param.md similarity index 100% rename from docs/en/guide/function/function-param.md rename to docs_deprecated/en/guide/function/function-param.md diff --git a/docs/en/guide/function/function-sdk.md b/docs_deprecated/en/guide/function/function-sdk.md similarity index 100% rename from docs/en/guide/function/function-sdk.md rename to docs_deprecated/en/guide/function/function-sdk.md diff --git a/docs/en/guide/function/index.md b/docs_deprecated/en/guide/function/index.md similarity index 100% rename from docs/en/guide/function/index.md rename to docs_deprecated/en/guide/function/index.md diff --git a/docs/en/guide/function/init.md b/docs_deprecated/en/guide/function/init.md similarity index 100% rename from docs/en/guide/function/init.md rename to docs_deprecated/en/guide/function/init.md diff --git a/docs/en/guide/function/interceptor.md b/docs_deprecated/en/guide/function/interceptor.md similarity index 100% rename from docs/en/guide/function/interceptor.md rename to docs_deprecated/en/guide/function/interceptor.md diff --git a/docs/en/guide/function/logs.md b/docs_deprecated/en/guide/function/logs.md similarity index 100% rename from docs/en/guide/function/logs.md rename to docs_deprecated/en/guide/function/logs.md diff --git a/docs/en/guide/function/trigger.md b/docs_deprecated/en/guide/function/trigger.md similarity index 100% rename from docs/en/guide/function/trigger.md rename to docs_deprecated/en/guide/function/trigger.md diff --git a/docs/en/guide/function/use-function.md b/docs_deprecated/en/guide/function/use-function.md similarity index 100% rename from docs/en/guide/function/use-function.md rename to docs_deprecated/en/guide/function/use-function.md diff --git a/docs/en/guide/function/websocket.md b/docs_deprecated/en/guide/function/websocket.md similarity index 100% rename from docs/en/guide/function/websocket.md rename to docs_deprecated/en/guide/function/websocket.md diff --git a/docs/en/guide/index.md b/docs_deprecated/en/guide/index.md similarity index 100% rename from docs/en/guide/index.md rename to docs_deprecated/en/guide/index.md diff --git a/docs/en/guide/laf-assistant/index.md b/docs_deprecated/en/guide/laf-assistant/index.md similarity index 100% rename from docs/en/guide/laf-assistant/index.md rename to docs_deprecated/en/guide/laf-assistant/index.md diff --git a/docs/en/guide/oss/get-sts.md b/docs_deprecated/en/guide/oss/get-sts.md similarity index 100% rename from docs/en/guide/oss/get-sts.md rename to docs_deprecated/en/guide/oss/get-sts.md diff --git a/docs/en/guide/oss/index.md b/docs_deprecated/en/guide/oss/index.md similarity index 100% rename from docs/en/guide/oss/index.md rename to docs_deprecated/en/guide/oss/index.md diff --git a/docs/en/guide/oss/oss-by-function.md b/docs_deprecated/en/guide/oss/oss-by-function.md similarity index 100% rename from docs/en/guide/oss/oss-by-function.md rename to docs_deprecated/en/guide/oss/oss-by-function.md diff --git a/docs/en/guide/oss/upload-by-function.md b/docs_deprecated/en/guide/oss/upload-by-function.md similarity index 100% rename from docs/en/guide/oss/upload-by-function.md rename to docs_deprecated/en/guide/oss/upload-by-function.md diff --git a/docs/en/guide/oss/use-sts-in-client.md b/docs_deprecated/en/guide/oss/use-sts-in-client.md similarity index 100% rename from docs/en/guide/oss/use-sts-in-client.md rename to docs_deprecated/en/guide/oss/use-sts-in-client.md diff --git a/docs/en/guide/quick-start/Todo.md b/docs_deprecated/en/guide/quick-start/Todo.md similarity index 100% rename from docs/en/guide/quick-start/Todo.md rename to docs_deprecated/en/guide/quick-start/Todo.md diff --git a/docs/en/guide/quick-start/login.md b/docs_deprecated/en/guide/quick-start/login.md similarity index 100% rename from docs/en/guide/quick-start/login.md rename to docs_deprecated/en/guide/quick-start/login.md diff --git a/docs/en/guide/web-ide/index.md b/docs_deprecated/en/guide/web-ide/index.md similarity index 100% rename from docs/en/guide/web-ide/index.md rename to docs_deprecated/en/guide/web-ide/index.md diff --git a/docs/en/guide/website-hosting/index.md b/docs_deprecated/en/guide/website-hosting/index.md similarity index 100% rename from docs/en/guide/website-hosting/index.md rename to docs_deprecated/en/guide/website-hosting/index.md diff --git a/docs_deprecated/en/index.md b/docs_deprecated/en/index.md new file mode 100644 index 0000000000..bf148f1a7a --- /dev/null +++ b/docs_deprecated/en/index.md @@ -0,0 +1,37 @@ +--- +title: laf Cloud Development Documentation +layout: home + +hero: + name: laf + text: Write code like writing a blog Go live anytime, anywhere + tagline: life is short, you need laf :) + actions: + - theme: brand + text: Get Started Quickly + link: /guide/ + - theme: alt + text: Start Using Now + link: https://laf.run/ + - theme: alt + text: GitHub Repository + link: https://github.com/labring/laf + +heroImage: https://socialify.git.ci/labring/laf/image?description=1& +tagline: Write functions like writing a blog, go live with ease +actionText: Get Started +actionLink: /guide/ +features: + - title: Cloud Functions + details: Code running in the cloud, write cloud functions using TypeScript, support WebSocket, can be directly called from the frontend. Cloud functions run on the Node.js runtime environment, no cold start required. + - title: Cloud Database + details: Ready to use, no need to create. The database can also be accessed "directly" by the client through access policies, saving more than 90% of backend APIs. Frontend developers can independently complete application development. + - title: Online IDE + details: Support AI-generated cloud functions, code with intelligence. Support intelligent autocompletion for all types, write, debug, and view logs online, code as content. Go live anytime, anywhere. + - title: Triggers + details: Cloud functions can be configured with timers and event triggers, and can listen for database change events. Data changes can trigger the execution of cloud functions (event triggers will be updated later). + - title: Cloud Storage + details: Provide a professional S3-compatible object storage service (MinIO), support Service Account open capabilities. + - title: Static Website Hosting + details: One-click deployment and hosting for frontend static websites, automatically assign subdomains that can be accessed directly. Support binding custom domains and automatically generate SSL certificates. +--- \ No newline at end of file diff --git a/docs/guide/cases/index.md b/docs_deprecated/guide/cases/index.md similarity index 100% rename from docs/guide/cases/index.md rename to docs_deprecated/guide/cases/index.md diff --git a/docs/guide/cli/index.md b/docs_deprecated/guide/cli/index.md similarity index 100% rename from docs/guide/cli/index.md rename to docs_deprecated/guide/cli/index.md diff --git a/docs/guide/client-sdk/index.md b/docs_deprecated/guide/client-sdk/index.md similarity index 100% rename from docs/guide/client-sdk/index.md rename to docs_deprecated/guide/client-sdk/index.md diff --git a/docs_deprecated/guide/db/add.md b/docs_deprecated/guide/db/add.md new file mode 100644 index 0000000000..ed68b67721 --- /dev/null +++ b/docs_deprecated/guide/db/add.md @@ -0,0 +1,64 @@ +--- +title: 新增数据 +--- + +# {{ $frontmatter.title }} + +Laf 云函数库中,新增数据非常简单,正规说法为插入文档。以下是插入单个文档和批量插入文档的写法。 + +同时 Laf 云数据库是 `Schema Free` 的,意味着你可以插入任意的字段和数据类型。 + +::: tip +使用 `cloud.database()`新增数据的方法无法自定义 id,所有新增的数据,都会自动生成 id,生成的 id 类型为为 `string` + +使用 `mongodb 原生写法` ,可以自定义 id,也可以自动生成 id,生成的 id 类型为 `ObjectId` +::: + +## 插入单个文档 + +下例向 user 集合中添加了一条记录。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export default async function (ctx: FunctionContext) { + // 向 user 集合中添加一条记录 + const res = await db.collection('user').add({ name: "jack" }) + console.log(res) +} +``` + +## 批量新增文档 + +当然我们也可以批量添加多条记录,只需要多传入一个对象`{ multi: true }`即可。 + +```typescript +const list = [ + { name: "jack" }, + { name: "rose" } +] +// 向 user 集合中加入多条记录 +const res = await db.collection('user').add(list, { multi: true }) +console.log(res) +``` + +## mongodb 原生写法 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export async function main(ctx: FunctionContext) { + // 向 user 集合中插入单个文档 + const result1 = await db.collection('user').insertOne({ name: "jack" }) + console.log(result1) + // 向 user 集合中批量插入文档 + const documents = [ + { name: "Jane Doe", age: 25 }, + { name: "Bob Smith", age: 40 } + ]; + const result2 = await db.collection('user').insertMany(documents); + console.log(result2) +} +``` diff --git a/docs_deprecated/guide/db/aggregate.md b/docs_deprecated/guide/db/aggregate.md new file mode 100644 index 0000000000..10274a32ed --- /dev/null +++ b/docs_deprecated/guide/db/aggregate.md @@ -0,0 +1,2329 @@ +--- +title: 数据库聚合操作 +--- + +# {{ $frontmatter.title }} + +在进行复杂的数据查询时,需要用到聚合操作。 + +## 获取数据库集合的聚合操作实例 + +```js +db.collection('scores').aggregate() +``` + +**注意:** + +- 聚合操作实例仅用于查询,不可执行增删改操作。在聚合操作实例上只能使用聚合操作方法,不能使用 `where/orderBy` 等基础方法,`where` 需改为 `match`,`orderBy` 应使用 `sort` 实现,细节请阅读下方聚合操作文档。 +- 聚合操作在大数据量下性能不如简单查询,请根据自身业务选择合适的用法 + +云函数中使用时切勿复用 aggregate 实例,容易引发 Bug。 + +以下两种写法均为错误示例: + +```js +const db = cloud.database() +const collection = db.collection('test') +const aggregate = collection.aggregate() // 云函数实例复用时,此聚合实例也会复用,导致 Bug +export default async function (ctx: FunctionContext) { + const res = await aggregate.match({a:1}).end() + return {res} +} +``` + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const aggregate = collection.aggregate() // 此聚合实例分别在两个请求内使用,导致 Bug + const res1 = await aggregate.match({a:1}).end() + const res2 = await aggregate.match({a:2}).end() + return {res1, res2} +} +``` + +将上述两个用法修正为正确用法分别如下: + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const aggregate = collection.aggregate() // 每次执行云函数会有独立的聚合实例 + const res = await aggregate.match({a:1}).end() + return {res} +} +``` + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const res1 = await collection.aggregate().match({a:1}).end() // 两个请求分别调用 aggregate 方法产生聚合实例 + const res2 = await collection.aggregate().match({a:2}).end() + return {res1, res2} +} +``` + +## 聚合表达式 + +表达式可以是字段路径、常量、或数据库运算方法。表达式可以嵌套表达式。 + +**字段路径** + +表达式用字段路径表示法来指定记录中的字段。字段路径的表示由一个 `$` 符号加上字段名或嵌套字段名。嵌套字段名用点将嵌套的各级字段连接起来。如 `$profile` 就表示 `profile` 的字段路径,`$profile.name` 就表示 `profile.name` 的字段路径(`profile` 字段中嵌套的 `name` 字段)。 + +例如:现有以下数据 + +```json +[{ + "profile": { + "name": "Chloe" + }, + "status": 0 +}] +``` + +```js +// 执行以下操作 +let res = await db.collection('scores').aggregate() + .addFields({ + name: '$profile.name' + }) + .end() + +// 返回值为 +{ + "data": [{ + "profile": { + "name": "Chloe" + }, + "status": 0, + "name": "Chloe" + }] +} +``` + +**常量** + +常量可以是任意类型。默认情况下 $ 开头的字符串都会被当做字段路径处理,如果想要避免这种行为,使用 `db.command.aggregate.literal` 声明为常量。 + +**数据库运算方法** + + + +参考数据库运算方法 + +## addFields + +聚合阶段。添加新字段到输出的记录。经过 `addFields` 聚合阶段,输出的所有记录中除了输入时带有的字段外,还将带有 `addFields` 指定的字段。 + +**API 说明** + +`addFields` 等同于同时指定了所有已有字段和新增字段的 `project` 阶段。 + +**`addFields` 的形式如下:** + +```js +addFields({ + <新字段>: <表达式> +}) +``` + +`addFields` 可指定多个新字段,每个新字段的值由使用的表达式决定。 + +如果指定的新字段与原有字段重名,则新字段的值会覆盖原有字段的值。注意 `addFields` 不能用来给数组字段添加元素。 + +**示例 1:连续两次 addFields** + +假设集合 scores 有如下记录: + +```js +{ + _id: 1, + student: "Maya", + homework: [ 10, 5, 10 ], + quiz: [ 10, 8 ], + extraCredit: 0 +} +{ + _id: 2, + student: "Ryan", + homework: [ 5, 6, 5 ], + quiz: [ 8, 8 ], + extraCredit: 8 +} +``` + +应用两次 `addFields`,第一次增加两个字段分别为 `homework` 和 `quiz` 的和值,第二次增加一个字段再基于上两个和值求一次和值。 + +```js +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .addFields({ + totalHomework: $.sum('$homework'), + totalQuiz: $.sum('$quiz') + }) + .addFields({ + totalScore: $.add(['$totalHomework', '$totalQuiz', '$extraCredit']) + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id" : 1, + "student" : "Maya", + "homework" : [ 10, 5, 10 ], + "quiz" : [ 10, 8 ], + "extraCredit" : 0, + "totalHomework" : 25, + "totalQuiz" : 18, + "totalScore" : 43 +} +{ + "_id" : 2, + "student" : "Ryan", + "homework" : [ 5, 6, 5 ], + "quiz" : [ 8, 8 ], + "extraCredit" : 8, + "totalHomework" : 16, + "totalQuiz" : 16, + "totalScore" : 40 +} +``` + +**示例 2:在嵌套记录里增加字段** + +可以用点表示法在嵌套记录里增加字段。假设 vehicles 集合含有如下记录: + +```js +{ _id: 1, type: "car", specs: { doors: 4, wheels: 4 } } +{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2 } } +{ _id: 3, type: "jet ski" } +``` + +可以用如下操作在 `specs` 字段下增加一个新的字段 `fuel_type`,值都设为固定字符串 `unleaded`: + +```js +let res = await db.collection('vehicles').aggregate() + .addFields({ + 'specs.fuel_type': 'unleaded' + }) + .end() +``` + +返回结果如下: + +```js +{ _id: 1, type: "car", + specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } +{ _id: 2, type: "motorcycle", + specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 3, type: "jet ski", + specs: { fuel_type: "unleaded" } } +``` + +**示例 3:设置字段值为另一个字段** + +可以通过 `$` 加字段名组成的字符串作为值的表达式来设置字段的值为另一个字段的值。 + +同样用上一个集合示例,可以用如下操作添加一个字段 `vehicle_type`,将其值设置为 `type` 字段的值: + +```js +let res = await db.collection('vehicles').aggregate() + .addFields({ + vehicle_type: '$type' + }) + .end() +``` + +返回结果如下: + +```js +{ _id: 1, type: "car", vehicle_type: "car", + specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } +{ _id: 2, type: "motorcycle", vehicle_type: "motorcycle", + specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 3, type: "jet ski", vehicle_type: "jet ski", + specs: { fuel_type: "unleaded" } } +``` + +## bucket + +聚合阶段。将输入记录根据给定的条件和边界划分成不同的组,每组即一个 `bucket`。 + +**API 说明** + +每组分别作为一个记录输出,包含一个以下界为值的 `_id` 字段和一个以组中记录数为值的 `count` 字段。`count` 在没有指定 `output` 的时候是默认输出的。 + +`bucket` 只会在组内有至少一个记录的时候输出。 + +**bucket 的形式如下:** + +```js +bucket({ + groupBy: , + boundaries: [, , ...], + default: , + output: { + : , + ... + : + } +}) +``` + +`groupBy` 是一个用以决定分组的表达式,会应用在各个输入记录上。可以用 `$` 前缀加上要用以分组的字段路径来作为表达式。除非用 `default` 指定了默认值,否则每个记录都需要包含指定的字段,且字段值必须在 `boundaries` 指定的范围之内。 + +`boundaries` 是一个数组,每个元素分别是每组的下界。必须至少指定两个边界值。数组值必须是同类型递增的值。 + +`default` 可选,指定之后,没有进入任何分组的记录将都进入一个默认分组,这个分组记录的 `_id` 即由 `default` 决定。`default` 的值必须小于 `boundaries` 中的最小值或大于等于其中的最大值。`default` 的值可以与 `boundaries` 元素值类型不同。 + +`output` 可选,用以决定输出记录除了 `_id` 外还要包含哪些字段,各个字段的值必须用累加器表达式指定。当 `output` 指定时,默认的 `count` 是不会被默认输出的,必须手动指定: + +```js +output: { + count: $.sum(1), + ... + : +} +``` + +使用 bucket 需要满足以下至少一个条件,否则会抛出错误: + +每一个输入记录应用 groupBy 表达式获取的值都必须是一个在 boundaries 内的值 + +指定一个 default 值,该值在 boundaries 以外,或与 boundaries 元素的值不同的类型。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10 +} +{ + _id: "2", + price: 50 +} +{ + _id: "3", + price: 20 +} +{ + _id: "4", + price: 80 +} +{ + _id: "5", + price: 200 +} +``` + +对上述记录进行分组,将 [0, 50) 分为一组,[50, 100) 分为一组,其他分为一组: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .bucket({ + groupBy: '$price', + boundaries: [0, 50, 100], + default: 'other', + output: { + count: $.sum(1), + ids: $.push('$_id') + } + }) + .end() +``` + +返回结果如下: + +```js +[ + { + "_id": 0, + "count": 2, + "ids": [ + "1", + "3" + ] + }, + { + "_id": 50, + "count": 2, + "ids": [ + "2", + "4" + ] + }, + { + "_id": "other", + "count": 1, + "ids": [ + "5" + ] + } +] +``` + +## bucketAuto + +聚合阶段。将输入记录根据给定的条件划分成不同的组,每组即一个 `bucket`。与 `bucket` 的其中一个不同之处在于无需指定 `boundaries`,`bucketAuto` 会自动尝试将记录尽可能平均的分散到每组中。 + +**API 说明** +每组分别作为一个记录输出,包含一个以包含组中最大值和最小值两个字段的对象为值的 _id 字段和一个以组中记录数为值的 count 字段。count 在没有指定 output 的时候是默认输出的。 + +**bucketAuto 的形式如下:** + +```js +bucketAuto({ + groupBy: , + buckets: , + granularity: , + output: { + : , + ... + : + } +}) +``` + +`groupBy` 是一个用以决定分组的表达式,会应用在各个输入记录上。可以用 $ 前缀加上要用以分组的字段路径来作为表达式。除非用 `default` 指定了默认值,否则每个记录都需要包含指定的字段,且字段值必须在 `boundaries` 指定的范围之内。 + +`buckets` 是一个用于指定划分组数的正整数。 + +`granularity` 是可选枚举值字符串,用于保证自动计算出的边界符合给定的规则。这个字段仅可在所有 `groupBy` 值都是数字并且没有 `NaN` 的情况下使用。枚举值包括:`R5、R10、R20、R40、R80、1-2-5、E6、E12、E24、E48、E96、E192、POWERSOF2`。 + +`output` 可选,用以决定输出记录除了 `_id` 外还要包含哪些字段,各个字段的值必须用累加器表达式指定。当 `output` 指定时,默认的 `count` 是不会被默认输出的,必须手动指定: + +```js +output: { + count: $.sum(1), + ... + : +} +``` + +在以下情况中,输出的分组可能会小于给定的组数: + +输入记录数少于分组数 + +- `groupBy` 计算得到的唯一值少于分组数 +- `granularity` 的间距少于分组数 +- `granularity` 不够精细以至于不能平均分配到各组 + +**granularity 详细说明** + +`granularity` 用于保证边界值属于一个给定的数字序列。 + +**Renard 序列** + +Renard 序列是以 10 的 5 / 10 / 20 / 40 / 80 次方根来推导的、在 1.0 到 10.0 (如果是 R80 则是 10.3) 之间的数字序列。 + +设置 granularity 为 R5 / R10 / R20 / R40 / R80 就把边界值限定在序列内。如果 groupBy 的值不在 1.0 到 10.0 (如果是 R80 则是 10.3) 内,则序列数字会自动乘以 10。 + +**E 序列** + +E 序列是以 10 的 6 / 12 / 24 / 48 / 96 / 192 次方跟来推导的、带有一个特定误差的、在 1.0 到 10.0 之间的数字序列。 + +**1-2-5 序列** + +1-2-5 序列 表现与三值 Renard 序列一样。 + +**2的次方序列** + +由 2 的各次方组成的序列数字。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10.5 +} +{ + _id: "2", + price: 50.3 +} +{ + _id: "3", + price: 20.8 +} +{ + _id: "4", + price: 80.2 +} +{ + _id: "5", + price: 200.3 +} +``` + +对上述记录进行自动分组,分成三组: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .bucketAuto({ + groupBy: '$price', + buckets: 3, + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": { + "min": 10.5, + "max": 50.3 + }, + "count": 2 +} +{ + "_id": { + "min": 50.3, + "max": 200.3 + }, + "count": 2 +} +{ + "_id": { + "min": 200.3, + "max": 200.3 + }, + "count": 1 +} +``` + +## count + +聚合阶段。计算上一聚合阶段输入到本阶段的记录数,输出一个记录,其中指定字段的值为记录数。 + +**API 说明** + +**count 的形式如下:** + +```js +count() +``` + +`` 是输出记录数的字段的名字,不能是空字符串,不能以 $ 开头,不能包含 . 字符。 + +count 阶段等同于 group + project 的操作: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .group({ + _id: null, + count: $.sum(1), + }) + .project({ + _id: 0, + }) + .end() +``` + +上述操作会输出一个包含 count 字段的记录。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10.5 +} +{ + _id: "2", + price: 50.3 +} +{ + _id: "3", + price: 20.8 +} +{ + _id: "4", + price: 80.2 +} +{ + _id: "5", + price: 200.3 +} +``` + +找出价格大于 50 的记录数: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .match({ + price: $.gt(50) + }) + .count('expensiveCount') + .end() +``` + +返回结果如下: + +```js +{ + "expensiveCount": 3 +} +``` + +## geoNear + +聚合阶段。将记录按照离给定点从近到远输出。 + +|属性 |类型 |默认值 |必填 |说明 | +|---- |---- |---- |---- |---- | +|near |GeoPoint | |是 |GeoJSON Point,用于判断距离的点 | +|spherical |true | |是 |必填,值为 true | +|maxDistance |number | |否 |距离最大值 | +|minDistance |number | |否 |距离最小值 | +|query |Object | |否 |要求记录必须同时满足该条件(语法同 where) | +|distanceMultiplier |number | |否 |返回时在距离上乘以该数字 | +|distanceField |string | |是 |存放距离的输出字段名,可以用点表示法表示一个嵌套字段 | +|includeLocs |string | |否 |列出要用于距离计算的字段,如果记录中有多个字段都是地理位置时有用 | +|key |string | |否 |选择要用的地理位置索引。如果集合由多个地理位置索引,则必须指定一个,指定的方式是指定对应的字段 | + +**API 说明** + +- `geoNear` 必须为第一个聚合阶段 +- 必须有地理位置索引。如果有多个,必须用 `key` 参数指定要使用的索引。 + +**示例** + +假设集合 attractions 有如下记录: + +```js +{ + "_id": "geoNear.0", + "city": "Guangzhou", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 113.30593, + 23.1361155 + ] + }, + "name": "Canton Tower" +}, +{ + "_id": "geoNear.1", + "city": "Guangzhou", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 113.306789, + 23.1564721 + ] + }, + "name": "Baiyun Mountain" +}, +{ + "_id": "geoNear.2", + "city": "Beijing", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 116.3949659, + 39.9163447 + ] + }, + "name": "The Palace Museum" +}, +{ + "_id": "geoNear.3", + "city": "Beijing", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 116.2328567, + 40.242373 + ] + }, + "name": "Great Wall" +} +``` + +```js +const $ = db.command.aggregate +let res = await db.collection('attractions').aggregate() + .geoNear({ + distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 + spherical: true, + near: new db.Geo.Point(113.3089506, 23.0968251), + query: { + docType: 'geoNear', + }, + key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填 + includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填 + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "geoNear.0", + "location": { + "type": "Point", + "coordinates": [ + 113.30593, + 23.1361155 + ] + }, + "docType": "geoNear", + "name": "Canton Tower", + "city": "Guangzhou", + "distance": 4384.68131486958 +}, +{ + "_id": "geoNear.1", + "city": "Guangzhou", + "location": { + "type": "Point", + "coordinates": [ + 113.306789, + 23.1564721 + ] + }, + "docType": "geoNear", + "name": "Baiyun Mountain", + "distance": 6643.521654040738 +}, +{ + "_id": "geoNear.2", + "docType": "geoNear", + "name": "The Palace Museum", + "city": "Beijing", + "location": { + "coordinates": [ + 116.3949659, + 39.9163447 + ], + "type": "Point" + }, + "distance": 1894750.4414538583 +}, +{ + "_id": "geoNear.3", + "docType": "geoNear", + "name": "Great Wall", + "city": "Beijing", + "location": { + "type": "Point", + "coordinates": [ + 116.2328567, + 40.242373 + ] + }, + "distance": 1928300.3308822548 +} +``` + +## group + +聚合阶段。将输入记录按给定表达式分组,输出时每个记录代表一个分组,每个记录的 _id 是区分不同组的 key。输出记录中也可以包括累计值,将输出字段设为累计值即会从该分组中计算累计值。 + +使用group可以很方便的实现类似SQL的distinct功能 + +**API 说明** + +**group 的形式如下:** + +```js +group({ + _id: , + : , + ... + : +}) +``` + +`_id` 参数是必填的,如果填常量则只有一组。其他字段是可选的,都是累计值,用 `$.sum` 等累计器(`const $ = db.command.aggregate`),但也可以使用其他表达式。 + +累计器必须是以下操作符之一: + +详细使用方法见[累计器操作符](#累计器操作符) + +|操作符 |说明 | +|---- |---- | +|addToSet |向数组中添加值,如果数组中已存在该值,不执行任何操作 | +|avg |返回一组集合中,指定字段对应数据的平均值 | +|sum |计算并且返回一组字段所有数值的总和 | +|first |返回指定字段在一组集合的第一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。 | +|last |返回指定字段在一组集合的最后一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。 | +|max |返回一组数值的最大值 | +|min |返回一组数值的最小值 | +|push |在 group 阶段,返回一组中表达式指定列与对应的值,一起组成的数组 | +|stdDevPop |返回一组字段对应值的标准差 | +|stdDevSamp |计算输入值的样本标准偏差。如果输入值代表数据总体,或者不概括更多的数据,请改用 db.command.aggregate.stdDevPop| +|mergeObjects |将多个文档合并为单个文档 | + +**内存限制** + +该阶段有 100M 内存使用限制。 + +**示例 1:按字段值分组** + +假设集合 avatar 有如下记录: + +```js +{ + _id: "1", + alias: "john", + region: "asia", + scores: [40, 20, 80], + coins: 100 +} +{ + _id: "2", + alias: "arthur", + region: "europe", + scores: [60, 90], + coins: 20 +} +{ + _id: "3", + alias: "george", + region: "europe", + scores: [50, 70, 90], + coins: 50 +} +{ + _id: "4", + alias: "john", + region: "asia", + scores: [30, 60, 100, 90], + coins: 40 +} +{ + _id: "5", + alias: "george", + region: "europe", + scores: [20], + coins: 60 +} +{ + _id: "6", + alias: "john", + region: "asia", + scores: [40, 80, 70], + coins: 120 +} +``` + +```js +const $ = db.command.aggregate +let res = await db.collection('avatar').aggregate() + .group({ + _id: '$alias', + num: $.sum(1) + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "john", + "num": 3 +} +{ + "_id": "authur", + "num": 1 +} +{ + "_id": "george", + "num": 2 +} +``` + +**示例 2:按多个值分组** + +可以给 _id 传入记录的方式按多个值分组。还是沿用上面的示例数据,按各个区域(region)获得相同最高分(score)的来分组,并求出各组虚拟币(coins)的总量: + +```js +const $ = db.command.aggregate +let res = await db.collection('avatar').aggregate() + .group({ + _id: { + region: '$region', + maxScore: $.max('$scores') + }, + totalCoins: $.sum('$coins') + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": { + "region": "asia", + "maxScore": 80 + }, + "totalCoins": 220 +} +{ + "_id": { + "region": "asia", + "maxScore": 100 + }, + "totalCoins": 40 +} +{ + "_id": { + "region": "europe", + "maxScore": 90 + }, + "totalCoins": 70 +} +{ + "_id": { + "region": "europe", + "maxScore": 20 + }, + "totalCoins": 60 +} +``` + +## limit + +聚合阶段。限制输出到下一阶段的记录数。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10 +} +{ + _id: "2", + price: 50 +} +{ + _id: "3", + price: 20 +} +{ + _id: "4", + price: 80 +} +{ + _id: "5", + price: 200 +} +``` + +返回价格大于 20 的记录的最小的两个记录: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .match({ + price: $.gt(20) + }) + .sort({ + price: 1, + }) + .limit(2) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "2", + "price": 50 +} +{ + "_id": "4", + "price": 80 +} +``` + +## lookup + +聚合阶段。联表查询。与同个数据库下的一个指定的集合做 left outer join(左外连接)。对该阶段的每一个输入记录,lookup 会在该记录中增加一个数组字段,该数组是被联表中满足匹配条件的记录列表。lookup 会将连接后的结果输出给下个阶段。 + +**API 说明** + +`lookup` 有两种使用方式 + +### 相等匹配 + +将输入记录的一个字段和被连接集合的一个字段进行相等匹配时,采用以下定义: + +```js +lookup({ + from: <要连接的集合名>, + localField: <输入记录的要进行相等匹配的字段>, + foreignField: <被连接集合的要进行相等匹配的字段>, + as: <输出的数组字段名> +}) +``` + +**参数详细说明** + +|参数字段 |说明 | +|---- |---- | +|from |要进行连接的另外一个集合的名字 | +|localField |当前流水线的输入记录的字段名,该字段将被用于与 from 指定的集合的 foreignField 进行相等匹配。如果输入记录中没有该字段,则该字段的值在匹配时会被视作 null| +|foreignField |被连接集合的字段名,该字段会被用于与 localField 进行相等匹配。如果被连接集合的记录中没有该字段,该字段的值将在匹配时被视作 null | +|as |指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 | + +这个操作等价于以下伪 SQL 操作: + +``` +SELECT *, +FROM collection +WHERE IN (SELECT * + FROM + WHERE = ); +``` + +**例子:** + +- 指定一个相等匹配条件 +- 对数组字段应用相等匹配 +- 组合 mergeObjects 应用相等匹配 + +### 自定义连接条件、拼接子查询 + +如果需要指定除相等匹配之外的连接条件,或指定多个相等匹配条件,或需要拼接被连接集合的子查询结果,那可以使用如下定义: + +```js +lookup({ + from: <要连接的集合名>, + let: { <变量 1>: <表达式 1>, ..., <变量 n>: <表达式 n> }, + pipeline: [ <在要连接的集合上进行的流水线操作> ], + as: <输出的数组字段名> +}) +``` + +**参数详细说明** + +|参数字段 |说明 | +|---- |---- | +|from |要进行连接的另外一个集合的名字 | +|let |可选。指定在 pipeline 中可以使用的变量,变量的值可以引用输入记录的字段,比如 let: { userName: '$name' } 就代表将输入记录的 name 字段作为变量 userName 的值。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 | +|pipeline |指定要在被连接集合中运行的聚合操作。如果要返回整个集合,则该字段取值空数组 []。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 | +|as |指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 | + +该操作等价于以下伪 SQL 语句: + +``` +SELECT *, +FROM collection +WHERE IN (SELECT + FROM + WHERE ); +``` + +**例子** + +- 指定多个连接条件 +- 拼接被连接集合的子查询 + +**示例** + +**指定一个相等匹配条件** + +假设 orders 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1}, + {"_id":6} +] +``` + +books 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"}, + {"_id":"book2","author":"author 2","category":"novel","stock":20,"title":"novel 2"}, + {"_id":"book5","author":"author 4","category":"science","stock":50,"title":null}, + {"_id":"book6","author":"author 5","category":"novel","stock":"60"} +] +``` + +以下聚合操作可以通过一个相等匹配条件连接 `orders` 和 `books` 集合,匹配的字段是 `orders` 集合的 `book` 字段和 `books` 集合的 title 字段: + +```js +const db = cloud.database() +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + localField: 'book', + foreignField: 'title', + as: 'bookList', + }) + .end() +``` + +结果: + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 30, + "quantity": 2, + "bookList": [ + { + "_id": "book1", + "title": "novel 1", + "author": "author 1", + "category": "novel", + "stock": 10 + } + ] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "author": "author 3", + "stock": 30 + } + ] + }, + { + "_id": 6, + "bookList": [ + { + "_id": "book5", + "category": "science", + "author": "author 4", + "stock": 50, + "title": null + }, + { + "_id": "book6", + "author": "author 5", + "stock": "60", + "category": "novel" + } + ] + } +] +``` + +对数组字段应用相等匹配 +假设 authors 集合有以下记录: + +```js +[ + {"_id": 1, "name": "author 1", "intro": "Two-time best-selling sci-fiction novelist"}, + {"_id": 3, "name": "author 3", "intro": "UCB assistant professor"}, + {"_id": 4, "name": "author 4", "intro": "major in CS"} +] +``` + +books 集合有以下记录: + +```js +[ + {"_id":"book1","authors":["author 1"],"category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","authors":["author 3", "author 4"],"category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","authors":["author 3"],"category":"science","stock":40,"title":"science 2"} +] +``` + +以下操作获取作者信息及他们分别发表的书籍,使用了 lookup 操作匹配 authors 集合的 name 字段和 books 集合的 authors 数组字段: + +```js +const db = cloud.database() +let res = await db.collection('authors').aggregate() + .lookup({ + from: 'books', + localField: 'name', + foreignField: 'authors', + as: 'publishedBooks', + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 1, + "intro": "Two-time best-selling sci-fiction novelist", + "name": "author 1", + "publishedBooks": [ + { + "_id": "book1", + "title": "novel 1", + "category": "novel", + "stock": 10, + "authors": [ + "author 1" + ] + } + ] + }, + { + "_id": 3, + "name": "author 3", + "intro": "UCB assistant professor", + "publishedBooks": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "stock": 30, + "authors": [ + "author 3", + "author 4" + ] + }, + { + "_id": "book4", + "title": "science 2", + "category": "science", + "stock": 40, + "authors": [ + "author 3" + ] + } + ] + }, + { + "_id": 4, + "intro": "major in CS", + "name": "author 4", + "publishedBooks": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "stock": 30, + "authors": [ + "author 3", + "author 4" + ] + } + ] + } +] +``` + +**组合 mergeObjects 应用相等匹配** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1}, + {"_id":6} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"}, + {"_id":"book2","author":"author 2","category":"novel","stock":20,"title":"novel 2"}, + {"_id":"book5","author":"author 4","category":"science","stock":50,"title":null}, + {"_id":"book6","author":"author 5","category":"novel","stock":"60"} +] +``` + +以下操作匹配 orders 的 book 字段和 books 的 title 字段,并将 books 匹配结果直接 merge 到 orders 记录中。 + +```js +var db = cloud.database() +var $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: "books", + localField: "book", + foreignField: "title", + as: "bookList" + }) + .replaceRoot({ + newRoot: $.mergeObjects([ $.arrayElemAt(['$bookList', 0]), '$$ROOT' ]) + }) + .project({ + bookList: 0 + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 4, + "title": "novel 1", + "author": "author 1", + "time": 1564456048486, + "category": "novel", + "stock": 10, + "book": "novel 1", + "price": 30, + "quantity": 2 + }, + { + "_id": 5, + "category": "science", + "title": "science 1", + "author": "author 3", + "stock": 30, + "book": "science 1", + "price": 20, + "quantity": 1 + }, + { + "_id": 6, + "category": "science", + "author": "author 4", + "stock": 50, + "title": null + } +] +``` + +**指定多个连接条件** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":300,"quantity":20}, + {"_id":5,"book":"science 1","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"} +] +``` + +以下操作连接 `orders` 和 `books` 集合,要求两个条件: + +- orders 的 book 字段与 books 的 title 字段相等 +- books 的 stock 字段 大于或等于 orders 的 quantity 字段 + +```js +const db = cloud.database() +const dbCmd = db.command +const $ = dbCmd.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + order_book: '$book', + order_quantity: '$quantity' + }, + pipeline: $.pipeline() + .match(dbCmd.expr($.and([ + $.eq(['$title', '$$order_book']), + $.gte(['$stock', '$$order_quantity']) + ]))) + .project({ + _id: 0, + title: 1, + author: 1, + stock: 1 + }) + .done(), + as: 'bookList', + }) + .end() +``` + +结果: + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 300, + "quantity": 20, + "bookList": [] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + } + ] + } +] +``` + +**拼接被连接集合的子查询** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"} +] +``` + +在每条输出记录上加上一个数组字段,该数组字段的值是对 books 集合的一个查询语句的结果: + +```js +const db = cloud.database() +const $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + order_book: '$book', + order_quantity: '$quantity' + }, + pipeline: $.pipeline() + .match({ + author: 'author 3' + }) + .project({ + _id: 0, + title: 1, + author: 1, + stock: 1 + }) + .done(), + as: 'bookList', + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 30, + "quantity": 20, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + }, + { + "title": "science 2", + "author": "author 3", + "stock": 40 + } + ] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + }, + { + "title": "science 2", + "author": "author 3", + "stock": 40 + } + ] + } +] +``` + +**多表联表查询** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"book1","price":30,"quantity":2}, + {"_id":5,"book":"book2","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author1","title":"novel 1"}, + {"_id":"book2","author":"author2","title":"science 1"}, +] +``` + +`authors` 集合有以下记录: + +```js +[ + {"_id":"author1","name":"A1"}, + {"_id":"author2","author":"A2"} +] +``` + +如需orders关联books,book再关联authors查询,可以在pipeline内再使用lookup + +```js +const db = cloud.database() +const dbCmd = db.command +const $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + book_id: '$book' + }, + pipeline: $.pipeline() + .match( + dbCmd.expr($.eq(['$_id', '$$book_id'])) + ) + .lookup({ + from: 'authors', + let: { + author_id: '$author' + }, + pipeline: $.pipeline() + .match( + dbCmd.expr($.eq(['$_id', '$$author_id'])) + ) + .done(), + as: 'authorList' + }) + .done(), + as: 'bookList', + }) + .end() + +``` + +结果如下 + +```js +[ + { + "_id":4, + "book":"book1", + "price":30, + "quantity":2, + "bookList": [{ + "_id":"book1", + "author":"author1", + "title":"novel 1", + authorList: [{ + "_id":"author1", + "name":"A1" + }] + }] + }, + { + "_id":5, + "book":"book2", + "price":20, + "quantity":1, + "bookList": [{ + "_id":"book2", + "author":"author2", + "title":"science 1", + authorList: [{ + "_id":"author2", + "name":"A2" + }] + }] + } +] +``` + +## match + +聚合阶段。根据条件过滤文档,并且把符合条件的文档传递给下一个流水线阶段。 + +**API 说明** + +**match 的形式如下:** + +```js +match(<查询条件>) +``` + +查询条件与普通查询一致,可以用普通查询操作符,注意 match 阶段和其他聚合阶段不同,不可使用数据库运算方法,只能使用查询操作符。 + +```js +// 直接使用字符串 +match({ + name: 'Tony Stark' +}) +``` + +```js +// 使用操作符 +const dbCmd = db.command +match({ + age: dbCmd.gt(18) +}) +``` + +**示例** + +假设集合 articles 有如下记录: + +```js +{ "_id" : "1", "author" : "stark", "score" : 80 } +{ "_id" : "2", "author" : "stark", "score" : 85 } +{ "_id" : "3", "author" : "bob", "score" : 60 } +{ "_id" : "4", "author" : "li", "score" : 55 } +{ "_id" : "5", "author" : "jimmy", "score" : 60 } +{ "_id" : "6", "author" : "li", "score" : 94 } +{ "_id" : "7", "author" : "justan", "score" : 95 } +``` + +**匹配** + +下面是一个直接匹配的例子: + +```js +let res = await db.collection('articles') + .aggregate() + .match({ + author: 'stark' + }) + .end() +``` + +这里的代码尝试找到所有 author 字段是 stark 的文章,那么匹配如下: + +```js +{ "_id" : "1", "author" : "stark", "score" : 80 } +{ "_id" : "2", "author" : "stark", "score" : 85 } +``` + +**计数** + +match 过滤出文档后,还可以与其他流水线阶段配合使用。 + +比如下面这个例子,我们使用 group 进行搭配,计算 score 字段大于 80 的文档数量: + +```js +const dbCmd = db.command +const $ = dbCmd.aggregate +let res = await db.collection('articles') + .aggregate() + .match({ + score: dbCmd.gt(80) + }) + .group({ + _id: null, + count: $.sum(1) + }) + .end() +``` + +返回值如下: + +```js +{ "_id" : null, "count" : 3 } +``` + +## project + +聚合阶段。把指定的字段传递给下一个流水线,指定的字段可以是某个已经存在的字段,也可以是计算出来的新字段。 + +**API 说明** + +**project 的形式如下:** + +```js +project({ + <表达式> +}) +``` + +表达式可以有以下格式: + +|格式 |说明 | +|---- |---- | +|<字段>: <1 或 true> |指定包含某个已有字段 | +|_id: <0 或 false> |舍弃 _id 字段 | +|<字段>: <表达式> |加入一个新字段,或者重置某个已有字段 | +|<字段>: <0 或 false> |舍弃某个字段(如果你指定舍弃了某个非 _id 字段,那么在此次 project 中,你不能再使用其它表达式) | + +**指定包含字段** + +_id 字段是默认包含在输出中的,除此之外其他任何字段,如果想要在输出中体现的话,必须在 project 中指定; 如果指定包含一个尚不存在的字段,那么 project 会忽略这个字段,不会加入到输出的文档中; + +**指定排除字段** + +如果你在 project 中指定排除某个字段,那么其它字段都会体现在输出中; 如果指定排除的是非 _id 字段,那么在本次 project 中,不能再使用其它表达式; + +**加入新的字段或重置某个已有字段** + +你可以使用一些特殊的表达式加入新的字段,或重置某个已有字段。 + +**多层嵌套的字段** + +有时有些字段处于多层嵌套的底层,我们可以使用点记法: + +```js +"contact.phone.number": <1 or 0 or 表达式> +``` + +也可以直接使用嵌套的格式: + +```js +contact: { phone: { number: <1 or 0 or 表达式> } } +``` + +**示例** + +假设我们有一个 articles 集合,其中含有以下文档: + +```js +{ + "_id": 666, + "title": "This is title", + "author": "Nobody", + "isbn": "123456789", + "introduction": "......" +} +``` + +**指定包含某些字段** + +下面的代码使用 project,让输出只包含 _id、title 和 author 字段: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + title: 1, + author: 1 + }) + .end() +``` + +输出如下: + +```js +{ "_id" : 666, "title" : "This is title", "author" : "Nobody" } +``` + +**去除输出中的 _id 字段** + +_id 是默认包含在输出中的,如果不想要它,可以指定去除它: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + _id: 0, // 指定去除 _id 字段 + title: 1, + author: 1 + }) + .end() +``` + +输出如下: + +```js +{ "title" : "This is title", "author" : "Nobody" } +``` + +**去除某个非 _id 字段** + +我们还可以指定在输出中去掉某个非 _id 字段,这样其它字段都会被输出: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + isbn: 0, // 指定去除 isbn 字段 + }) + .end() +``` + +输出如下,相比输入,没有了 isbn 字段: + +```js +{ + "_id" : 666, + "title" : "This is title", + "author" : "Nobody", + "introduction": "......" +} +``` + +**加入计算出的新字段** + +假设我们有一个 students 集合,其中包含以下文档: + +```js +{ + "_id": 1, + "name": "小明", + "scores": { + "chinese": 80, + "math": 90, + "english": 70 + } +} +``` + +下面的代码,我们使用 project,在输出中加入了一个新的字段 totalScore: + +```js +const { sum } = db.command.aggregate +let res = await db.collection('students') + .aggregate() + .project({ + _id: 0, + name: 1, + totalScore: sum([ + "$scores.chinese", + "$scores.math", + "$scores.english" + ]) + }) + .end() +``` + +输出为: + +```js +{ "name": "小明", "totalScore": 240 } +``` + +**加入新的数组字段** + +假设我们有一个 points 集合,包含以下文档: + +```js +{ "_id": 1, "x": 1, "y": 1 } +{ "_id": 2, "x": 2, "y": 2 } +{ "_id": 3, "x": 3, "y": 3 } +``` + +下面的代码,我们使用 project,把 x 和 y 字段,放入到一个新的数组字段 coordinate 中: + +```js +let res = await db.collection('points') + .aggregate() + .project({ + coordinate: ["$x", "$y"] + }) + .end() +``` + +输出如下: + +```js +{ "_id": 1, "coordinate": [1, 1] } +{ "_id": 2, "coordinate": [2, 2] } +{ "_id": 3, "coordinate": [3, 3] } +``` + +## replaceRoot + +聚合阶段。指定一个已有字段作为输出的根节点,也可以指定一个计算出的新字段作为根节点。 + +**API 说明** + +**replaceRoot 使用形式如下:** + +```js +replaceRoot({ + newRoot: <表达式> +}) +``` + +表达式格式如下: + +|格式 |说明 | +|---- |---- | +|<字段名> |指定一个已有字段作为输出的根节点(如果字段不存在则报错) | +|<对象> |计算一个新字段,并且把这个新字段作为根节点 | + +**示例** + +**使用已有字段作为根节点** + +假设我们有一个 schools 集合,内容如下: + +```js +{ + "_id": 1, + "name": "SFLS", + "teachers": { + "chinese": 22, + "math": 18, + "english": 21, + "other": 123 + } +} +``` + +下面的代码使用 replaceRoot,把 teachers 字段作为根节点输出: + +```js +let res = await db.collection('schools') + .aggregate() + .replaceRoot({ + newRoot: '$teachers' + }) + .end() +``` + +输出如下: + +```js +{ + "chinese": 22, + "math": 18, + "english": 21, + "other": 123 +} +``` + +**使用计算出的新字段作为根节点** + +假设我们有一个 roles 集合,内容如下: + +```js +{ "_id": 1, "first_name": "四郎", "last_name": "黄" } +{ "_id": 2, "first_name": "邦德", "last_name": "马" } +{ "_id": 3, "first_name": "牧之", "last_name": "张" } +``` + +下面的代码使用 replaceRoot,把 first_name 和 last_name 拼在一起: + +```js +const { concat } = db.command.aggregate +let res = await db.collection('roles') + .aggregate() + .replaceRoot({ + newRoot: { + full_name: concat(['$last_name', '$first_name']) + } + }) + .end() +``` + +输出如下: + +```js +{ "full_name": "黄四郎" } +{ "full_name": "马邦德" } +{ "full_name": "张牧之" } +``` + +## sample + +**注意** + +- 此方法在数据量大的集合高频调用时可能会导致响应缓慢 +- 腾讯云数据库操作有默认20的limit,如需使用sample返回20条以上数据,请额外指定limit,例:`sample({size:40}).limit(40)` + +聚合阶段。随机从文档中选取指定数量的记录。 + +**API 说明** + +**sample 的形式如下:** + +```js +sample({ + size: <正整数> +}) +``` + +请注意:size 是正整数,否则会出错。 + +**示例** + +假设文档 users 有以下记录: + +```js +{ "name": "a" } +{ "name": "b" } +``` + +**随机选取** + +如果现在进行抽奖活动,需要选出一名幸运用户。那么 sample 的调用方式如下: + +```js +let res = await db.collection('users') + .aggregate() + .sample({ + size: 1 + }) + .end() +``` + +返回了随机选中的一个用户对应的记录,结果如下: + +```js +{ "_id": "696529e4-7e82-4e7f-812e-5144714edff6", "name": "b" } +``` + +## skip + +聚合阶段。指定一个正整数,跳过对应数量的文档,输出剩下的文档。 + +**示例** + +```js +let res = await db.collection('users') + .aggregate() + .skip(5) + .end() +``` + +这段代码会跳过查找到的前 5 个文档,并且把剩余的文档输出。 + +## sort + +聚合阶段。根据指定的字段,对输入的文档进行排序。 + +**API 说明** + +**形式如下:** + +```js +sort({ + <字段名 1>: <排序规则>, + <字段名 2>: <排序规则>, +}) +``` + +<排序规则>可以是以下取值: + +- 1 代表升序排列(从小到大); +- -1 代表降序排列(从大到小); + +**示例** + +升序/降序排列 + +假设我们有集合 articles,其中包含数据如下: + +```js +{ "_id": "1", "author": "stark", "score": 80, "age": 18 } +{ "_id": "2", "author": "bob", "score": 60, "age": 18 } +{ "_id": "3", "author": "li", "score": 55, "age": 19 } +{ "_id": "4", "author": "jimmy", "score": 60, "age": 22 } +{ "_id": "5", "author": "justan", "score": 95, "age": 33 } +``` + +```js +let res = await db.collection('articles') + .aggregate() + .sort({ + age: -1, + score: -1 + }) + .end() +``` + +上面的代码在 students 集合中进行聚合搜索,并且将结果排序,首先根据 age 字段降序排列,然后再根据 score 字段进行降序排列。 + +输出结果如下: + +```js +{ "_id": "5", "author": "justan", "score": 95, "age": 33 } +{ "_id": "4", "author": "jimmy", "score": 60, "age": 22 } +{ "_id": "3", "author": "li", "score": 55, "age": 19 } +{ "_id": "1", "author": "stark", "score": 80, "age": 18 } +{ "_id": "2", "author": "bob", "score": 60, "age": 18 } +``` + +## sortByCount + +聚合阶段。根据传入的表达式,将传入的集合进行分组(group)。然后计算不同组的数量,并且将这些组按照它们的数量进行排序,返回排序后的结果。 + +**API 说明** + +**sortByCount 的调用方式如下:** + +```js +sortByCount(<表达式>) +``` + +表达式的形式是:$ + 指定字段。请注意:不要漏写 $ 符号。 + +**示例** + +**统计基础类型** + +假设集合 passages 的记录如下: + +```js +{ "category": "Web" } +{ "category": "Web" } +{ "category": "Life" } +``` + +下面的代码就可以统计文章的分类信息,并且计算每个分类的数量。即对 category 字段执行 sortByCount 聚合操作。 + +```js +let res = await db.collection('passages') + .aggregate() + .sortByCount('$category') + .end() +``` + +返回的结果如下所示:Web 分类下有2篇文章,Life 分类下有1篇文章。 + +```js +{ "_id": "Web", "count": 2 } +{ "_id": "Life", "count": 1 } +``` + +**解构数组类型** + +假设集合 passages 的记录如下:tags 字段对应的值是数组类型。 + +```js +{ "tags": [ "JavaScript", "C#" ] } +{ "tags": [ "Go", "C#" ] } +{ "tags": [ "Go", "Python", "JavaScript" ] } +``` + +如何统计文章的标签信息,并且计算每个标签的数量?因为 tags 字段对应的数组,所以需要借助 unwind 操作解构 tags 字段,然后再调用 sortByCount。 + +下面的代码实现了这个功能: + +```js +let res = await db.collection('passages') + .aggregate() + .unwind(`$tags`) + .sortByCount(`$tags`) + .end() +``` + +返回的结果如下所示: + +```js +{ "_id": "Go", "count": 2 } +{ "_id": "C#", "count": 2 } +{ "_id": "JavaScript", "count": 2 } +{ "_id": "Python", "count": 1 } +``` + +## unwind + +聚合阶段。使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 + +**API 说明** + +使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 + +**unwind 有两种使用形式:** + +**参数是一个字段名** + +```js +unwind(<字段名>) +``` + +**参数是一个对象** + +```js +unwind({ + path: <字段名>, + includeArrayIndex: , + preserveNullAndEmptyArrays: +}) +``` + +|字段 |类型 |说明 | +|---- |---- |---- | +|path |string |想要拆分的数组的字段名,需要以 $ 开头。 | +|includeArrayIndex |string |可选项,传入一个新的字段名,数组索引会保存在这个新的字段上。新的字段名不能以 $ 开头。 | +|preserveNullAndEmptyArrays |boolean|如果为 true,那么在 path 对应的字段为 null、空数组或者这个字段不存在时,依然会输出这个文档;如果为 false,unwind 将不会输出这些文档。默认为 false。| + +**示例** + +**拆分数组** + +假设我们有一个 products 集合,包含数据如下: + +```js +{ "_id": "1", "product": "tshirt", "size": ["S", "M", "L"] } +{ "_id": "2", "product": "pants", "size": [] } +{ "_id": "3", "product": "socks", "size": null } +{ "_id": "4", "product": "trousers", "size": ["S"] } +{ "_id": "5", "product": "sweater", "size": ["M", "L"] } +``` + +我们根据 size 字段对这些文档进行拆分 + +```js +db.collection('products') + .aggregate() + .unwind('$size') + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S" } +{ "_id": "1", "product": "tshirt", "size": "M" } +{ "_id": "1", "product": "tshirt", "size": "L" } +{ "_id": "4", "product": "trousers", "size": "S" } +{ "_id": "5", "product": "sweater", "size": "M" } +{ "_id": "5", "product": "sweater", "size": "L" } +``` + +**拆分后,保留原数组的索引** + +我们根据 size 字段对文档进行拆分后,想要保留原数组索引在新的 index 字段中。 + +```js +let res = await db.collection('products') + .aggregate() + .unwind({ + path: '$size', + includeArrayIndex: 'index' + }) + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S", "index": 0 } +{ "_id": "1", "product": "tshirt", "size": "M", "index": 1 } +{ "_id": "1", "product": "tshirt", "size": "L", "index": 2 } +{ "_id": "4", "product": "trousers", "size": "S", "index": 0 } +{ "_id": "5", "product": "sweater", "size": "M", "index": 0 } +{ "_id": "5", "product": "sweater", "size": "L", "index": 1 } +``` + +**保留字段为空的文档** + +注意到我们的集合中有两行特殊的空值数据: + +```js +... +{ "_id": "2", "product": "pants", "size": [] } +{ "_id": "3", "product": "socks", "size": null } +... +``` + +如果想要在输出中保留 size 为空数组、null,或者 size 字段不存在的文档,可以使用 preserveNullAndEmptyArrays 参数 + +```js +let res = await db.collection('products') + .aggregate() + .unwind({ + path: '$size', + preserveNullAndEmptyArrays: true + }) + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S" } +{ "_id": "1", "product": "tshirt", "size": "M" } +{ "_id": "1", "product": "tshirt", "size": "L" } +{ "_id": "2", "product": "pants", "size": null } +{ "_id": "3", "product": "socks", "size": null } +{ "_id": "4", "product": "trousers", "size": "S" } +{ "_id": "5", "product": "sweater", "size": "M" } +{ "_id": "5", "product": "sweater", "size": "L" } +``` + +## end + +标志聚合操作定义完成,发起实际聚合操作 + +**返回值** + +Promise.<Object> + +|属性 |类型 |说明 | +|--- |--- |--- | +|list |Array.<any>|聚合结果列表 | + +**示例代码** + +```js +const $ = db.command.aggregate +let res = await db.collection('books').aggregate() + .group({ + // 按 category 字段分组 + _id: '$category', + // 让输出的每组记录有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值 + avgSales: $.avg('$sales') + }) + .end() +``` diff --git a/docs_deprecated/guide/db/command.md b/docs_deprecated/guide/db/command.md new file mode 100644 index 0000000000..389e3a3842 --- /dev/null +++ b/docs_deprecated/guide/db/command.md @@ -0,0 +1,1132 @@ +--- +title: 数据库操作符 +--- + +# {{ $frontmatter.title }} + +Laf 云函数支持多种不同的数据库操作符,用于执行查询、更新、删除等操作。 + +## 初始化操作符 + +```typescript +const db = cloud.database() +const _ = db.command +// 后续操作 用 _ 即可 +``` + +## 查询·逻辑操作符 + +### and + +查询操作符,用于表示逻辑 "与" 的关系,表示需同时满足多个查询筛选条件 + +#### 使用说明 + + `and` 有两种使用情况: + +**1. 用在根查询条件** + + 此时需传入多个查询条件,表示需同时满足提供的多个完整查询条件 + +```js +const _ = db.command +let res = await db.collection('todo').where(_.and([ + { + progress: _.gt(50) + }, + { + tags: 'cloud' + } +])).get() +``` + +但以上用 `and` 组成的查询条件是不必要的,因为传入的对象的各字段隐式组成了 "与" 的关系,上述条件等价于下方更简洁的写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50), + tags: 'cloud' +}).get() +``` + +通常需要显示使用 `and` 是用在有跨字段或操作的时候 + +**2. 用在字段查询条件** + + 需传入多个查询操作符或常量,表示字段需满足或匹配给定的条件。 + + 如以下用前置写法的方式表示 "progress 字段值大于 50 且小于 100" + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.and(_.gt(50), _.lt(100)) +}).get() +``` + +还可以用后置写法的方式表示同样的条件: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50).and(_.lt(100)) +}).get() +``` + +注意 `Command` 默认也可以直接链式调用其他 `Command`,默认表示多个 `Command` 的与操作,因此上述代码还可以精简为: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50).lt(100) +}).get() +``` + +### or + +查询操作符,用于表示逻辑 "或" 的关系,表示需同时满足多个查询筛选条件。或指令有两种用法,一是可以进行字段值的 "或" 操作,二是也可以进行跨字段的“或”操作。 + +#### 字段值的或操作 + + 字段值的“或”操作指的是指定一个字段值为多个值之一即可。 + + 如筛选出进度大于 80 或小于 20 的 todo: + + 流式写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(80).or(_.lt(20)) +}).get() +``` + +前置写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.or(_.gt(80), _.lt(20)) +}).get() +``` + +前置写法也可接收一个数组: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.or([_.gt(80), _.lt(20)]) +}).get() +``` + +#### 跨字段的或操作 + + 跨字段的“或”操作指条件“或”,相当于可以传入多个 where 语句,满足其中一个即可。 + + 如筛选出进度大于 80 或已标为已完成的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where(_.or([ + { + progress: _.gt(80) + }, + { + done: true + } +])).get() +``` + +### not + +查询操作符,用于表示逻辑 "非" 的关系,表示需不满足指定的条件。 + +#### 示例 + + 如筛选出进度不等于 100 的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.not(_.eq(100)) +}).get() +``` + +`not` 也可搭配其他逻辑指令使用,包括 `and`, `or`, `nor`, `not`,如 `or`: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.not(_.or([_.lt(50), _.eq(100)])) +}).get() +``` + +### nor + +查询操作符,用于表示逻辑 "都不" 的关系,表示需不满足指定的所有条件。如果记录中没有对应的字段,则默认满足条件。 + +#### 示例 1 + + 筛选出进度既不小于 20 又不大于 80 的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.nor([_.lt(20), _.gt(80)]) +}).get() +``` + +以上同时会筛选出不存在 `progress` 字段的记录,如果要要求 `progress` 字段存在,可以用 `exists` 指令: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.exists(true).nor([_.lt(20), _.gt(80)]) + // 等价于以下非链式调用的写法: + // progress: _.exists(true).and(_.nor([_.lt(20), _.gt(80)])) +}).get() +``` + +#### 示例 2 + + 筛选出 `progress` 不小于 20 且 `tags` 数组不包含 `miniprogram` 字符串的记录: + +```js +const _ = db.command +db.collection('todo').where(_.nor([{ + progress: _.lt(20), +}, { + tags: 'miniprogram', +}])).get() +``` + +以上会筛选出满足以下条件之一的记录: + +1. `progress` 不小于 20 且 `tags` 数组不包含 `miniprogram` 字符串 3. `progress` 不小于 20 且 `tags` 字段不存在 5. `progress` 字段不存在 且 `tags` 数组不包含 `miniprogram` 字符串 7. `progress` 不小于 20 且 `tags` 字段不存在 + 如果要求 `progress` 和 `tags` 字段存在,可以用 `exists` 指令: + +```js +const _ = db.command +let res = await db.collection('todo').where( + _.nor([{ + progress: _.lt(20), + }, { + tags: 'miniprogram', + }]) + .and({ + progress: _.exists(true), + tags: _.exists(true), + }) +).get() +``` + +## 查询·比较操作符 + +### eq + +查询筛选条件,表示字段等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`, `Date`。 + +#### 使用说明 + + 比如筛选出所有自己发表的文章,除了用传对象的方式: + +```js +const openID = 'xxx' +let res = await db.collection('articles').where({ + _openid: openID +}).get() +``` + +还可以用指令: + +```js +const _ = db.command +const openID = 'xxx' +let res = await db.collection('articles').where({ + _openid: _.eq(openid) +}).get() +``` + +注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如: + +```js +// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN' +let res = await db.collection('articles').where({ + stat: { + publishYear: 2018, + language: 'zh-CN' + } +}).get() +// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' } +const _ = db.command +let res = await db.collection('articles').where({ + stat: _.eq({ + publishYear: 2018, + language: 'zh-CN' + }) +}).get() +``` + +### neq + +查询筛选条件,表示字段不等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`, `Date`。 + +#### 使用说明 + + 表示字段不等于某个值,和 [eq](#eq) 相反 + +### lt + +查询筛选操作符,表示需小于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度小于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.lt(50) +}) +.get() +``` + +### lte + +查询筛选操作符,表示需小于或等于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度小于或等于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.lte(50) +}) +.get() +``` + +### gt + +查询筛选操作符,表示需大于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度大于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.gt(50) +}) +.get() +``` + +### gte + +查询筛选操作符,表示需大于或等于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度大于或等于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.gte(50) +}) +.get() +``` + +### in + +查询筛选操作符,表示要求值在给定的数组内。 + +#### 示例代码 + + 找出进度为 0 或 100 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.in([0, 100]) +}) +.get() +``` + +### nin + +查询筛选操作符,表示要求值不在给定的数组内。 + +#### 示例代码 + + 找出进度不是 0 或 100 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.nin([0, 100]) +}) +.get() +``` + +## 查询·字段操作符 + +### exists + +判断字段是否存在,true 为存在,false 为不存在 + +#### 示例代码 + + 找出存在 tags 字段的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + tags: _.exists(true) +}) +.get() +``` + +### mod + +查询筛选操作符,给定除数 divisor 和余数 remainder,要求字段作为被除数时 value % divisor = remainder。 + +#### 示例代码 + + 找出进度为 10 的倍数的字段的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.mod(10, 0) +}) +.get() +``` + +## 查询·数组操作符 + +### all + +数组查询操作符。用于数组字段的查询筛选条件,要求数组字段中包含给定数组的所有元素。 + +#### 示例代码 1:普通数组 + + 找出 tags 数组字段同时包含 cloud 和 database 的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + tags: _.all(['cloud', 'database']) +}) +.get() +``` + +#### 示例代码 2:对象数组 + + 如果数组元素是对象,则可以用 `_.elemMatch` 匹配对象的部分字段 + + 假设有字段 `places` 定义如下: + +```js +{ + "type": string + "area": number + "age": number +} +``` + +找出数组字段中至少同时包含一个满足“area 大于 100 且 age 小于 2”的元素和一个满足“type 为 mall 且 age 大于 5”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.all([ + _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }), + _.elemMatch({ + type: 'mall', + age: _.gt(5), + }), + ]), +}) +.get() +``` + +### elemMatch + +用于数组字段的查询筛选条件,要求数组中包含至少一个满足 `elemMatch` 给定的所有条件的元素 + +#### 示例代码:数组是对象数组的情况 + + 假设集合示例数据如下: + +```js +{ + "_id": "a0", + "city": "x0", + "places": [{ + "type": "garden", + "area": 300, + "age": 1 + }, { + "type": "theatre", + "area": 50, + "age": 15 + }] +} +``` + +找出 `places` 数组字段中至少同时包含一个满足“area 大于 100 且 age 小于 2”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }) +}) +.get() +``` + +*注意**:如果不使用 `elemMatch` 而直接如下指定条件,则表示的是 `places` 数组字段中至少有一个元素的 `area` 字段大于 100 且 `places` 数组字段中至少有一个元素的 `age` 字段小于 2: + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: { + area: _.gt(100), + age: _.lt(2), + } +}) +.get() +``` + +#### 示例代码:数组元素都是普通数据类型的情况 + + 假设集合示例数据如下: + +```js +{ + "_id": "a0", + "scores": [60, 80, 90] +} +``` + +找出 `scores` 数组字段中至少同时包含一个满足“大于 80 且小于 100”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + scores: _.elemMatch(_.gt(80).lt(100)) +}) +.get() +``` + +### size + +更新操作符,用于数组字段的查询筛选条件,要求数组长度为给定值 + +#### 示例 + + 找出 tags 数组字段长度为 2 的所有记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.size(2) +}) +.get() +``` + +## 查询·地理位置操作符 + +### geoNear + +按从近到远的顺序,找出字段值在给定点的附近的记录。 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码 + + 找出离给定位置 1 公里到 5 公里范围内的记录 + +```js +const _ = db.command +let res = await db.collection('restaurants').where({ + location: _.geoNear({ + geometry: new db.Geo.Point(113.323809, 23.097732), + minDistance: 1000, + maxDistance: 5000, + }) +}).get() +``` + +### geoWithin + +找出字段值在指定区域内的记录,无排序。指定的区域必须是多边形(Polygon)或多边形集合(MultiPolygon)。 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码 1:给定多边形 + +```js +const _ = db.command +const { Point, LineString, Polygon } = db.Geo +let res = await .collection('restaurants').where({ + location: _.geoWithin({ + geometry: new Polygon([ + new LineString([ + new Point(0, 0), + new Point(3, 2), + new Point(2, 3), + new Point(0, 0) + ]) + ]), + }) +}).get() +``` + +#### 示例代码 2:给定圆形 + + 可以不用 `geometry` 而用 `centerSphere` 构建一个圆形。 + + `centerSphere` 对应的值的定义是:`[ [经度, 纬度], 半径 ]` + + 半径需以弧度计,比如需要 10km 的半径,则用距离除以地球半径 6378.1km 得出的数字。 + +```js +const _ = db.command +let res = await db.collection('restaurants').where({ + location: _.geoWithin({ + centerSphere: [ + [-88, 30], + 10 / 6378.1, + ] + }) +}).get() +``` + +### geoIntersects + +找出给定的地理位置图形相交的记录 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码:找出和一个多边形相交的记录 + +```js +const _ = db.command +const { Point, LineString, Polygon } = db.Geo +let res = await db.collection('restaurants').where({ + location: _.geoIntersects({ + geometry: new Polygon([ + new LineString([ + new Point(0, 0), + new Point(3, 2), + new Point(2, 3), + new Point(0, 0) + ]) + ]), + }) +}).get() +``` + +## 查询·表达式操作符 + +### expr + +查询操作符,用于在查询语句中使用聚合表达式,方法接收一个参数,该参数必须为聚合表达式 + +#### 使用说明 + +1. `expr` 可用于在聚合 `match`流水线阶段中引入聚合表达式 3. 如果聚合 `match`阶段是在 `lookup`) 阶段内,此时的 `expr` 表达式内可使用 `lookup` 中使用 `let` 参数定义的变量,具体示例可见 `lookup` 的 `指定多个连接条件` 例子 5. `expr` 可用在普通查询语句(`where`)中引入聚合表达式 + +#### 示例代码 1:比较同一个记录中的两个字段 + + 假设 `items` 集合的数据结构如下: + +```js +{ + "_id": string, + "inStock": number, // 库存量 + "ordered": number // 被订量 +} +``` + +找出被订量大于库存量的记录: + +```js +const _ = db.command +const $ = _.aggregate +let res = await db.collection('items').where(_.expr($.gt(['$ordered', '$inStock']))).get() +``` + +#### 示例代码 2:与条件语句组合使用 + + 假设 `items` 集合的数据结构如下: + +```json +{ + "_id": string, + "price": number +} +``` + +假设价格小于等于 10 的打 8 折,大于 10 的打 5 折,让数据库查询返回打折后价格小于等于 8 的记录: + +```js +const _ = db.command +const $ = _.aggregate +let res = await db.collection('items').where( + _.expr( + $.lt([ + $.cond({ + if: $.gte(['$price', 10]), + then: $.multiply(['$price', '0.5']), + else: $.multiply(['$price', '0.8']), + }) + , + 8 + ]) +)).get() +``` + +## 更新·字段操作符 + +### set + +更新操作符,用于设定字段等于指定值。 + +#### 使用说明 + + 这种方法相比传入纯 JS 对象的好处是能够指定字段等于一个对象 + +#### 示例 + +```js +// 以下方法只会更新 style.color 为 red,而不是将 style 更新为 { color: 'red' },即不影响 style 中的其他字段 +let res = await db.collection('todos').doc('doc-id').update({ + style: { + color: 'red' + } +}) + +// 以下方法更新 style 为 { color: 'red', size: 'large' } +let res = await db.collection('todos').doc('doc-id').update({ + style: _.set({ + color: 'red', + size: 'large' + }) +}) +``` + +### remove + +更新操作符,用于表示删除某个字段。 + +#### 示例代码 + + 删除 style 字段: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + style: _.remove() +}) +``` + +### inc + +更新操作符,原子操作,用于指示字段自增 + +#### 原子自增 + + 多个用户同时写,对数据库来说都是将字段自增,不会有后来者覆写前者的情况 + +#### 示例代码 + + 将一个 todo 的进度自增 10: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + progress: _.inc(10) +}) +``` + +### mul + +更新操作符,原子操作,用于指示字段自乘某个值 + +#### 原子自乘 + + 多个用户同时写,对数据库来说都是将字段自乘,不会有后来者覆写前者的情况 + +#### 示例代码 + + 将一个 todo 的进度自乘 10: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + progress: _.mul(10) +}) +``` + +### min + +更新操作符,给定一个值,只有该值小于字段当前值才进行更新。 + +#### 示例代码 + + 如果字段 progress > 50,则更新到 50 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.min(50) +}) +``` + +### max + +更新操作符,给定一个值,只有该值大于字段当前值才进行更新。 + +#### 示例代码 + + 如果字段 progress < 50,则更新到 50 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.max(50) +}) +``` + +### rename + +更新操作符,字段重命名。如果需要对嵌套深层的字段做重命名,需要用点路径表示法。不能对嵌套在数组里的对象的字段进行重命名。 + +#### 示例 1:重命名顶层字段 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.rename('totalProgress') +}) +``` + +#### 示例 2:重命名嵌套字段 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + someObject: { + someField: _.rename('someObject.renamedField') + } +}) +``` + +或: + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + 'someObject.someField': _.rename('someObject.renamedField') +}) +``` + +## 更新·数组操作符 + +### push + +数组更新操作符。对一个值为数组的字段,往数组添加一个或多个值。或字段原为空,则创建该字段并设数组为传入值。 + +#### 参数说明 + +**position 说明** + + 要求必须同时有 `each` 参数存在。 + + 非负数代表从数组开始位置数的位置,从 0 开始计。如果数值大于等于数组长度,则视为在尾部添加。负数代表从数组尾部倒数的位置,比如 -1 就代表倒数第二个元素的位置。如果负数数值的绝对值大于等于数组长度,则视为从数组头部添加。 + +**sort 说明** + + 要求必须同时有 `each` 参数存在。给定 1 代表升序,-1 代表降序。 + + 如果数组元素是记录,则用 `{ <字段>: 1 | -1 }` 的格式表示根据记录中的什么字段做升降序排序。 + +**slice** 说明** + + 要求必须同时有 `each` 参数存在 + +|值 |说明 | +|:-: |:-: | +|0 |将字段更新为空数组 | +|正数 |数组只保留前 n 个元素| +|负数 |数组只保留后 n 个元素| + +#### 示例 1:尾部添加元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push(['mini-program', 'cloud']) +}) +``` + +#### 示例 2:从第二个位置开始插入 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + position: 1, + }) +}) +``` + +#### 示例 3:排序 + +插入后对整个数组做排序 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + sort: 1, + }) +}) +``` + +不插入,只对数组做排序 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: [], + sort: 1, + }) +}) +``` + +如果字段是对象数组,可以如下根据元素对象里的字段进行排序: + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: [ + { name: 'miniprogram', weight: 8 }, + { name: 'cloud', weight: 6 }, + ], + sort: { + weight: 1, + }, + }) +}) +``` + +#### 示例 4:截断保留 + + 插入后只保留后 2 个元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + slice: -2, + }) +}) +``` + +#### 示例 5:在指定位置插入、然后排序、最后只保留前 2 个元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + position: 1, + slice: 2, + sort: 1, + }) +}) +``` + +### pop + +数组更新操作符,对一个值为数组的字段,将数组尾部元素删除,仅可以删除末尾一个 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pop() +}) +``` + +### unshift + +数组更新操作符,对一个值为数组的字段,往数组头部添加一个或多个值。或字段原为空,则创建该字段并设数组为传入值。 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.unshift(['mini-program', 'cloud']) +}) +``` + +### shift + +数组更新操作符,对一个值为数组的字段,将数组头部元素删除。 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.shift() +}) +``` + +### pull + +数组更新操作符。给定一个值或一个查询条件,将数组中所有匹配给定值或查询条件的元素都移除掉。 + +#### 示例代码 1:根据常量匹配移除 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pull('database') +}) +``` + +#### 示例代码 2:根据查询条件匹配移除 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pull(_.in(['database', 'cloud'])) +}) +``` + +#### 示例代码 3:对象数组时,根据查询条件匹配移除 + + 假设有字段 `places` 数组中的元素结构如下 + +```json +{ + "type": string + "area": number + "age": number +} +``` + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + places: _.pull({ + area: _.gt(100), + age: _.lt(2), + }) +}) +``` + +#### 示例代码 4:有嵌套对象的对象数组时,根据查询条件匹配移除 + + 假设有字段 `cities` 数组中的元素结构如下 + +```js +{ + "name": string + "places": Place[] +} +``` + +`Place` 结构如下: + +```js +{ + "type": string + "area": number + "age": number +} +``` + +可用 `elemMatch` 匹配嵌套在对象数组里面的对象数组字段 places + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + cities: _.pull({ + places: _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }) + }) +}) +``` + +### pullAll + +数组更新操作符。给定一个值或一个查询条件,将数组中所有匹配给定值的元素都移除掉。跟 `pull` 的差别在于只能指定常量值、传入的是数组。 + +#### 示例代码:根据常量匹配移除 + + 从 tags 中移除所有 database 和 cloud 字符串 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pullAll(['database', 'cloud']) +}) +``` + +### addToSet + +数组更新操作符。原子操作。给定一个或多个元素,除非数组中已存在该元素,否则添加进数组。 + +#### 示例代码 1:添加一个元素 + + 如果 tags 数组中不包含 database,添加进去 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.addToSet('database') +}) +``` + +#### 示例代码 2:添加多个元素 + +需传入一个对象,其中有一个字段 `each`,其值为数组,每个元素就是要添加的元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.addToSet({ + $each: ['database', 'cloud'] + }) +}) +``` diff --git a/docs_deprecated/guide/db/del.md b/docs_deprecated/guide/db/del.md new file mode 100644 index 0000000000..ce65d21a24 --- /dev/null +++ b/docs_deprecated/guide/db/del.md @@ -0,0 +1,37 @@ +--- +title: 删除数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库删除数据,包括删除文档和删除集合。同时支持单个删除和批量删除。 + +## 通过指定条件删除单个文档 + +我们可以配合 `where` 以及各种高级指令来使用 `remove`。 + +```js + // 删除 user 集合中,name 为 jack 的一条记录 + const res = await db.collection('user').where({ name: "jack" }).remove() + console.log(res) +``` + +## 通过指定条件批量删除文档 + +上面示例执行一次只能删除一条数据,如果想要批量删除要在 `remove()` 中添加 `{multi: true}` + +```js +// 删除 user 表中所有 name 为 jack 的记录 +await db.collection('user') +.where({ name: "jack" }) +.remove({ multi: true }) +``` + +## 清空集合(危险操作) + +如果我们想删除一个集合中的所有数据,可以这样操作。 + +```js +// 清空 user 集合 +await db.collection('user').remove({ multi: true }) +``` diff --git a/docs/guide/db/find.md b/docs_deprecated/guide/db/find.md similarity index 100% rename from docs/guide/db/find.md rename to docs_deprecated/guide/db/find.md diff --git a/docs_deprecated/guide/db/geo.md b/docs_deprecated/guide/db/geo.md new file mode 100644 index 0000000000..a9dd4ee202 --- /dev/null +++ b/docs_deprecated/guide/db/geo.md @@ -0,0 +1,202 @@ +--- +title: 地理信息 API +--- + +# {{ $frontmatter.title }} + +注意:**如果需要对类型为地理位置的字段进行搜索,一定要建立地理位置索引**。 + +## GEO 数据类型 + +### Point + +用于表示地理位置点,用经纬度唯一标记一个点,这是一个特殊的数据存储类型。 + +签名:`Point(longitude: number, latitude: number)` + +示例: + +```js +new db.Geo.Point(longitude, latitude); +``` + +### LineString + +用于表示地理路径,是由两个或者更多的 `Point` 组成的线段。 + +签名:`LineString(points: Point[])` + +示例: + +```js +new db.Geo.LineString([ + new db.Geo.Point(lngA, latA), + new db.Geo.Point(lngB, latB), + // ... +]); +``` + +### Polygon + +用于表示地理上的一个多边形(有洞或无洞均可),它是由一个或多个**闭环** `LineString` 组成的几何图形。 + +由一个环组成的 `Polygon` 是没有洞的多边形,由多个环组成的是有洞的多边形。对由多个环(`LineString`)组成的多边形(`Polygon`),第一个环是外环,所有其他环是内环(洞)。 + +签名:`Polygon(lines: LineString[])` + +示例: + +```js +new db.Geo.Polygon([ + new db.Geo.LineString(...), + new db.Geo.LineString(...), + // ... +]) +``` + +### MultiPoint + +用于表示多个点 `Point` 的集合。 + +签名:`MultiPoint(points: Point[])` + +示例: + +```js +new db.Geo.MultiPoint([ + new db.Geo.Point(lngA, latA), + new db.Geo.Point(lngB, latB), + // ... +]); +``` + +### MultiLineString + +用于表示多个地理路径 `LineString` 的集合。 + +签名:`MultiLineString(lines: LineString[])` + +示例: + +```js +new db.Geo.MultiLineString([ + new db.Geo.LineString(...), + new db.Geo.LineString(...), + // ... +]) +``` + +### MultiPolygon + +用于表示多个地理多边形 `Polygon` 的集合。 + +签名:`MultiPolygon(polygons: Polygon[])` + +示例: + +```js +new db.Geo.MultiPolygon([ + new db.Geo.Polygon(...), + new db.Geo.Polygon(...), + // ... +]) +``` + +## GEO 操作符 + +### geoNear + +按从近到远的顺序,找出字段值在给定点的附近的记录。 + +签名: + +```js +db.command.geoNear(options: IOptions) + +interface IOptions { + geometry: Point // 点的地理位置 + maxDistance?: number // 选填,最大距离,米为单位 + minDistance?: number // 选填,最小距离,米为单位 +} +``` + +示例: + +```js +db.collection("user").where({ + location: db.command.geoNear({ + geometry: new db.Geo.Point(lngA, latA), + maxDistance: 1000, + minDistance: 0, + }), +}); +``` + +### geoWithin + +找出字段值在指定 Polygon / MultiPolygon 内的记录,无排序 + +签名: + +```js +db.command.geoWithin(IOptions); + +interface IOptions { + geometry: Polygon | MultiPolygon; // 地理位置 +} +``` + +示例: + +```js +// 一个闭合的区域 +const area = new Polygon([ + new LineString([ + new Point(lngA, latA), + new Point(lngB, latB), + new Point(lngC, latC), + new Point(lngA, latA), + ]), +]); + +// 搜索 location 字段在这个区域中的 user +db.collection("user").where({ + location: db.command.geoWithin({ + geometry: area, + }), +}); +``` + +### geoIntersects + +找出字段值和给定的地理位置图形相交的记录 + +签名: + +```js +db.command.geoIntersects(IOptions); + +interface IOptions { + geometry: + | Point + | LineString + | MultiPoint + | MultiLineString + | Polygon + | MultiPolygon; // 地理位置 +} +``` + +示例: + +```js +// 一条路径 +const line = new LineString([new Point(lngA, latA), new Point(lngB, latB)]); + +// 搜索 location 与这条路径相交的 user +db.collection("user").where({ + location: db.command.geoIntersects({ + geometry: line, + }), +}); +``` diff --git a/docs/guide/db/index.md b/docs_deprecated/guide/db/index.md similarity index 100% rename from docs/guide/db/index.md rename to docs_deprecated/guide/db/index.md diff --git a/docs_deprecated/guide/db/operator.md b/docs_deprecated/guide/db/operator.md new file mode 100644 index 0000000000..bf5eb14017 --- /dev/null +++ b/docs_deprecated/guide/db/operator.md @@ -0,0 +1,4663 @@ +--- +title: 数据库运算 +--- + +# {{ $frontmatter.title }} + +**等同于 mongoDB 聚合操作符概念** + +## 算术操作符 + +### abs + + + +返回一个数字的绝对值。 + +#### API 说明 + +语法如下: + +```typescript +db.command.aggregate.abs() +``` + +`abs` 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。 + + 如果表达式解析为 `null` 或者指向一个不存在的字段,则 `abs` 的结果是 `null`。如果值解析为 `NaN`,则结果是 `NaN`。 + +#### 示例代码 + + 假设集合 `ratings` 有如下记录: + +```typescript +{ _id: 1, start: 5, end: 8 } +{ _id: 2, start: 4, end: 4 } +{ _id: 3, start: 9, end: 7 } +{ _id: 4, start: 6, end: 7 } +``` + +··· +可以用如下方式求得各个记录的 `start` 和 `end` 之间的绝对差异大小: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('ratings').aggregate() + .project({ + delta: $.abs($.subtract(['$start', '$end'])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id" : 1, "delta" : 3 } +{ "_id" : 2, "delta" : 0 } +{ "_id" : 3, "delta" : 2 } +{ "_id" : 4, "delta" : 1 } +``` + +### add + + + +将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.add([<表达式1>, <表达式2>, ...]) +``` + +表达式可以是形如 `$ + 指定字段`,也可以是普通字符串。只要能够被解析成字符串即可。 + +#### 示例代码 + + 假设集合 `staff` 有如下记录: + +```typescript +{ _id: 1, department: "x", sales: 5, engineer: 10, lastUpdate: ISODate("2019-05-01T00:00:00Z") } +{ _id: 2, department: "y", sales: 10, engineer: 20, lastUpdate: ISODate("2019-05-01T02:00:00Z") } +{ _id: 3, department: "z", sales: 20, engineer: 5, lastUpdate: ISODate("2019-05-02T03:00:00Z") } +``` + +**数字求和** + + 可以用如下方式求得各个记录人数总数: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('staff').aggregate() + .project({ + department: 1, + total: $.add(['$sales', '$engineer']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, department: "x", total: 15 } +{ _id: 2, department: "y", total: 30 } +{ _id: 3, department: "z", total: 25 } +``` + +**增加日期值** + + 如下操作可以获取各个记录的 `lastUpdate` 加一个小时之后的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('staff').aggregate() + .project({ + department: 1, + lastUpdate: $.add(['$lastUpdate', 60*60*1000]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, department: "x", lastUpdate: ISODate("2019-05-01T01:00:00Z") } +{ _id: 2, department: "y", lastUpdate: ISODate("2019-05-01T03:00:00Z") } +{ _id: 3, department: "z", lastUpdate: ISODate("2019-05-02T04:00:00Z") } +``` + +### ceil + +向上取整,返回大于或等于给定数字的最小整数。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.ceil() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `sales` 有如下记录: + +```typescript +{ _id: 1, sales: 5.2 } +{ _id: 2, sales: 1.32 } +{ _id: 3, sales: -3.2 } +``` + +可以用如下方式取各个数字的向上取整值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + sales: $.ceil('$sales') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, sales: 6 } +{ _id: 2, sales: 2 } +{ _id: 3, sales: -3 } +``` + +### divide + +传入被除数和除数,求商。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.divide([<被除数表达式>, <除数表达式>]) +``` + +表达式可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `railroads` 有如下记录: + +```typescript +{ _id: 1, meters: 5300 } +{ _id: 2, meters: 64000 } +{ _id: 3, meters: 130 } +``` + +可以用如下方式取各个数字转换为千米之后的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('railroads').aggregate() + .project({ + km: $.divide(['$meters', 1000]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, km: 5.3 } +{ _id: 2, km: 64 } +{ _id: 3, km: 0.13 } +``` + +### exp + +取 e(自然对数的底数,欧拉数)的 n 次方。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.exp() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `math` 有如下记录: + +```typescript +{ _id: 1, exp: 0 } +{ _id: 2, exp: 1 } +{ _id: 3, exp: 2 } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('math').aggregate() + .project({ + result: $.exp('$exp') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, result: 1 } +{ _id: 2, result: 2.71828182845905 } +{ _id: 3, result: 7.38905609893065 } +``` + +### floor + +向下取整,返回大于或等于给定数字的最小整数。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.floor() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `sales` 有如下记录: + +```typescript +{ _id: 1, sales: 5.2 } +{ _id: 2, sales: 1.32 } +{ _id: 3, sales: -3.2 } +``` + +可以用如下方式取各个数字的向下取整值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + sales: $.floor('$sales') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, sales: 5 } +{ _id: 2, sales: 1 } +{ _id: 3, sales: -4 } +``` + +### ln + +计算给定数字在自然对数值。 + +#### API 说明 + +语法如下: + +```typescript +db.command.aggregate.ln() +``` + +`` 可以是任意解析为非负数字的表达式。 + +`ln` 等价于 `log([, Math.E])`,其中 `Math.E` 是 `JavaScript` 获取 `e` 的值的方法。 + +#### 示例代码 + +假设集合 curve 有如下记录: + +```typescript +{ _id: 1, x: 1 } +{ _id: 2, x: 2 } +{ _id: 3, x: 3 } +``` + +计算 ln(x) 的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('curve').aggregate() + .project({ + log: $.ln('$x') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, ln: 0 } +{ _id: 2, ln: 0.6931471805599453 } +{ _id: 3, ln: 1.0986122886681098 } +``` + +### log + +计算给定数字在给定对数底下的 log 值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.log([, ]) +``` + +`` 可以是任意解析为非负数字的表达式。`` 可以是任意解析为大于 1 的数字的表达式。 + + 如果任一参数解析为 `null` 或指向任意一个不存在的字段,`log` 返回 `null`。如果任一参数解析为 `NaN`,`log` 返回 `NaN`。 + +#### 示例代码 + + 假设集合 `curve` 有如下记录: + +```typescript +{ _id: 1, x: 1 } +{ _id: 2, x: 2 } +{ _id: 3, x: 3 } +``` + +计算 `log2(x)` 的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('curve').aggregate() + .project({ + log: $.log(['$x', 2]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, log: 0 } +{ _id: 2, log: 1 } +{ _id: 3, log: 1.58496250072 } +``` + +### log10 + +计算给定数字在对数底为 10 下的 log 值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.log() +``` + +`` 可以是任意解析为非负数字的表达式。 + + `log10` 等同于 `log` 方法的第二个参数固定为 10。 + +#### 示例代码 + +#### db.command.aggregate.log10 + +计算给定数字在对数底为 10 下的 log 值。 + +语法如下: + +```typescript +db.command.aggregate.log() +``` + +`` 可以是任意解析为非负数字的表达式。 + + `log10` 等同于 `log` 方法的第二个参数固定为 10。 + +### mod + +取模运算,取数字取模后的值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.mod([, ]) +``` + +第一个数字是被除数,第二个数字是除数。参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `shopping` 有如下记录: + +```typescript +{ _id: 1, bags: 3, items: 5 } +{ _id: 2, bags: 2, items: 8 } +{ _id: 3, bags: 5, items: 16 } +``` + +各记录取 `items` 除以 `bags` 的余数(`items % bags`): + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shopping').aggregate() + .project({ + overflow: $.mod(['$items', '$bags']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, overflow: 2 } +{ _id: 2, overflow: 0 } +{ _id: 3, overflow: 1 } +``` + +### multiply + +取传入的数字参数相乘的结果。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.multiply([, , ...]) +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `fruits` 有如下记录: + +```typescript +{ "_id": 1, "name": "apple", "price": 10, "quantity": 100 } +{ "_id": 2, "name": "orange", "price": 15, "quantity": 50 } +{ "_id": 3, "name": "lemon", "price": 5, "quantity": 20 } +``` + +求各个水果的的总价值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + name: 1, + total: $.multiply(['$price', '$quantity']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "name": "apple", "total": 1000 } +{ "_id": 2, "name": "orange", "total": 750 } +{ "_id": 3, "name": "lemo", "total": 100 } +``` + +### pow + +求给定基数的指数次幂。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.pow([, ]) +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "x": 2, "y": 3 } +{ "_id": 2, "x": 5, "y": 7 } +{ "_id": 3, "x": 10, "y": 20 } +``` + +求 `x` 和 `y` 的平方和: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + sumOfSquares: $.add([$.pow(['$x', 2]), $.pow(['$y', 2])]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sumOfSquares": 13 } +{ "_id": 2, "sumOfSquares": 74 } +{ "_id": 3, "sumOfSquares": 500 } +``` + +### sqrt + +求平方根。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.sqrt([]) +``` + +参数可以是任意解析为非负数字的表达式。 + +#### 示例代码 + + 假设直角三角形集合 `triangle` 有如下记录: + +```typescript +{ "_id": 1, "x": 2, "y": 3 } +{ "_id": 2, "x": 5, "y": 7 } +{ "_id": 3, "x": 10, "y": 20 } +``` + +假设 `x` 和 `y` 分别为两直角边,则求斜边长: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('triangle').aggregate() + .project({ + len: $.sqrt([$.add([$.pow(['$x', 2]), $.pow(['$y', 2])])]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "len": 3.605551275463989 } +{ "_id": 2, "len": 8.602325267042627 } +{ "_id": 3, "len": 22.360679774997898 } +``` + +### subtract + +将两个数字相减然后返回差值,或将两个日期相减然后返回相差的毫秒数,或将一个日期减去一个数字返回结果的日期。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.subtract([, ]) +``` + +参数可以是任意解析为数字或日期的表达式。 + +#### 示例代码 + + 假设集合 `scores` 有如下记录: + +```typescript +{ "_id": 1, "max": 10, "min": 1 } +{ "_id": 2, "max": 7, "min": 5 } +{ "_id": 3, "max": 6, "min": 6 } +``` + +求各个记录的 `max` 和 `min` 的差值。: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .project({ + diff: $.subtract(['$max', '$min']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "diff": 9 } +{ "_id": 2, "diff": 2 } +{ "_id": 3, "diff": 0 } +``` + +### trunc + +将数字截断为整形。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.trunc() +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `scores` 有如下记录: + +```typescript +{ "_id": 1, "value": 1.21 } +{ "_id": 2, "value": 3.83 } +{ "_id": 3, "value": -4.94 } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .project({ + int: $.trunc('$value') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "value": 1 } +{ "_id": 2, "value": 3 } +{ "_id": 3, "value": -4 } +``` + +## 数组操作符 + +### arrayElemAt + +返回在指定数组下标的元素。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.arrayElemAt([, ]) +``` + +`` 可以是任意解析为数组的表达式。 + + `` 可以是任意解析为整形的表达式。如果是正数,`arrayElemAt` 返回在 `index` 位置的元素,如果是负数,`arrayElemAt` 返回从数组尾部算起的 `index` 位置的元素。 + +#### 示例代码 + + 假设集合 `exams` 有如下记录: + +```typescript +{ "_id": 1, "scores": [80, 60, 65, 90] } +{ "_id": 2, "scores": [78] } +{ "_id": 3, "scores": [95, 88, 92] } +``` + +求各个第一次考试的分数和和最后一次的分数: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('exams').aggregate() + .project({ + first: $.arrayElemAt(['$scores', 0]), + last: $.arrayElemAt(['$scores', -1]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "first": 80, "last": 90 } +{ "_id": 2, "first": 78, "last": 78 } +{ "_id": 3, "first": 95, "last": 92 } +``` + +### arrayToObject + +将一个数组转换为对象。 + +#### API 说明 + + 语法可以取两种: + + 第一种:传入一个二维数组,第二维的数组长度必须为 2,其第一个值为字段名,第二个值为字段值 + +```typescript +db.command.aggregate.arrayToObject([ + [, ], + [, ], + ... +]) +``` + +第二种:传入一个对象数组,各个对象必须包含字段 `k` 和 `v`,分别指定字段名和字段值 + +```typescript +db.command.aggregate.arrayToObject([ + { "k": , "v": }, + { "k": , "v": }, + ... +]) +``` + +传入 `arrayToObject` 的参数只要可以解析为上述两种表示法之一即可。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "sales": [ ["max", 100], ["min", 50] ] } +{ "_id": 2, "sales": [ ["max", 70], ["min", 60] ] } +{ "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] } +``` + +将数组转换为对象: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shops').aggregate() + .project({ + sales: $.arrayToObject('$sales'), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sales": { "max": 100, "min": 50 } } +{ "_id": 2, "sales": { "max": 70, "min": 60 } } +{ "_id": 3, "sales": { "max": 50, "min": 30 } } +``` + +### concatArrays + +将多个数组拼接成一个数组。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.concatArrays([ , , ... ]) +``` + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `items` 有如下记录: + +```typescript +{ "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] } +{ "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] } +{ "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + list: $.concatArrays(['$fruits', '$vegetables']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "list": [ "apple", "carrot" ] } +{ "_id": 2, "list": [ "orange", "lemon", "cabbage" ] } +{ "_id": 3, "list": [ "strawberry", "spinach" ] } +``` + +### filter + +根据给定条件返回满足条件的数组的子集。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.filter({ + input: , + as: , + cond: +}) +``` + +|字段 |说明 | +|---- |---- | +|input|一个可以解析为数组的表达式 | +|as |可选,用于表示数组各个元素的变量,默认为 this | +|cond |一个可以解析为布尔值的表达式,用于判断各个元素是否满足条件,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)| + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `fruits` 有如下记录: + +```typescript +{ + "_id": 1, + "stock": [ + { "name": "apple", "price": 10 }, + { "name": "orange", "price": 20 } + ], +} +{ + "_id": 2, + "stock": [ + { "name": "lemon", "price": 15 }, + ], +} +``` + +```typescript +const _ = db.command +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + stock: $.filter({ + input: '$stock', + as: 'item', + cond: $.gte(['$$item.price', 15]) + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "stock": [ { "name": "orange", "price": 20} ] } +{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] } +``` + +### in + +给定一个值和一个数组,如果值在数组中则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.in([, ]) +``` + +`` 可以是任意表达式。 + + `` 可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "topsellers": ["bread", "ice cream", "butter"] } +{ "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] } +{ "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] } +``` + +标记销量最高的商品包含 `ice cream` 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + included: $.in(['ice cream', '$topsellers']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "included": true } +{ "_id": 2, "included": true } +{ "_id": 3, "included": false } +``` + +### indexOfArray + +在数组中找出等于给定值的第一个元素的下标,如果找不到则返回 -1。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.indexOfArray([ , , , ]) +``` + +|字段 |类型 |说明 | +|---- |---- |---- | +|- |string |一个可以解析为数组的表达式,如果解析为 null,则 indexOfArray 返回 null | +|- |string |对数据各个元素应用的条件匹配表达式 | +|- |integer|可选,用于指定搜索的开始下标,必须是非负整数 | +|- |integer|可选,用于指定搜索的结束下标,必须是非负整数,指定了 时也应指定,否则 默认当做| + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1, 6, 2, 2, 5 ] +} +{ + "_id": 2, + "sales": [ 4, 2, 1, 5, 2 ] +} +{ + "_id": 3, + "sales": [ 2, 5, 3, 3, 1 ] +} +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + index: $.indexOfArray(['$sales', 2, 2]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "index": 2 } +{ "_id": 2, "index": 4 } +{ "_id": 3, "index": -1 } +``` + +### isArray + +判断给定表达式是否是数组,返回布尔值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.isArray() +``` + +参数可以是任意表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "base": 10, + "sales": [ 1, 6, 2, 2, 5 ] +} +{ + "_id": 2, + "base": 1, + "sales": 100 +} +``` + +计算总销量,如果 `sales` 是数字,则求 `sales * base`,如果 `sales` 是数组,则求数组元素之和与 `base` 的乘积。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + sum: $.cond({ + if: $.isArray('$sales'), + then: $.multiply([$.sum(['$sales']), '$base']), + else: $.multiply(['$sales', '$base']), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sum": 160 } +{ "_id": 2, "sum": 100 } +``` + +### map + +类似 JavaScript Array 上的 `map` 方法,将给定数组的每个元素按给定转换方法转换后得出新的数组。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.map({ + input: , + as: , + in: +}) +``` + +|字段 |说明 | +|---- |---- | +|input|一个可以解析为数组的表达式 | +|as |可选,用于表示数组各个元素的变量,默认为 this | +|in |一个可以应用在给定数组的各个元素上的表达式,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)| + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1.32, 6.93, 2.48, 2.82, 5.74 ] +} +{ + "_id": 2, + "sales": [ 2.97, 7.13, 1.58, 6.37, 3.69 ] +} +``` + +将各个数字截断为整形,然后求和 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + truncated: $.map({ + input: '$sales', + as: 'num', + in: $.trunc('$$num'), + }) + }) + .project({ + total: $.sum('$truncated') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "total": 16 } +{ "_id": 2, "total": 19 } +``` + +### objectToArray + +将一个对象转换为数组。方法把对象的每个键值对都变成输出数组的一个元素,元素形如 `{ k: , v: }`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.objectToArray() +``` + +#### 示例代码 + + 假设集合 `items` 有如下记录: + +```typescript +{ "_id": 1, "attributes": { "color": "red", "price": 150 } } +{ "_id": 2, "attributes": { "color": "blue", "price": 50 } } +{ "_id": 3, "attributes": { "color": "yellow", "price": 10 } } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + array: $.objectToArray('$attributes') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "array": [{ "k": "color", "v": "red" }, { "k": "price", "v": 150 }] } +{ "_id": 2, "array": [{ "k": "color", "v": "blue" }, { "k": "price", "v": 50 }] } +{ "_id": 3, "array": [{ "k": "color", "v": "yellow" }, { "k": "price", "v": 10 }] } +``` + +### range + +返回一组生成的序列数字。给定开始值、结束值、非零的步长,`range` 会返回从开始值开始逐步增长、步长为给定步长、但不包括结束值的序列。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.range([, , ]) +``` + +|字段 |说明 | +|---- |---- | +|start |开始值,一个可以解析为整形的表达式 | +|end |结束值,一个可以解析为整形的表达式 | +|non-zero step|可选,步长,一个可以解析为非零整形的表达式,默认为 1 | + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "max": 52 } +{ "_id": 2, "max": 38 } +``` + +```typescript +const $ = db.command.aggregate +db.collection('stats').aggregate() + .project({ + points: $.range([0, '$max', 10]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "points": [0, 10, 20, 30, 40, 50] } +{ "_id": 2, "points": [0, 10, 20, 30] } +``` + +### reduce + +类似 JavaScript 的 `reduce` 方法,应用一个表达式于数组各个元素然后归一成一个元素。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.reduce({ + input: + initialValue: , + in: +}) +``` + +|字段 |说明 | +|---- |---- | +|input |输入数组,可以是任意解析为数组的表达式 | +|initialValue |初始值 | +|in |用来作用于每个元素的表达式,在 in 中有两个可用变量,value 是表示累计值的变量,this 是表示当前数组元素的变量| + +#### 示例代码 + +**简易字符串拼接** + + 假设集合 `player` 有如下记录: + +```typescript +{ "_id": 1, "fullname": [ "Stephen", "Curry" ] } +{ "_id": 2, "fullname": [ "Klay", "Thompsom" ] } +``` + +获取各个球员的全名,并加 `Player:` 前缀: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('player').aggregate() + .project({ + info: $.reduce({ + input: '$fullname', + initialValue: 'Player:', + in: $.concat(['$$value', ' ', '$$this']), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "info": "Player: Stephen Curry" } +{ "_id": 2, "info": "Player: Klay Thompson" } +``` + +获取各个球员的全名,不加前缀: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('player').aggregate() + .project({ + name: $.reduce({ + input: '$fullname', + initialValue: '', + in: $.concat([ + '$$value', + $.cond({ + if: $.eq(['$$value', '']), + then: '', + else: ' ', + }), + '$$this', + ]), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "name": "Stephen Curry" } +{ "_id": 2, "name": "Klay Thompson" } +``` + +### reverseArray + +返回给定数组的倒序形式。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.reverseArray() +``` + +参数可以是任意解析为数组表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1, 2, 3, 4, 5 ] +} +``` + +取 `sales` 倒序: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + reversed: $.reverseArray('$sales'), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "reversed": [5, 4, 3, 2, 1] } +``` + +### size + +返回数组长度。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.size() +``` + +`` 可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "staff": [ "John", "Middleton", "George" ] } +{ "_id": 2, "staff": [ "Steph", "Jack" ] } +``` + +计算各个商店的雇员数量: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shops').aggregate() + .project({ + totalStaff: $.size('$staff') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "totalStaff": 3 } +{ "_id": 2, "totalStaff": 2 } +``` + +### slice + +类似 JavaScritp 的 `slice` 方法。返回给定数组的指定子集。 + +#### API 说明 + + 语法有两种: + + 返回从开头或结尾开始的 `n` 个元素: + +```typescript +db.command.aggregate.slice([, ]) +``` + +返回从指定位置算作数组开头、再向后或向前的 `n` 个元素: + +```typescript +db.command.aggregate.slice([, , ]) +``` + +`` 可以是任意解析为数组的表达式。 + + `` 可以是任意解析为整形的表达式。如果是正数,则将数组的第 `` 个元素作为数组开始;如果 `` 比数组长度更长,`slice` 返回空数组。如果是负数,则将数组倒数第 `` 个元素作为数组开始;如果 `` 的绝对值大于数组长度,则开始位置即为数组开始位置。 + + `` 可以是任意解析为整形的表达式。如果 `` 有提供,则 `` 必须为正整数。如果是正数,`slice` 返回前 `n` 个元素。如果是负数,`slice` 返回后 `n` 个元素。 + +#### 示例代码 + + 假设集合 `people` 有如下记录: + +```typescript +{ "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] } +{ "_id": 2, "hobbies": [ "golf", "handball" ] } +{ "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] } +``` + +统一返回前两个爱好: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + hobbies: $.slice(['$hobbies', 2]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "hobbies": [ "basketball", "football" ] } +{ "_id": 2, "hobbies": [ "golf", "handball" ] } +{ "_id": 3, "hobbies": [ "table tennis", "swimming" ] } +``` + +### zip + +把二维数组的第二维数组中的相同序号的元素分别拼装成一个新的数组进而组装成一个新的二维数组。如可将 `[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]` 转换成 `[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.zip({ + inputs: [, , ...], + useLongestLength: , + defaults: +}) +``` + +`inputs` 是一个二维数组(`inputs` 不可以是字段引用),其中每个元素的表达式(这个可以是字段引用)都可以解析为数组。如果其中任意一个表达式返回 `null`,`` 也返回 `null`。如果其中任意一个表达式不是指向一个合法的字段 / 解析为数组 / 解析为 `null`,则返回错误。 + + `useLongestLength` 决定输出数组的长度是否采用输入数组中的最长数组的长度。默认为 `false`,即输入数组中的最短的数组的长度即是输出数组的各个元素的长度。 + + `defaults` 是一个数组,用于指定在输入数组长度不一的情况下时采用的数组各元素默认值。指定这个字段则必须指定 `useLongestLength`,否则返回错误。如果 `useLongestLength` 是 `true` 但是 `defaults` 是空或没有指定,则 `zip` 用 `null` 做数组元素的缺省默认值。指定各元素默认值时 `defaults` 数组的长度必须是输入数组最大的长度。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "zip1": [1, 2], "zip2": [3, 4], "zip3": [5, 6] ] } +{ "_id": 2, "zip1": [1, 2], "zip2": [3], "zip3": [4, 5, 6] ] } +{ "_id": 3, "zip1": [1, 2], "zip2": [3] ] } +``` + +**只传 inputs** + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4] ] } +{ "_id": 3, "zip": null } +``` + +**设置 useLongestLength** + + 如果设 `useLongestLength` 为 `true`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + useLongestLength: true, + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4], [2, null, 5], [null, null, 6] ] } +{ "_id": 3, "zip": null } +``` + +**设置 defaults** + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + useLongestLength: true, + defaults: [-300, -200, -100], + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4], [2, -200, 5], [-300, -200, 6] ] } +{ "_id": 3, "zip": null } +``` + +## 布尔操作符 + +### and + +给定多个表达式,`and` 仅在所有表达式都返回 `true` 时返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.and([, , ...]) +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 60, "max": 80 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 大于等于 30 且 `max` 小于等于 80 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.and([$.gte(['$min', 30]), $.lte(['$max', 80])]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": false } +{ "_id": 2, "fullfilled": true } +{ "_id": 3, "fullfilled": true } +``` + +### not + +给定一个表达式,如果表达式返回 `true`,则 `not` 返回 `false`,否则返回 `true`。注意表达式不能为逻辑表达式(`and`、`or`、`nor`、`not`)。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.not() +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 60, "max": 80 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 不大于 40 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.not($.gt(['$min', 40])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": true } +{ "_id": 2, "fullfilled": false } +{ "_id": 3, "fullfilled": true } +``` + +### or + +给定多个表达式,如果任意一个表达式返回 `true`,则 `or` 返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.or([, , ...]) +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 50, "max": 60 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 小于 40 或 `max` 大于 60 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.or([$.lt(['$min', 40]), $.gt(['$max', 60])]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": true } +{ "_id": 2, "fullfilled": false } +{ "_id": 3, "fullfilled": true } +``` + +## 比较操作符 + +### cmp + +给定两个值,返回其比较值: + +#### API 说明 + + 如果第一个值小于第二个值,返回 -1 +如果第一个值大于第二个值,返回 1 +如果两个值相等,返回 0 + + 语法如下: + +```typescript +db.command.aggregate.cmp([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "shop1": 10, "shop2": 100 } +{ "_id": 2, "shop1": 80, "shop2": 20 } +{ "_id": 3, "shop1": 50, "shop2": 50 } +``` + +求 `shop1` 和 `shop2` 的各个物品的价格对比。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + compare: $.cmp(['$shop1', '$shop2'])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "compare": -1 } +{ "_id": 2, "compare": 1 } +{ "_id": 3, "compare": 0 } +``` + +### eq + +匹配两个值,如果相等则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.eq([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +求 `value` 等于 50 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.eq(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": true } +``` + +### gt + +匹配两个值,如果前者大于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.gt([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否大于 50。 + +```typescript +const $ = db.command.aggregate +db.collection('price').aggregate() + .project({ + matched: $.gt(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": false } +``` + +### gte + +匹配两个值,如果前者大于或等于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.gte([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否大于或等于 50。 + +```typescript +const $ = db.command.aggregate +let res = await b.collection('price').aggregate() + .project({ + matched: $.gte(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": true } +``` + +### lt + +匹配两个值,如果前者小于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.lt([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +``` +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否小于 50。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.lt(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": false } +``` + +### lte + +匹配两个值,如果前者小于或等于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.lte([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否小于 50。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.lte(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": true } +``` + +### neq + +匹配两个值,如果不相等则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.neq([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +求 `value` 不等于 50 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.neq(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": false } +``` + +## 条件操作符 + +### cond + +计算布尔表达式,返回指定的两个值其中之一。 + +#### API 说明 + + `cond` 的使用形式如下: + +```typescript +cond({ if: <布尔表达式>, then: <真值>, else: <假值> }) +``` + +或者: + +```typescript +cond([ <布尔表达式>, <真值>, <假值> ]) +``` + +两种形式中,三个参数(`if`、`then`、`else`)都是必须的。 + + 如果布尔表达式为真,那么 `$cond` 将会返回 `<真值>`,否则会返回 `<假值>` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "item-a", "amount": 100 } +{ "_id": "1", "name": "item-b", "amount": 200 } +{ "_id": "2", "name": "item-c", "amount": 300 } +``` + +我们可以使用 `cond`,根据 `amount` 字段,来生成新的字段 `discount`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + name: 1, + discount: $.cond({ + if: $.gte(['$amount', 200]), + then: 0.7, + else: 0.9 + }) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "name": "item-a", "discount": 0.9 } +{ "_id": "1", "name": "item-b", "discount": 0.7 } +{ "_id": "2", "name": "item-c", "discount": 0.7 } +``` + +### ifNull + +计算给定的表达式,如果表达式结果为 null、undefined 或者不存在,那么返回一个替代值;否则返回原值。 + +#### API 说明 + + `ifNull` 的使用形式如下: + +```typescript +ifNull([ <表达式>, <替代值> ]) +``` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "A", "description": "这是商品 A" } +{ "_id": "1", "name": "B", "description": null } +{ "_id": "2", "name": "C" } +``` + +我们可以使用 `ifNull`,对不存在 `desc` 字段的文档,或者 `desc` 字段为 `null` 的文档,补充一个替代值。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + _id: 0, + name: 1, + description: $.ifNull(['$description', '商品描述空缺']) + }) + .end() +``` + +输出如下: + +```typescript +{ "name": "A", "description": "这是商品 A" } +{ "name": "B", "description": "商品描述空缺" } +{ "name": "C", "description": "商品描述空缺" } +``` + +### switch + +根据给定的 `switch-case-default` 计算返回值、 + +#### API 说明 + + `switch` 的使用形式如下: + +```typescript +switch({ + branches: [ + case: <表达式>, then: <表达式>, + case: <表达式>, then: <表达式>, + ... + ], + default: <表达式> +}) +``` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "item-a", "amount": 100 } +{ "_id": "1", "name": "item-b", "amount": 200 } +{ "_id": "2", "name": "item-c", "amount": 300 } +``` + +我们可以使用 `switch`,根据 `amount` 字段,来生成新的字段 `discount`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + name: 1, + discount: $.switch({ + branches: [ + { case: $.gt(['$amount', 250]), then: 0.8 }, + { case: $.gt(['$amount', 150]), then: 0.9 } + ], + default: 1 + }) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "name": "item-a", "discount": 1 } +{ "_id": "1", "name": "item-b", "discount": 0.9 } +{ "_id": "2", "name": "item-c", "discount": 0.8 } +``` + +## 日期操作符 + +**注意** + +- 以下日期操作符中`timezone`均支持以下几种形式 + +```typescript +timezone: "Asia/Shanghai" // Asia/Shanghai时区 +timezone: "+08" // utc+8 时区 +timezone: "+08:30" // 时区偏移 8 小时 30 分 +timezone: "+0830" // 时区偏移 8 小时 30 分,同上 +``` + +### dateFromParts + +给定日期的相关信息,构建并返回一个日期对象。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.dateFromParts({ + year: , + month: , + day: , + hour: , + minute: , + second: , + millisecond: , + timezone: +}) +``` + +你也可以使用 ISO 8601 的标准: + +```typescript +db.command.aggregate.dateFromParts({ + isoWeekYear: , + isoWeek: , + isoDayOfWeek: , + hour: , + minute: , + second: , + millisecond: , + timezone: +}) +``` + +#### 示例代码 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + date: $.dateFromParts({ + year: 2017, + month: 2, + day: 8, + hour: 12, + timezone: 'America/New_York' + }), + }) + .end() +``` + +输出如下: + +```typescript +{ + "date": ISODate("2017-02-08T17:00:00.000Z") +} +``` + +### dateFromString + +将一个日期/时间字符串转换为日期对象 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.dateFromString({ + dateString: , + timezone: +}) +``` + +#### 示例代码 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + date: $.dateFromString({ + dateString: "2019-05-14T09:38:51.686Z" + }) + }) + .end() +``` + +输出如下: + +```typescript +{ + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +### dateToString + +根据指定的表达式将日期对象格式化为符合要求的字符串。 + +#### API 说明 + + `dateToString` 的调用形式如下: + +```typescript +db.command.aggregate.dateToString({ + date: <日期表达式>, + format: <格式化表达式>, + timezone: <时区表达式>, + onNull: <空值表达式> +}) +``` + +下面是四种表达式的详细说明: + +|名称 |描述 | +|---- |---- | +|日期表达式 |必选。指定字段值应该是能转化为字符串的日期。 | +|格式化表达式 |可选。它可以是任何包含“格式说明符”的有效字符串。 | +|时区表达式 |可选。指明运算结果的时区。它可以解析格式为 [UTC Offset](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) 或者 [Olson Timezone Identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) 的字符串。| +|空值表达式 |可选。当 <日期表达式> 返回空或者不存在的时候,会返回此表达式指明的值。 | + +下面是格式说明符的详细说明: + +|说明符 |描述 |合法值 | +|---- |---- |---- | +|%d |月份的日期(2 位数,0 填充) |01 - 31 | +|%G |ISO 8601 格式的年份 |0000 - 9999| +|%H |小时(2 位数,0 填充,24 小时制) |00 - 23 | +|%j |一年中的一天(3 位数,0 填充) |001 - 366 | +|%L |毫秒(3 位数,0 填充) |000 - 999 | +|%m |月份(2 位数,0 填充) |01 - 12 | +|%M |分钟(2 位数,0 填充) |00 - 59 | +|%S |秒(2 位数,0 填充) |00 - 60 | +|%w |星期几 |1 - 7 | +|%u |ISO 8601 格式的星期几 |1 - 7 | +|%U |一年中的一周(2 位数,0 填充) |00 - 53 | +|%V |ISO 8601 格式的一年中的一周 |1 - 53 | +|%Y |年份(4 位数,0 填充) |0000 - 9999| +|%z |与 UTC 的时区偏移量 |+/-[hh][mm]| +|%Z |以分钟为单位,与 UTC 的时区偏移量|+/-mmm | +|%% |百分号作为字符 |% | + +#### 示例代码 + + 假设集合 `students` 有如下记录: + +```typescript +{ "date": "1999-12-11T16:00:00.000Z", "firstName": "Yuanxin", "lastName": "Dong" } +{ "date": "1998-11-10T16:00:00.000Z", "firstName": "Weijia", "lastName": "Wang" } +{ "date": "1997-10-09T16:00:00.000Z", "firstName": "Chengxi", "lastName": "Li" } +``` + +**格式化日期** + + 下面是将 `date` 字段的值,格式化成形如 `年份-月份-日期` 的字符串: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$date', + format: '%Y-%m-%d' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "1999-12-11" } +{ "formatDate": "1998-11-10" } +{ "formatDate": "1997-10-09" } +``` + +**时区时间** + + 下面是将 `date` 字段值格式化为上海时区时间的例子: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$date', + format: '%H:%M:%S', + timezone: 'Asia/Shanghai' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "00:00:00" } +{ "formatDate": "00:00:00" } +{ "formatDate": "00:00:00" } +``` + +**缺失情况的默认值** + + 当指定的 `<日期表达式>` 返回空或者不存在的时候,可以设置缺失情况下的默认值: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$empty', + onNull: 'null' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "null" } +{ "formatDate": "null" } +{ "formatDate": "null" } +``` + +### dayOfMonth + +返回日期字段对应的天数(一个月中的哪一天),是一个介于 1 至 31 之间的数字。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfMonth(<日期字段>) + +db.command.aggregate.dayOfMonth({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfMonth()` 对 `date` 字段进行投影,获取对应的日期: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfMonth: $.dayOfMonth('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfMonth": 14 +} +``` + +### dayOfWeek + +返回日期字段对应的天数(一周中的第几天),是一个介于 1(周日)到 7(周六)之间的整数。 + +#### API 说明 + +**注意:周日是每周的第 1 天** + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfWeek(<日期字段>) + +db.command.aggregate.dayOfWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfWeek()` 对 `date` 字段进行投影,获取对应的天数(一周中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfWeek: $.dayOfWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfWeek": 3 +} +``` + +### dayOfYear + +返回日期字段对应的天数(一年中的第几天),是一个介于 1 到 366 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfYear(<日期字段>) + +db.command.aggregate.dayOfYear({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfYear()` 对 `date` 字段进行投影,获取对应的天数(一年中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfYear: $.dayOfYear('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfYear": 134 +} +``` + +### hour + +返回日期字段对应的小时数,是一个介于 0 到 23 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.hour(<日期字段>) + +db.command.aggregate.hour({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `hour()` 对 `date` 字段进行投影,获取对应的小时数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + hour: $.hour('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "hour": 9 +} +``` + +### isoDayOfWeek + +返回日期字段对应的 ISO 8601 标准的天数(一周中的第几天),是一个介于 1(周一)到 7(周日)之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoDayOfWeek(<日期字段>) + +db.command.aggregate.isoDayOfWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoDayOfWeek()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的天数(一周中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoDayOfWeek: $.isoDayOfWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoDayOfWeek": 2 +} +``` + +### isoWeek + +返回日期字段对应的 ISO 8601 标准的周数(一年中的第几周),是一个介于 1 到 53 之间的整数。 + +#### API 说明 + +根据 ISO 8601 标准,周一到周日视为一周,本年度第一个周四所在的那周,视为本年度的第 1 周。 + +例如:2016 年 1 月 7 日是那年的第一个周四,那么 2016.01.04(周一)到 2016.01.10(周日)即为第 1 周。同理,2016 年 1 月 1 日的周数为 53。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoWeek(<日期字段>) + +db.command.aggregate.isoWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoWeek()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的周数(一年中的第几周): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoWeek: $.isoWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoWeek": 20 +} +``` + +### isoWeekYear + +返回日期字段对应的 ISO 8601 标准的天数(一年中的第几天)。 + +#### API 说明 + +此处的“年”以第一周的周一为开始,以最后一周的周日为结束。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoWeekYear(<日期字段>) + +db.command.aggregate.isoWeekYear({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoWeekYear()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的天数(一年中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoWeekYear: $.isoWeekYear('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoWeekYear": 2019 +} +``` + +### millisecond + +返回日期字段对应的毫秒数,是一个介于 0 到 999 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.millisecond(<日期字段>) + +db.command.aggregate.millisecond({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `millisecond()` 对 `date` 字段进行投影,获取对应的毫秒数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + millisecond: $.millisecond('$date'), + }) + .end() +``` + +输出如下: + +```typescript +{ + "millisecond": 686 +} +``` + +### minute + +返回日期字段对应的分钟数,是一个介于 0 到 59 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.minute(<日期字段>) + +db.command.aggregate.minute({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `minute()` 对 `date` 字段进行投影,获取对应的分钟数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + minute: $.minute('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "minute": 38 +} +``` + +### month + +返回日期字段对应的月份,是一个介于 1 到 12 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.month(<日期字段>) + +db.command.aggregate.month({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `month()` 对 `date` 字段进行投影,获取对应的月份: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + month: $.month('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "month": 5 +} +``` + +### second + +返回日期字段对应的秒数,是一个介于 0 到 59 之间的整数,在特殊情况下(闰秒)可能等于 60。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.second(<日期字段>) + +db.command.aggregate.second({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `second()` 对 `date` 字段进行投影,获取对应的秒数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + second: $.second('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "second": 51 +} +``` + +### week + +返回日期字段对应的周数(一年中的第几周),是一个介于 0 到 53 之间的整数。 + +#### API 说明 + +每周以周日为开头,**每年的第一个周日**即为 `week 1` 的开始,这天之前是 `week 0`。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.week(<日期字段>) + +db.command.aggregate.week({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `week()` 对 `date` 字段进行投影,获取对应的周数(一年中的第几周): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + week: $.week('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "week": 19 +} +``` + +### year + +返回日期字段对应的年份。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.year(<日期字段>) + +db.command.aggregate.year({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `year()` 对 `date` 字段进行投影,获取对应的年份: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + year: $.year('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "year": 2019 +} +``` + +## 常量操作符 + +### literal + +直接返回一个值的字面量,不经过任何解析和处理。 + +#### API 说明 + + `literal` 使用形式如下: + +```typescript +literal(<值>) +``` + +如果 `<值>` 是一个表达式,那么 `literal` **不会**解析或者计算这个表达式,而是直接返回这个表达式。 + +#### 示例代码 + + 比如我们有一个 `items` 集合,其中数据如下: + +```typescript +{ "_id": "0", "price": "$1" } +{ "_id": "1", "price": "$5.60" } +{ "_id": "2", "price": "$8.90" } +``` + +**以字面量的形式使用 $** + + 下面的代码使用 `literal`,生成了一个新的字段 `isOneDollar`,表示 `price` 字段是否严格等于 `"$1"`。 + + 注意:我们这里无法使用 `eq(['$price', '$1'])`,因为 `"$1"` 是一个表达式,代表 `"1"` 字段对应的值,而不是字符串字面量 `"$1"`。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + isOneDollar: $.eq(['$price', $.literal('$1')]) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "isOneDollar": true } +{ "_id": "1", "isOneDollar": false } +{ "_id": "2", "isOneDollar": false } +``` + +**投影一个字段,对应的值为 1** + + 下面的代码使用 `literal`,投影了一个新的字段 `amount`,其值为 `1`。 + +```typescript +const $ = db.command.aggregate +db.collection('items').aggregate() + .project({ + price: 1, + amount: $.literal(1) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "price": "$1", "amount": 1 } +{ "_id": "1", "price": "$5.60", "amount": 1 } +{ "_id": "2", "price": "$8.90", "amount": 1 } +``` + +## 对象操作符 + +### mergeObjects + +将多个文档合并为单个文档。 + +#### API 说明 + + 使用形式如下: +在 `group()` 中使用时: + +```typescript +mergeObjects() +``` + +在其它表达式中使用时: + +```typescript +mergeObjects([, , ...]) +``` + +#### 示例代码 + +**搭配 `group()` 使用** + + 假设集合 `sales` 存在以下文档: + +```typescript +{ "_id": 1, "year": 2018, "name": "A", "volume": { "2018Q1": 500, "2018Q2": 500 } } +{ "_id": 2, "year": 2017, "name": "A", "volume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0 } } +{ "_id": 3, "year": 2018, "name": "B", "volume": { "2018Q1": 100 } } +{ "_id": 4, "year": 2017, "name": "B", "volume": { "2017Q3": 100, "2017Q4": 250 } } +``` + +下面的代码使用 `mergeObjects()`,将用相同 `name` 的文档合并: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .group({ + _id: '$name', + mergedVolume: $.mergeObjects('$volume') + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "A", "mergedVolume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0, "2018Q1": 500, "2018Q2": 500 } } +{ "_id": "B", "mergedVolume": { "2017Q3": 100, "2017Q4": 250, "2018Q1": 100 } } +``` + +**一般用法** + +假设集合 `test` 存在以下文档: + +```typescript +{ "_id": 1, "foo": { "a": 1 }, "bar": { "b": 2 } } +{ "_id": 2, "foo": { "c": 1 }, "bar": { "d": 2 } } +{ "_id": 3, "foo": { "e": 1 }, "bar": { "f": 2 } } +``` + +下面的代码使用 `mergeObjects()`,将文档中的 `foo` 和 `bar` 字段合并为 `foobar`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + foobar: $.mergeObjects(['$foo', '$bar']) + }) + .end() +``` + +输出结果如下: + +```typescript +{ "_id": 1, "foobar": { "a": 1, "b": 2 } } +{ "_id": 2, "foobar": { "c": 1, "d": 2 } } +{ "_id": 3, "foobar": { "e": 1, "f": 2 } } +``` + +## 集合操作符 + +### allElementsTrue + +输入一个数组,或者数组字段的表达式。如果数组中所有元素均为真值,那么返回 `true`,否则返回 `false`。空数组永远返回 `true`。 + +#### API 说明 + +语法如下: + +```typescript +allElementsTrue([]) +``` + +#### 示例代码 + +假设集合 `test` 有如下记录: + +```typescript +{ "_id": 1, "array": [ true ] } +{ "_id": 2, "array": [ ] } +{ "_id": 3, "array": [ false ] } +{ "_id": 4, "array": [ true, false ] } +{ "_id": 5, "array": [ 0 ] } +{ "_id": 6, "array": [ "stark" ] } +``` + +下面的代码使用 `allElementsTrue()`,判断 `array` 字段中是否均为真值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price') + .aggregate() + .project({ + isAllTrue: $.allElementsTrue(['$array']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "isAllTrue": true } +{ "_id": 2, "isAllTrue": true } +{ "_id": 3, "isAllTrue": false } +{ "_id": 4, "isAllTrue": false } +{ "_id": 5, "isAllTrue": false } +{ "_id": 6, "isAllTrue": true } +``` + +### anyElementTrue + +输入一个数组,或者数组字段的表达式。如果数组中任意一个元素为真值,那么返回 `true`,否则返回 `false`。空数组永远返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +anyElementTrue([]) +``` + +#### 示例代码 + + 假设集合 `test` 有如下记录: + +```typescript +{ "_id": 1, "array": [ true ] } +{ "_id": 2, "array": [ ] } +{ "_id": 3, "array": [ false ] } +{ "_id": 4, "array": [ true, false ] } +{ "_id": 5, "array": [ 0 ] } +{ "_id": 6, "array": [ "stark" ] } +``` + +下面的代码使用 `anyElementTrue()`,判断 `array` 字段中是否含有真值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price') + .aggregate() + .project({ + isAnyTrue: $.anyElementTrue(['$array']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "isAnyTrue": true } +{ "_id": 2, "isAnyTrue": false } +{ "_id": 3, "isAnyTrue": false } +{ "_id": 4, "isAnyTrue": true } +{ "_id": 5, "isAnyTrue": false } +{ "_id": 6, "isAnyTrue": true } +``` + +### setDifference + +输入两个集合,输出只存在于第一个集合中的元素。 + +#### API 说明 + + 使用形式如下: + +```typescript +setDifference([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setDifference`,找到只存在于 `B` 中的数字: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + isBOnly: $.setDifference(['$B', '$A']) + }) + .end() +``` + +```typescript +{ "_id": 1, "isBOnly": [] } +{ "_id": 2, "isBOnly": [] } +{ "_id": 3, "isBOnly": [3] } +{ "_id": 4, "isBOnly": [3] } +{ "_id": 5, "isBOnly": [] } +{ "_id": 6, "isBOnly": [{}, []] } +{ "_id": 7, "isBOnly": [] } +{ "_id": 8, "isBOnly": [1] } +``` + +### setEquals + +输入两个集合,判断两个集合中包含的元素是否相同(不考虑顺序、去重)。 + +#### API 说明 + + 使用形式如下: + +```typescript +setEquals([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setEquals`,判断两个集合中包含的元素是否相同: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + sameElements: $.setEquals(['$A', '$B']) + }) + .end() +``` + +```typescript +{ "_id": 1, "sameElements": true } +{ "_id": 2, "sameElements": true } +{ "_id": 3, "sameElements": false } +{ "_id": 4, "sameElements": false } +{ "_id": 5, "sameElements": false } +{ "_id": 6, "sameElements": false } +{ "_id": 7, "sameElements": true } +{ "_id": 8, "sameElements": false } +``` + +### setIntersection + +输入两个集合,输出两个集合的交集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setIntersection([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setIntersection`,输出两个集合的交集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + commonToBoth: $.setIntersection(['$A', '$B']) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": 1, "commonToBoth": [ 1, 2 ] } +{ "_id": 2, "commonToBoth": [ 1, 2 ] } +{ "_id": 3, "commonToBoth": [ 1, 2 ] } +{ "_id": 4, "commonToBoth": [ 1 ] } +{ "_id": 5, "commonToBoth": [ ] } +{ "_id": 6, "commonToBoth": [ ] } +{ "_id": 7, "commonToBoth": [ ] } +{ "_id": 8, "commonToBoth": [ ] } +``` + +### setIsSubset + +输入两个集合,判断第一个集合是否是第二个集合的子集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setIsSubset([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setIsSubset`,判断第一个集合是否是第二个集合的子集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + AisSubsetOfB: $.setIsSubset(['$A', '$B']) + }) + .end() +``` + +```typescript +{ "_id": 1, "AisSubsetOfB": true } +{ "_id": 2, "AisSubsetOfB": true } +{ "_id": 3, "AisSubsetOfB": true } +{ "_id": 4, "AisSubsetOfB": false } +{ "_id": 5, "AisSubsetOfB": false } +{ "_id": 6, "AisSubsetOfB": false } +{ "_id": 7, "AisSubsetOfB": true } +{ "_id": 8, "AisSubsetOfB": true } +``` + +### setUnion + +输入两个集合,输出两个集合的并集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setUnion([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setUnion`,输出两个集合的并集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + AB: $.setUnion(['$A', '$B']) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": 1, "AB": [ 1, 2 ] } +{ "_id": 2, "AB": [ 1, 2 ] } +{ "_id": 3, "AB": [ 1, 2, 3 ] } +{ "_id": 4, "AB": [ 1, 2, 3 ] } +{ "_id": 5, "AB": [ 1, 2 ] } +{ "_id": 6, "AB": [ 1, 2, {}, [] ] } +{ "_id": 7, "AB": [ ] } +{ "_id": 8, "AB": [ 1 ] } +``` + +## 字符串操作符 + +### concat + +连接字符串,返回拼接后的字符串。 + +#### API 说明 + + `concat` 的语法如下: + +```typescript +db.command.aggregate.concat([<表达式1>, <表达式2>, ...]) +``` + +表达式可以是形如 `$ + 指定字段`,也可以是普通字符串。只要能够被解析成字符串即可。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `concat` 可以拼接 `lastName` 和 `firstName` 字段,得到每位学生的名字全称: + +```typescript +const $ = db.command.aggregate +db + .collection('students') + .aggregate() + .project({ + _id: 0, + fullName: $.concat(['$firstName', ' ', '$lastName']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "fullName": "Yuanxin Dong" } +{ "fullName": "Weijia Wang" } +{ "fullName": "Chengxi Li" } +``` + +### indexOfBytes + +在目标字符串中查找子字符串,并返回第一次出现的 `UTF-8` 的字节索引(从 0 开始)。如果不存在子字符串,返回 -1。 + +#### API 说明 + + `indexOfBytes` 的语法如下: + +```typescript +db.command.aggregate.indexOfBytes([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>]) +``` + +下面是 4 种表达式的详细描述: + +|表达式 |描述 | +|---- |---- | +|目标字符串表达式 |任何可以被解析为字符串的表达式 | +|子字符串表达式 |任何可以被解析为字符串的表达式 | +|开始位置表达式 |任何可以被解析为非负整数的表达式 | +|结束位置表达式 |任何可以被解析为非负整数的表达式 | + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `indexOfBytes` 查找字符 `"a"` 在字段 `firstName` 中的位置: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + aStrIndex: $.indexOfBytes(['$firstName', 'a']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "aStrIndex": 2 } +{ "aStrIndex": 5 } +{ "aStrIndex": -1 } +``` + +### indexOfCP + +在目标字符串中查找子字符串,并返回第一次出现的 `UTF-8` 的 `code point` 索引(从 0 开始)。如果不存在子字符串,返回 -1。 + +#### API 说明 + + `code point` 是“码位”,又名“编码位置”。这里特指 `Unicode` 包中的码位,范围是从 0(16 进制)到 10FFFF(16 进制)。 + + `indexOfCP` 的语法如下: + +```typescript +db.command.aggregate.indexOfCP([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>]) +``` + +下面是 4 种表达式的详细描述: + +|表达式 |描述 | +|---- |---- | +|目标字符串表达式 |任何可以被解析为字符串的表达式 | +|子字符串表达式 |任何可以被解析为字符串的表达式 | +|开始位置表达式 |任何可以被解析为非负整数的表达式 | +|结束位置表达式 |任何可以被解析为非负整数的表达式 | + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `indexOfCP` 查找字符 `"a"` 在字段 `firstName` 中的位置: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + aStrIndex: $.indexOfCP(['$firstName', 'a']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "aStrIndex": 2 } +{ "aStrIndex": 5 } +{ "aStrIndex": -1 } +``` + +### split + +按照分隔符分隔数组,并且删除分隔符,返回子字符串组成的数组。如果字符串无法找到分隔符进行分隔,返回原字符串作为数组的唯一元素。 + +#### API 说明 + + `split` 的语法如下: + +```typescript +db.command.aggregate.split([<字符串表达式>, <分隔符表达式>]) +``` + +字符串表达式和分隔符表达式可以是任意形式的表达式,只要它可以被解析为字符串即可。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12" } +{ "birthday": "1998/11/11" } +{ "birthday": "1997/10/10" } +``` + +通过 `split` 将每条记录中的 `birthday` 字段对应值分隔成数组,每个数组分别由代表年、月、日的 3 个元素组成: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + birthday: $.split(['$birthday', '/']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "birthday": [ "1999", "12", "12" ] } +{ "birthday": [ "1998", "11", "11" ] } +{ "birthday": [ "1997", "10", "10" ] } +``` + +### strLenBytes + +计算并返回指定字符串中 `utf-8` 编码的字节数量。 + +#### API 说明 + + `strLenBytes` 的语法如下: + +```typescript +db.command.aggregate.strLenBytes(<表达式>) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `strLenBytes` 计算 `name` 字段和 `nickname` 字段对应值的字节长度: + +```typescript +const $ = db.command.aggregate +db + .collection('students') + .aggregate() + .project({ + _id: 0, + nameLength: $.strLenBytes('$name'), + nicknameLength: $.strLenBytes('$nickname') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "nameLength": 11, "nicknameLength": 6 } +``` + +### strLenCP + +计算并返回指定字符串的 UTF-8 [code points](http://www.unicode.org/glossary/#code_point) 数量。 + +#### API 说明 + + `strLenCP` 的语法如下: + +```typescript +db.command.aggregate.strLenCP(<表达式>) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `strLenCP` 计算 `name` 字段和 `nickname` 字段对应值的 UTF-8 [code points](http://www.unicode.org/glossary/#code_point)的数量: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + nameLength: $.strLenCP('$name'), + nicknameLength: $.strLenCP('$nickname') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "nameLength": 11, "nicknameLength": 2 } +``` + +### strcasecmp + +对两个字符串在不区分大小写的情况下进行大小比较,并返回比较的结果。 + +#### API 说明 + + `strcasecmp` 的语法如下: + +```typescript +db.command.aggregate.strcasecmp([<表达式1>, <表达式2>]) +``` + +只要 `表达式1`和 `表达式2` 可以被解析成字符串,那么它们就是有效的。 + + 返回的比较结果有 1,0 和 -1 三种: + +- 1:`表达式1` 解析的字符串 > `表达式2` 解析的字符串 - 0:`表达式1` 解析的字符串 = `表达式2` 解析的字符串 - -1:`表达式1` 解析的字符串 < `表达式2` 解析的字符串 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `strcasecmp` 比较 `firstName` 字段值和 `lastName` 字段值的大小: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.strcasecmp(['$firstName', '$lastName']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "result": 1 } +{ "result": 1 } +{ "result": -1 } +``` + +### substr + +返回字符串从指定位置开始的指定长度的子字符串。它是 `db.command.aggregate.substrBytes` 的别名,更推荐使用后者。 + +#### API 说明 + + `substr` 的语法如下: + +```typescript +db.command.aggregate.substr([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `substr` 可以提取 `birthday` 中的年、月、日信息,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + year: $.substr(['$birthday', 0, 4]), + month: $.substr(['$birthday', 5, 2]), + day: $.substr(['$birthday', 8, -1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "day": "12", "month": "12", "year": "1999" } +{ "day": "11", "month": "11", "year": "1998" } +{ "day": "10", "month": "10", "year": "1997" } +``` + +### substrBytes + +返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 `UTF-8` 字节索引的字符开始,长度为指定的字节数。 + +#### API 说明 + + `substrBytes` 的语法如下: + +```typescript +db.command.aggregate.substrBytes([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `substrBytes` 可以提取 `birthday` 中的年、月、日信息,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + year: $.substrBytes(['$birthday', 0, 4]), + month: $.substrBytes(['$birthday', 5, 2]), + day: $.substrBytes(['$birthday', 8, -1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "day": "12", "month": "12", "year": "1999" } +{ "day": "11", "month": "11", "year": "1998" } +{ "day": "10", "month": "10", "year": "1997" } +``` + +### substrCP + +返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 `UTF-8` 字节索引的字符开始,长度为指定的字节数。 + +#### API 说明 + + `substrCP` 的语法如下: + +```typescript +db.command.aggregate.substrCP([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `substrCP` 可以提取 `nickname` 字段值的第一个汉字: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + firstCh: $.substrCP(['$nickname', 0, 1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "firstCh": "心" } +``` + +### toLower + +将字符串转化为小写并返回。 + +#### API 说明 + + `toLower` 的语法如下: + +```typescript +db.command.aggregate.toLower(表达式) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。例如:`$ + 指定字段`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `toLower` 将 `firstName` 的字段值转化为小写: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.toLower('$firstName'), + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "result": "yuanxin" } +{ "result": "weijia" } +{ "result": "chengxi" } +``` + +### toUpper + +将字符串转化为大写并返回。 + +#### API 说明 + + `toUpper` 的语法如下: + +```typescript +db.command.aggregate.toUpper(表达式) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。例如:`$ + 指定字段`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `toUpper` 将 `lastName` 的字段值转化为大写: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.toUpper('$lastName'), + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "result": "DONG" } +{ "result": "WANG" } +{ "result": "LI" } +``` + +## 分组运算方法 + +### addToSet + +聚合运算符。向数组中添加值,如果数组中已存在该值,不执行任何操作。它只能在 `group stage` 中使用。 + +#### API 说明 + +`addToSet` 语法如下: + +```typescript +db.command.aggregate.addToSet(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。如果指定字段的值是数组,那么整个数组会被当作一个元素。 + +#### 示例代码 + +假设集合 `passages` 的记录如下: + +```typescript +{ "category": "web", "tags": [ "JavaScript", "CSS" ], "title": "title1" } +{ "category": "System", "tags": [ "C++", "C" ], "title": "title2" } +``` + +**非数组字段** + + 每条记录的 `category` 对应值的类型是非数组,利用 `addToSet` 统计所有分类: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('passages') + .aggregate() + .group({ + _id: null, + categories: $.addToSet('$category') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "categories": [ "System", "web" ] } +``` + +**数组字段** + + 每条记录的 `tags` 对应值的类型是数组,数组不会被自动展开: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('passages') + .aggregate() + .group({ + _id: null, + tagsList: $.addToSet('$tags') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "tagsList": [ [ "C++", "C" ], [ "JavaScript", "CSS" ] ] } +``` + +### avg + + + +返回一组集合中,指定字段对应数据的平均值。 + +#### API 说明 + + `avg` 的语法如下: + +```typescript +db.command.aggregate.avg() +``` + +`avg` 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。它会忽略非数字值。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `avg` 可以计算所有记录的 `score` 的平均值: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: null, + average: $.avg('$score') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "average": 90 } +``` + +### first + +返回指定字段在一组集合的第一条记录对应的值。仅当这组集合是按照某种定义排序( `sort` )后,此操作才有意义。 + +#### API 说明 + + `first` 的语法如下: + +```typescript +db.command.aggregate.first(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + + `first` 只能在 `group` 阶段被使用,并且需要配合 `sort` 才有意义。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +如果需要得到所有记录中 `score` 的最小值,可以先将所有记录按照 `score` 排序,然后取出第一条记录的 `first`。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .sort({ + score: 1 + }) + .group({ + _id: null, + min: $.first('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "min": 80 } +``` + +### last + +返回指定字段在一组集合的最后一条记录对应的值。仅当这组集合是按照某种定义排序( `sort` )后,此操作才有意义。 + +#### API 说明 + + `last` 的语法如下: + +```typescript +db.command.aggregate.last(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + + `last` 只能在 `group` 阶段被使用,并且需要配合 `sort` 才有意义。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +如果需要得到所有记录中 `score` 的最大值,可以先将所有记录按照 `score` 排序,然后取出最后一条记录的 `last`。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .sort({ + score: 1 + }) + .group({ + _id: null, + max: $.last('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "max": 100 } +``` + +### max + +返回一组数值的最大值。 + +#### API 说明 + + `max` 的语法如下: + +```typescript +db.command.aggregate.max(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `max` 可以统计不同组( `group` )中成绩的最高值,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + maxScore: $.max('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "maxScore": 100 } +{ "_id": "a", "maxScore": 96 } +... +``` + +### min + +返回一组数值的最小值。 + +#### API 说明 + + `min` 的语法如下: + +```typescript +db.command.aggregate.min(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `min` 可以统计不同组( `group` )中成绩的最低值,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + minScore: $.min('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "minScore": 80 } +{ "_id": "a", "minScore": 84 } +``` + +### push + +在 `group` 阶段,返回一组中表达式指定列与对应的值,一起组成的数组。 + +#### API 说明 + + `push` 语法如下: + +```typescript +db.command.aggregate.push({ + <字段名1>: <指定字段1>, + <字段名2>: <指定字段2>, + ... +}) +``` + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `push` 操作,对不同分组 ( `group` ) 的所有记录,聚合所有数据并且将其放入一个新的字段中,进一步结构化和语义化数据。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + students: $.push({ + name: '$name', + score: '$score' + }) + }) + .end() +``` + +输出结果如下: + +```typescript +{ "_id": "b", "students": [{ "name": "stu3", "score": 80 }, { "name": "stu4", "score": 100 }] } +{ "_id": "a", "students": [{ "name": "stu1", "score": 84 }, { "name": "stu2", "score": 96 }] } +``` + +### stdDevPop + +返回一组字段对应值的标准差。 + +#### API 说明 + + `stdDevPop` 的使用形式如下: + +```typescript +db.command.aggregate.stdDevPop(<表达式>) +``` + +表达式传入的是指定字段,指定字段对应的值的数据类型必须是 `number` ,否则结果会返回 `null`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下:`a` 组同学的成绩分别是 84 和 96,`b`组同学的成绩分别是 80 和 100。 + +```typescript +{ "group":"a", "score":84 } +{ "group":"a", "score":96 } +{ "group":"b", "score":80 } +{ "group":"b", "score":100 } +``` + +可以用 `stdDevPop` 来分别计算 `a` 和 `b` 两组同学成绩的标准差,以此来比较哪一组同学的成绩更稳定。代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('students').aggregate() + .group({ + _id: '$group', + stdDev: $.stdDevPop('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "stdDev": 10 } +{ "_id": "a", "stdDev": 6 } +``` + +### stdDevSamp + +计算输入值的样本标准偏差。如果输入值代表数据总体,或者不概括更多的数据,请改用 `db.command.aggregate.stdDevPop`。 + +#### API 说明 + + `stdDevSamp` 的使用形式如下: + +```typescript +db.command.aggregate.stdDevSamp(<表达式>) +``` + +表达式传入的是指定字段,`stdDevSamp` 会自动忽略非数字值。如果指定字段所有的值均是非数字,那么结果返回 `null`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "score": 80 } +{ "score": 100 } +``` + +可以用 `stdDevSamp` 来计算成绩的标准样本偏差。代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('students').aggregate() + .group({ + _id: null, + ageStdDev: $.stdDevSamp('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "ageStdDev": 14.142135623730951 } +``` + +如果向集合 `students` 添加一条新记录,它的 `score` 字段类型是 `string`: + +```typescript +{ "score": "aa" } +``` + +用上面代码计算标准样本偏差时,`stdDevSamp` 会自动忽略类型不为 `number` 的记录,返回结果保持不变。 + +### sum + + + +计算并且返回一组字段所有数值的总和。 + +#### API 说明 + + `sum` 的使用形式如下: + +```typescript +db.command.aggregate.sum(<表达式>) +``` + +表达式可以传入指定字段,也可以传入指定字段组成的列表。`sum` 会自动忽略非数字值。如果字段下的所有值均是非数字,那么结果返回 0。若传入数字常量,则当做所有记录该字段的值都给给定常量,在聚合时相加,最终值为输入记录数乘以常量。 + +#### 示例代码 + + 假设代表商品的集合 `goods` 的记录如下:`price` 代表商品销售额,`cost` 代表商品成本 + +```typescript +{ "cost": -10, "price": 100 } +{ "cost": -15, "price": 1 } +{ "cost": -10, "price": 10 } +``` + +**单独字段** + + 借助 `sum` 可以计算所有商品的销售总和,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .group({ + _id: null, + totalPrice: $.sum('$price') + }) + .end() +``` + +返回的数据结果如下:销售额是 111 + +```typescript +{ "_id": null, "totalPrice": 111 } +``` + +**字段列表** + + 如果需要计算所有商品的利润总额,那么需要将每条记录的 `cost` 和 `price` 相加得到此记录对应商品的利润。最后再计算所有商品的利润总额。 + + 借助 `sum`,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .group({ + _id: null, + totalProfit: $.sum( + $.sum(['$price', '$cost']) + ) + }) + .end() +``` + +返回的数据结果如下:利润总额为 76 + +```typescript +{ "_id": null, "totalProfit": 76 } +``` + +## 变量操作符 + +### let + +自定义变量,并且在指定表达式中使用,返回的结果是表达式的结果。 + +#### API 说明 + + `let` 的语法如下: + +```typescript +db.command.aggregate.let({ + vars: { + <变量1>: <变量表达式>, + <变量2>: <变量表达式>, + ... + }, + in: <结果表达式> +}) +``` + +`vars` 中可以定义多个变量,变量的值由 `变量表达式` 计算而来,并且被定义的变量只有在 `in` 中的 `结果表达式` 才可以访问。 + + 在 `in` 的结果表达式中访问自定义变量时候,请在变量名前加上双美元符号 ( `$$` ) 并用引号括起来。 + +#### 示例代码 + + 假设代表商品的集合 `goods` 的记录如下:`price` 代表商品价格,`discount` 代表商品折扣率,`cost` 代表商品成本 + +```typescript +{ "cost": -10, "discount": 0.95, "price": 100 } +{ "cost": -15, "discount": 0.98, "price": 1 } +{ "cost": -10, "discount": 1, "price": 10 } +``` + +借助 `let` 可以定义并计算每件商品实际的销售价格,并将其赋值给自定义变量 `priceTotal`。最后再将 `priceTotal` 与 `cost` 进行取和 ( `sum` ) 运算,得到每件商品的利润。 + + 代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .project({ + profit: $.let({ + vars: { + priceTotal: $.multiply(['$price', '$discount']) + }, + in: $.sum(['$$priceTotal', '$cost']) + }) + }) + .end() +``` + +返回的数据结果如下: + +``` +{ "profit": 85 } +{ "profit": -14.02 } +{ "profit": 0 } +``` diff --git a/docs_deprecated/guide/db/policy.md b/docs_deprecated/guide/db/policy.md new file mode 100644 index 0000000000..86a1a48f59 --- /dev/null +++ b/docs_deprecated/guide/db/policy.md @@ -0,0 +1,265 @@ +--- +title: 访问策略 +--- + +# {{ $frontmatter.title }} + +前端可使用 [laf-client-sdk](https://github.com/labring/laf/tree/main/packages/client-sdk) “直连”数据库,无需与服务端对接口。 + +访问策略用来对客户端对数据库的操作进行安全控制,一个访问策略由多个集合的访问规则组成,每个集合可配置读写操作权限的访问规则。 + +开发者可以为应用创建多个访问策略,以供不同的客户端使用。 + +通常应用可创建两个访问策略: + +- `app` 用于用户端客户端的访问策略,一般可以是 App、小程序、H5 等 +- `admin` 用于应用的后台管理的访问策略 + +## 创建策略 + +首先我们切换到集合页面,按照下面步骤为 user 集合添加一个访问策略。 + +:::tip +如果你还没有 user 集合就先创建一个。 +::: + +![creat-polocy](../../doc-images/creat-polocy.png) + +![add-polocy](../../doc-images/add-polocy.png) + +做完这两步之后,我们就成功的创建了一个访问策略,并且把策略放在了 user 集合上。 +这里我们解释一下规则内容: + +```js +{ + "read": true, // 查询权限 + "count": true, // 计数权限 + "update": false, // 修改权限 + "remove": false, // 删除权限 + "add": false // 新增权限 +} +``` + +我们把值设为 true 则代表允许,false 则为不允许,按照我们刚刚默认的规则,前端可以直接对我们的集合进行`查询`和`计数`操作,而增 删 改,是不允许的。 +这里还有另外一个值得留意的地方,就是"入口地址" 刚刚我们设置的策略名称为 app,那么入口地址就是 /proxy/app,接下来演示一下如何使用。 + +## 前端“直连” + +在演示之前我们先往 user 集合中加一点数据。 + +![polocy-db-data](../../doc-images/polocy-db-data.png) + +我们来到前端项目,这里使用 Vue 项目来演示,其他项目同理。 + +### 首先安装 SDK + +```bash +npm i laf-client-sdk +``` + +### 然后创建 cloud 对像 + +这里注意了,我们多填写一个参数 dbProxyUrl,那么它的值就是我们刚刚强调的入口地址 `/proxy/app` + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https:/.laf.run", // 在首页应用列表获取 + getAccessToken: () => "", // 这里不需要授权,先填空 + dbProxyUrl: "/proxy/app", // 这里就填写我们刚刚强调的“入口地址” +}) +``` + +创建完 cloud 对像之后我们尝试一下在前端直接发起查询。 + +```js +async function get() { + const res = await cloud.database().collection("user").get(); + console.log(res); +// { +// "data": [ +// { +// "_id": "641d22292de2b789c963e5fd", +// "name": "jack" +// }, +// { +// "_id": "641e87d52c9ce609db4d6047", +// "name": "rose" +// } +// ], +// "ok": true +// } +} +``` + +现在我们来试试 count。 + +```js +async function get() { + const res = await cloud.database().collection("user").count(); + console.log(res); + // { + // "total": 2, + // "ok": true + // } +} +``` + +可以看到,简单的查询计数我们已经不需要写云函数,直接在前端即可实现,如果你想体验 `增删改` 可以修改对应策略的权限为 true,但这是一个很危险的行为。 + +访问策略也可以是表达式,以下为 `users` (用户集合)的访问策略示例: +其中`query` 是数据查询的条件对象,`uid === query._id` 表示该策略只允许当前用户读取自己的用户数据。 + +```json + "users" + { + "read": "uid === query._id" + } +``` + +> 注意: `uid` 为 JWT Payload 中的字段,代表当前登录用户的 ID,你可在云函数中生成 JWT 令牌,其中 payload 中的字段都可在访问策略中使用。 + +## 验证器 + +访问规则由一个或多个验证器组成,`"read": true` 使用的是 `condition` 验证器,该验证器接一个表达式来控制是否允许访问。 +以上使用的是简写形式,完整的写法如下: + +```json +{ + "read": { + "condition": true + } +} +``` + +当前内置了以下验证器: + +- `condition` 条件验证器,接受一个表达式,返回真值即代表允许访问,表达式中默认可用对象有 + - `JWT Payloads` JWT 令牌 payload 中的字段,如示例中的 `uid` + - `query` 数据查询条件 + - `data` 更新或新增数据操作时的数据对象 +- `data` 数据验证器,接受一个对象,对「更新或新增数据操作时的数据对象」中的各字段进行验证,具体参考以下示例 +- `query` 查询条件对象验证器,接受一个对象,对「查询条件对象」中的各字段进行验证,具体参考以下示例 +- `multi` 是否允许批量操作,接受一个表达式做为配置。默认只有 `read` 操作允许批量操作,如需开启其它批量操作需要显式指定此验证器 + +## 实践建议 + +初识访问规则,可能会觉其烦琐难以掌握,而且容易写错,或是对其安全性不自信、自知,所以根据我们在大量项目中的实践经验,给出一些建议: + +- 最小权限原则,即只给客户端必要的访问权限,只开放给客户端必要的集合; + + - 即便只开放 `read` 权限,也可能节省 30%~ 50% 的后端接口; + - 再配合一些基本的 `condition` 判断,可有效减少 70%~ 90% 的后端接口; + +- 事务性的数据操作、复杂的表单提交,建议使用云函数实现: + + - 云函数与客户端 SDK 接口一致,简单、轻量、快捷,无二次学习成本,调试更容易、无部署负担 + - 云函数中访问数据库,无需编写访问规则,因为云函数是服务端执行的可信代码 + +- 访问规则虽然也可以完成很多复杂的验证,但是除非你非常熟练的掌握了它,否则建议用云函数来实现这部分逻辑 + +## 访问规则示例 + +> 提供几个简单的示例以供参考和理解。 + +### 简单示例 1:简单个人博客 + +```json +"categories" +{ + "read": true, + "update": "uid", + "add": "uid", + "remove": "uid" +}, +"articles" +{ + "read": true, + "update": "uid", + "add": "uid", + "remove": "uid" +} +``` + +> 提示:其中类似 `"update": "uid"` 的规则,是 `uid` 不为假值的意思 (undefined | null | false 等) + +### 简单示例 2:多用户博客 + +```json + +{ + "read": true, + "update": "uid === query.author_id", + "add": "uid === query.author_id", + "remove": "uid === query.author_id" +} + +``` + +### 复杂示例 1:数据验证 + +```json +{ + "read": true, + "add": { + "condition": "uid === query.author_id", + "data": { + "title": { "length": [1, 64], "required": true }, + "content": { "length": [1, 4096] }, + "status": { "boolean": [true, false] }, + "likes": { "number": [0], "default": 0 }, + "author_id": "$value == uid" + } + }, + "remove": "uid === query.author_id", + "count": true +} +``` + +### 复杂示例 2:更高级的数据验证 + +> 场景介绍:用户之间站内消息表访问规则 + +```json +{ + "read": "uid === query.receiver || uid === query.sender", + "update": { + "condition": "$uid === query.receiver", + "data": { + "read": { "in": [true] } + } + }, + "add": { + "condition": "uid === data.sender", + "data": { + "read": { "in": [false] }, + "content": { "length": [1, 20480], "required": true }, + "receiver": { "exists": "/users/id" }, + "read": { "in": [true, false], "default": false } + } + }, + "remove": false +} +``` + +### data 验证器示例 + +```json + "categories" +{ + "read": true, + "update": "role === 'admin'", + "add": { + "condition": "role === 'admin'", + "data": { + "password": { "match": "^\\d{6,10}$" }, + "author_id": "$value == uid", + "type": { "required": true, "in": ["choice", "fill"] }, + "title": { "length": [4, 64], "required": true, "unique": true }, + "content": { "length": [4, 20480] }, + "total": { "number": [0, 100], "default": 0, "required": true } + } + } +} +``` diff --git a/docs_deprecated/guide/db/quickstart.md b/docs_deprecated/guide/db/quickstart.md new file mode 100644 index 0000000000..b2bd2278db --- /dev/null +++ b/docs_deprecated/guide/db/quickstart.md @@ -0,0 +1,146 @@ +--- +title: 数据库入门 +--- + +# {{ $frontmatter.title }} + +Laf 为每个应用提供了一个开箱即用的数据库,并且非常易用。下面是一个简单的数据库的增删改查的例子,来快速的了解 Laf 的数据库操作。 + +## 新建数据库实例 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() +// db 为新建的数据库实例 +``` + +## 云函数插入文档 + +使用 `add` 方法可以往集合插入数据 + +如下例子:往 `user` 集合中添加一个文档,`name` 为 `Jack` 的数据 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').add({ + name: 'Jack' + }) + console.log(res) +} +``` + +```json +// 集合 test 中会新增数据,_id 为自动生成 +{ + "_id": "6442b2cac4f3afd9a186ecd9", + "name": "Jack" +} +``` + +## 云函数查询文档 + +使用 `get` 方法可以查询集合中的文档 + +::: tip +`get` 方法一次最多能获取 100 条记录,如需一次查询更多请看数据查询文档 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').get() + console.log(res) + // 查询结果 + // { + // data: [ { _id: '6442b2cac4f3afd9a186ecd9', name: 'Jack' } ], + // requestId: undefined, + // ok: true + // } +} +``` + +使用 `getOne` 方法查询集合中的文档 + +::: tip +`getOne` 方法一次获取一条最新数据 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').getOne() + console.log(res) + // 查询结果 + // { + // ok: true, + // data: { _id: '6442b2cac4f3afd9a186ecd9', name: 'Jack' }, + // requestId: undefined + // } +} +``` + +## 云函数修改文档 + +查出 `name` 为 `Jack` 的文档的_id,然后根据_id 修改文档 + +使用 `update` 方法修改文档 + +::: tip +`where` 可设置查询条件,`doc` 根据 id 查询 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('test').where({ + name:'Jack' + }).get() + // console.log(res) + const id = res.data[0]._id + const updateRes = await db.collection('test').doc(id).update({ + name:'Tom' + }) + console.log(updateRes) + // 修改结果:updated:1 代表已成功修改 1 个文档 + // { + // requestId: undefined, + // updated: 1, + // matched: 1, + // upsertId: null, + // ok: true + // } +} +``` + +## 云函数删除文档 + +先查出 `name` 为 `Tom` 的文档并删除 + +::: tip +`remove` 默认只能删除单条数据,如需批量删除,请查看数据删除文档 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('test').where({ name: "Tom" }).remove() + console.log(res) + // 删除结果:deleted:1 代表已成功删除 1 个文档 + // { requestId: undefined, deleted: 1, ok: true } +} +``` + +-------- + +相信一步一步跟着文档操作,已经初步的了解数据库的增删改查,但是如果需要深入使用数据库操作,还需要仔细查看后续的文档 diff --git a/docs/guide/db/update.md b/docs_deprecated/guide/db/update.md similarity index 100% rename from docs/guide/db/update.md rename to docs_deprecated/guide/db/update.md diff --git a/docs/guide/function/call-function-in-client.md b/docs_deprecated/guide/function/call-function-in-client.md similarity index 100% rename from docs/guide/function/call-function-in-client.md rename to docs_deprecated/guide/function/call-function-in-client.md diff --git a/docs/guide/function/call-function-in-http.md b/docs_deprecated/guide/function/call-function-in-http.md similarity index 100% rename from docs/guide/function/call-function-in-http.md rename to docs_deprecated/guide/function/call-function-in-http.md diff --git a/docs/guide/function/depend.md b/docs_deprecated/guide/function/depend.md similarity index 100% rename from docs/guide/function/depend.md rename to docs_deprecated/guide/function/depend.md diff --git a/docs/guide/function/env.md b/docs_deprecated/guide/function/env.md similarity index 100% rename from docs/guide/function/env.md rename to docs_deprecated/guide/function/env.md diff --git a/docs/guide/function/faq.md b/docs_deprecated/guide/function/faq.md similarity index 100% rename from docs/guide/function/faq.md rename to docs_deprecated/guide/function/faq.md diff --git a/docs/guide/function/function-market.md b/docs_deprecated/guide/function/function-market.md similarity index 100% rename from docs/guide/function/function-market.md rename to docs_deprecated/guide/function/function-market.md diff --git a/docs/guide/function/function-param.md b/docs_deprecated/guide/function/function-param.md similarity index 100% rename from docs/guide/function/function-param.md rename to docs_deprecated/guide/function/function-param.md diff --git a/docs/guide/function/function-sdk.md b/docs_deprecated/guide/function/function-sdk.md similarity index 100% rename from docs/guide/function/function-sdk.md rename to docs_deprecated/guide/function/function-sdk.md diff --git a/docs/guide/function/index.md b/docs_deprecated/guide/function/index.md similarity index 100% rename from docs/guide/function/index.md rename to docs_deprecated/guide/function/index.md diff --git a/docs/guide/function/init.md b/docs_deprecated/guide/function/init.md similarity index 100% rename from docs/guide/function/init.md rename to docs_deprecated/guide/function/init.md diff --git a/docs/guide/function/interceptor.md b/docs_deprecated/guide/function/interceptor.md similarity index 100% rename from docs/guide/function/interceptor.md rename to docs_deprecated/guide/function/interceptor.md diff --git a/docs/guide/function/logs.md b/docs_deprecated/guide/function/logs.md similarity index 100% rename from docs/guide/function/logs.md rename to docs_deprecated/guide/function/logs.md diff --git a/docs/guide/function/pilot.md b/docs_deprecated/guide/function/pilot.md similarity index 100% rename from docs/guide/function/pilot.md rename to docs_deprecated/guide/function/pilot.md diff --git a/docs/guide/function/trigger.md b/docs_deprecated/guide/function/trigger.md similarity index 100% rename from docs/guide/function/trigger.md rename to docs_deprecated/guide/function/trigger.md diff --git a/docs/guide/function/use-function.md b/docs_deprecated/guide/function/use-function.md similarity index 100% rename from docs/guide/function/use-function.md rename to docs_deprecated/guide/function/use-function.md diff --git a/docs/guide/function/websocket.md b/docs_deprecated/guide/function/websocket.md similarity index 100% rename from docs/guide/function/websocket.md rename to docs_deprecated/guide/function/websocket.md diff --git a/docs/guide/index.md b/docs_deprecated/guide/index.md similarity index 100% rename from docs/guide/index.md rename to docs_deprecated/guide/index.md diff --git a/docs/guide/laf-assistant/index.md b/docs_deprecated/guide/laf-assistant/index.md similarity index 100% rename from docs/guide/laf-assistant/index.md rename to docs_deprecated/guide/laf-assistant/index.md diff --git a/docs/guide/oss/gen-oss-url.md b/docs_deprecated/guide/oss/gen-oss-url.md similarity index 100% rename from docs/guide/oss/gen-oss-url.md rename to docs_deprecated/guide/oss/gen-oss-url.md diff --git a/docs/guide/oss/get-sts.md b/docs_deprecated/guide/oss/get-sts.md similarity index 100% rename from docs/guide/oss/get-sts.md rename to docs_deprecated/guide/oss/get-sts.md diff --git a/docs/guide/oss/index.md b/docs_deprecated/guide/oss/index.md similarity index 100% rename from docs/guide/oss/index.md rename to docs_deprecated/guide/oss/index.md diff --git a/docs/guide/oss/oss-by-function.md b/docs_deprecated/guide/oss/oss-by-function.md similarity index 100% rename from docs/guide/oss/oss-by-function.md rename to docs_deprecated/guide/oss/oss-by-function.md diff --git a/docs/guide/oss/upload-by-function.md b/docs_deprecated/guide/oss/upload-by-function.md similarity index 100% rename from docs/guide/oss/upload-by-function.md rename to docs_deprecated/guide/oss/upload-by-function.md diff --git a/docs/guide/oss/use-sts-in-client.md b/docs_deprecated/guide/oss/use-sts-in-client.md similarity index 100% rename from docs/guide/oss/use-sts-in-client.md rename to docs_deprecated/guide/oss/use-sts-in-client.md diff --git a/docs/guide/quick-start/Todo.md b/docs_deprecated/guide/quick-start/Todo.md similarity index 100% rename from docs/guide/quick-start/Todo.md rename to docs_deprecated/guide/quick-start/Todo.md diff --git a/docs/guide/quick-start/login.md b/docs_deprecated/guide/quick-start/login.md similarity index 100% rename from docs/guide/quick-start/login.md rename to docs_deprecated/guide/quick-start/login.md diff --git a/docs/guide/specification/index.md b/docs_deprecated/guide/specification/index.md similarity index 100% rename from docs/guide/specification/index.md rename to docs_deprecated/guide/specification/index.md diff --git a/docs/guide/web-ide/index.md b/docs_deprecated/guide/web-ide/index.md similarity index 100% rename from docs/guide/web-ide/index.md rename to docs_deprecated/guide/web-ide/index.md diff --git a/docs/guide/website-hosting/index.md b/docs_deprecated/guide/website-hosting/index.md similarity index 100% rename from docs/guide/website-hosting/index.md rename to docs_deprecated/guide/website-hosting/index.md diff --git a/docs/index.md b/docs_deprecated/index.md similarity index 100% rename from docs/index.md rename to docs_deprecated/index.md diff --git a/docs_deprecated/package-lock.json b/docs_deprecated/package-lock.json new file mode 100644 index 0000000000..1470416b89 --- /dev/null +++ b/docs_deprecated/package-lock.json @@ -0,0 +1,2052 @@ +{ + "name": "laf-docs", + "version": "1.0.0-beta.11", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "laf-docs", + "version": "1.0.0-beta.11", + "hasInstallScript": true, + "dependencies": { + "markdown-it-custom-attrs": "^1.0.2", + "vitepress": "^1.0.0-alpha.29" + }, + "devDependencies": { + "flexsearch": "^0.7.31", + "vitepress-plugin-search": "^1.0.4-alpha.20" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", + "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", + "dependencies": { + "@algolia/autocomplete-shared": "1.7.4" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", + "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", + "dependencies": { + "@algolia/autocomplete-shared": "1.7.4" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", + "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", + "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", + "dependencies": { + "@algolia/cache-common": "4.17.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", + "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", + "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", + "dependencies": { + "@algolia/cache-common": "4.17.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", + "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", + "dependencies": { + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", + "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", + "dependencies": { + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", + "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", + "dependencies": { + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", + "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", + "dependencies": { + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", + "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", + "dependencies": { + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", + "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", + "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", + "dependencies": { + "@algolia/logger-common": "4.17.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", + "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", + "dependencies": { + "@algolia/requester-common": "4.17.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", + "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", + "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", + "dependencies": { + "@algolia/requester-common": "4.17.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", + "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", + "dependencies": { + "@algolia/cache-common": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/requester-common": "4.17.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", + "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" + }, + "node_modules/@docsearch/js": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", + "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", + "dependencies": { + "@docsearch/react": "3.3.3", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/react": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", + "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", + "dependencies": { + "@algolia/autocomplete-core": "1.7.4", + "@algolia/autocomplete-preset-algolia": "1.7.4", + "@docsearch/css": "3.3.3", + "algoliasearch": "^4.0.0" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", + "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", + "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", + "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", + "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", + "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", + "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", + "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", + "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", + "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", + "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", + "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", + "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", + "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", + "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", + "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", + "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", + "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", + "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", + "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", + "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", + "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", + "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/flexsearch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", + "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", + "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", + "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", + "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", + "dependencies": { + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", + "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.47", + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-ssr": "3.2.47", + "@vue/reactivity-transform": "3.2.47", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", + "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", + "dependencies": { + "@vue/compiler-dom": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", + "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" + }, + "node_modules/@vue/reactivity": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", + "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", + "dependencies": { + "@vue/shared": "3.2.47" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", + "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", + "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", + "dependencies": { + "@vue/reactivity": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", + "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", + "dependencies": { + "@vue/runtime-core": "3.2.47", + "@vue/shared": "3.2.47", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", + "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", + "dependencies": { + "@vue/compiler-ssr": "3.2.47", + "@vue/shared": "3.2.47" + }, + "peerDependencies": { + "vue": "3.2.47" + } + }, + "node_modules/@vue/shared": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", + "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" + }, + "node_modules/@vueuse/core": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", + "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "10.0.2", + "@vueuse/shared": "10.0.2", + "vue-demi": ">=0.14.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", + "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", + "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", + "dependencies": { + "vue-demi": ">=0.14.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "node_modules/algoliasearch": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", + "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.17.0", + "@algolia/cache-common": "4.17.0", + "@algolia/cache-in-memory": "4.17.0", + "@algolia/client-account": "4.17.0", + "@algolia/client-analytics": "4.17.0", + "@algolia/client-common": "4.17.0", + "@algolia/client-personalization": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/logger-console": "4.17.0", + "@algolia/requester-browser-xhr": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/requester-node-http": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/body-scroll-lock": { + "version": "4.0.0-beta.0", + "resolved": "https://registry.npmmirror.com/body-scroll-lock/-/body-scroll-lock-4.0.0-beta.0.tgz", + "integrity": "sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==" + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", + "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.17", + "@esbuild/android-arm64": "0.17.17", + "@esbuild/android-x64": "0.17.17", + "@esbuild/darwin-arm64": "0.17.17", + "@esbuild/darwin-x64": "0.17.17", + "@esbuild/freebsd-arm64": "0.17.17", + "@esbuild/freebsd-x64": "0.17.17", + "@esbuild/linux-arm": "0.17.17", + "@esbuild/linux-arm64": "0.17.17", + "@esbuild/linux-ia32": "0.17.17", + "@esbuild/linux-loong64": "0.17.17", + "@esbuild/linux-mips64el": "0.17.17", + "@esbuild/linux-ppc64": "0.17.17", + "@esbuild/linux-riscv64": "0.17.17", + "@esbuild/linux-s390x": "0.17.17", + "@esbuild/linux-x64": "0.17.17", + "@esbuild/netbsd-x64": "0.17.17", + "@esbuild/openbsd-x64": "0.17.17", + "@esbuild/sunos-x64": "0.17.17", + "@esbuild/win32-arm64": "0.17.17", + "@esbuild/win32-ia32": "0.17.17", + "@esbuild/win32-x64": "0.17.17" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/flexsearch": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", + "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/hexo-pagination": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.1.0.tgz", + "integrity": "sha512-Ji/LYq7xP7cdBdG15CJ4YZZNA/c6Kf64rXj+Jp2bKsC2JTgcBmz+GGkHwpk6aoMHXRP2XraxGcGjXhITr7ooYg==", + "dependencies": { + "object-assign": "^4.1.0" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + }, + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-custom-attrs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", + "integrity": "sha512-6jiuxs//DhkFe7K3z5Y3nF1E6Lk2GRKGVzk8IpusxPZL90rOOhwEAtYjOGjRBPQctK56kJreCnFmPSUW0n3YeQ==", + "dependencies": { + "hexo-pagination": "^0.1.0", + "lodash.pick": "^4.4.0", + "nunjucks": "^3.0.1" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/minisearch": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", + "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/rollup": { + "version": "3.20.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", + "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/shiki": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", + "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/vite": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", + "dependencies": { + "esbuild": "^0.17.5", + "postcss": "^8.4.21", + "rollup": "^3.20.2" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitepress": { + "version": "1.0.0-alpha.72", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", + "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", + "dependencies": { + "@docsearch/css": "^3.3.3", + "@docsearch/js": "^3.3.3", + "@vitejs/plugin-vue": "^4.1.0", + "@vue/devtools-api": "^6.5.0", + "@vueuse/core": "^10.0.2", + "body-scroll-lock": "4.0.0-beta.0", + "mark.js": "^8.11.1", + "minisearch": "^6.0.1", + "shiki": "^0.14.1", + "vite": "^4.2.1", + "vue": "^3.2.47" + }, + "bin": { + "vitepress": "bin/vitepress.js" + } + }, + "node_modules/vitepress-plugin-search": { + "version": "1.0.4-alpha.20", + "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", + "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", + "dev": true, + "dependencies": { + "@types/flexsearch": "^0.7.3", + "@types/markdown-it": "^12.2.3", + "glob-to-regexp": "^0.4.1", + "markdown-it": "^13.0.1" + }, + "engines": { + "node": "^14.13.1 || ^16.7.0 || >=18" + }, + "peerDependencies": { + "flexsearch": "^0.7.31", + "vitepress": "^1.0.0-alpha.65", + "vue": "3" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" + }, + "node_modules/vue": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", + "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", + "dependencies": { + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-sfc": "3.2.47", + "@vue/runtime-dom": "3.2.47", + "@vue/server-renderer": "3.2.47", + "@vue/shared": "3.2.47" + } + } + }, + "dependencies": { + "@algolia/autocomplete-core": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz", + "integrity": "sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==", + "requires": { + "@algolia/autocomplete-shared": "1.7.4" + } + }, + "@algolia/autocomplete-preset-algolia": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.4.tgz", + "integrity": "sha512-s37hrvLEIfcmKY8VU9LsAXgm2yfmkdHT3DnA3SgHaY93yjZ2qL57wzb5QweVkYuEBZkT2PIREvRoLXC2sxTbpQ==", + "requires": { + "@algolia/autocomplete-shared": "1.7.4" + } + }, + "@algolia/autocomplete-shared": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.4.tgz", + "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" + }, + "@algolia/cache-browser-local-storage": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", + "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", + "requires": { + "@algolia/cache-common": "4.17.0" + } + }, + "@algolia/cache-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", + "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" + }, + "@algolia/cache-in-memory": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", + "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", + "requires": { + "@algolia/cache-common": "4.17.0" + } + }, + "@algolia/client-account": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", + "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", + "requires": { + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "@algolia/client-analytics": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", + "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", + "requires": { + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "@algolia/client-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", + "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", + "requires": { + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "@algolia/client-personalization": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", + "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", + "requires": { + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "@algolia/client-search": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", + "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", + "requires": { + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "@algolia/logger-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", + "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" + }, + "@algolia/logger-console": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", + "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", + "requires": { + "@algolia/logger-common": "4.17.0" + } + }, + "@algolia/requester-browser-xhr": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", + "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", + "requires": { + "@algolia/requester-common": "4.17.0" + } + }, + "@algolia/requester-common": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", + "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" + }, + "@algolia/requester-node-http": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", + "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", + "requires": { + "@algolia/requester-common": "4.17.0" + } + }, + "@algolia/transporter": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", + "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", + "requires": { + "@algolia/cache-common": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/requester-common": "4.17.0" + } + }, + "@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==" + }, + "@docsearch/css": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", + "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" + }, + "@docsearch/js": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", + "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", + "requires": { + "@docsearch/react": "3.3.3", + "preact": "^10.0.0" + } + }, + "@docsearch/react": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", + "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", + "requires": { + "@algolia/autocomplete-core": "1.7.4", + "@algolia/autocomplete-preset-algolia": "1.7.4", + "@docsearch/css": "3.3.3", + "algoliasearch": "^4.0.0" + } + }, + "@esbuild/android-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", + "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", + "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", + "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", + "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", + "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", + "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", + "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", + "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", + "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", + "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", + "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", + "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", + "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", + "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", + "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", + "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", + "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", + "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", + "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", + "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", + "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", + "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", + "optional": true + }, + "@types/flexsearch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", + "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", + "dev": true + }, + "@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, + "@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + }, + "@vitejs/plugin-vue": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", + "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", + "requires": {} + }, + "@vue/compiler-core": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", + "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", + "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", + "requires": { + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "@vue/compiler-sfc": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", + "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.47", + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-ssr": "3.2.47", + "@vue/reactivity-transform": "3.2.47", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-ssr": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", + "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", + "requires": { + "@vue/compiler-dom": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "@vue/devtools-api": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", + "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" + }, + "@vue/reactivity": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", + "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", + "requires": { + "@vue/shared": "3.2.47" + } + }, + "@vue/reactivity-transform": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", + "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.47", + "@vue/shared": "3.2.47", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "@vue/runtime-core": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", + "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", + "requires": { + "@vue/reactivity": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "@vue/runtime-dom": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", + "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", + "requires": { + "@vue/runtime-core": "3.2.47", + "@vue/shared": "3.2.47", + "csstype": "^2.6.8" + } + }, + "@vue/server-renderer": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", + "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", + "requires": { + "@vue/compiler-ssr": "3.2.47", + "@vue/shared": "3.2.47" + } + }, + "@vue/shared": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", + "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" + }, + "@vueuse/core": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", + "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", + "requires": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "10.0.2", + "@vueuse/shared": "10.0.2", + "vue-demi": ">=0.14.0" + }, + "dependencies": { + "vue-demi": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "requires": {} + } + } + }, + "@vueuse/metadata": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", + "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==" + }, + "@vueuse/shared": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", + "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", + "requires": { + "vue-demi": ">=0.14.0" + }, + "dependencies": { + "vue-demi": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", + "requires": {} + } + } + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "algoliasearch": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", + "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", + "requires": { + "@algolia/cache-browser-local-storage": "4.17.0", + "@algolia/cache-common": "4.17.0", + "@algolia/cache-in-memory": "4.17.0", + "@algolia/client-account": "4.17.0", + "@algolia/client-analytics": "4.17.0", + "@algolia/client-common": "4.17.0", + "@algolia/client-personalization": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/logger-console": "4.17.0", + "@algolia/requester-browser-xhr": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/requester-node-http": "4.17.0", + "@algolia/transporter": "4.17.0" + } + }, + "ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "body-scroll-lock": { + "version": "4.0.0-beta.0", + "resolved": "https://registry.npmmirror.com/body-scroll-lock/-/body-scroll-lock-4.0.0-beta.0.tgz", + "integrity": "sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, + "esbuild": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", + "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", + "requires": { + "@esbuild/android-arm": "0.17.17", + "@esbuild/android-arm64": "0.17.17", + "@esbuild/android-x64": "0.17.17", + "@esbuild/darwin-arm64": "0.17.17", + "@esbuild/darwin-x64": "0.17.17", + "@esbuild/freebsd-arm64": "0.17.17", + "@esbuild/freebsd-x64": "0.17.17", + "@esbuild/linux-arm": "0.17.17", + "@esbuild/linux-arm64": "0.17.17", + "@esbuild/linux-ia32": "0.17.17", + "@esbuild/linux-loong64": "0.17.17", + "@esbuild/linux-mips64el": "0.17.17", + "@esbuild/linux-ppc64": "0.17.17", + "@esbuild/linux-riscv64": "0.17.17", + "@esbuild/linux-s390x": "0.17.17", + "@esbuild/linux-x64": "0.17.17", + "@esbuild/netbsd-x64": "0.17.17", + "@esbuild/openbsd-x64": "0.17.17", + "@esbuild/sunos-x64": "0.17.17", + "@esbuild/win32-arm64": "0.17.17", + "@esbuild/win32-ia32": "0.17.17", + "@esbuild/win32-x64": "0.17.17" + } + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "flexsearch": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", + "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "hexo-pagination": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.1.0.tgz", + "integrity": "sha512-Ji/LYq7xP7cdBdG15CJ4YZZNA/c6Kf64rXj+Jp2bKsC2JTgcBmz+GGkHwpk6aoMHXRP2XraxGcGjXhITr7ooYg==", + "requires": { + "object-assign": "^4.1.0" + } + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-custom-attrs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", + "integrity": "sha512-6jiuxs//DhkFe7K3z5Y3nF1E6Lk2GRKGVzk8IpusxPZL90rOOhwEAtYjOGjRBPQctK56kJreCnFmPSUW0n3YeQ==", + "requires": { + "hexo-pagination": "^0.1.0", + "lodash.pick": "^4.4.0", + "nunjucks": "^3.0.1" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "minisearch": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", + "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "nunjucks": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", + "integrity": "sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==", + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "preact": { + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==" + }, + "rollup": { + "version": "3.20.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", + "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "shiki": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", + "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", + "requires": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "vite": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", + "requires": { + "esbuild": "^0.17.5", + "fsevents": "~2.3.2", + "postcss": "^8.4.21", + "rollup": "^3.20.2" + } + }, + "vitepress": { + "version": "1.0.0-alpha.72", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", + "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", + "requires": { + "@docsearch/css": "^3.3.3", + "@docsearch/js": "^3.3.3", + "@vitejs/plugin-vue": "^4.1.0", + "@vue/devtools-api": "^6.5.0", + "@vueuse/core": "^10.0.2", + "body-scroll-lock": "4.0.0-beta.0", + "mark.js": "^8.11.1", + "minisearch": "^6.0.1", + "shiki": "^0.14.1", + "vite": "^4.2.1", + "vue": "^3.2.47" + } + }, + "vitepress-plugin-search": { + "version": "1.0.4-alpha.20", + "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", + "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", + "dev": true, + "requires": { + "@types/flexsearch": "^0.7.3", + "@types/markdown-it": "^12.2.3", + "glob-to-regexp": "^0.4.1", + "markdown-it": "^13.0.1" + } + }, + "vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" + }, + "vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" + }, + "vue": { + "version": "3.2.47", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", + "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", + "requires": { + "@vue/compiler-dom": "3.2.47", + "@vue/compiler-sfc": "3.2.47", + "@vue/runtime-dom": "3.2.47", + "@vue/server-renderer": "3.2.47", + "@vue/shared": "3.2.47" + } + } + } +} diff --git a/docs_deprecated/package.json b/docs_deprecated/package.json new file mode 100644 index 0000000000..ba69409e1d --- /dev/null +++ b/docs_deprecated/package.json @@ -0,0 +1,27 @@ +{ + "version": "1.0.0-beta.11", + "name": "laf-docs", + "private": true, + "scripts": { + "start": "npm run dev", + "dev": "vitepress dev", + "preinstall": "node ./scripts/check-version.js", + "build": "vitepress build", + "serve": "vitepress serve", + "after-build": "sed -i -e \"s@@@g\" ./.vitepress/dist/index.html", + "docs:deploy": "npm run build && sh ./deploy.sh", + "docker-build": "docker build --platform linux/amd64 -t lafyun/docs:latest .", + "lint": "eslint . --fix --ext .ts --ext .js" + }, + "dependencies": { + "markdown-it-custom-attrs": "^1.0.2", + "vitepress": "^1.0.0-alpha.29" + }, + "devDependencies": { + "flexsearch": "^0.7.31", + "vitepress-plugin-search": "^1.0.4-alpha.20" + }, + "lint-staged": { + "*.{ts,js}": "eslint --fix" + } +} \ No newline at end of file diff --git a/docs_deprecated/public/CNAME b/docs_deprecated/public/CNAME new file mode 100644 index 0000000000..c79e13da62 --- /dev/null +++ b/docs_deprecated/public/CNAME @@ -0,0 +1 @@ +lafjs.github.io \ No newline at end of file diff --git a/docs_deprecated/public/fancybox.css b/docs_deprecated/public/fancybox.css new file mode 100644 index 0000000000..43b5537b1a --- /dev/null +++ b/docs_deprecated/public/fancybox.css @@ -0,0 +1 @@ +.carousel{position:relative;box-sizing:border-box}.carousel *,.carousel *:before,.carousel *:after{box-sizing:inherit}.carousel.is-draggable{cursor:move;cursor:grab}.carousel.is-dragging{cursor:move;cursor:grabbing}.carousel__viewport{position:relative;overflow:hidden;max-width:100%;max-height:100%}.carousel__track{display:flex}.carousel__slide{flex:0 0 auto;width:var(--carousel-slide-width, 60%);max-width:100%;padding:1rem;position:relative;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.has-dots{margin-bottom:calc(0.5rem + 22px)}.carousel__dots{margin:0 auto;padding:0;position:absolute;top:calc(100% + 0.5rem);left:0;right:0;display:flex;justify-content:center;list-style:none;user-select:none}.carousel__dots .carousel__dot{margin:0;padding:0;display:block;position:relative;width:22px;height:22px;cursor:pointer}.carousel__dots .carousel__dot:after{content:"";width:8px;height:8px;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background-color:currentColor;opacity:.25;transition:opacity .15s ease-in-out}.carousel__dots .carousel__dot.is-selected:after{opacity:1}.carousel__button{width:var(--carousel-button-width, 48px);height:var(--carousel-button-height, 48px);padding:0;border:0;display:flex;justify-content:center;align-items:center;pointer-events:all;cursor:pointer;color:var(--carousel-button-color, currentColor);background:var(--carousel-button-bg, transparent);border-radius:var(--carousel-button-border-radius, 50%);box-shadow:var(--carousel-button-shadow, none);transition:opacity .15s ease}.carousel__button.is-prev,.carousel__button.is-next{position:absolute;top:50%;transform:translateY(-50%)}.carousel__button.is-prev{left:10px}.carousel__button.is-next{right:10px}.carousel__button[disabled]{cursor:default;opacity:.3}.carousel__button svg{width:var(--carousel-button-svg-width, 50%);height:var(--carousel-button-svg-height, 50%);fill:none;stroke:currentColor;stroke-width:var(--carousel-button-svg-stroke-width, 1.5);stroke-linejoin:bevel;stroke-linecap:round;filter:var(--carousel-button-svg-filter, none);pointer-events:none}html.with-fancybox{scroll-behavior:auto}body.compensate-for-scrollbar{overflow:hidden !important;touch-action:none}.fancybox__container{position:fixed;top:0;left:0;bottom:0;right:0;direction:ltr;margin:0;padding:env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);box-sizing:border-box;display:flex;flex-direction:column;color:var(--fancybox-color, #fff);-webkit-tap-highlight-color:rgba(0,0,0,0);overflow:hidden;z-index:1050;outline:none;transform-origin:top left;--carousel-button-width: 48px;--carousel-button-height: 48px;--carousel-button-svg-width: 24px;--carousel-button-svg-height: 24px;--carousel-button-svg-stroke-width: 2.5;--carousel-button-svg-filter: drop-shadow(1px 1px 1px rgba(0, 0, 0, 0.4))}.fancybox__container *,.fancybox__container *::before,.fancybox__container *::after{box-sizing:inherit}.fancybox__container :focus{outline:none}body:not(.is-using-mouse) .fancybox__container :focus{box-shadow:0 0 0 1px #fff,0 0 0 2px var(--fancybox-accent-color, rgba(1, 210, 232, 0.94))}@media all and (min-width: 1024px){.fancybox__container{--carousel-button-width:48px;--carousel-button-height:48px;--carousel-button-svg-width:27px;--carousel-button-svg-height:27px}}.fancybox__backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;background:var(--fancybox-bg, rgba(24, 24, 27, 0.92))}.fancybox__carousel{position:relative;flex:1 1 auto;min-height:0;height:100%;z-index:10}.fancybox__carousel.has-dots{margin-bottom:calc(0.5rem + 22px)}.fancybox__viewport{position:relative;width:100%;height:100%;overflow:visible;cursor:default}.fancybox__track{display:flex;height:100%}.fancybox__slide{flex:0 0 auto;width:100%;max-width:100%;margin:0;padding:48px 8px 8px 8px;position:relative;overscroll-behavior:contain;display:flex;flex-direction:column;outline:0;overflow:auto;--carousel-button-width: 36px;--carousel-button-height: 36px;--carousel-button-svg-width: 22px;--carousel-button-svg-height: 22px}.fancybox__slide::before,.fancybox__slide::after{content:"";flex:0 0 0;margin:auto}@media all and (min-width: 1024px){.fancybox__slide{padding:64px 100px}}.fancybox__content{margin:0 env(safe-area-inset-right, 0px) 0 env(safe-area-inset-left, 0px);padding:36px;color:var(--fancybox-content-color, #374151);background:var(--fancybox-content-bg, #fff);position:relative;align-self:center;display:flex;flex-direction:column;z-index:20}.fancybox__content :focus:not(.carousel__button.is-close){outline:thin dotted;box-shadow:none}.fancybox__caption{align-self:center;max-width:100%;margin:0;padding:1rem 0 0 0;line-height:1.375;color:var(--fancybox-color, currentColor);visibility:visible;cursor:auto;flex-shrink:0;overflow-wrap:anywhere}.is-loading .fancybox__caption{visibility:hidden}.fancybox__container>.carousel__dots{top:100%;color:var(--fancybox-color, #fff)}.fancybox__nav .carousel__button{z-index:40}.fancybox__nav .carousel__button.is-next{right:8px}@media all and (min-width: 1024px){.fancybox__nav .carousel__button.is-next{right:40px}}.fancybox__nav .carousel__button.is-prev{left:8px}@media all and (min-width: 1024px){.fancybox__nav .carousel__button.is-prev{left:40px}}.carousel__button.is-close{position:absolute;top:8px;right:8px;top:calc(env(safe-area-inset-top, 0px) + 8px);right:calc(env(safe-area-inset-right, 0px) + 8px);z-index:40}@media all and (min-width: 1024px){.carousel__button.is-close{right:40px}}.fancybox__content>.carousel__button.is-close{position:absolute;top:-40px;right:0;color:var(--fancybox-color, #fff)}.fancybox__no-click,.fancybox__no-click button{pointer-events:none}.fancybox__spinner{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);width:50px;height:50px;color:var(--fancybox-color, currentColor)}.fancybox__slide .fancybox__spinner{cursor:pointer;z-index:1053}.fancybox__spinner svg{animation:fancybox-rotate 2s linear infinite;transform-origin:center center;position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;width:100%;height:100%}.fancybox__spinner svg circle{fill:none;stroke-width:2.75;stroke-miterlimit:10;stroke-dasharray:1,200;stroke-dashoffset:0;animation:fancybox-dash 1.5s ease-in-out infinite;stroke-linecap:round;stroke:currentColor}@keyframes fancybox-rotate{100%{transform:rotate(360deg)}}@keyframes fancybox-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}100%{stroke-dasharray:89,200;stroke-dashoffset:-124px}}.fancybox__backdrop,.fancybox__caption,.fancybox__nav,.carousel__dots,.carousel__button.is-close{opacity:var(--fancybox-opacity, 1)}.fancybox__container.is-animated[aria-hidden=false] .fancybox__backdrop,.fancybox__container.is-animated[aria-hidden=false] .fancybox__caption,.fancybox__container.is-animated[aria-hidden=false] .fancybox__nav,.fancybox__container.is-animated[aria-hidden=false] .carousel__dots,.fancybox__container.is-animated[aria-hidden=false] .carousel__button.is-close{animation:.15s ease backwards fancybox-fadeIn}.fancybox__container.is-animated.is-closing .fancybox__backdrop,.fancybox__container.is-animated.is-closing .fancybox__caption,.fancybox__container.is-animated.is-closing .fancybox__nav,.fancybox__container.is-animated.is-closing .carousel__dots,.fancybox__container.is-animated.is-closing .carousel__button.is-close{animation:.15s ease both fancybox-fadeOut}.fancybox-fadeIn{animation:.15s ease both fancybox-fadeIn}.fancybox-fadeOut{animation:.1s ease both fancybox-fadeOut}.fancybox-zoomInUp{animation:.2s ease both fancybox-zoomInUp}.fancybox-zoomOutDown{animation:.15s ease both fancybox-zoomOutDown}.fancybox-throwOutUp{animation:.15s ease both fancybox-throwOutUp}.fancybox-throwOutDown{animation:.15s ease both fancybox-throwOutDown}@keyframes fancybox-fadeIn{from{opacity:0}to{opacity:1}}@keyframes fancybox-fadeOut{to{opacity:0}}@keyframes fancybox-zoomInUp{from{transform:scale(0.97) translate3d(0, 16px, 0);opacity:0}to{transform:scale(1) translate3d(0, 0, 0);opacity:1}}@keyframes fancybox-zoomOutDown{to{transform:scale(0.97) translate3d(0, 16px, 0);opacity:0}}@keyframes fancybox-throwOutUp{to{transform:translate3d(0, -30%, 0);opacity:0}}@keyframes fancybox-throwOutDown{to{transform:translate3d(0, 30%, 0);opacity:0}}.fancybox__carousel .carousel__slide{scrollbar-width:thin;scrollbar-color:#ccc rgba(255,255,255,.1)}.fancybox__carousel .carousel__slide::-webkit-scrollbar{width:8px;height:8px}.fancybox__carousel .carousel__slide::-webkit-scrollbar-track{background-color:rgba(255,255,255,.1)}.fancybox__carousel .carousel__slide::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:2px;box-shadow:inset 0 0 4px rgba(0,0,0,.2)}.fancybox__carousel.is-draggable .fancybox__slide,.fancybox__carousel.is-draggable .fancybox__slide .fancybox__content{cursor:move;cursor:grab}.fancybox__carousel.is-dragging .fancybox__slide,.fancybox__carousel.is-dragging .fancybox__slide .fancybox__content{cursor:move;cursor:grabbing}.fancybox__carousel .fancybox__slide .fancybox__content{cursor:auto}.fancybox__carousel .fancybox__slide.can-zoom_in .fancybox__content{cursor:zoom-in}.fancybox__carousel .fancybox__slide.can-zoom_out .fancybox__content{cursor:zoom-out}.fancybox__carousel .fancybox__slide.is-draggable .fancybox__content{cursor:move;cursor:grab}.fancybox__carousel .fancybox__slide.is-dragging .fancybox__content{cursor:move;cursor:grabbing}.fancybox__image{transform-origin:0 0;user-select:none;transition:none}.has-image .fancybox__content{padding:0;background:rgba(0,0,0,0);min-height:1px}.is-closing .has-image .fancybox__content{overflow:visible}.has-image[data-image-fit=contain]{overflow:visible;touch-action:none}.has-image[data-image-fit=contain] .fancybox__content{flex-direction:row;flex-wrap:wrap}.has-image[data-image-fit=contain] .fancybox__image{max-width:100%;max-height:100%;object-fit:contain}.has-image[data-image-fit=contain-w]{overflow-x:hidden;overflow-y:auto}.has-image[data-image-fit=contain-w] .fancybox__content{min-height:auto}.has-image[data-image-fit=contain-w] .fancybox__image{max-width:100%;height:auto}.has-image[data-image-fit=cover]{overflow:visible;touch-action:none}.has-image[data-image-fit=cover] .fancybox__content{width:100%;height:100%}.has-image[data-image-fit=cover] .fancybox__image{width:100%;height:100%;object-fit:cover}.fancybox__carousel .fancybox__slide.has-iframe .fancybox__content,.fancybox__carousel .fancybox__slide.has-map .fancybox__content,.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content,.fancybox__carousel .fancybox__slide.has-video .fancybox__content,.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content{max-width:100%;flex-shrink:1;min-height:1px;overflow:visible}.fancybox__carousel .fancybox__slide.has-iframe .fancybox__content,.fancybox__carousel .fancybox__slide.has-map .fancybox__content,.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content{width:100%;height:80%}.fancybox__carousel .fancybox__slide.has-video .fancybox__content,.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content{width:960px;height:540px;max-width:100%;max-height:100%}.fancybox__carousel .fancybox__slide.has-map .fancybox__content,.fancybox__carousel .fancybox__slide.has-pdf .fancybox__content,.fancybox__carousel .fancybox__slide.has-video .fancybox__content,.fancybox__carousel .fancybox__slide.has-html5video .fancybox__content{padding:0;background:rgba(24,24,27,.9);color:#fff}.fancybox__carousel .fancybox__slide.has-map .fancybox__content{background:#e5e3df}.fancybox__html5video,.fancybox__iframe{border:0;display:block;height:100%;width:100%;background:rgba(0,0,0,0)}.fancybox-placeholder{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.fancybox__thumbs{flex:0 0 auto;position:relative;padding:0px 3px;opacity:var(--fancybox-opacity, 1)}.fancybox__container.is-animated[aria-hidden=false] .fancybox__thumbs{animation:.15s ease-in backwards fancybox-fadeIn}.fancybox__container.is-animated.is-closing .fancybox__thumbs{opacity:0}.fancybox__thumbs .carousel__slide{flex:0 0 auto;width:var(--fancybox-thumbs-width, 96px);margin:0;padding:8px 3px;box-sizing:content-box;display:flex;align-items:center;justify-content:center;overflow:visible;cursor:pointer}.fancybox__thumbs .carousel__slide .fancybox__thumb::after{content:"";position:absolute;top:0;left:0;right:0;bottom:0;border-width:5px;border-style:solid;border-color:var(--fancybox-accent-color, rgba(34, 213, 233, 0.96));opacity:0;transition:opacity .15s ease;border-radius:var(--fancybox-thumbs-border-radius, 4px)}.fancybox__thumbs .carousel__slide.is-nav-selected .fancybox__thumb::after{opacity:.92}.fancybox__thumbs .carousel__slide>*{pointer-events:none;user-select:none}.fancybox__thumb{position:relative;width:100%;padding-top:calc(100%/(var(--fancybox-thumbs-ratio, 1.5)));background-size:cover;background-position:center center;background-color:rgba(255,255,255,.1);background-repeat:no-repeat;border-radius:var(--fancybox-thumbs-border-radius, 4px)}.fancybox__toolbar{position:absolute;top:0;right:0;left:0;z-index:20;background:linear-gradient(to top, hsla(0deg, 0%, 0%, 0) 0%, hsla(0deg, 0%, 0%, 0.006) 8.1%, hsla(0deg, 0%, 0%, 0.021) 15.5%, hsla(0deg, 0%, 0%, 0.046) 22.5%, hsla(0deg, 0%, 0%, 0.077) 29%, hsla(0deg, 0%, 0%, 0.114) 35.3%, hsla(0deg, 0%, 0%, 0.155) 41.2%, hsla(0deg, 0%, 0%, 0.198) 47.1%, hsla(0deg, 0%, 0%, 0.242) 52.9%, hsla(0deg, 0%, 0%, 0.285) 58.8%, hsla(0deg, 0%, 0%, 0.326) 64.7%, hsla(0deg, 0%, 0%, 0.363) 71%, hsla(0deg, 0%, 0%, 0.394) 77.5%, hsla(0deg, 0%, 0%, 0.419) 84.5%, hsla(0deg, 0%, 0%, 0.434) 91.9%, hsla(0deg, 0%, 0%, 0.44) 100%);padding:0;touch-action:none;display:flex;justify-content:space-between;--carousel-button-svg-width: 20px;--carousel-button-svg-height: 20px;opacity:var(--fancybox-opacity, 1);text-shadow:var(--fancybox-toolbar-text-shadow, 1px 1px 1px rgba(0, 0, 0, 0.4))}@media all and (min-width: 1024px){.fancybox__toolbar{padding:8px}}.fancybox__container.is-animated[aria-hidden=false] .fancybox__toolbar{animation:.15s ease-in backwards fancybox-fadeIn}.fancybox__container.is-animated.is-closing .fancybox__toolbar{opacity:0}.fancybox__toolbar__items{display:flex}.fancybox__toolbar__items--left{margin-right:auto}.fancybox__toolbar__items--center{position:absolute;left:50%;transform:translateX(-50%)}.fancybox__toolbar__items--right{margin-left:auto}@media(max-width: 640px){.fancybox__toolbar__items--center:not(:last-child){display:none}}.fancybox__counter{min-width:72px;padding:0 10px;line-height:var(--carousel-button-height, 48px);text-align:center;font-size:17px;font-variant-numeric:tabular-nums;-webkit-font-smoothing:subpixel-antialiased}.fancybox__progress{background:var(--fancybox-accent-color, rgba(34, 213, 233, 0.96));height:3px;left:0;position:absolute;right:0;top:0;transform:scaleX(0);transform-origin:0;transition-property:transform;transition-timing-function:linear;z-index:30;user-select:none}.fancybox__container:fullscreen::backdrop{opacity:0}.fancybox__button--fullscreen g:nth-child(2){display:none}.fancybox__container:fullscreen .fancybox__button--fullscreen g:nth-child(1){display:none}.fancybox__container:fullscreen .fancybox__button--fullscreen g:nth-child(2){display:block}.fancybox__button--slideshow g:nth-child(2){display:none}.fancybox__container.has-slideshow .fancybox__button--slideshow g:nth-child(1){display:none}.fancybox__container.has-slideshow .fancybox__button--slideshow g:nth-child(2){display:block} \ No newline at end of file diff --git a/docs_deprecated/public/fancybox.umd.js b/docs_deprecated/public/fancybox.umd.js new file mode 100644 index 0000000000..f096207277 --- /dev/null +++ b/docs_deprecated/public/fancybox.umd.js @@ -0,0 +1,2 @@ +// @fancyapps/ui/Fancybox v4.0.31 +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).window=t.window||{})}(this,(function(t){"use strict";function e(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,n)}return i}function i(t){for(var i=1;it.length)&&(e=t.length);for(var i=0,n=new Array(e);i=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,r=!1;return{s:function(){i=i.call(t)},n:function(){var t=i.next();return s=t.done,t},e:function(t){r=!0,a=t},f:function(){try{s||null==i.return||i.return()}finally{if(r)throw a}}}}var w=function(t){return"object"===n(t)&&null!==t&&t.constructor===Object&&"[object Object]"===Object.prototype.toString.call(t)},k=function t(){for(var e=!1,i=arguments.length,o=new Array(i),a=0;a1&&void 0!==arguments[1]?arguments[1]:1e4;return t=parseFloat(t)||0,Math.round((t+Number.EPSILON)*e)/e},C=function t(e){return!!(e&&"object"===n(e)&&e instanceof Element&&e!==document.body)&&(!e.__Panzoom&&(function(t){var e=getComputedStyle(t)["overflow-y"],i=getComputedStyle(t)["overflow-x"],n=("scroll"===e||"auto"===e)&&Math.abs(t.scrollHeight-t.clientHeight)>1,o=("scroll"===i||"auto"===i)&&Math.abs(t.scrollWidth-t.clientWidth)>1;return n||o}(e)?e:t(e.parentNode)))},$="undefined"!=typeof window&&window.ResizeObserver||function(){function t(e){o(this,t),this.observables=[],this.boundCheck=this.check.bind(this),this.boundCheck(),this.callback=e}return s(t,[{key:"observe",value:function(t){if(!this.observables.some((function(e){return e.el===t}))){var e={el:t,size:{height:t.clientHeight,width:t.clientWidth}};this.observables.push(e)}}},{key:"unobserve",value:function(t){this.observables=this.observables.filter((function(e){return e.el!==t}))}},{key:"disconnect",value:function(){this.observables=[]}},{key:"check",value:function(){var t=this.observables.filter((function(t){var e=t.el.clientHeight,i=t.el.clientWidth;if(t.size.height!==e||t.size.width!==i)return t.size.height=e,t.size.width=i,!0})).map((function(t){return t.el}));t.length>0&&this.callback(t),window.requestAnimationFrame(this.boundCheck)}}]),t}(),E=s((function t(e){o(this,t),this.id=self.Touch&&e instanceof Touch?e.identifier:-1,this.pageX=e.pageX,this.pageY=e.pageY,this.clientX=e.clientX,this.clientY=e.clientY})),P=function(t,e){return e?Math.sqrt(Math.pow(e.clientX-t.clientX,2)+Math.pow(e.clientY-t.clientY,2)):0},T=function(t,e){return e?{clientX:(t.clientX+e.clientX)/2,clientY:(t.clientY+e.clientY)/2}:t},L=function(t){return"changedTouches"in t},_=function(){function t(e){var i=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=n.start,s=void 0===a?function(){return!0}:a,r=n.move,l=void 0===r?function(){}:r,c=n.end,h=void 0===c?function(){}:c;o(this,t),this._element=e,this.startPointers=[],this.currentPointers=[],this._pointerStart=function(t){if(!(t.buttons>0&&0!==t.button)){var e=new E(t);i.currentPointers.some((function(t){return t.id===e.id}))||i._triggerPointerStart(e,t)&&(window.addEventListener("mousemove",i._move),window.addEventListener("mouseup",i._pointerEnd))}},this._touchStart=function(t){for(var e=0,n=Array.from(t.changedTouches||[]);e0&&0!==t.button||i._triggerPointerEnd(new E(t),t)&&(window.removeEventListener("mousemove",i._move,{passive:!1}),window.removeEventListener("mouseup",i._pointerEnd,{passive:!1}))},this._touchEnd=function(t){for(var e=0,n=Array.from(t.changedTouches||[]);e0&&void 0!==arguments[0]?arguments[0]:{};o(this,t),this.options=k(!0,{},e),this.plugins=[],this.events={};for(var i=0,n=["on","once"];i2?o-2:0),s=2;s1&&void 0!==arguments[1]?arguments[1]:[];return t=(t=String(t).replace(/\{\{(\w+).?(\w+)?\}\}/g,(function(t,n,o){var a="";o?a=e.option("".concat(n[0]+n.toLowerCase().substring(1),".l10n.").concat(o)):n&&(a=e.option("l10n.".concat(n))),a||(a=t);for(var s=0;s1?e-1:0),n=1;n1&&void 0!==arguments[1]?arguments[1]:{};o(this,n),(i=e.call(this,k(!0,{},z,a))).state="init",i.$container=t;for(var s=0,r=["onLoad","onWheel","onClick"];s1||Math.abs(e.left-this.dragStart.rect.left)>1))return t.preventDefault(),void t.stopPropagation();!1!==this.trigger("click",t)&&this.option("zoom")&&"toggleZoom"===this.option("click")&&(t.preventDefault(),t.stopPropagation(),this.zoomWithClick(t))}else t.stopPropagation()}},{key:"onWheel",value:function(t){!1!==this.trigger("wheel",t)&&this.option("zoom")&&this.option("wheel")&&this.zoomWithWheel(t)}},{key:"zoomWithWheel",value:function(t){void 0===this.changedDelta&&(this.changedDelta=0);var e=Math.max(-1,Math.min(1,-t.deltaY||-t.deltaX||t.wheelDelta||-t.detail)),i=this.content.scale,n=i*(100+e*this.option("wheelFactor"))/100;if(e<0&&Math.abs(i-this.option("minScale"))<.01||e>0&&Math.abs(i-this.option("maxScale"))<.01?(this.changedDelta+=Math.abs(e),n=i):(this.changedDelta=0,n=Math.max(Math.min(n,this.option("maxScale")),this.option("minScale"))),!(this.changedDelta>this.option("wheelLimit"))&&(t.preventDefault(),n!==i)){var o=this.$content.getBoundingClientRect(),a=t.clientX-o.left,s=t.clientY-o.top;this.zoomTo(n,{x:a,y:s})}}},{key:"zoomWithClick",value:function(t){var e=this.$content.getClientRects()[0],i=t.clientX-e.left,n=t.clientY-e.top;this.toggleZoom({x:i,y:n})}},{key:"attachEvents",value:function(){var t=this;this.$content.addEventListener("load",this.onLoad),this.$container.addEventListener("wheel",this.onWheel,{passive:!1}),this.$container.addEventListener("click",this.onClick,{passive:!1}),this.initObserver();var e=new _(this.$container,{start:function(i,n){if(!t.option("touch"))return!1;if(t.velocity.scale<0)return!1;var o=n.composedPath()[0];if(!e.currentPointers.length){if(-1!==["BUTTON","TEXTAREA","OPTION","INPUT","SELECT","VIDEO"].indexOf(o.nodeName))return!1;if(t.option("textSelection")&&function(t,e,i){for(var n=t.childNodes,o=document.createRange(),a=0;a=r.left&&i>=r.top&&e<=r.right&&i<=r.bottom)return s}}return!1}(o,i.clientX,i.clientY))return!1}return!C(o)&&(!1!==t.trigger("touchStart",n)&&("mousedown"===n.type&&n.preventDefault(),t.state="pointerdown",t.resetDragPosition(),t.dragPosition.midPoint=null,t.dragPosition.time=Date.now(),!0))},move:function(i,n,o){if("pointerdown"===t.state)if(!1!==t.trigger("touchMove",o)){if(!(n.length<2&&!0===t.option("panOnlyZoomed")&&t.content.width<=t.viewport.width&&t.content.height<=t.viewport.height&&t.transform.scale<=t.option("baseScale"))&&(!(n.length>1)||t.option("zoom")&&!1!==t.option("pinchToZoom"))){var a=T(i[0],i[1]),s=T(n[0],n[1]),r=s.clientX-a.clientX,l=s.clientY-a.clientY,c=P(i[0],i[1]),h=P(n[0],n[1]),d=c&&h?h/c:1;t.dragOffset.x+=r,t.dragOffset.y+=l,t.dragOffset.scale*=d,t.dragOffset.time=Date.now()-t.dragPosition.time;var u=1===t.dragStart.scale&&t.option("lockAxis");if(u&&!t.lockAxis){if(Math.abs(t.dragOffset.x)<6&&Math.abs(t.dragOffset.y)<6)return void o.preventDefault();var f=Math.abs(180*Math.atan2(t.dragOffset.y,t.dragOffset.x)/Math.PI);t.lockAxis=f>45&&f<135?"y":"x"}if("xy"===u||"y"!==t.lockAxis){if(o.preventDefault(),o.stopPropagation(),o.stopImmediatePropagation(),t.lockAxis&&(t.dragOffset["x"===t.lockAxis?"y":"x"]=0),t.$container.classList.add(t.option("draggingClass")),t.transform.scale===t.option("baseScale")&&"y"===t.lockAxis||(t.dragPosition.x=t.dragStart.x+t.dragOffset.x),t.transform.scale===t.option("baseScale")&&"x"===t.lockAxis||(t.dragPosition.y=t.dragStart.y+t.dragOffset.y),t.dragPosition.scale=t.dragStart.scale*t.dragOffset.scale,n.length>1){var v=T(e.startPointers[0],e.startPointers[1]),p=v.clientX-t.dragStart.rect.x,g=v.clientY-t.dragStart.rect.y,m=t.getZoomDelta(t.content.scale*t.dragOffset.scale,p,g),y=m.deltaX,b=m.deltaY;t.dragPosition.x-=y,t.dragPosition.y-=b,t.dragPosition.midPoint=s}else t.setDragResistance();t.transform={x:t.dragPosition.x,y:t.dragPosition.y,scale:t.dragPosition.scale},t.startAnimation()}}}else o.preventDefault()},end:function(n,o){if("pointerdown"===t.state)if(t._dragOffset=i({},t.dragOffset),e.currentPointers.length)t.resetDragPosition();else if(t.state="decel",t.friction=t.option("decelFriction"),t.recalculateTransform(),t.$container.classList.remove(t.option("draggingClass")),!1!==t.trigger("touchEnd",o)&&"decel"===t.state){var a=t.option("minScale");if(t.transform.scale.01){var r=t.dragPosition.midPoint||n,l=t.$content.getClientRects()[0];t.zoomTo(s,{friction:.64,x:r.clientX-l.left,y:r.clientY-l.top})}else;}}}});this.pointerTracker=e}},{key:"initObserver",value:function(){var t=this;this.resizeObserver||(this.resizeObserver=new $((function(){t.updateTimer||(t.updateTimer=setTimeout((function(){var e=t.$container.getBoundingClientRect();e.width&&e.height?((Math.abs(e.width-t.container.width)>1||Math.abs(e.height-t.container.height)>1)&&(t.isAnimating()&&t.endAnimation(!0),t.updateMetrics(),t.panTo({x:t.content.x,y:t.content.y,scale:t.option("baseScale"),friction:0})),t.updateTimer=null):t.updateTimer=null}),t.updateRate))})),this.resizeObserver.observe(this.$container))}},{key:"resetDragPosition",value:function(){this.lockAxis=null,this.friction=this.option("friction"),this.velocity={x:0,y:0,scale:0};var t=this.content,e=t.x,n=t.y,o=t.scale;this.dragStart={rect:this.$content.getBoundingClientRect(),x:e,y:n,scale:o},this.dragPosition=i(i({},this.dragPosition),{},{x:e,y:n,scale:o}),this.dragOffset={x:0,y:0,scale:1,time:0}}},{key:"updateMetrics",value:function(t){!0!==t&&this.trigger("beforeUpdate");var e,n=this.$container,o=this.$content,a=this.$viewport,s=o instanceof HTMLImageElement,r=this.option("zoom"),l=this.option("resizeParent",r),c=this.option("width"),h=this.option("height"),d=c||(e=o,Math.max(parseFloat(e.naturalWidth||0),parseFloat(e.width&&e.width.baseVal&&e.width.baseVal.value||0),parseFloat(e.offsetWidth||0),parseFloat(e.scrollWidth||0))),u=h||function(t){return Math.max(parseFloat(t.naturalHeight||0),parseFloat(t.height&&t.height.baseVal&&t.height.baseVal.value||0),parseFloat(t.offsetHeight||0),parseFloat(t.scrollHeight||0))}(o);Object.assign(o.style,{width:c?"".concat(c,"px"):"",height:h?"".concat(h,"px"):"",maxWidth:"",maxHeight:""}),l&&Object.assign(a.style,{width:"",height:""});var f=this.option("ratio");c=d=S(d*f),h=u=S(u*f);var v=o.getBoundingClientRect(),p=a.getBoundingClientRect(),g=a==n?p:n.getBoundingClientRect(),m=Math.max(a.offsetWidth,S(p.width)),y=Math.max(a.offsetHeight,S(p.height)),b=window.getComputedStyle(a);if(m-=parseFloat(b.paddingLeft)+parseFloat(b.paddingRight),y-=parseFloat(b.paddingTop)+parseFloat(b.paddingBottom),this.viewport.width=m,this.viewport.height=y,r){if(Math.abs(d-v.width)>.1||Math.abs(u-v.height)>.1){var x=function(t,e,i,n){var o=Math.min(i/t||0,n/e);return{width:t*o||0,height:e*o||0}}(d,u,Math.min(d,v.width),Math.min(u,v.height));c=S(x.width),h=S(x.height)}Object.assign(o.style,{width:"".concat(c,"px"),height:"".concat(h,"px"),transform:""})}if(l&&(Object.assign(a.style,{width:"".concat(c,"px"),height:"".concat(h,"px")}),this.viewport=i(i({},this.viewport),{},{width:c,height:h})),s&&r&&"function"!=typeof this.options.maxScale){var w=this.option("maxScale");this.options.maxScale=function(){return this.content.origWidth>0&&this.content.fitWidth>0?this.content.origWidth/this.content.fitWidth:w}}this.content=i(i({},this.content),{},{origWidth:d,origHeight:u,fitWidth:c,fitHeight:h,width:c,height:h,scale:1,isZoomable:r}),this.container={width:g.width,height:g.height},!0!==t&&this.trigger("afterUpdate")}},{key:"zoomIn",value:function(t){this.zoomTo(this.content.scale+(t||this.option("step")))}},{key:"zoomOut",value:function(t){this.zoomTo(this.content.scale-(t||this.option("step")))}},{key:"toggleZoom",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=this.option("maxScale"),i=this.option("baseScale"),n=this.content.scale>i+.5*(e-i)?i:e;this.zoomTo(n,t)}},{key:"zoomTo",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.option("baseScale"),e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=e.x,n=void 0===i?null:i,o=e.y,a=void 0===o?null:o;t=Math.max(Math.min(t,this.option("maxScale")),this.option("minScale"));var s=S(this.content.scale/(this.content.width/this.content.fitWidth),1e7);null===n&&(n=this.content.width*s*.5),null===a&&(a=this.content.height*s*.5);var r=this.getZoomDelta(t,n,a),l=r.deltaX,c=r.deltaY;n=this.content.x-l,a=this.content.y-c,this.panTo({x:n,y:a,scale:t,friction:this.option("zoomFriction")})}},{key:"getZoomDelta",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=this.content.fitWidth*this.content.scale,o=this.content.fitHeight*this.content.scale,a=e>0&&n?e/n:0,s=i>0&&o?i/o:0,r=this.content.fitWidth*t,l=this.content.fitHeight*t,c=(r-n)*a,h=(l-o)*s;return{deltaX:c,deltaY:h}}},{key:"panTo",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.x,n=void 0===e?this.content.x:e,o=t.y,a=void 0===o?this.content.y:o,s=t.scale,r=t.friction,l=void 0===r?this.option("friction"):r,c=t.ignoreBounds,h=void 0!==c&&c;if(s=s||this.content.scale||1,!h){var d=this.getBounds(s),u=d.boundX,f=d.boundY;u&&(n=Math.max(Math.min(n,u.to),u.from)),f&&(a=Math.max(Math.min(a,f.to),f.from))}this.friction=l,this.transform=i(i({},this.transform),{},{x:n,y:a,scale:s}),l?(this.state="panning",this.velocity={x:(1/this.friction-1)*(n-this.content.x),y:(1/this.friction-1)*(a-this.content.y),scale:(1/this.friction-1)*(s-this.content.scale)},this.startAnimation()):this.endAnimation()}},{key:"startAnimation",value:function(){var t=this;this.rAF?cancelAnimationFrame(this.rAF):this.trigger("startAnimation"),this.rAF=requestAnimationFrame((function(){return t.animate()}))}},{key:"animate",value:function(){var t=this;if(this.setEdgeForce(),this.setDragForce(),this.velocity.x*=this.friction,this.velocity.y*=this.friction,this.velocity.scale*=this.friction,this.content.x+=this.velocity.x,this.content.y+=this.velocity.y,this.content.scale+=this.velocity.scale,this.isAnimating())this.setTransform();else if("pointerdown"!==this.state)return void this.endAnimation();this.rAF=requestAnimationFrame((function(){return t.animate()}))}},{key:"getBounds",value:function(t){var e=this.boundX,i=this.boundY;if(void 0!==e&&void 0!==i)return{boundX:e,boundY:i};e={from:0,to:0},i={from:0,to:0},t=t||this.transform.scale;var n=this.content.fitWidth*t,o=this.content.fitHeight*t,a=this.viewport.width,s=this.viewport.height;if(ns.to),r&&(i=this.content.yr.to),t||e){var l=((t?s.from:s.to)-this.content.x)*o,c=this.content.x+(this.velocity.x+l)/this.friction;c>=s.from&&c<=s.to&&(l+=this.velocity.x),this.velocity.x=l,this.recalculateTransform()}if(i||n){var h=((i?r.from:r.to)-this.content.y)*o,d=this.content.y+(h+this.velocity.y)/this.friction;d>=r.from&&d<=r.to&&(h+=this.velocity.y),this.velocity.y=h,this.recalculateTransform()}}}},{key:"setDragResistance",value:function(){if("pointerdown"===this.state){var t,e,i,n,o=this.getBounds(this.dragPosition.scale),a=o.boundX,s=o.boundY;if(a&&(t=this.dragPosition.xa.to),s&&(i=this.dragPosition.ys.to),(t||e)&&(!t||!e)){var r=t?a.from:a.to,l=r-this.dragPosition.x;this.dragPosition.x=r-.3*l}if((i||n)&&(!i||!n)){var c=i?s.from:s.to,h=c-this.dragPosition.y;this.dragPosition.y=c-.3*h}}}},{key:"setDragForce",value:function(){"pointerdown"===this.state&&(this.velocity.x=this.dragPosition.x-this.content.x,this.velocity.y=this.dragPosition.y-this.content.y,this.velocity.scale=this.dragPosition.scale-this.content.scale)}},{key:"recalculateTransform",value:function(){this.transform.x=this.content.x+this.velocity.x/(1/this.friction-1),this.transform.y=this.content.y+this.velocity.y/(1/this.friction-1),this.transform.scale=this.content.scale+this.velocity.scale/(1/this.friction-1)}},{key:"isAnimating",value:function(){return!(!this.friction||!(Math.abs(this.velocity.x)>.05||Math.abs(this.velocity.y)>.05||Math.abs(this.velocity.scale)>.05))}},{key:"setTransform",value:function(t){var e,n,o,a,s;(t?(e=S(this.transform.x),n=S(this.transform.y),o=this.transform.scale,this.content=i(i({},this.content),{},{x:e,y:n,scale:o})):(e=S(this.content.x),n=S(this.content.y),o=this.content.scale/(this.content.width/this.content.fitWidth),this.content=i(i({},this.content),{},{x:e,y:n})),this.trigger("beforeTransform"),e=S(this.content.x),n=S(this.content.y),t&&this.option("zoom"))?(a=S(this.content.fitWidth*o),s=S(this.content.fitHeight*o),this.content.width=a,this.content.height=s,this.transform=i(i({},this.transform),{},{width:a,height:s,scale:o}),Object.assign(this.$content.style,{width:"".concat(a,"px"),height:"".concat(s,"px"),maxWidth:"none",maxHeight:"none",transform:"translate3d(".concat(e,"px, ").concat(n,"px, 0) scale(1)")})):this.$content.style.transform="translate3d(".concat(e,"px, ").concat(n,"px, 0) scale(").concat(o,")");this.trigger("afterTransform")}},{key:"endAnimation",value:function(t){cancelAnimationFrame(this.rAF),this.rAF=null,this.velocity={x:0,y:0,scale:0},this.setTransform(!0),this.state="ready",this.handleCursor(),!0!==t&&this.trigger("endAnimation")}},{key:"handleCursor",value:function(){var t=this.option("draggableClass");t&&this.option("touch")&&(1==this.option("panOnlyZoomed")&&this.content.width<=this.viewport.width&&this.content.height<=this.viewport.height&&this.transform.scale<=this.option("baseScale")?this.$container.classList.remove(t):this.$container.classList.add(t))}},{key:"detachEvents",value:function(){this.$content.removeEventListener("load",this.onLoad),this.$container.removeEventListener("wheel",this.onWheel,{passive:!1}),this.$container.removeEventListener("click",this.onClick,{passive:!1}),this.pointerTracker&&(this.pointerTracker.stop(),this.pointerTracker=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}},{key:"destroy",value:function(){"destroy"!==this.state&&(this.state="destroy",clearTimeout(this.updateTimer),this.updateTimer=null,cancelAnimationFrame(this.rAF),this.rAF=null,this.detachEvents(),this.detachPlugins(),this.resetDragPosition())}}]),n}(O);M.version="4.0.31",M.Plugins={};var I=function(t,e){var i=0;return function(){var n=(new Date).getTime();if(!(n-i1&&this.carousel.elemDimWidth=t-1&&this.$next.setAttribute("disabled","")))}},{key:"cleanup",value:function(){this.$prev&&this.$prev.remove(),this.$prev=null,this.$next&&this.$next.remove(),this.$next=null,this.$container&&this.$container.remove(),this.$container=null}},{key:"attach",value:function(){this.carousel.on("refresh change",this.onRefresh)}},{key:"detach",value:function(){this.carousel.off("refresh change",this.onRefresh),this.cleanup()}}]),t}();R.defaults={prevTpl:'',nextTpl:'',classNames:{main:"carousel__nav",button:"carousel__button",next:"is-next",prev:"is-prev"}};var F=function(){function t(e){o(this,t),this.carousel=e,this.$list=null,this.events={change:this.onChange.bind(this),refresh:this.onRefresh.bind(this)}}return s(t,[{key:"buildList",value:function(){var t=this;if(!(this.carousel.pages.lengthn)for(var a=n;a1&&void 0!==arguments[1]?arguments[1]:{};if(o(this,n),a=k(!0,{},B,a),(i=e.call(this,a)).state="init",i.$container=t,!(i.$container instanceof HTMLElement))throw new Error("No root element provided");return i.slideNext=I(i.slideNext.bind(d(i)),250),i.slidePrev=I(i.slidePrev.bind(d(i)),250),i.init(),t.__Carousel=d(i),i}return s(n,[{key:"init",value:function(){this.pages=[],this.page=this.pageIndex=null,this.prevPage=this.prevPageIndex=null,this.attachPlugins(n.Plugins),this.trigger("init"),this.initLayout(),this.initSlides(),this.updateMetrics(),this.$track&&this.pages.length&&(this.$track.style.transform="translate3d(".concat(-1*this.pages[this.page].left,"px, 0px, 0) scale(1)")),this.manageSlideVisiblity(),this.initPanzoom(),this.state="ready",this.trigger("ready")}},{key:"initLayout",value:function(){var t,e,i,n,o=this.option("prefix"),a=this.option("classNames");(this.$viewport=this.option("viewport")||this.$container.querySelector(".".concat(o).concat(a.viewport)),this.$viewport)||(this.$viewport=document.createElement("div"),(t=this.$viewport.classList).add.apply(t,m((o+a.viewport).split(" "))),(e=this.$viewport).append.apply(e,m(this.$container.childNodes)),this.$container.appendChild(this.$viewport));(this.$track=this.option("track")||this.$container.querySelector(".".concat(o).concat(a.track)),this.$track)||(this.$track=document.createElement("div"),(i=this.$track.classList).add.apply(i,m((o+a.track).split(" "))),(n=this.$track).append.apply(n,m(this.$viewport.childNodes)),this.$viewport.appendChild(this.$track))}},{key:"initSlides",value:function(){var t=this;this.slides=[],this.$viewport.querySelectorAll(".".concat(this.option("prefix")).concat(this.option("classNames.slide"))).forEach((function(e){var i={$el:e,isDom:!0};t.slides.push(i),t.trigger("createSlide",i,t.slides.length)})),Array.isArray(this.options.slides)&&(this.slides=k(!0,m(this.slides),this.options.slides))}},{key:"updateMetrics",value:function(){var t,e=this,n=0,o=[];this.slides.forEach((function(i,a){var s=i.$el,r=i.isDom||!t?e.getSlideMetrics(s):t;i.index=a,i.width=r,i.left=n,t=r,n+=r,o.push(a)}));var a=Math.max(this.$track.offsetWidth,S(this.$track.getBoundingClientRect().width)),s=getComputedStyle(this.$track);a-=parseFloat(s.paddingLeft)+parseFloat(s.paddingRight),this.contentWidth=n,this.viewportWidth=a;var r=[],l=this.option("slidesPerPage");if(Number.isInteger(l)&&n>a)for(var c=0;ca)&&(r.push({indexes:[],slides:[]}),h=r.length-1,d=0),d+=f.width,r[h].indexes.push(u),r[h].slides.push(f)}var v=this.option("center"),p=this.option("fill");r.forEach((function(t,i){t.index=i,t.width=t.slides.reduce((function(t,e){return t+e.width}),0),t.left=t.slides[0].left,v&&(t.left+=.5*(a-t.width)*-1),p&&!e.option("infiniteX",e.option("infinite"))&&n>a&&(t.left=Math.max(t.left,0),t.left=Math.min(t.left,n-a))}));var g,y=[];r.forEach((function(t){var e=i({},t);g&&e.left===g.left?(g.width+=e.width,g.slides=[].concat(m(g.slides),m(e.slides)),g.indexes=[].concat(m(g.indexes),m(e.indexes))):(e.index=y.length,g=e,y.push(e))})),this.pages=y;var b=this.page;if(null===b){var x=this.option("initialSlide");b=null!==x?this.findPageForSlide(x):parseInt(this.option("initialPage",0),10)||0,y[b]||(b=y.length&&b>y.length?y[y.length-1].index:0),this.page=b,this.pageIndex=b}this.updatePanzoom(),this.trigger("refresh")}},{key:"getSlideMetrics",value:function(t){if(!t){var e,i,n=this.slides[0];if((t=document.createElement("div")).dataset.isTestEl=1,t.style.visibility="hidden",(e=t.classList).add.apply(e,m((this.option("prefix")+this.option("classNames.slide")).split(" "))),n.customClass)(i=t.classList).add.apply(i,m(n.customClass.split(" ")));this.$track.prepend(t)}var o=Math.max(t.offsetWidth,S(t.getBoundingClientRect().width)),a=t.currentStyle||window.getComputedStyle(t);return o=o+(parseFloat(a.marginLeft)||0)+(parseFloat(a.marginRight)||0),t.dataset.isTestEl&&t.remove(),o}},{key:"findPageForSlide",value:function(t){t=parseInt(t,10)||0;var e=this.pages.find((function(e){return e.indexes.indexOf(t)>-1}));return e?e.index:null}},{key:"slideNext",value:function(){this.slideTo(this.pageIndex+1)}},{key:"slidePrev",value:function(){this.slideTo(this.pageIndex-1)}},{key:"slideTo",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=e.x,n=void 0===i?-1*this.setPage(t,!0):i,o=e.y,a=void 0===o?0:o,s=e.friction,r=void 0===s?this.option("friction"):s;this.Panzoom.content.x===n&&!this.Panzoom.velocity.x&&r||(this.Panzoom.panTo({x:n,y:a,friction:r,ignoreBounds:!0}),"ready"===this.state&&"ready"===this.Panzoom.state&&this.trigger("settle"))}},{key:"initPanzoom",value:function(){var t=this;this.Panzoom&&this.Panzoom.destroy();var e=k(!0,{},{content:this.$track,wrapInner:!1,resizeParent:!1,zoom:!1,click:!1,lockAxis:"x",x:this.pages.length?-1*this.pages[this.page].left:0,centerOnStart:!1,textSelection:function(){return t.option("textSelection",!1)},panOnlyZoomed:function(){return this.content.width<=this.viewport.width}},this.option("Panzoom"));this.Panzoom=new M(this.$container,e),this.Panzoom.on({"*":function(e){for(var i=arguments.length,n=new Array(i>1?i-1:0),o=1;o1&&this.option("infiniteX",this.option("infinite"))?this.Panzoom.boundX=null:this.pages.length&&(this.Panzoom.boundX={from:-1*this.pages[this.pages.length-1].left,to:-1*this.pages[0].left}),this.option("infiniteY",this.option("infinite"))?this.Panzoom.boundY=null:this.Panzoom.boundY={from:0,to:0},this.Panzoom.handleCursor())}},{key:"manageSlideVisiblity",value:function(){var t=this,e=this.contentWidth,i=this.viewportWidth,n=this.Panzoom?-1*this.Panzoom.content.x:this.pages.length?this.pages[this.page].left:0,o=this.option("preload"),a=this.option("infiniteX",this.option("infinite")),s=parseFloat(getComputedStyle(this.$viewport,null).getPropertyValue("padding-left")),r=parseFloat(getComputedStyle(this.$viewport,null).getPropertyValue("padding-right"));this.slides.forEach((function(l){var c,h,d=0;c=n-s,h=n+i+r,c-=o*(i+s+r),h+=o*(i+s+r);var u=l.left+l.width>c&&l.leftc&&l.leftc&&l.leftn&&l.left<=n+i+r&&(d=0)):t.removeSlideEl(l),l.hasDiff=d}));var l=0,c=0;this.slides.forEach((function(t,i){var n=0;t.$el?(i!==l||t.hasDiff?n=c+t.hasDiff*e:c=0,t.$el.style.left=Math.abs(n)>.1?"".concat(c+t.hasDiff*e,"px"):"",l++):c+=t.width})),this.markSelectedSlides()}},{key:"createSlideEl",value:function(t){var e;if(t){if(!t.$el){var i,n=document.createElement("div");if(n.dataset.index=t.index,(e=n.classList).add.apply(e,m((this.option("prefix")+this.option("classNames.slide")).split(" "))),t.customClass)(i=n.classList).add.apply(i,m(t.customClass.split(" ")));t.html&&(n.innerHTML=t.html);var o=[];this.slides.forEach((function(t,e){t.$el&&o.push(e)}));var a=t.index,s=null;if(o.length){var r=o.reduce((function(t,e){return Math.abs(e-a)-1?(e&&!a.classList.contains(e)&&(a.classList.add(e),t.trigger("selectSlide",n)),a.removeAttribute(i)):(e&&a.classList.contains(e)&&(a.classList.remove(e),t.trigger("unselectSlide",n)),a.setAttribute(i,!0))}}))}},{key:"updatePage",value:function(){this.updateMetrics(),this.slideTo(this.page,{friction:0})}},{key:"onBeforeTransform",value:function(){this.option("infiniteX",this.option("infinite"))&&this.manageInfiniteTrack(),this.manageSlideVisiblity()}},{key:"manageInfiniteTrack",value:function(){var t=this.contentWidth,e=this.viewportWidth;if(!(!this.option("infiniteX",this.option("infinite"))||this.pages.length<2||te&&(i.content.x-=t,this.pageIndex=this.pageIndex+this.pages.length,n=!0),n&&"pointerdown"===i.state&&i.resetDragPosition(),n}}},{key:"onTouchEnd",value:function(t,e){var i=this.option("dragFree");if(!i&&this.pages.length>1&&t.dragOffset.time<350&&Math.abs(t.dragOffset.y)<1&&Math.abs(t.dragOffset.x)>5)this[t.dragOffset.x<0?"slideNext":"slidePrev"]();else if(i){var n=g(this.getPageFromPosition(-1*t.transform.x),2)[1];this.setPage(n)}else this.slideToClosest()}},{key:"slideToClosest",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=this.getPageFromPosition(-1*this.Panzoom.content.x),i=g(e,2),n=i[1];this.slideTo(n,t)}},{key:"getPageFromPosition",value:function(t){var e=this.pages.length;this.option("center")&&(t+=.5*this.viewportWidth);var i=Math.floor(t/this.contentWidth);t-=i*this.contentWidth;var n=this.slides.find((function(e){return e.left<=t&&e.left+e.width>t}));if(n){var o=this.findPageForSlide(n.index);return[o,o+i*e]}return[0,0]}},{key:"setPage",value:function(t,e){var i=0,n=parseInt(t,10)||0,o=this.page,a=this.pageIndex,s=this.pages.length,r=this.contentWidth,l=this.viewportWidth;if(t=(n%s+s)%s,this.option("infiniteX",this.option("infinite"))&&r>l){var c=Math.floor(n/s)||0,h=r;if(i=this.pages[t].left+c*h,!0===e&&s>2){var d=-1*this.Panzoom.content.x,u=i-h,f=i+h,v=Math.abs(d-i),p=Math.abs(d-u),g=Math.abs(d-f);g.1&&(o="".concat(e.width*i,"px"),a="".concat(e.height*i,"px"),s="translate3d(".concat(e.offsetLeft,"px, ").concat(e.offsetTop,"px, 0) scale(").concat(1/i,")")),n.style.width=o,n.style.height=a,n.style.transform=s}}},{key:"onTouchstart",value:function(t){this.startY=t.touches?t.touches[0].screenY:t.screenY}},{key:"onTouchmove",value:function(t){var e=this.startY,i=window.innerWidth/window.document.documentElement.clientWidth;if(t.cancelable&&!(t.touches.length>1||1!==i)){var n=C(t.composedPath()[0]);if(n){var o=window.getComputedStyle(n),a=parseInt(o.getPropertyValue("height"),10),s=t.touches?t.touches[0].screenY:t.screenY,r=e<=s&&0===n.scrollTop,l=e>=s&&n.scrollHeight-n.scrollTop===a;(r||l)&&t.preventDefault()}else t.preventDefault()}}},{key:"onWheel",value:function(t){C(t.composedPath()[0])||t.preventDefault()}},{key:"cleanup",value:function(){this.pendingUpdate&&(cancelAnimationFrame(this.pendingUpdate),this.pendingUpdate=null);var t=this.viewport;t&&(t.removeEventListener("resize",this.onResize),this.viewport=null),window.removeEventListener("touchstart",this.onTouchstart,!1),window.removeEventListener("touchmove",this.onTouchmove,!1),window.removeEventListener("wheel",this.onWheel,{passive:!1})}},{key:"attach",value:function(){this.fancybox.on("initLayout",this.onReady)}},{key:"detach",value:function(){this.fancybox.off("initLayout",this.onReady),this.cleanup()}}]),t}(),Y=function(){function t(e){o(this,t),this.fancybox=e,this.$container=null,this.state="init";for(var i=0,n=["onPrepare","onClosing","onKeydown"];i=this.fancybox.option("Thumbs.minScreenHeight")&&this.build()}},{key:"onClosing",value:function(){this.Carousel&&this.Carousel.Panzoom.detachEvents()}},{key:"onKeydown",value:function(t,e){e===t.option("Thumbs.key")&&this.toggle()}},{key:"build",value:function(){var t=this;if(!this.$container){var e=document.createElement("div");e.classList.add("fancybox__thumbs"),this.fancybox.$carousel.parentNode.insertBefore(e,this.fancybox.$carousel.nextSibling),this.Carousel=new H(e,k(!0,{Dots:!1,Navigation:!1,Sync:{friction:0},infinite:!1,center:!0,fill:!0,dragFree:!0,slidesPerPage:1,preload:1},this.fancybox.option("Thumbs.Carousel"),{Sync:{target:this.fancybox.Carousel},slides:this.getSlides()})),this.Carousel.Panzoom.on("wheel",(function(e,i){i.preventDefault(),t.fancybox[i.deltaY<0?"prev":"next"]()})),this.$container=e,this.state="visible"}}},{key:"getSlides",value:function(){var t,e=[],i=x(this.fancybox.items);try{for(i.s();!(t=i.n()).done;){var n=t.value,o=n.thumb;o&&e.push({html:this.fancybox.option("Thumbs.tpl").replace(/\{\{src\}\}/gi,o),customClass:"has-thumb has-".concat(n.type||"image")})}}catch(t){i.e(t)}finally{i.f()}return e}},{key:"toggle",value:function(){"visible"===this.state?this.hide():"hidden"===this.state?this.show():this.build()}},{key:"show",value:function(){"hidden"===this.state&&(this.$container.style.display="",this.Carousel.Panzoom.attachEvents(),this.state="visible")}},{key:"hide",value:function(){"visible"===this.state&&(this.Carousel.Panzoom.detachEvents(),this.$container.style.display="none",this.state="hidden")}},{key:"cleanup",value:function(){this.Carousel&&(this.Carousel.destroy(),this.Carousel=null),this.$container&&(this.$container.remove(),this.$container=null),this.state="init"}},{key:"attach",value:function(){this.fancybox.on(this.events)}},{key:"detach",value:function(){this.fancybox.off(this.events),this.cleanup()}}]),t}();Y.defaults={minSlideCount:2,minScreenHeight:500,autoStart:!0,key:"t",Carousel:{},tpl:'
'};var V=function(t,e){for(var i=new URL(t),n=new URLSearchParams(i.search),o=new URLSearchParams,a=0,s=[].concat(m(n),m(Object.entries(e)));a\n Sorry, your browser doesn\'t support embedded videos.',format:""}},G=function(){function t(e){o(this,t),this.fancybox=e;for(var i=0,n=["onInit","onReady","onCreateSlide","onRemoveSlide","onSelectSlide","onUnselectSlide","onRefresh","onMessage"];i0?"svembed":"embed"),i="map"):(n=e.match(/(?:maps\.)?google\.([a-z]{2,3}(?:\.[a-z]{2})?)\/(?:maps\/search\/)(.*)/i))&&(t.src="//maps.google.".concat(n[1],"/maps?q=").concat(n[2].replace("query=","q=").replace("api=1",""),"&output=embed"),i="map");i||("#"===e.charAt(0)?i="inline":(n=e.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))?(i="html5video",t.format=t.format||"video/"+("ogv"===n[1]?"ogg":n[1])):e.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)?i="image":e.match(/\.(pdf)((\?|#).*)?$/i)&&(i="pdf")),t.type=i||this.fancybox.option("defaultType","image"),"html5video"!==i&&"video"!==i||(t.video=k({},this.fancybox.option("Html.video"),t.video),t._width&&t._height?t.ratio=parseFloat(t._width)/parseFloat(t._height):t.ratio=t.ratio||t.video.ratio||Z.video.ratio)}}},{key:"onReady",value:function(){var t=this;this.fancybox.Carousel.slides.forEach((function(e){e.$el&&(t.setContent(e),e.index===t.fancybox.getSlide().index&&t.playVideo(e))}))}},{key:"onCreateSlide",value:function(t,e,i){"ready"===this.fancybox.state&&this.setContent(i)}},{key:"loadInlineContent",value:function(t){var e;if(t.src instanceof HTMLElement)e=t.src;else if("string"==typeof t.src){var i=t.src.split("#",2),n=2===i.length&&""===i[0]?i[1]:i[0];e=document.getElementById(n)}if(e){if("clone"===t.type||e.$placeHolder){var o=(e=e.cloneNode(!0)).getAttribute("id");o=o?"".concat(o,"--clone"):"clone-".concat(this.fancybox.id,"-").concat(t.index),e.setAttribute("id",o)}else{var a=document.createElement("div");a.classList.add("fancybox-placeholder"),e.parentNode.insertBefore(a,e),e.$placeHolder=a}this.fancybox.setContent(t,e)}else this.fancybox.setError(t,"{{ELEMENT_NOT_FOUND}}")}},{key:"loadAjaxContent",value:function(t){var e=this.fancybox,i=new XMLHttpRequest;e.showLoading(t),i.onreadystatechange=function(){i.readyState===XMLHttpRequest.DONE&&"ready"===e.state&&(e.hideLoading(t),200===i.status?e.setContent(t,i.responseText):e.setError(t,404===i.status?"{{AJAX_NOT_FOUND}}":"{{AJAX_FORBIDDEN}}"))};var n=t.ajax||null;i.open(n?"POST":"GET",t.src),i.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),i.setRequestHeader("X-Requested-With","XMLHttpRequest"),i.send(n),t.xhr=i}},{key:"loadIframeContent",value:function(t){var e=this,i=this.fancybox,n=document.createElement("iframe");if(n.className="fancybox__iframe",n.setAttribute("id","fancybox__iframe_".concat(i.id,"_").concat(t.index)),n.setAttribute("allow","autoplay; fullscreen"),n.setAttribute("scrolling","auto"),t.$iframe=n,"iframe"!==t.type||!1===t.preload)return n.setAttribute("src",t.src),this.fancybox.setContent(t,n),void this.resizeIframe(t);i.showLoading(t);var o=document.createElement("div");o.style.visibility="hidden",this.fancybox.setContent(t,o),o.appendChild(n),n.onerror=function(){i.setError(t,"{{IFRAME_ERROR}}")},n.onload=function(){i.hideLoading(t);var o=!1;n.isReady||(n.isReady=!0,o=!0),n.src.length&&(n.parentNode.style.visibility="",e.resizeIframe(t),o&&i.revealContent(t))},n.setAttribute("src",t.src)}},{key:"setAspectRatio",value:function(t){var e=t.$content,i=t.ratio;if(e){var n=t._width,o=t._height;if(i||n&&o){Object.assign(e.style,{width:n&&o?"100%":"",height:n&&o?"100%":"",maxWidth:"",maxHeight:""});var a=e.offsetWidth,s=e.offsetHeight;if(o=o||s,(n=n||a)>a||o>s){var r=Math.min(a/n,s/o);n*=r,o*=r}Math.abs(n/o-i)>.01&&(i.1),{top:r,left:l,scale:a&&i?i/a:1,opacity:c}}},{key:"canZoom",value:function(t){var e=this.fancybox,i=e.$container;if(window.visualViewport&&1!==window.visualViewport.scale)return!1;if(t.Panzoom&&!t.Panzoom.content.width)return!1;if(!e.option("Image.zoom")||"contain"!==e.option("Image.fit"))return!1;var n=t.$thumb;if(!n||"loading"===t.state)return!1;i.classList.add("fancybox__no-click");var o,a=n.getBoundingClientRect();if(this.fancybox.option("Image.ignoreCoveredThumbnail")){var s=document.elementFromPoint(a.left+1,a.top+1)===n,r=document.elementFromPoint(a.right-1,a.bottom-1)===n;o=s&&r}else o=document.elementFromPoint(a.left+.5*a.width,a.top+.5*a.height)===n;return i.classList.remove("fancybox__no-click"),o}},{key:"zoomIn",value:function(){var t=this.fancybox,e=t.getSlide(),i=e.Panzoom,n=this.getZoomInfo(e),o=n.top,a=n.left,s=n.scale,r=n.opacity;t.trigger("reveal",e),i.panTo({x:-1*a,y:-1*o,scale:s,friction:0,ignoreBounds:!0}),e.$content.style.visibility="",e.state="zoomIn",!0===r&&i.on("afterTransform",(function(t){"zoomIn"!==e.state&&"zoomOut"!==e.state||(t.$content.style.opacity=Math.min(1,1-(1-t.content.scale)/(1-s)))})),i.panTo({x:0,y:0,scale:1,friction:this.fancybox.option("Image.zoomFriction")})}},{key:"zoomOut",value:function(){var t=this,e=this.fancybox,i=e.getSlide(),n=i.Panzoom;if(n){i.state="zoomOut",e.state="customClosing",i.$caption&&(i.$caption.style.visibility="hidden");var o=this.fancybox.option("Image.zoomFriction"),a=function(e){var a=t.getZoomInfo(i),s=a.top,r=a.left,l=a.scale,c=a.opacity;e||c||(o*=.82),n.panTo({x:-1*r,y:-1*s,scale:l,friction:o,ignoreBounds:!0}),o*=.98};window.addEventListener("scroll",a),n.once("endAnimation",(function(){window.removeEventListener("scroll",a),e.destroy()})),a()}}},{key:"handleCursor",value:function(t){if("image"===t.type&&t.$el){var e=t.Panzoom,i=this.fancybox.option("Image.click",!1,t),n=this.fancybox.option("Image.touch"),o=t.$el.classList,a=this.fancybox.option("Image.canZoomInClass"),s=this.fancybox.option("Image.canZoomOutClass");if(o.remove(s),o.remove(a),e&&"toggleZoom"===i)e&&1===e.content.scale&&e.option("maxScale")-e.content.scale>.01?o.add(a):e.content.scale>1&&!n&&o.add(s);else"close"===i&&o.add(s)}}},{key:"onWheel",value:function(t,e){if("ready"===this.fancybox.state&&!1!==this.fancybox.trigger("Image.wheel",e))switch(this.fancybox.option("Image.wheel")){case"zoom":"done"===t.state&&t.Panzoom&&t.Panzoom.zoomWithWheel(e);break;case"close":this.fancybox.close();break;case"slide":this.fancybox[e.deltaY<0?"prev":"next"]()}}},{key:"onClick",value:function(t,e){var i=this;if("ready"===this.fancybox.state){var n=t.Panzoom;if(!n||!n.dragPosition.midPoint&&0===n.dragOffset.x&&0===n.dragOffset.y&&1===n.dragOffset.scale){if(this.fancybox.Carousel.Panzoom.lockAxis)return!1;var o=function(n){switch(n){case"toggleZoom":e.stopPropagation(),t.Panzoom&&t.Panzoom.zoomWithClick(e);break;case"close":i.fancybox.close();break;case"next":e.stopPropagation(),i.fancybox.next()}},a=this.fancybox.option("Image.click"),s=this.fancybox.option("Image.doubleClick");s?this.clickTimer?(clearTimeout(this.clickTimer),this.clickTimer=null,o(s)):this.clickTimer=setTimeout((function(){i.clickTimer=null,o(a)}),300):o(a)}}}},{key:"onPageChange",value:function(t,e){var i=t.getSlide();e.slides.forEach((function(t){t.Panzoom&&"done"===t.state&&t.index!==i.index&&t.Panzoom.panTo({x:0,y:0,scale:1,friction:.8})}))}},{key:"attach",value:function(){this.fancybox.on(this.events)}},{key:"detach",value:function(){this.fancybox.off(this.events)}}]),t}();K.defaults={canZoomInClass:"can-zoom_in",canZoomOutClass:"can-zoom_out",zoom:!0,zoomOpacity:"auto",zoomFriction:.82,ignoreCoveredThumbnail:!1,touch:!0,click:"toggleZoom",doubleClick:null,wheel:"zoom",fit:"contain",wrap:!1,Panzoom:{ratio:1}};var J=function(){function t(e){o(this,t),this.fancybox=e;for(var i=0,n=["onChange","onClosing"];i1?"-"+(o.index+1):""))}n&&(this.origHash=a!==s?a:""),s&&a!==s&&(this.timer=setTimeout((function(){try{window.history[n?"pushState":"replaceState"]({},document.title,window.location.pathname+window.location.search+s),n&&(e.hasCreatedHistory=!0)}catch(t){}}),300))}},{key:"onClosing",value:function(){if(this.timer&&clearTimeout(this.timer),!0!==this.hasSilentClose)try{return void window.history.replaceState({},document.title,window.location.pathname+window.location.search+(this.origHash||""))}catch(t){}}},{key:"attach",value:function(t){t.on(this.events)}},{key:"detach",value:function(t){t.off(this.events)}}],[{key:"startFromUrl",value:function(){var e=t.Fancybox;if(e&&!e.getInstance()&&!1!==e.defaults.Hash){var i=t.getParsedURL(),n=i.hash,o=i.slug,a=i.index;if(o){var s=document.querySelector('[data-slug="'.concat(n,'"]'));if(s&&s.dispatchEvent(new CustomEvent("click",{bubbles:!0,cancelable:!0})),!e.getInstance()){var r=document.querySelectorAll('[data-fancybox="'.concat(o,'"]'));r.length&&(null===a&&1===r.length?s=r[0]:a&&(s=r[a-1]),s&&s.dispatchEvent(new CustomEvent("click",{bubbles:!0,cancelable:!0})))}}}}},{key:"onHashChange",value:function(){var e=t.getParsedURL(),i=e.slug,n=e.index,o=t.Fancybox,a=o&&o.getInstance();if(a&&a.plugins.Hash){if(i){var s=a.Carousel;if(i===a.option("slug"))return s.slideTo(n-1);var r,l=x(s.slides);try{for(l.s();!(r=l.n()).done;){var c=r.value;if(c.slug&&c.slug===i)return s.slideTo(c.index)}}catch(t){l.e(t)}finally{l.f()}var h=a.getSlide(),d=h.$trigger&&h.$trigger.dataset;if(d&&d.fancybox===i)return s.slideTo(n-1)}a.plugins.Hash.hasSilentClose=!0,a.close()}t.startFromUrl()}},{key:"create",value:function(e){function i(){window.addEventListener("hashchange",t.onHashChange,!1),t.startFromUrl()}t.Fancybox=e,W&&window.requestAnimationFrame((function(){/complete|interactive|loaded/.test(document.readyState)?i():document.addEventListener("DOMContentLoaded",i)}))}},{key:"destroy",value:function(){window.removeEventListener("hashchange",t.onHashChange,!1)}},{key:"getParsedURL",value:function(){var t=window.location.hash.substr(1),e=t.split("-"),i=e.length>1&&/^\+?\d+$/.test(e[e.length-1])&&parseInt(e.pop(-1),10)||null;return{hash:t,slug:e.join("-"),index:i}}}]),t}(),Q={pageXOffset:0,pageYOffset:0,element:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement},activate:function(t){Q.pageXOffset=window.pageXOffset,Q.pageYOffset=window.pageYOffset,t.requestFullscreen?t.requestFullscreen():t.mozRequestFullScreen?t.mozRequestFullScreen():t.webkitRequestFullscreen?t.webkitRequestFullscreen():t.msRequestFullscreen&&t.msRequestFullscreen()},deactivate:function(){document.exitFullscreen?document.exitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()}},tt=function(){function t(e){o(this,t),this.fancybox=e,this.active=!1,this.handleVisibilityChange=this.handleVisibilityChange.bind(this)}return s(t,[{key:"isActive",value:function(){return this.active}},{key:"setTimer",value:function(){var t=this;if(this.active&&!this.timer){var e=this.fancybox.option("slideshow.delay",3e3);this.timer=setTimeout((function(){t.timer=null,t.fancybox.option("infinite")||t.fancybox.getSlide().index!==t.fancybox.Carousel.slides.length-1?t.fancybox.next():t.fancybox.jumpTo(0,{friction:0})}),e);var i=this.$progress;i||((i=document.createElement("div")).classList.add("fancybox__progress"),this.fancybox.$carousel.parentNode.insertBefore(i,this.fancybox.$carousel),this.$progress=i,i.offsetHeight),i.style.transitionDuration="".concat(e,"ms"),i.style.transform="scaleX(1)"}}},{key:"clearTimer",value:function(){clearTimeout(this.timer),this.timer=null,this.$progress&&(this.$progress.style.transitionDuration="",this.$progress.style.transform="",this.$progress.offsetHeight)}},{key:"activate",value:function(){this.active||(this.active=!0,this.fancybox.$container.classList.add("has-slideshow"),"done"===this.fancybox.getSlide().state&&this.setTimer(),document.addEventListener("visibilitychange",this.handleVisibilityChange,!1))}},{key:"handleVisibilityChange",value:function(){this.deactivate()}},{key:"deactivate",value:function(){this.active=!1,this.clearTimer(),this.fancybox.$container.classList.remove("has-slideshow"),document.removeEventListener("visibilitychange",this.handleVisibilityChange,!1)}},{key:"toggle",value:function(){this.active?this.deactivate():this.fancybox.Carousel.slides.length>1&&this.activate()}}]),t}(),et={display:["counter","zoom","slideshow","fullscreen","thumbs","close"],autoEnable:!0,items:{counter:{position:"left",type:"div",class:"fancybox__counter",html:' / ',attr:{tabindex:-1}},prev:{type:"button",class:"fancybox__button--prev",label:"PREV",html:'',attr:{"data-fancybox-prev":""}},next:{type:"button",class:"fancybox__button--next",label:"NEXT",html:'',attr:{"data-fancybox-next":""}},fullscreen:{type:"button",class:"fancybox__button--fullscreen",label:"TOGGLE_FULLSCREEN",html:'\n \n \n ',click:function(t){t.preventDefault(),Q.element()?Q.deactivate():Q.activate(this.fancybox.$container)}},slideshow:{type:"button",class:"fancybox__button--slideshow",label:"TOGGLE_SLIDESHOW",html:'\n \n \n ',click:function(t){t.preventDefault(),this.Slideshow.toggle()}},zoom:{type:"button",class:"fancybox__button--zoom",label:"TOGGLE_ZOOM",html:'',click:function(t){t.preventDefault();var e=this.fancybox.getSlide().Panzoom;e&&e.toggleZoom()}},download:{type:"link",label:"DOWNLOAD",class:"fancybox__button--download",html:'',click:function(t){t.stopPropagation()}},thumbs:{type:"button",label:"TOGGLE_THUMBS",class:"fancybox__button--thumbs",html:'',click:function(t){t.stopPropagation();var e=this.fancybox.plugins.Thumbs;e&&e.toggle()}},close:{type:"button",label:"CLOSE",class:"fancybox__button--close",html:'',attr:{"data-fancybox-close":"",tabindex:0}}}},it=function(){function t(e){var i=this;o(this,t),this.fancybox=e,this.$container=null,this.state="init";for(var n=0,a=["onInit","onPrepare","onDone","onKeydown","onClosing","onChange","onSettle","onRefresh"];nl.option("baseScale"),h=x(this.fancybox.$container.querySelectorAll(".fancybox__button--zoom"));try{for(h.s();!(r=h.n()).done;){var d=r.value;c?d.removeAttribute("disabled"):d.setAttribute("disabled","")}}catch(t){h.e(t)}finally{h.f()}var u,f=x(this.fancybox.$container.querySelectorAll("[data-fancybox-index]"));try{for(f.s();!(u=f.n()).done;){u.value.innerHTML=e.index+1}}catch(t){f.e(t)}finally{f.f()}var v,p=x(this.fancybox.$container.querySelectorAll("[data-fancybox-count]"));try{for(p.s();!(v=p.n()).done;){v.value.innerHTML=n}}catch(t){p.e(t)}finally{p.f()}if(!this.fancybox.option("infinite")){var g,m=x(this.fancybox.$container.querySelectorAll("[data-fancybox-prev]"));try{for(m.s();!(g=m.n()).done;){var y=g.value;0===i?y.setAttribute("disabled",""):y.removeAttribute("disabled")}}catch(t){m.e(t)}finally{m.f()}var b,w=x(this.fancybox.$container.querySelectorAll("[data-fancybox-next]"));try{for(w.s();!(b=w.n()).done;){var k=b.value;i===n-1?k.setAttribute("disabled",""):k.removeAttribute("disabled")}}catch(t){w.e(t)}finally{w.f()}}}},{key:"cleanup",value:function(){this.Slideshow&&this.Slideshow.isActive()&&this.Slideshow.clearTimer(),this.$container&&this.$container.remove(),this.$container=null}},{key:"attach",value:function(){this.fancybox.on(this.events)}},{key:"detach",value:function(){this.fancybox.off(this.events),this.cleanup()}}]),t}();it.defaults=et;var nt={ScrollLock:U,Thumbs:Y,Html:G,Toolbar:it,Image:K,Hash:J},ot={startIndex:0,preload:1,infinite:!0,showClass:"fancybox-zoomInUp",hideClass:"fancybox-fadeOut",animated:!0,hideScrollbar:!0,parentEl:null,mainClass:null,autoFocus:!0,trapFocus:!0,placeFocusBack:!0,click:"close",closeButton:"inside",dragToClose:!0,keyboard:{Escape:"close",Delete:"close",Backspace:"close",PageUp:"next",PageDown:"prev",ArrowUp:"next",ArrowDown:"prev",ArrowRight:"next",ArrowLeft:"prev"},template:{closeButton:'',spinner:'',main:null},l10n:{CLOSE:"Close",NEXT:"Next",PREV:"Previous",MODAL:"You can close this modal content with the ESC key",ERROR:"Something Went Wrong, Please Try Again Later",IMAGE_ERROR:"Image Not Found",ELEMENT_NOT_FOUND:"HTML Element Not Found",AJAX_NOT_FOUND:"Error Loading AJAX : Not Found",AJAX_FORBIDDEN:"Error Loading AJAX : Forbidden",IFRAME_ERROR:"Error Loading Page",TOGGLE_ZOOM:"Toggle zoom level",TOGGLE_THUMBS:"Toggle thumbnails",TOGGLE_SLIDESHOW:"Toggle slideshow",TOGGLE_FULLSCREEN:"Toggle full-screen mode",DOWNLOAD:"Download"}},at=new Map,st=0,rt=function(t){l(i,t);var e=f(i);function i(t){var n,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return o(this,i),t=t.map((function(t){return t.width&&(t._width=t.width),t.height&&(t._height=t.height),t})),(n=e.call(this,k(!0,{},ot,a))).bindHandlers(),n.state="init",n.setItems(t),n.attachPlugins(i.Plugins),n.trigger("init"),!0===n.option("hideScrollbar")&&n.hideScrollbar(),n.initLayout(),n.initCarousel(),n.attachEvents(),at.set(n.id,d(n)),n.trigger("prepare"),n.state="ready",n.trigger("ready"),n.$container.setAttribute("aria-hidden","false"),n.option("trapFocus")&&n.focus(),n}return s(i,[{key:"option",value:function(t){for(var e,n=this.getSlide(),o=n?n[t]:void 0,a=arguments.length,s=new Array(a>1?a-1:0),r=1;r1?i-1:0),o=1;o=150||Math.abs(e)>=35&&t.dragOffset.time<350?(this.option("hideClass")&&(this.getSlide().hideClass="fancybox-throwOut".concat(t.content.y<0?"Up":"Down")),this.close()):"y"===t.lockAxis&&t.panTo({y:0})}},{key:"onTransform",value:function(t){if(this.$backdrop){var e=Math.abs(t.content.y),i=e<1?"":Math.max(.33,Math.min(1,1-e/t.content.fitHeight*1.5));this.$container.style.setProperty("--fancybox-ts",i?"0s":""),this.$container.style.setProperty("--fancybox-opacity",i)}}},{key:"onMousedown",value:function(){"ready"===this.state&&document.body.classList.add("is-using-mouse")}},{key:"onKeydown",value:function(t){if(this.isTopmost()){document.body.classList.remove("is-using-mouse");var e=t.key,i=this.option("keyboard");if(i&&!t.ctrlKey&&!t.altKey&&!t.shiftKey){var n=t.composedPath()[0],o=document.activeElement&&document.activeElement.classList,a=o&&o.contains("carousel__button");if("Escape"!==e&&!a)if(t.target.isContentEditable||-1!==["BUTTON","TEXTAREA","OPTION","INPUT","SELECT","VIDEO"].indexOf(n.nodeName))return;if(!1!==this.trigger("keydown",e,t)){var s=i[e];"function"==typeof this[s]&&this[s]()}}}}},{key:"getSlide",value:function(){var t=this.Carousel;if(!t)return null;var e=null===t.page?t.option("initialPage"):t.page,i=t.pages||[];return i.length&&i[e]?i[e].slides[0]:null}},{key:"focus",value:function(t){if(!(i.ignoreFocusChange||["init","closing","customClosing","destroy"].indexOf(this.state)>-1)){var e=this.$container,n=this.getSlide(),o="done"===n.state?n.$el:null;if(!o||!o.contains(document.activeElement)){t&&t.preventDefault(),i.ignoreFocusChange=!0;for(var a,s=[],r=0,l=Array.from(e.querySelectorAll(X));r-1?this.lastFocus=t.target:this.lastFocus===e?q(s[s.length-1]):q(e):this.option("autoFocus")&&a?q(a):s.indexOf(document.activeElement)<0&&q(e),this.lastFocus=document.activeElement,i.ignoreFocusChange=!1}}}},{key:"hideScrollbar",value:function(){if(W){var t=window.innerWidth-document.documentElement.getBoundingClientRect().width,e="fancybox-style-noscroll",i=document.getElementById(e);i||t>0&&((i=document.createElement("style")).id=e,i.type="text/css",i.innerHTML=".compensate-for-scrollbar {padding-right: ".concat(t,"px;}"),document.getElementsByTagName("head")[0].appendChild(i),document.body.classList.add("compensate-for-scrollbar"))}}},{key:"revealScrollbar",value:function(){document.body.classList.remove("compensate-for-scrollbar");var t=document.getElementById("fancybox-style-noscroll");t&&t.remove()}},{key:"clearContent",value:function(t){this.Carousel.trigger("removeSlide",t),t.$content&&(t.$content.remove(),t.$content=null),t.$closeButton&&(t.$closeButton.remove(),t.$closeButton=null),t._className&&t.$el.classList.remove(t._className)}},{key:"setContent",value:function(t,e){var i,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=t.$el;if(e instanceof HTMLElement)["img","iframe","video","audio"].indexOf(e.nodeName.toLowerCase())>-1?(i=document.createElement("div")).appendChild(e):i=e;else{var a=document.createRange().createContextualFragment(e);(i=document.createElement("div")).appendChild(a)}if(t.filter&&!t.error&&(i=i.querySelector(t.filter)),i instanceof Element)return t._className="has-".concat(n.suffix||t.type||"unknown"),o.classList.add(t._className),i.classList.add("fancybox__content"),"none"!==i.style.display&&"none"!==getComputedStyle(i).getPropertyValue("display")||(i.style.display=t.display||this.option("defaultDisplay")||"flex"),t.id&&i.setAttribute("id",t.id),t.$content=i,o.prepend(i),this.manageCloseButton(t),"loading"!==t.state&&this.revealContent(t),i;this.setError(t,"{{ELEMENT_NOT_FOUND}}")}},{key:"manageCloseButton",value:function(t){var e=this,i=void 0===t.closeButton?this.option("closeButton"):t.closeButton;if(i&&("top"!==i||!this.$closeButton)){var n=document.createElement("button");n.classList.add("carousel__button","is-close"),n.setAttribute("title",this.options.l10n.CLOSE),n.innerHTML=this.option("template.closeButton"),n.addEventListener("click",(function(t){return e.close(t)})),"inside"===i?(t.$closeButton&&t.$closeButton.remove(),t.$closeButton=t.$content.appendChild(n)):this.$closeButton=this.$container.insertBefore(n,this.$container.firstChild)}}},{key:"revealContent",value:function(t){var e=this;this.trigger("reveal",t),t.$content.style.visibility="";var i=!1;t.error||"loading"===t.state||null!==this.Carousel.prevPage||t.index!==this.options.startIndex||(i=void 0===t.showClass?this.option("showClass"):t.showClass),i?(t.state="animating",this.animateCSS(t.$content,i,(function(){e.done(t)}))):this.done(t)}},{key:"animateCSS",value:function(t,e,i){if(t&&t.dispatchEvent(new CustomEvent("animationend",{bubbles:!0,cancelable:!0})),t&&e){t.addEventListener("animationend",(function n(o){o.currentTarget===this&&(t.removeEventListener("animationend",n),i&&i(),t.classList.remove(e))})),t.classList.add(e)}else"function"==typeof i&&i()}},{key:"done",value:function(t){t.state="done",this.trigger("done",t);var e=this.getSlide();e&&t.index===e.index&&this.option("autoFocus")&&this.focus()}},{key:"setError",value:function(t,e){t.error=e,this.hideLoading(t),this.clearContent(t);var i=document.createElement("div");i.classList.add("fancybox-error"),i.innerHTML=this.localize(e||"

{{ERROR}}

"),this.setContent(t,i,{suffix:"error"})}},{key:"showLoading",value:function(t){var e=this;t.state="loading",t.$el.classList.add("is-loading");var i=t.$el.querySelector(".fancybox__spinner");i||((i=document.createElement("div")).classList.add("fancybox__spinner"),i.innerHTML=this.option("template.spinner"),i.addEventListener("click",(function(){e.Carousel.Panzoom.velocity||e.close()})),t.$el.prepend(i))}},{key:"hideLoading",value:function(t){var e=t.$el&&t.$el.querySelector(".fancybox__spinner");e&&(e.remove(),t.$el.classList.remove("is-loading")),"loading"===t.state&&(this.trigger("load",t),t.state="ready")}},{key:"next",value:function(){var t=this.Carousel;t&&t.pages.length>1&&t.slideNext()}},{key:"prev",value:function(){var t=this.Carousel;t&&t.pages.length>1&&t.slidePrev()}},{key:"jumpTo",value:function(){var t;this.Carousel&&(t=this.Carousel).slideTo.apply(t,arguments)}},{key:"isClosing",value:function(){return["closing","customClosing","destroy"].includes(this.state)}},{key:"isTopmost",value:function(){return i.getInstance().id==this.id}},{key:"close",value:function(t){var e=this;if(t&&t.preventDefault(),!this.isClosing()&&!1!==this.trigger("shouldClose",t)&&(this.state="closing",this.Carousel.Panzoom.destroy(),this.detachEvents(),this.trigger("closing",t),"destroy"!==this.state)){this.$container.setAttribute("aria-hidden","true"),this.$container.classList.add("is-closing");var i=this.getSlide();if(this.Carousel.slides.forEach((function(t){t.$content&&t.index!==i.index&&e.Carousel.trigger("removeSlide",t)})),"closing"===this.state){var n=void 0===i.hideClass?this.option("hideClass"):i.hideClass;this.animateCSS(i.$content,n,(function(){e.destroy()}),!0)}}}},{key:"destroy",value:function(){if("destroy"!==this.state){this.state="destroy",this.trigger("destroy");var t=this.option("placeFocusBack")?this.option("triggerTarget",this.getSlide().$trigger):null;this.Carousel.destroy(),this.detachPlugins(),this.Carousel=null,this.options={},this.events={},this.$container.remove(),this.$container=this.$backdrop=this.$carousel=null,t&&q(t),at.delete(this.id);var e=i.getInstance();e?e.focus():(document.documentElement.classList.remove("with-fancybox"),document.body.classList.remove("is-using-mouse"),this.revealScrollbar())}}}],[{key:"show",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new i(t,e)}},{key:"fromEvent",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!t.defaultPrevented&&!(t.button&&0!==t.button||t.ctrlKey||t.metaKey||t.shiftKey)){var n,o,a,s=t.composedPath()[0],r=s;if((r.matches("[data-fancybox-trigger]")||(r=r.closest("[data-fancybox-trigger]")))&&(e.triggerTarget=r,n=r&&r.dataset&&r.dataset.fancyboxTrigger),n){var l=document.querySelectorAll('[data-fancybox="'.concat(n,'"]')),c=parseInt(r.dataset.fancyboxIndex,10)||0;r=l.length?l[c]:r}Array.from(i.openers.keys()).reverse().some((function(e){a=r||s;var i=!1;try{a instanceof Element&&("string"==typeof e||e instanceof String)&&(i=a.matches(e)||(a=a.closest(e)))}catch(t){}return!!i&&(t.preventDefault(),o=e,!0)}));var h=!1;if(o){e.event=t,e.target=a,a.origTarget=s,h=i.fromOpener(o,e);var d=i.getInstance();d&&"ready"===d.state&&t.detail&&document.body.classList.add("is-using-mouse")}return h}}},{key:"fromOpener",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=function(t){for(var e=["false","0","no","null","undefined"],i=["true","1","yes"],n=Object.assign({},t.dataset),o={},a=0,s=Object.entries(n);a-1)o[l]=!1;else if(i.indexOf(o[l])>-1)o[l]=!0;else try{o[l]=JSON.parse(c)}catch(t){o[l]=c}else o[l]=c}return t instanceof Element&&(o.$trigger=t),o},o=[],a=e.startIndex||0,s=e.target||null,r=void 0!==(e=k({},e,i.openers.get(t))).groupAll&&e.groupAll,l=void 0===e.groupAttr?"data-fancybox":e.groupAttr,c=l&&s?s.getAttribute("".concat(l)):"";if(!s||c||r){var h=e.root||(s?s.getRootNode():document.body);o=[].slice.call(h.querySelectorAll(t))}if(s&&!r&&(o=c?o.filter((function(t){return t.getAttribute("".concat(l))===c})):[s]),!o.length)return!1;var d=i.getInstance();return!(d&&o.indexOf(d.options.$trigger)>-1)&&(a=s?o.indexOf(s):a,new i(o=o.map(n),k({},e,{startIndex:a,$trigger:s})))}},{key:"bind",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function n(){document.body.addEventListener("click",i.fromEvent,!1)}W&&(i.openers.size||(/complete|interactive|loaded/.test(document.readyState)?n():document.addEventListener("DOMContentLoaded",n)),i.openers.set(t,e))}},{key:"unbind",value:function(t){i.openers.delete(t),i.openers.size||i.destroy()}},{key:"destroy",value:function(){for(var t;t=i.getInstance();)t.destroy();i.openers=new Map,document.body.removeEventListener("click",i.fromEvent,!1)}},{key:"getInstance",value:function(t){return t?at.get(t):Array.from(at.values()).reverse().find((function(t){return!t.isClosing()&&t}))||null}},{key:"close",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=arguments.length>1?arguments[1]:void 0;if(t){var n,o=x(at.values());try{for(o.s();!(n=o.n()).done;){var a=n.value;a.close(e)}}catch(t){o.e(t)}finally{o.f()}}else{var s=i.getInstance();s&&s.close(e)}}},{key:"next",value:function(){var t=i.getInstance();t&&t.next()}},{key:"prev",value:function(){var t=i.getInstance();t&&t.prev()}}]),i}(O);rt.version="4.0.31",rt.defaults=ot,rt.openers=new Map,rt.Plugins=nt,rt.bind("[data-fancybox]");for(var lt=0,ct=Object.entries(rt.Plugins||{});lt= 16 not satisfied with current version ${process.version}.` + ) + process.exit(1) +} diff --git a/docs/vite.config.js b/docs_deprecated/vite.config.js similarity index 100% rename from docs/vite.config.js rename to docs_deprecated/vite.config.js diff --git a/packages/cloud-sdk/package-lock.json b/packages/cloud-sdk/package-lock.json index f4fda59684..d2f82e91db 100644 --- a/packages/cloud-sdk/package-lock.json +++ b/packages/cloud-sdk/package-lock.json @@ -813,7 +813,10 @@ "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", "optional": true, "dependencies": { - "sparse-bitfield": "^3.0.3" + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@smithy/abort-controller": { @@ -1733,7 +1736,7 @@ }, "node_modules/memory-pager": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "resolved": "https://registry.npmmirror.com/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, @@ -1805,6 +1808,14 @@ "whatwg-url": "^11.0.0" } }, + "node_modules/mongodb/node_modules/bson": { + "version": "5.5.1", + "resolved": "https://registry.npmmirror.com/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", + "engines": { + "node": ">=14.20.1" + } + }, "node_modules/mysql2": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", @@ -1889,7 +1900,7 @@ }, "node_modules/sparse-bitfield": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "resolved": "https://registry.npmmirror.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "dependencies": { diff --git a/packages/database-proxy/package-lock.json b/packages/database-proxy/package-lock.json index 5aa7b784c5..ba3d33157a 100644 --- a/packages/database-proxy/package-lock.json +++ b/packages/database-proxy/package-lock.json @@ -677,7 +677,7 @@ }, "node_modules/memory-pager": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "resolved": "https://registry.npmmirror.com/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, diff --git a/packages/database-proxy/package.json b/packages/database-proxy/package.json index 120b99c298..c01f5905a8 100644 --- a/packages/database-proxy/package.json +++ b/packages/database-proxy/package.json @@ -41,4 +41,4 @@ "lint-staged": { "*.{ts,js}": "eslint --fix" } -} \ No newline at end of file +} diff --git a/runtimes/nodejs/package-lock.json b/runtimes/nodejs/package-lock.json index acf24aba5a..6a81334285 100644 --- a/runtimes/nodejs/package-lock.json +++ b/runtimes/nodejs/package-lock.json @@ -182,36 +182,36 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-s3": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.478.0.tgz", - "integrity": "sha512-OUpbCCnK71lQQ07BohJOx9ZER0rPqRAGOVIIVhNEkeN0uYFLzB7/o5a7+FEPUQXEd5rZRZgbxN5xEmnNW/0Waw==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.484.0.tgz", + "integrity": "sha512-6+N1TflOHAPMRAbOXVuJgGouWhSVIznKLuf+3ZDHYWuMUd+FLDhQvplxjVG1czRXsYwROEFylirAU1zJOHA6gA==", "dependencies": { "@aws-crypto/sha1-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.478.0", - "@aws-sdk/core": "3.477.0", - "@aws-sdk/credential-provider-node": "3.478.0", - "@aws-sdk/middleware-bucket-endpoint": "3.470.0", + "@aws-sdk/client-sts": "3.484.0", + "@aws-sdk/core": "3.481.0", + "@aws-sdk/credential-provider-node": "3.484.0", + "@aws-sdk/middleware-bucket-endpoint": "3.484.0", "@aws-sdk/middleware-expect-continue": "3.468.0", "@aws-sdk/middleware-flexible-checksums": "3.468.0", "@aws-sdk/middleware-host-header": "3.468.0", "@aws-sdk/middleware-location-constraint": "3.468.0", "@aws-sdk/middleware-logger": "3.468.0", "@aws-sdk/middleware-recursion-detection": "3.468.0", - "@aws-sdk/middleware-sdk-s3": "3.474.0", + "@aws-sdk/middleware-sdk-s3": "3.484.0", "@aws-sdk/middleware-signing": "3.468.0", "@aws-sdk/middleware-ssec": "3.468.0", "@aws-sdk/middleware-user-agent": "3.478.0", - "@aws-sdk/region-config-resolver": "3.470.0", - "@aws-sdk/signature-v4-multi-region": "3.474.0", + "@aws-sdk/region-config-resolver": "3.484.0", + "@aws-sdk/signature-v4-multi-region": "3.484.0", "@aws-sdk/types": "3.468.0", "@aws-sdk/util-endpoints": "3.478.0", "@aws-sdk/util-user-agent-browser": "3.468.0", "@aws-sdk/util-user-agent-node": "3.470.0", "@aws-sdk/xml-builder": "3.472.0", - "@smithy/config-resolver": "^2.0.21", - "@smithy/core": "^1.2.0", + "@smithy/config-resolver": "^2.0.22", + "@smithy/core": "^1.2.1", "@smithy/eventstream-serde-browser": "^2.0.15", "@smithy/eventstream-serde-config-resolver": "^2.0.15", "@smithy/eventstream-serde-node": "^2.0.15", @@ -223,20 +223,20 @@ "@smithy/md5-js": "^2.0.17", "@smithy/middleware-content-length": "^2.0.17", "@smithy/middleware-endpoint": "^2.2.3", - "@smithy/middleware-retry": "^2.0.24", + "@smithy/middleware-retry": "^2.0.25", "@smithy/middleware-serde": "^2.0.15", "@smithy/middleware-stack": "^2.0.9", "@smithy/node-config-provider": "^2.1.8", "@smithy/node-http-handler": "^2.2.1", "@smithy/protocol-http": "^3.0.11", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/url-parser": "^2.0.15", "@smithy/util-base64": "^2.0.1", "@smithy/util-body-length-browser": "^2.0.1", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.22", - "@smithy/util-defaults-mode-node": "^2.0.29", + "@smithy/util-defaults-mode-browser": "^2.0.23", + "@smithy/util-defaults-mode-node": "^2.0.31", "@smithy/util-endpoints": "^1.0.7", "@smithy/util-retry": "^2.0.8", "@smithy/util-stream": "^2.0.23", @@ -249,44 +249,55 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-s3/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.478.0.tgz", - "integrity": "sha512-Jxy9cE1JMkPR0PklCpq3cORHnZq/Z4klhSTNGgZNeBWovMa+plor52kyh8iUNHKl3XEJvTbHM7V+dvrr/x0P1g==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.484.0.tgz", + "integrity": "sha512-eHKXDHqgPt99977hNissa1y/efwXZ9kg3EKPLK13b6VzTC8s0+Ih+YZemNE22ahw6SYnRiGglYdkdypJ/uPHkg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.477.0", + "@aws-sdk/core": "3.481.0", "@aws-sdk/middleware-host-header": "3.468.0", "@aws-sdk/middleware-logger": "3.468.0", "@aws-sdk/middleware-recursion-detection": "3.468.0", "@aws-sdk/middleware-user-agent": "3.478.0", - "@aws-sdk/region-config-resolver": "3.470.0", + "@aws-sdk/region-config-resolver": "3.484.0", "@aws-sdk/types": "3.468.0", "@aws-sdk/util-endpoints": "3.478.0", "@aws-sdk/util-user-agent-browser": "3.468.0", "@aws-sdk/util-user-agent-node": "3.470.0", - "@smithy/config-resolver": "^2.0.21", - "@smithy/core": "^1.2.0", + "@smithy/config-resolver": "^2.0.22", + "@smithy/core": "^1.2.1", "@smithy/fetch-http-handler": "^2.3.1", "@smithy/hash-node": "^2.0.17", "@smithy/invalid-dependency": "^2.0.15", "@smithy/middleware-content-length": "^2.0.17", "@smithy/middleware-endpoint": "^2.2.3", - "@smithy/middleware-retry": "^2.0.24", + "@smithy/middleware-retry": "^2.0.25", "@smithy/middleware-serde": "^2.0.15", "@smithy/middleware-stack": "^2.0.9", "@smithy/node-config-provider": "^2.1.8", "@smithy/node-http-handler": "^2.2.1", "@smithy/protocol-http": "^3.0.11", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/url-parser": "^2.0.15", "@smithy/util-base64": "^2.0.1", "@smithy/util-body-length-browser": "^2.0.1", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.22", - "@smithy/util-defaults-mode-node": "^2.0.29", + "@smithy/util-defaults-mode-browser": "^2.0.23", + "@smithy/util-defaults-mode-node": "^2.0.31", "@smithy/util-endpoints": "^1.0.7", "@smithy/util-retry": "^2.0.8", "@smithy/util-utf8": "^2.0.2", @@ -296,45 +307,56 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-sso/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/client-sts": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.478.0.tgz", - "integrity": "sha512-D+QID0dYzmn9dcxgKP3/nMndUqiQbDLsqI0Zf2pG4MW5gPhVNKlDGIV3Ztz8SkMjzGJExNOLW2L569o8jshJVw==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.484.0.tgz", + "integrity": "sha512-psQxH0mYhTVvZhfca3s9NbXgnuOM8l+5LtF7fZBF5y4xaPpfAPicPWp6po69J3ynwyXi/MpHNXd/13d/L09TTA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.477.0", - "@aws-sdk/credential-provider-node": "3.478.0", + "@aws-sdk/core": "3.481.0", + "@aws-sdk/credential-provider-node": "3.484.0", "@aws-sdk/middleware-host-header": "3.468.0", "@aws-sdk/middleware-logger": "3.468.0", "@aws-sdk/middleware-recursion-detection": "3.468.0", "@aws-sdk/middleware-user-agent": "3.478.0", - "@aws-sdk/region-config-resolver": "3.470.0", + "@aws-sdk/region-config-resolver": "3.484.0", "@aws-sdk/types": "3.468.0", "@aws-sdk/util-endpoints": "3.478.0", "@aws-sdk/util-user-agent-browser": "3.468.0", "@aws-sdk/util-user-agent-node": "3.470.0", - "@smithy/config-resolver": "^2.0.21", - "@smithy/core": "^1.2.0", + "@smithy/config-resolver": "^2.0.22", + "@smithy/core": "^1.2.1", "@smithy/fetch-http-handler": "^2.3.1", "@smithy/hash-node": "^2.0.17", "@smithy/invalid-dependency": "^2.0.15", "@smithy/middleware-content-length": "^2.0.17", "@smithy/middleware-endpoint": "^2.2.3", - "@smithy/middleware-retry": "^2.0.24", + "@smithy/middleware-retry": "^2.0.25", "@smithy/middleware-serde": "^2.0.15", "@smithy/middleware-stack": "^2.0.9", "@smithy/node-config-provider": "^2.1.8", "@smithy/node-http-handler": "^2.2.1", "@smithy/protocol-http": "^3.0.11", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/url-parser": "^2.0.15", "@smithy/util-base64": "^2.0.1", "@smithy/util-body-length-browser": "^2.0.1", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.22", - "@smithy/util-defaults-mode-node": "^2.0.29", + "@smithy/util-defaults-mode-browser": "^2.0.23", + "@smithy/util-defaults-mode-node": "^2.0.31", "@smithy/util-endpoints": "^1.0.7", "@smithy/util-middleware": "^2.0.8", "@smithy/util-retry": "^2.0.8", @@ -346,15 +368,26 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-sts/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/core": { - "version": "3.477.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.477.0.tgz", - "integrity": "sha512-o0434EH+d1BxHZvgG7z8vph2SYefciQ5RnJw2MgvETGnthgqsnI4nnNJLSw0FVeqCeS18n6vRtzqlGYR2YPCNg==", + "version": "3.481.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.481.0.tgz", + "integrity": "sha512-UeyAc2FnWQDts81vPVBWKEj0WagYK4SVAgNfGcg6zCzzqsUG4unr4NPKQoca2L+XOU55yMCy+5l2K6R3YsFGKg==", "dependencies": { - "@smithy/core": "^1.2.0", + "@smithy/core": "^1.2.1", "@smithy/protocol-http": "^3.0.11", "@smithy/signature-v4": "^2.0.0", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "tslib": "^2.5.0" }, @@ -362,6 +395,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/core/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-env": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.468.0.tgz", @@ -376,14 +420,25 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.478.0.tgz", - "integrity": "sha512-SsrYEYUvTG9ZoPC+zB19AnVoOKID+QIEHJDIi1GCZXW5kTVyr1saTVm4orG2TjYvbHQMddsWtHOvGYXZWAYMbw==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.484.0.tgz", + "integrity": "sha512-BbvU7seI0RPPwpujnz4LA1lC53Cj4BOSRpYYZbrxA6C7SzW0D/IQBZQP3JBbrxIhqewSROSsYGDjvYbyi5aDEw==", "dependencies": { "@aws-sdk/credential-provider-env": "3.468.0", "@aws-sdk/credential-provider-process": "3.468.0", - "@aws-sdk/credential-provider-sso": "3.478.0", + "@aws-sdk/credential-provider-sso": "3.484.0", "@aws-sdk/credential-provider-web-identity": "3.468.0", "@aws-sdk/types": "3.468.0", "@smithy/credential-provider-imds": "^2.0.0", @@ -396,15 +451,26 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.478.0.tgz", - "integrity": "sha512-nwDutJYeHiIZCQDgKIUrsgwAWTil0mNe+cbd+j8fi+wwxkWUzip+F0+z02molJ8WrUUKNRhqB1V5aVx7IranuA==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.484.0.tgz", + "integrity": "sha512-Ylqej3FqRwUD3I7929k214LRH1bUz7f2hfV4ZqY7teM9hQC5Ov5SpVtOtLKNfgaaxAkhD2ffMNfmq8TAg824+g==", "dependencies": { "@aws-sdk/credential-provider-env": "3.468.0", - "@aws-sdk/credential-provider-ini": "3.478.0", + "@aws-sdk/credential-provider-ini": "3.484.0", "@aws-sdk/credential-provider-process": "3.468.0", - "@aws-sdk/credential-provider-sso": "3.478.0", + "@aws-sdk/credential-provider-sso": "3.484.0", "@aws-sdk/credential-provider-web-identity": "3.468.0", "@aws-sdk/types": "3.468.0", "@smithy/credential-provider-imds": "^2.0.0", @@ -417,6 +483,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-process": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.468.0.tgz", @@ -432,13 +509,24 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.478.0.tgz", - "integrity": "sha512-LsDShG51X/q+s5ZFN7kHVqrd8ZHdyEyHqdhoocmRvvw2Dif50M0AqQfvCrW1ndj5CNzXO4x/eH8EK5ZOVlS6Sg==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.484.0.tgz", + "integrity": "sha512-Fl7+YhrlU2icZkz18z9aj4SiWb2aQlWp5LsVqMfSzTlJFc9yPlD9e7F33gnL7kKLVSnAVxsr5v4y4pFC6FZUSw==", "dependencies": { - "@aws-sdk/client-sso": "3.478.0", - "@aws-sdk/token-providers": "3.478.0", + "@aws-sdk/client-sso": "3.484.0", + "@aws-sdk/token-providers": "3.484.0", "@aws-sdk/types": "3.468.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", @@ -449,6 +537,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.468.0.tgz", @@ -463,17 +562,39 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.470.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.470.0.tgz", - "integrity": "sha512-vLXXNWtsRmEIwzJ9HUQfIuTNAsEzvCv0Icsnkvt2BiBZXnmHdp2vIC3e3+kfy1D7dVQloXqMmnfcLu/BUMu2Jw==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.484.0.tgz", + "integrity": "sha512-FzaUGUAat+m96diDMdFTgaG7AiyYOtT97m1Iu4luZP47eiocaHsjgtaMXg1ivoH2atlczLn/7ueYqUnwEcpFlQ==", "dependencies": { "@aws-sdk/types": "3.468.0", "@aws-sdk/util-arn-parser": "3.465.0", "@smithy/node-config-provider": "^2.1.8", "@smithy/protocol-http": "^3.0.11", "@smithy/types": "^2.7.0", - "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-config-provider": "^2.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { "tslib": "^2.5.0" }, "engines": { @@ -494,6 +615,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-expect-continue/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-flexible-checksums": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.468.0.tgz", @@ -512,6 +644,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-host-header": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.468.0.tgz", @@ -526,6 +669,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-location-constraint": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.468.0.tgz", @@ -539,6 +693,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-location-constraint/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-logger": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.468.0.tgz", @@ -552,6 +717,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-logger/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.468.0.tgz", @@ -566,19 +742,41 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.474.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.474.0.tgz", - "integrity": "sha512-62aAo/8u5daIabeJ+gseYeHeShe9eYH6mH+kfWmLsHybXCCv1EaD/ZkdXWNhL0HZ3bUI1z1SF1p8jjTAWALnwA==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.484.0.tgz", + "integrity": "sha512-7K/HcCBQov5nRp3M25APm+6hqrFp4RDc+0NMcA1DGTWKwfYAEqZzn1AurxBCE/nTR4iECV9y1IwdIp8FTdYKSQ==", "dependencies": { "@aws-sdk/types": "3.468.0", "@aws-sdk/util-arn-parser": "3.465.0", "@smithy/node-config-provider": "^2.1.8", "@smithy/protocol-http": "^3.0.11", "@smithy/signature-v4": "^2.0.0", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", - "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-config-provider": "^2.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { "tslib": "^2.5.0" }, "engines": { @@ -602,6 +800,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-signing/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-ssec": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.468.0.tgz", @@ -615,6 +824,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-ssec/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-user-agent": { "version": "3.478.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.478.0.tgz", @@ -630,14 +850,25 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.470.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.470.0.tgz", - "integrity": "sha512-C1o1J06iIw8cyAAOvHqT4Bbqf+PgQ/RDlSyjt2gFfP2OovDpc2o2S90dE8f8iZdSGpg70N5MikT1DBhW9NbhtQ==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.484.0.tgz", + "integrity": "sha512-qfYSwSIc9GasHFrJidydlQE433mB93d31dfypFWhrJPXRv1fhopO72NSfsY2WCcbaRkADc4AajLZFly4J96abw==", "dependencies": { "@smithy/node-config-provider": "^2.1.8", "@smithy/types": "^2.7.0", - "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-config-provider": "^2.1.0", "@smithy/util-middleware": "^2.0.8", "tslib": "^2.5.0" }, @@ -645,17 +876,28 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.478.0.tgz", - "integrity": "sha512-Ra9ptlSZvMlmw+4zujuVhWRN4QxCpmNnnZPn8KHnll7Jmat6Fii7zMf9NUIJ5etLvTlY8y/yUEleRf9KXPBNlA==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.484.0.tgz", + "integrity": "sha512-e5nhewNNuT7bKR9z4SpqeqlVFVMtY7EAOptXFbykOOwW91+EKHnEXjnaKowyVTkwzI6eGFeJi9z6XnoMrpJSuA==", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.474.0", + "@aws-sdk/signature-v4-multi-region": "3.484.0", "@aws-sdk/types": "3.468.0", "@aws-sdk/util-format-url": "3.468.0", "@smithy/middleware-endpoint": "^2.2.3", "@smithy/protocol-http": "^3.0.11", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "tslib": "^2.5.0" }, @@ -663,12 +905,23 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/s3-request-presigner/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.474.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.474.0.tgz", - "integrity": "sha512-93OWRQgTJZASXLrlUNX7mmXknNkYxFYldRLARmYQccONmnIqgYQW0lQj8BFwqkHJTzSMik3/UsU0SHKwZ9ynYA==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.484.0.tgz", + "integrity": "sha512-9LrO9Le/oB7+9NITeW2RcO4V4EAfOCbxE9TvwRbg5CEvWgBdMU7qc1ZnCPXF4i2AsGTsnRUlzaql/M7/ln2lIg==", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.474.0", + "@aws-sdk/middleware-sdk-s3": "3.484.0", "@aws-sdk/types": "3.468.0", "@smithy/protocol-http": "^3.0.11", "@smithy/signature-v4": "^2.0.0", @@ -679,10 +932,21 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/token-providers": { - "version": "3.478.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.478.0.tgz", - "integrity": "sha512-7b5tj1y/wGHZIZ+ckjOUKgKrMuCJMF/G1UKZKIqqdekeEsjcThbvoxAMeY0FEowu2ODVk/ggOmpBFxcu0iYd6A==", + "version": "3.484.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.484.0.tgz", + "integrity": "sha512-9Eb7X0sNhJANfYCeEYWCvfeD4shMZEse3YUz5EALzbpzi/So56ZaeA/lWWeh0fkYiByq74eA2QkC/tXZkHw6EQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -690,18 +954,18 @@ "@aws-sdk/middleware-logger": "3.468.0", "@aws-sdk/middleware-recursion-detection": "3.468.0", "@aws-sdk/middleware-user-agent": "3.478.0", - "@aws-sdk/region-config-resolver": "3.470.0", + "@aws-sdk/region-config-resolver": "3.484.0", "@aws-sdk/types": "3.468.0", "@aws-sdk/util-endpoints": "3.478.0", "@aws-sdk/util-user-agent-browser": "3.468.0", "@aws-sdk/util-user-agent-node": "3.470.0", - "@smithy/config-resolver": "^2.0.21", + "@smithy/config-resolver": "^2.0.22", "@smithy/fetch-http-handler": "^2.3.1", "@smithy/hash-node": "^2.0.17", "@smithy/invalid-dependency": "^2.0.15", "@smithy/middleware-content-length": "^2.0.17", "@smithy/middleware-endpoint": "^2.2.3", - "@smithy/middleware-retry": "^2.0.24", + "@smithy/middleware-retry": "^2.0.25", "@smithy/middleware-serde": "^2.0.15", "@smithy/middleware-stack": "^2.0.9", "@smithy/node-config-provider": "^2.1.8", @@ -709,14 +973,14 @@ "@smithy/property-provider": "^2.0.0", "@smithy/protocol-http": "^3.0.11", "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/url-parser": "^2.0.15", "@smithy/util-base64": "^2.0.1", "@smithy/util-body-length-browser": "^2.0.1", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.22", - "@smithy/util-defaults-mode-node": "^2.0.29", + "@smithy/util-defaults-mode-browser": "^2.0.23", + "@smithy/util-defaults-mode-node": "^2.0.31", "@smithy/util-endpoints": "^1.0.7", "@smithy/util-retry": "^2.0.8", "@smithy/util-utf8": "^2.0.2", @@ -726,12 +990,34 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/types": { - "version": "3.468.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.468.0.tgz", - "integrity": "sha512-rx/9uHI4inRbp2tw3Y4Ih4PNZkVj32h7WneSg3MVgVjAoVD5Zti9KhS5hkvsBxfgmQmg0AQbE+b1sy5WGAgntA==", - "dependencies": { - "@smithy/types": "^2.7.0", + "node_modules/@aws-sdk/token-providers/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.468.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.468.0.tgz", + "integrity": "sha512-rx/9uHI4inRbp2tw3Y4Ih4PNZkVj32h7WneSg3MVgVjAoVD5Zti9KhS5hkvsBxfgmQmg0AQbE+b1sy5WGAgntA==", + "dependencies": { + "@smithy/types": "^2.7.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { "tslib": "^2.5.0" }, "engines": { @@ -776,10 +1062,10 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.465.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.465.0.tgz", - "integrity": "sha512-f+QNcWGswredzC1ExNAB/QzODlxwaTdXkNT5cvke2RLX8SFU5pYk6h4uCtWC0vWPELzOfMfloBrJefBzlarhsw==", + "node_modules/@aws-sdk/util-format-url/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", "dependencies": { "tslib": "^2.5.0" }, @@ -787,6 +1073,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.55.0.tgz", + "integrity": "sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.468.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.468.0.tgz", @@ -798,6 +1095,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@aws-sdk/util-user-agent-browser/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/util-user-agent-node": { "version": "3.470.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.470.0.tgz", @@ -820,12 +1128,71 @@ } } }, + "node_modules/@aws-sdk/util-user-agent-node/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "version": "3.188.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz", + "integrity": "sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==", "dependencies": { - "tslib": "^2.3.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, "node_modules/@aws-sdk/xml-builder": { @@ -840,6 +1207,17 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/xml-builder/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -1045,9 +1423,9 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.15.tgz", - "integrity": "sha512-JkS36PIS3/UCbq/MaozzV7jECeL+BTt4R75bwY8i+4RASys4xOyUS1HsRyUNSqUXFP4QyCz5aNnh3ltuaxv+pw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.0.2.tgz", + "integrity": "sha512-tb2h0b+JvMee+eAxTmhnyqyNk51UXIK949HnE14lFeezKsVJTB30maan+CO2IMwnig2wVYQH84B5qk6ylmKCuA==", "dependencies": { "@smithy/types": "^2.7.0", "tslib": "^2.5.0" @@ -1056,31 +1434,25 @@ "node": ">=14.0.0" } }, - "node_modules/@smithy/chunked-blob-reader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-2.0.0.tgz", - "integrity": "sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg==", + "node_modules/@smithy/abort-controller/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", "dependencies": { "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/chunked-blob-reader-native": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-2.0.1.tgz", - "integrity": "sha512-N2oCZRglhWKm7iMBu7S6wDzXirjAofi7tAd26cxmgibRYOBS4D3hGfmkwCpHdASZzwZDD8rluh0Rcqw1JeZDRw==", - "dependencies": { - "@smithy/util-base64": "^2.0.1", - "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.21.tgz", - "integrity": "sha512-rlLIGT+BeqjnA6C2FWumPRJS1UW07iU5ZxDHtFuyam4W65gIaOFMjkB90ofKCIh+0mLVQrQFrl/VLtQT/6FWTA==", + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.22.tgz", + "integrity": "sha512-YuPjsLnq6I5ZQBTx6BL5NsCLtcLel5YIMf3gDeEa+GSCXn5mgRXm+8XO8HtjR3Xf69b88aY4c7bwKQQS2i8vtA==", "dependencies": { "@smithy/node-config-provider": "^2.1.8", "@smithy/types": "^2.7.0", - "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-config-provider": "^2.1.0", "@smithy/util-middleware": "^2.0.8", "tslib": "^2.5.0" }, @@ -1088,16 +1460,27 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/config-resolver/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.2.0.tgz", - "integrity": "sha512-l8R89X7+hlt2FEFg+OrNq29LP3h9DfGPmO6ObwT9IXWHD6V7ycpj5u2rVQyIis26ovrgOYakl6nfgmPMm8m1IQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.2.1.tgz", + "integrity": "sha512-f6cwmMuHo7RIw/c184NBd2rGeGvGIX6p55HSrG5jfR3qkNYo80PHRfhzkJMq1+mv1ZjI5p8NhenWMMkIRJR4tw==", "dependencies": { "@smithy/middleware-endpoint": "^2.2.3", - "@smithy/middleware-retry": "^2.0.24", + "@smithy/middleware-retry": "^2.0.25", "@smithy/middleware-serde": "^2.0.15", "@smithy/protocol-http": "^3.0.11", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/util-middleware": "^2.0.8", "tslib": "^2.5.0" @@ -1106,6 +1489,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/core/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/credential-provider-imds": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.1.4.tgz", @@ -1121,24 +1515,59 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.15.tgz", - "integrity": "sha512-crjvz3j1gGPwA0us6cwS7+5gAn35CTmqu/oIxVbYJo2Qm/sGAye6zGJnMDk3BKhWZw5kcU1G4MxciTkuBpOZPg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-1.1.0.tgz", + "integrity": "sha512-3tEbUb8t8an226jKB6V/Q2XU/J53lCwCzULuBPEaF4JjSh+FlCMp7TmogE/Aij5J9DwlsZ4VAD/IRDuQ/0ZtMw==", "dependencies": { "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.7.0", - "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/types": "^1.2.0", + "@smithy/util-hex-encoding": "^1.1.0", "tslib": "^2.5.0" } }, + "node_modules/@smithy/eventstream-codec/node_modules/@smithy/util-hex-encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-1.1.0.tgz", + "integrity": "sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/eventstream-serde-browser": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.15.tgz", "integrity": "sha512-WiFG5N9j3jmS5P0z5Xev6dO0c3lf7EJYC2Ncb0xDnWFvShwXNn741AF71ABr5EcZw8F4rQma0362MMjAwJeZog==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.15", - "@smithy/types": "^2.7.0", + "@smithy/eventstream-serde-universal": "^1.0.2", + "@smithy/types": "^1.1.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser/node_modules/@smithy/eventstream-serde-universal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-1.1.0.tgz", + "integrity": "sha512-8nQttgdbefJbLfz7Mao0FtkdRUlc92fCiHV3vClAl1N/qetm/I6Lsu5mLt9CzG7TGFkFb5t3qzAV2FaeAqF+ag==", + "dependencies": { + "@smithy/eventstream-codec": "^1.1.0", + "@smithy/types": "^1.2.0", "tslib": "^2.5.0" }, "engines": { @@ -1150,7 +1579,7 @@ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.15.tgz", "integrity": "sha512-o65d2LRjgCbWYH+VVNlWXtmsI231SO99ZTOL4UuIPa6WTjbSHWtlXvUcJG9libhEKWmEV9DIUiH2IqyPWi7ubA==", "dependencies": { - "@smithy/types": "^2.7.0", + "@smithy/types": "^1.1.1", "tslib": "^2.5.0" }, "engines": { @@ -1162,21 +1591,21 @@ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.15.tgz", "integrity": "sha512-9OOXiIhHq1VeOG6xdHkn2ZayfMYM3vzdUTV3zhcCnt+tMqA3BJK3XXTJFRR2BV28rtRM778DzqbBTf+hqwQPTg==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.15", - "@smithy/types": "^2.7.0", + "@smithy/eventstream-serde-universal": "^1.0.2", + "@smithy/types": "^1.1.1", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.15.tgz", - "integrity": "sha512-dP8AQp/pXlWBjvL0TaPBJC3rM0GoYv7O0Uim8d/7UKZ2Wo13bFI3/BhQfY/1DeiP1m23iCHFNFtOQxfQNBB8rQ==", + "node_modules/@smithy/eventstream-serde-node/node_modules/@smithy/eventstream-serde-universal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-1.1.0.tgz", + "integrity": "sha512-8nQttgdbefJbLfz7Mao0FtkdRUlc92fCiHV3vClAl1N/qetm/I6Lsu5mLt9CzG7TGFkFb5t3qzAV2FaeAqF+ag==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.15", - "@smithy/types": "^2.7.0", + "@smithy/eventstream-codec": "^1.1.0", + "@smithy/types": "^1.2.0", "tslib": "^2.5.0" }, "engines": { @@ -1195,6 +1624,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/hash-blob-browser": { "version": "2.0.16", "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.16.tgz", @@ -1206,6 +1646,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@smithy/hash-blob-browser/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/hash-node": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.17.tgz", @@ -1220,6 +1671,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/hash-node/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/hash-stream-node": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.17.tgz", @@ -1233,6 +1695,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/hash-stream-node/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/invalid-dependency": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.15.tgz", @@ -1242,6 +1715,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@smithy/invalid-dependency/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/is-array-buffer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", @@ -1263,6 +1747,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@smithy/md5-js/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/middleware-content-length": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.17.tgz", @@ -1276,6 +1771,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-content-length/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/middleware-endpoint": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.2.3.tgz", @@ -1293,15 +1799,26 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-endpoint/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.24", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.24.tgz", - "integrity": "sha512-q2SvHTYu96N7lYrn3VSuX3vRpxXHR/Cig6MJpGWxd0BWodUQUWlKvXpWQZA+lTaFJU7tUvpKhRd4p4MU3PbeJg==", + "version": "2.0.25", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.25.tgz", + "integrity": "sha512-FXhafCPvx/9L9OgHJ3cdo/pD1f7ngC7DKsjDV2J7k6LO/Yl69POoBLk4sI1OZPUGc4dfxriENlTma9Nj1hI+IQ==", "dependencies": { "@smithy/node-config-provider": "^2.1.8", "@smithy/protocol-http": "^3.0.11", "@smithy/service-error-classification": "^2.0.8", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "@smithy/util-middleware": "^2.0.8", "@smithy/util-retry": "^2.0.8", @@ -1312,6 +1829,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-retry/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/middleware-serde": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.15.tgz", @@ -1324,6 +1852,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-serde/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/middleware-stack": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.9.tgz", @@ -1336,6 +1875,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-stack/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/node-config-provider": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.8.tgz", @@ -1350,6 +1900,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/node-config-provider/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/node-http-handler": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.2.1.tgz", @@ -1365,6 +1926,29 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/node-http-handler/node_modules/@smithy/abort-controller": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.15.tgz", + "integrity": "sha512-JkS36PIS3/UCbq/MaozzV7jECeL+BTt4R75bwY8i+4RASys4xOyUS1HsRyUNSqUXFP4QyCz5aNnh3ltuaxv+pw==", + "dependencies": { + "@smithy/types": "^2.7.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-http-handler/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/property-provider": { "version": "2.0.16", "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.16.tgz", @@ -1377,6 +1961,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/property-provider/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/protocol-http": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.11.tgz", @@ -1389,6 +1984,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/protocol-http/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/querystring-builder": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.15.tgz", @@ -1402,6 +2008,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/querystring-builder/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/querystring-parser": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.15.tgz", @@ -1414,6 +2031,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/querystring-parser/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/service-error-classification": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.8.tgz", @@ -1425,6 +2053,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/service-error-classification/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/shared-ini-file-loader": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.7.tgz", @@ -1437,6 +2076,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/signature-v4": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.18.tgz", @@ -1455,12 +2105,36 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/eventstream-codec": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.15.tgz", + "integrity": "sha512-crjvz3j1gGPwA0us6cwS7+5gAn35CTmqu/oIxVbYJo2Qm/sGAye6zGJnMDk3BKhWZw5kcU1G4MxciTkuBpOZPg==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.7.0", + "@smithy/util-hex-encoding": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/smithy-client": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.18.tgz", - "integrity": "sha512-7FqdbaJiVaHJDD9IfDhmzhSDbpjyx+ZsfdYuOpDJF09rl8qlIAIlZNoSaflKrQ3cEXZN2YxGPaNWGhbYimyIRQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.2.0.tgz", + "integrity": "sha512-C/bkNue5H5Obgl83SnlBt4v6VM68CqIjIELh3vAabud87xFYznLNKtj6Qb69Z+QOnLp9T+We++sEem/f2AHE+Q==", "dependencies": { + "@smithy/middleware-endpoint": "^2.2.3", "@smithy/middleware-stack": "^2.0.9", + "@smithy/protocol-http": "^3.0.11", "@smithy/types": "^2.7.0", "@smithy/util-stream": "^2.0.23", "tslib": "^2.5.0" @@ -1469,7 +2143,7 @@ "node": ">=14.0.0" } }, - "node_modules/@smithy/types": { + "node_modules/@smithy/smithy-client/node_modules/@smithy/types": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", @@ -1480,6 +2154,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/types": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", + "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/url-parser": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.15.tgz", @@ -1490,6 +2175,17 @@ "tslib": "^2.5.0" } }, + "node_modules/@smithy/url-parser/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-base64": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.1.tgz", @@ -1534,9 +2230,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz", - "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.1.0.tgz", + "integrity": "sha512-S6V0JvvhQgFSGLcJeT1CBsaTR03MM8qTuxMH9WPCCddlSo2W0V5jIHimHtIQALMLEDPGQ0ROSRr/dU0O+mxiQg==", "dependencies": { "tslib": "^2.5.0" }, @@ -1545,12 +2241,12 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.22.tgz", - "integrity": "sha512-qcF20IHHH96FlktvBRICDXDhLPtpVmtksHmqNGtotb9B0DYWXsC6jWXrkhrrwF7tH26nj+npVTqh9isiFV1gdA==", + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.23.tgz", + "integrity": "sha512-2u+7t7Wgz1jlfsf6il3pz6DIzyJHS3qrnNnmATICm00pQeqp2D4kUOYauOgKGIeKgVpwzzq8+hFQe749r3xR5w==", "dependencies": { "@smithy/property-provider": "^2.0.16", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "bowser": "^2.11.0", "tslib": "^2.5.0" @@ -1559,16 +2255,27 @@ "node": ">= 10.0.0" } }, + "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.29", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.29.tgz", - "integrity": "sha512-+uG/15VoUh6JV2fdY9CM++vnSuMQ1VKZ6BdnkUM7R++C/vLjnlg+ToiSR1FqKZbMmKBXmsr8c/TsDWMAYvxbxQ==", + "version": "2.0.31", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.31.tgz", + "integrity": "sha512-ZwdjAJAFkkQQ4hdE8HOcxFAWC3GPFXQ3yQ8IBwHH5nQBlr9q+p5eRQ7Y8iRRORJe4vksR+NASRXZ+E81Us1aXQ==", "dependencies": { - "@smithy/config-resolver": "^2.0.21", + "@smithy/config-resolver": "^2.0.22", "@smithy/credential-provider-imds": "^2.1.4", "@smithy/node-config-provider": "^2.1.8", "@smithy/property-provider": "^2.0.16", - "@smithy/smithy-client": "^2.1.18", + "@smithy/smithy-client": "^2.2.0", "@smithy/types": "^2.7.0", "tslib": "^2.5.0" }, @@ -1576,6 +2283,17 @@ "node": ">= 10.0.0" } }, + "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-endpoints": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.0.7.tgz", @@ -1589,6 +2307,17 @@ "node": ">= 14.0.0" } }, + "node_modules/@smithy/util-endpoints/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-hex-encoding": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz", @@ -1612,6 +2341,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/util-middleware/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-retry": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.8.tgz", @@ -1625,6 +2365,17 @@ "node": ">= 14.0.0" } }, + "node_modules/@smithy/util-retry/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-stream": { "version": "2.0.23", "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.23.tgz", @@ -1643,6 +2394,17 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/util-stream/node_modules/@smithy/types": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.7.0.tgz", + "integrity": "sha512-1OIFyhK+vOkMbu4aN2HZz/MomREkrAC/HqY5mlJMUJfGrPRwijJDTeiN8Rnj9zUaB8ogXAfIOtZrrgqZ4w7Wnw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@smithy/util-uri-escape": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz", @@ -1671,8 +2433,8 @@ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.15.tgz", "integrity": "sha512-9Y+btzzB7MhLADW7xgD6SjvmoYaRkrb/9SCbNGmNdfO47v38rxb90IGXyDtAK0Shl9bMthTmLgjlfYc+vtz2Qw==", "dependencies": { - "@smithy/abort-controller": "^2.0.15", - "@smithy/types": "^2.7.0", + "@smithy/abort-controller": "^1.0.2", + "@smithy/types": "^1.1.1", "tslib": "^2.5.0" }, "engines": { diff --git a/server/package.json b/server/package.json index 4b27bc2cfa..5c345b4018 100644 --- a/server/package.json +++ b/server/package.json @@ -118,4 +118,4 @@ "lint-staged": { "*.{ts,js}": "eslint --fix" } -} +} \ No newline at end of file