diff --git a/.github/funding.yml b/.github/funding.yml index c548d3e..e89127a 100644 --- a/.github/funding.yml +++ b/.github/funding.yml @@ -2,3 +2,4 @@ #github: tanthanhdev ko_fi: devphan +custom: ["https://www.paypal.me/ThanhPhan481"] diff --git a/.github/workflows/update-frontmatter.yml b/.github/workflows/update-frontmatter.yml new file mode 100644 index 0000000..1a187f3 --- /dev/null +++ b/.github/workflows/update-frontmatter.yml @@ -0,0 +1,60 @@ +name: Update Markdown Frontmatter + +on: + push: + paths: + - 'docs/**/*.md' + - 'i18n/**/*.md' + pull_request: + paths: + - 'docs/**/*.md' + - 'i18n/**/*.md' + schedule: + # Run at 00:00 UTC every Monday + - cron: '0 0 * * 1' + # Allow manual runs from GitHub interface + workflow_dispatch: + +jobs: + update-frontmatter: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + # Fetch full history to allow creating commits + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + cache: 'npm' + + - name: Install dependencies + run: npm install gray-matter glob + + - name: Run update script + run: | + chmod +x tools/update-frontmatter.js + node tools/update-frontmatter.js + + - name: Check for changes + id: git-check + run: | + git diff --exit-code || echo "changes=true" >> $GITHUB_OUTPUT + + - name: Commit changes if any + if: steps.git-check.outputs.changes == 'true' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add -A + git commit -m "chore: update markdown frontmatter [skip ci]" + + - name: Push changes + if: steps.git-check.outputs.changes == 'true' + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} diff --git a/.gitignore b/.gitignore index 078c693..ffb7886 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ @@ -67,7 +66,7 @@ coverage.xml *.rej # Ignore public site build if using static site generator (optional) -public/ +# public/ .cache/ # Ignore Markdown preview temp files (e.g., Typora) @@ -88,3 +87,6 @@ docker-compose.override.yml .env !.env.example docker/environments/databases/.env + +# Not follow website +!website/ \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..fc17f9a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,52 @@ +# Tech Notes Hub Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender characteristics, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [CONTACT EMAIL]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +## Summary + +* Treat everyone with respect and courtesy +* Gracefully accept constructive feedback +* Focus on helping others and growing the community +* Don't use offensive language or imagery +* Don't harass, threaten, or discriminate against anyone +* If you witness inappropriate behavior, report it to project maintainers diff --git a/CODE_OF_CONDUCT_vi.md b/CODE_OF_CONDUCT_vi.md new file mode 100644 index 0000000..d7d7a31 --- /dev/null +++ b/CODE_OF_CONDUCT_vi.md @@ -0,0 +1,52 @@ +# Quy tắc Ứng xử của Tech Notes Hub + +## Cam kết của chúng tôi + +Nhằm thúc đẩy một môi trường mở và thân thiện, chúng tôi - những người đóng góp và duy trì dự án - cam kết đảm bảo việc tham gia vào dự án và cộng đồng của chúng tôi là một trải nghiệm không quấy rối cho tất cả mọi người, bất kể tuổi tác, kích thước cơ thể, khuyết tật, dân tộc, đặc điểm giới tính, bản dạng và biểu hiện giới tính, trình độ kinh nghiệm, quốc tịch, ngoại hình cá nhân, chủng tộc, tôn giáo, hoặc bản dạng và khuynh hướng tình dục. + +## Tiêu chuẩn của chúng tôi + +Các ví dụ về hành vi góp phần tạo ra môi trường tích cực bao gồm: + +* Sử dụng ngôn ngữ chào đón và hòa nhập +* Tôn trọng các quan điểm và kinh nghiệm khác nhau +* Nhã nhặn chấp nhận phê bình mang tính xây dựng +* Tập trung vào điều tốt nhất cho cộng đồng +* Thể hiện sự đồng cảm với các thành viên khác trong cộng đồng + +Các ví dụ về hành vi không thể chấp nhận từ người tham gia bao gồm: + +* Việc sử dụng ngôn ngữ hoặc hình ảnh mang tính gợi dục và sự chú ý hoặc tiến triển tình dục không được chào đón +* Trolling, bình luận xúc phạm/miệt thị, và tấn công cá nhân hoặc mang tính chính trị +* Quấy rối công khai hoặc riêng tư +* Công bố thông tin cá nhân của người khác, chẳng hạn như địa chỉ vật lý hoặc điện tử, mà không được phép rõ ràng +* Các hành vi khác có thể hợp lý được coi là không phù hợp trong môi trường chuyên nghiệp + +## Trách nhiệm của chúng tôi + +Người duy trì dự án có trách nhiệm làm rõ các tiêu chuẩn về hành vi có thể chấp nhận được và được mong đợi sẽ thực hiện các hành động khắc phục phù hợp và công bằng để đáp lại bất kỳ trường hợp hành vi không thể chấp nhận nào. + +Người duy trì dự án có quyền và trách nhiệm xóa, chỉnh sửa hoặc từ chối nhận xét, commit, mã, chỉnh sửa wiki, issues và các đóng góp khác không phù hợp với Quy tắc Ứng xử này, hoặc tạm thời hoặc vĩnh viễn cấm bất kỳ người đóng góp nào vì các hành vi khác mà họ cho là không phù hợp, đe dọa, xúc phạm hoặc có hại. + +## Phạm vi + +Quy tắc Ứng xử này áp dụng trong cả không gian dự án và không gian công cộng khi một cá nhân đại diện cho dự án hoặc cộng đồng của dự án. Ví dụ về việc đại diện cho một dự án hoặc cộng đồng bao gồm việc sử dụng địa chỉ email chính thức của dự án, đăng thông qua tài khoản mạng xã hội chính thức, hoặc làm đại diện được chỉ định tại một sự kiện trực tuyến hoặc ngoại tuyến. Đại diện của một dự án có thể được người duy trì dự án xác định và làm rõ thêm. + +## Thực thi + +Các trường hợp hành vi lạm dụng, quấy rối hoặc không thể chấp nhận khác có thể được báo cáo bằng cách liên hệ với nhóm dự án tại [EMAIL LIÊN HỆ]. Tất cả khiếu nại sẽ được xem xét và điều tra, và sẽ dẫn đến phản hồi được coi là cần thiết và phù hợp với hoàn cảnh. Nhóm dự án có nghĩa vụ duy trì tính bảo mật đối với người báo cáo về một sự cố. Các chi tiết cụ thể hơn về chính sách thực thi có thể được đăng riêng. + +Người duy trì dự án không tuân theo hoặc thực thi Quy tắc Ứng xử một cách thiện chí có thể phải đối mặt với hậu quả tạm thời hoặc vĩnh viễn do các thành viên lãnh đạo khác của dự án quyết định. + +## Ghi nhận + +Quy tắc Ứng xử này được điều chỉnh từ [Contributor Covenant](https://www.contributor-covenant.org), phiên bản 1.4, có tại https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +## Tóm tắt + +* Đối xử với mọi người bằng sự tôn trọng và lịch sự +* Chấp nhận các góp ý mang tính xây dựng một cách nhã nhặn +* Tập trung vào việc giúp đỡ người khác và phát triển cộng đồng +* Không sử dụng ngôn ngữ hoặc hình ảnh xúc phạm +* Không quấy rối, đe dọa hoặc phân biệt đối xử với bất kỳ ai +* Nếu bạn chứng kiến hành vi không phù hợp, hãy báo cáo cho người quản lý dự án diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 13e1ccd..fbbe7f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -113,9 +113,24 @@ Before submitting, ensure: ## 📁 File & Folder Naming Conventions * Use lowercase and hyphens for file and folder names: `graph_traversal.md` (except for code files like C# using PascalCase such as `GraphTraversal.cs`, or Java using CamelCase like `GraphTraversal.java`) -* For translations, add language suffix: `graph_traversal_vi.md` +* For translations, add language suffix: `graph_traversal_vi.md`, but no suffix is needed if in the /i18n/[language_code]/ folder * Notes should be grouped by docs folders (e.g., `docs/algorithms/`, `docs/aws/`, `docs/design-patterns/`) +### 📂 Code Snippets Structure + +Code snippets must follow this directory structure for proper display on the website: + +``` +snippets/[category]/[topic-name]/[filename].[extension] +``` + +Examples: +- `snippets/algorithms/graph-traversal/graph_traversal.py` +- `snippets/devops/ci-cd/ci-cd.sh` +- `snippets/databases/mongodb/mongodb_query.js` + +The `[topic-name]` folder must match the slug of your blog post for snippets to appear automatically. All files inside this folder will be displayed as code snippets on the corresponding blog post page. + ## 🤝 Code of Conduct Be respectful, open, and constructive in all interactions. We're building a friendly and inclusive learning space for all developers. diff --git a/CONTRIBUTING_vi.md b/CONTRIBUTING_vi.md index 11991dd..6c2710c 100644 --- a/CONTRIBUTING_vi.md +++ b/CONTRIBUTING_vi.md @@ -1,128 +1,142 @@ -# Đóng góp vào Tech Notes Hub +# Đóng góp cho Tech Notes Hub -Trước hết, xin chân thành cảm ơn bạn đã dành thời gian đóng góp! 🎉 -Sự đóng góp của bạn giúp dự án này trở nên hữu ích hơn cho cộng đồng lập trình viên. +Trước hết, cảm ơn bạn đã dành thời gian đóng góp! 🎉 +Sự đóng góp của bạn giúp dự án này trở nên giá trị hơn cho cộng đồng lập trình viên. -## 🚀 Cách bạn có thể đóng góp +## 🚀 Cách Đóng góp -Có nhiều hình thức để bạn tham gia: +Có nhiều cách để bạn tham gia: -- 📚 Thêm ghi chú kỹ thuật hoặc chủ đề mới -- 💡 Cải thiện các phần giải thích hoặc đoạn mã hiện có -- 🐛 Báo lỗi hoặc đề xuất cải tiến -- ✨ Dọn dẹp, chuẩn hóa định dạng nội dung -- 🌍 Dịch các ghi chú sang ngôn ngữ khác (tính năng sắp ra mắt) +- 📚 Thêm các ghi chú kỹ thuật hoặc chủ đề mới +- 💡 Cải thiện giải thích hoặc code snippets hiện có +- 🐛 Báo cáo lỗi hoặc đề xuất cải tiến +- ✨ Dọn dẹp và chuẩn hóa định dạng nội dung +- 🌍 Dịch ghi chú sang các ngôn ngữ khác -## 📝 Hướng dẫn đóng góp +## 📝 Hướng dẫn Đóng góp -Vui lòng tuân theo các hướng dẫn sau để đảm bảo tính nhất quán và dễ quản lý: +Vui lòng tuân thủ các hướng dẫn sau để đảm bảo tính nhất quán và khả năng bảo trì: ### 1. Fork Repository -Nhấn nút "Fork" ở góc trên bên phải trang GitHub để tạo một bản sao của repository vào tài khoản của bạn. +Nhấp vào nút "Fork" ở góc trên bên phải của trang GitHub để tạo bản sao của repository trong tài khoản của bạn. -### 2. Clone về máy +### 2. Clone về Máy của Bạn ```bash -git clone https://github.com/ten-cua-ban/tech-notes.git +git clone https://github.com/your-username/tech-notes.git cd tech-notes-hub ``` -### 3. Tạo nhánh mới +### 3. Tạo Nhánh Mới -Đặt tên nhánh rõ ràng, mô tả ngắn gọn nội dung bạn sẽ thêm hoặc sửa: +Đặt tên nhánh của bạn rõ ràng, mô tả ngắn gọn những gì bạn sẽ thêm hoặc sửa đổi: ```bash git checkout -b feature/add-graph-algorithms ``` -### 🧩 Quy tắc đặt tên nhánh (branch naming) +### 🧩 Quy tắc Đặt tên Nhánh -Tên nhánh nên theo cấu trúc: +Tên nhánh nên tuân theo cấu trúc này: ```bash / ``` -| Loại | Ý nghĩa | Ví dụ | -| ---------- | -------------------------------------------------------- | -------------------------------- | -| `feature` | Thêm ghi chú/mục mới | `feature/add-docker-notes` | -| `fix` | Sửa lỗi nội dung, chính tả, ví dụ | `fix/typo-in-graph-note` | -| `update` | Cập nhật hoặc cải tiến ghi chú hiện có | `update/aws-ec2-note` | -| `refactor` | Tái cấu trúc lại file/nội dung mà không thay đổi ý chính | `refactor/reorganize-folders` | -| `remove` | Xoá nội dung lỗi thời hoặc không còn phù hợp | `remove/duplicate-array-example` | -| `docs` | Cập nhật tài liệu dự án như README, CONTRIBUTING,... | `docs/improve-readme` | +| Loại | Ý nghĩa | Ví dụ | +| ---------- | ---------------------------------------------------- | --------------------------------- | +| `feature` | Thêm ghi chú/phần mới | `feature/add-docker-notes` | +| `fix` | Sửa lỗi nội dung, lỗi chính tả, ví dụ | `fix/typo-in-graph-note` | +| `update` | Cập nhật hoặc cải thiện ghi chú hiện có | `update/aws-ec2-note` | +| `refactor` | Tái cấu trúc tệp/nội dung mà không thay đổi ý chính | `refactor/reorganize-folders` | +| `remove` | Xóa nội dung lỗi thời hoặc không phù hợp | `remove/duplicate-array-example` | +| `docs` | Cập nhật tài liệu dự án như README, CONTRIBUTING | `docs/improve-readme` | -### 4. Thực hiện thay đổi +### 4. Thực hiện Thay đổi của Bạn -* Tuân theo cấu trúc thư mục và file có sẵn -* Ghi chú dùng định dạng Markdown (`.md`) -* Mã nguồn nên đặt trong khối mã (fenced code block) ví dụ: \`\`\`python -* Diễn giải ngắn gọn, rõ ràng -* Có thể thêm chú thích nội tuyến nếu cần thiết +* Tuân theo cấu trúc thư mục và tệp hiện có +* Ghi chú nên sử dụng định dạng Markdown (`.md`) +* Code nên được đặt trong khối code có hàng rào, ví dụ: \`\`\`python +* Giữ các giải thích ngắn gọn và rõ ràng +* Thêm nhận xét nội tuyến nếu cần thiết -### 💬 Quy tắc viết commit message +### 💬 Quy tắc Viết Commit Message -Viết commit rõ ràng, có ý nghĩa và dễ hiểu. Cấu trúc đề xuất: +Viết các commit message rõ ràng, có ý nghĩa và dễ hiểu. Cấu trúc đề xuất: ```bash -: +: ``` #### 📌 Ví dụ: -- `feature: add notes on HTTP Status Codes` -- `fix: correct typos in design-patterns.md` -- `update: improve binary search examples` -- `refactor: reorganize folder structure` -- `remove: delete duplicate notes in aws folder` -- `docs: add instructions for creating pull requests` +- `feature: thêm ghi chú về HTTP Status Codes` +- `fix: sửa lỗi chính tả trong design-patterns.md` +- `update: cải thiện ví dụ tìm kiếm nhị phân` +- `refactor: sắp xếp lại cấu trúc thư mục` +- `remove: xóa ghi chú trùng lặp trong thư mục aws` +- `docs: thêm hướng dẫn tạo pull request` -#### 🧠 Gợi ý thêm: +#### 🧠 Mẹo Bổ sung: -- Bạn chỉ có thể viết bằng **tiếng Anh** +- Bạn có thể viết bằng **tiếng Anh** hoặc **tiếng Việt** - **Tránh commit mơ hồ** như: `update 1`, `fix bug`, `test` -- Nếu liên quan issue, thêm số vào cuối: - 👉 `fix: typo in aws-note #12` - +- Nếu liên quan đến issue, thêm số issue vào cuối: + 👉 `fix: lỗi chính tả trong aws-note #12` ### 5. Commit & Push ```bash git add . -git commit -m "Add notes on graph algorithms" +git commit -m "Thêm ghi chú về thuật toán đồ thị" git push origin feature/add-graph-algorithms ``` ### 6. Tạo Pull Request -Quay lại repository gốc và nhấn **"Compare & Pull Request"**. Nhớ điền: +Quay lại repository gốc và nhấp vào **"Compare & Pull Request"**. Hãy nhớ bao gồm: -* Tiêu đề ngắn gọn, rõ ràng -* Mô tả chi tiết về nội dung bạn thêm/sửa -* Đề cập đến issue liên quan nếu có +* Tiêu đề rõ ràng, ngắn gọn +* Mô tả chi tiết về những gì bạn đã thêm/sửa đổi +* Tham chiếu đến các issue liên quan nếu có -## ✅ Kiểm tra trước khi gửi Pull Request +## ✅ Danh sách kiểm tra trước khi Gửi Pull Request Trước khi gửi, hãy đảm bảo: -* [ ] Định dạng nội dung đúng và theo cấu trúc dự án +* [ ] Nội dung được định dạng đúng và tuân theo cấu trúc dự án * [ ] Không có lỗi chính tả hoặc liên kết hỏng -* [ ] Đoạn mã (nếu có) hoạt động chính xác -* [ ] Không chứa thông tin nhạy cảm hoặc tài sản độc quyền +* [ ] Các đoạn mã (nếu có) hoạt động đúng +* [ ] Không có thông tin nhạy cảm hoặc tài sản độc quyền được đưa vào + +## 📁 Quy ước Đặt tên Tệp & Thư mục + +* Sử dụng chữ thường và dấu gạch ngang cho tên tệp và thư mục: `graph_traversal.md` (ngoại trừ các tệp mã như C# sử dụng PascalCase như `GraphTraversal.cs`, hoặc Java sử dụng camelCase như `GraphTraversal.java`) +* Đối với bản dịch, thêm hậu tố ngôn ngữ: `graph_traversal_vi.md`, nhưng không cần hậu tố nếu trong thư mục /i18n/[mã_ngôn_ngữ]/ +* Ghi chú nên được nhóm theo các thư mục docs (ví dụ: `docs/algorithms/`, `docs/aws/`, `docs/design-patterns/`) + +### 📂 Cấu trúc Code Snippets + +Code snippets phải tuân theo cấu trúc thư mục này để hiển thị đúng trên website: + +``` +snippets/[danh-mục]/[tên-chủ-đề]/[tên-tệp].[phần-mở-rộng] +``` -## 📁 Quy tắc đặt tên file & thư mục +Ví dụ: +- `snippets/algorithms/graph-traversal/graph_traversal.py` +- `snippets/devops/ci-cd/ci-cd.sh` +- `snippets/databases/mongodb/mongodb_query.js` -* Tên file và thư mục dùng chữ thường và dấu gạch ngang: `graph_traversal.md` (trừ code như C# sử dụng PascalCase như `GraphTraversal.cs`, hoặc Java sử dụng CamelCase như `GraphTraversal.java`) -* Nếu là bản dịch, thêm hậu tố ngôn ngữ: `graph_traversal_vi.md` -* Ghi chú nên được nhóm theo thư mục trong docs (ví dụ: `docs/algorithms/`, `docs/aws/`, `docs/design-patterns/`) +Thư mục `[tên-chủ-đề]` phải khớp với slug của bài viết blog để snippets hiển thị tự động. Tất cả các tệp trong thư mục này sẽ được hiển thị dưới dạng code snippets trên trang bài viết blog tương ứng. -## 🤝 Quy tắc ứng xử +## 🤝 Quy tắc Ứng xử -Tôn trọng, cởi mở và xây dựng trong mọi tương tác. Chúng ta đang xây dựng một không gian học tập thân thiện và hòa nhập cho tất cả lập trình viên. +Hãy tôn trọng, cởi mở và mang tính xây dựng trong tất cả các tương tác. Chúng tôi đang xây dựng một không gian học tập thân thiện và hòa nhập cho tất cả các lập trình viên. -## 📩 Cần hỗ trợ? +## 📩 Cần Trợ giúp? -Nếu bạn có thắc mắc hoặc ý tưởng, hãy [tạo issue mới](https://github.com/tech-notes-hub/tech-notes/issues). +Nếu bạn có câu hỏi hoặc ý tưởng, vui lòng [tạo issue mới](https://github.com/tech-notes-hub/tech-notes/issues). Một lần nữa, cảm ơn bạn đã đóng góp cho **Tech Notes Hub**! 🙌 diff --git a/PULL_REQUEST_RULES_vi.md b/PULL_REQUEST_RULES_vi.md index bdcdb86..d20bfa7 100644 --- a/PULL_REQUEST_RULES_vi.md +++ b/PULL_REQUEST_RULES_vi.md @@ -52,7 +52,7 @@ Chọn các tùy chọn thích hợp: - Sửa lỗi chính tả, ngữ pháp - Cập nhật liên kết hoặc định dạng Markdown - **Bản dịch ghi chú**: - - Sử dụng cấu trúc thư mục `i18n/[mã_ngôn_ngữ]/` (ví dụ: `i18n/vi/`, `i18n/fr/`) + - Sử dụng cấu trúc thư mục `i18n/[mã_ngôn_ngữ]/` (ví dụ: `i18n/vi/`, `i18n/es/`) - Nội dung bám sát logic file gốc - Cập nhật trong SUMMARY.md dưới phần ngôn ngữ tương ứng diff --git a/README.md b/README.md index 97b5e37..231ec36 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,27 @@ This repository includes Docker configurations for running code snippets in vari For more information on Docker usage, see the [Docker README](docker/README.md). +### 🛠️ Utilities + +This repository contains utility scripts in the `/tools` directory to help maintain the documentation. + +#### Updating Markdown Frontmatter + +The `update-frontmatter.js` script automatically updates metadata in Markdown files: + +```bash +# First, install Node.js dependencies +npm install + +# Run the script (updates all Markdown files) +node tools/update-frontmatter.js + +# Update a specific file +node tools/update-frontmatter.js algorithms/sorting-algorithms.md +``` + +For more information about available tools, see the [Tools README](tools/README.md). + ## 🤝 Contribution Contributions are highly welcome! If you want to: diff --git a/README_WEBSITE.md b/README_WEBSITE.md new file mode 100644 index 0000000..72207f9 --- /dev/null +++ b/README_WEBSITE.md @@ -0,0 +1,41 @@ +# Tech Notes Hub Blog Website + +This is the blog website component of the Tech Notes Hub project. The website is built using Next.js, Tailwind CSS, shadcn UI, and i18n support for multilingual content (Vietnamese and English). + +## Overview + +The blog website serves as a frontend for displaying technical content and notes from the Tech Notes Hub repository. It provides a modern, responsive interface for users to browse and read technical articles. + +## Getting Started + +The blog website is located in the `/website` directory. To start working with it: + +```bash +cd website +npm install +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to view the site in your browser. + +## Features + +- **Modern UI**: Clean, minimal design with Tailwind CSS and shadcn UI components +- **Bilingual Support**: Full i18n integration with Vietnamese and English translations +- **Blog System**: Complete blog functionality with Markdown content rendering +- **Dark/Light Mode**: Theme switching with system preference detection +- **SEO Optimized**: Meta tags and OpenGraph support for better search engine visibility +- **Responsive Design**: Mobile-first approach, works on all devices + +## Tech Stack + +- [Next.js 14](https://nextjs.org/) - React framework +- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework +- [shadcn UI](https://ui.shadcn.com/) - UI component library +- [React Markdown](https://github.com/remarkjs/react-markdown) - Markdown renderer +- [i18n](https://nextjs.org/docs/app/building-your-application/routing/internationalization) - Internationalization +- [next-themes](https://github.com/pacocoursey/next-themes) - Theme management + +## Documentation + +For detailed information about the blog website, including setup instructions, project structure, and deployment guidelines, please refer to the [Website README](/website/README.md) in the website directory. diff --git a/README_vi.md b/README_vi.md index 2663314..cfaa252 100644 --- a/README_vi.md +++ b/README_vi.md @@ -64,6 +64,27 @@ Kho lưu trữ này bao gồm cấu hình Docker để chạy đoạn mã trong Để biết thêm thông tin về cách sử dụng Docker, hãy xem [Docker README](docker/README_vi.md). +### 🛠️ Công cụ tiện ích + +Kho lưu trữ này chứa các script tiện ích trong thư mục `/tools` để hỗ trợ việc duy trì tài liệu. + +#### Cập nhật Frontmatter cho file Markdown + +Script `update-frontmatter.js` tự động cập nhật metadata trong các file Markdown: + +```bash +# Đầu tiên, cài đặt các gói phụ thuộc Node.js +npm install + +# Chạy script (cập nhật tất cả file Markdown) +node tools/update-frontmatter.js + +# Cập nhật một file cụ thể +node tools/update-frontmatter.js algorithms/sorting-algorithms.md +``` + +Để biết thêm thông tin về các công cụ có sẵn, hãy xem [README của Tools](tools/README.md). + ## 🤝 Đóng góp Mọi đóng góp đều rất hoan nghênh! Nếu bạn muốn: diff --git a/docs/algorithms/graph-traversal.md b/docs/algorithms/graph-traversal.md index b16b9a2..009b0cf 100644 --- a/docs/algorithms/graph-traversal.md +++ b/docs/algorithms/graph-traversal.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Graph Traversal +description: Guide about Graph Traversal +--- # Graph Traversal Algorithms Graph traversal algorithms are fundamental techniques used to visit every vertex in a graph. They serve as building blocks for many more complex graph algorithms. @@ -30,16 +38,16 @@ def bfs(graph, start): visited = set([start]) queue = deque([start]) result = [] - + while queue: vertex = queue.popleft() result.append(vertex) - + for neighbor in graph[vertex]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) - + return result # Example usage @@ -74,14 +82,14 @@ def dfs_recursive(graph, vertex, visited=None, result=None): visited = set() if result is None: result = [] - + visited.add(vertex) result.append(vertex) - + for neighbor in graph[vertex]: if neighbor not in visited: dfs_recursive(graph, neighbor, visited, result) - + return result # Iterative implementation using a stack @@ -89,18 +97,18 @@ def dfs_iterative(graph, start): visited = set() stack = [start] result = [] - + while stack: vertex = stack.pop() if vertex not in visited: visited.add(vertex) result.append(vertex) - + # Add neighbors in reverse order to simulate recursive DFS for neighbor in reversed(graph[vertex]): if neighbor not in visited: stack.append(neighbor) - + return result # Example usage (same graph as BFS example) @@ -145,4 +153,4 @@ Space complexity: ## References 1. Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press. -2. Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley Professional. \ No newline at end of file +2. Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley Professional. diff --git a/docs/algorithms/sorting-algorithms.md b/docs/algorithms/sorting-algorithms.md new file mode 100644 index 0000000..afc7ae7 --- /dev/null +++ b/docs/algorithms/sorting-algorithms.md @@ -0,0 +1,130 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Sorting Algorithms +description: Guide about Sorting Algorithms +--- +# Sorting Algorithms + +Sorting is one of the most fundamental operations in computer science. This article explores various sorting algorithms, their implementations, and performance characteristics. + +## Quick Sort + +Quick Sort is a divide-and-conquer algorithm that works by selecting a 'pivot' element from the array and partitioning the other elements into two sub-arrays according to whether they are less than or greater than the pivot. + +```python +def quick_sort(arr): + if len(arr) <= 1: + return arr + pivot = arr[len(arr) // 2] + left = [x for x in arr if x < pivot] + middle = [x for x in arr if x == pivot] + right = [x for x in arr if x > pivot] + return quick_sort(left) + middle + quick_sort(right) + +# Example usage +arr = [3, 6, 8, 10, 1, 2, 1] +print(quick_sort(arr)) # Output: [1, 1, 2, 3, 6, 8, 10] +``` + +**Time Complexity**: +- Best Case: O(n log n) +- Average Case: O(n log n) +- Worst Case: O(n²) + +## Merge Sort + +Merge Sort is another divide-and-conquer algorithm that divides the input array into two halves, recursively sorts them, and then merges the sorted halves. + +```python +def merge_sort(arr): + if len(arr) <= 1: + return arr + + mid = len(arr) // 2 + left = merge_sort(arr[:mid]) + right = merge_sort(arr[mid:]) + + return merge(left, right) + +def merge(left, right): + result = [] + i = j = 0 + + while i < len(left) and j < len(right): + if left[i] < right[j]: + result.append(left[i]) + i += 1 + else: + result.append(right[j]) + j += 1 + + result.extend(left[i:]) + result.extend(right[j:]) + return result +``` + +**Time Complexity**: +- Best Case: O(n log n) +- Average Case: O(n log n) +- Worst Case: O(n log n) + +## Bubble Sort + +Bubble Sort is a simple comparison-based algorithm that repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. + +```python +def bubble_sort(arr): + n = len(arr) + for i in range(n): + # Flag to optimize if array is already sorted + swapped = False + + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + swapped = True + + # If no swapping occurred in this pass, array is sorted + if not swapped: + break + + return arr +``` + +**Time Complexity**: +- Best Case: O(n) - when array is already sorted +- Average Case: O(n²) +- Worst Case: O(n²) + +## Comparison of Sorting Algorithms + +| Algorithm | Time Complexity (Best) | Time Complexity (Average) | Time Complexity (Worst) | Space Complexity | Stable | +|-----------|------------------------|---------------------------|-------------------------|-----------------|--------| +| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(log n) | No | +| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes | +| Bubble Sort | O(n) | O(n²) | O(n²) | O(1) | Yes | +| Insertion Sort | O(n) | O(n²) | O(n²) | O(1) | Yes | +| Selection Sort | O(n²) | O(n²) | O(n²) | O(1) | No | +| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | No | +| Counting Sort | O(n+k) | O(n+k) | O(n+k) | O(k) | Yes | +| Radix Sort | O(nk) | O(nk) | O(nk) | O(n+k) | Yes | + +Where: +- n is the number of elements +- k is the range of the input + +## When to Use Each Algorithm + +- **Quick Sort**: General-purpose sorting, works well for arrays that fit in memory +- **Merge Sort**: When stability is needed and O(n log n) worst-case is required +- **Bubble Sort**: Educational purposes or very small datasets +- **Insertion Sort**: Small datasets or nearly sorted arrays +- **Heap Sort**: When consistent performance is needed without worst-case scenarios +- **Counting/Radix Sort**: When the range of input values is limited + +## Conclusion + +Choosing the right sorting algorithm depends on your specific requirements, including the size of the dataset, memory constraints, and whether stability is important. In practice, most programming languages implement hybrid sorting algorithms that combine the benefits of different approaches. diff --git a/docs/databases/relational.md b/docs/databases/relational.md index 82132a6..518babb 100644 --- a/docs/databases/relational.md +++ b/docs/databases/relational.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Relational +description: Guide about Relational +--- # Relational Databases Relational databases are organized collections of data that store information in tables with rows and columns. They follow the relational model proposed by Edgar F. Codd in 1970, which emphasizes relationships between data entities. @@ -114,4 +122,4 @@ Relational databases are ideal for: - Codd, E.F. (1970). "A Relational Model of Data for Large Shared Data Banks" - Date, C.J. "An Introduction to Database Systems" -- Garcia-Molina, H., Ullman, J.D., & Widom, J. "Database Systems: The Complete Book" \ No newline at end of file +- Garcia-Molina, H., Ullman, J.D., & Widom, J. "Database Systems: The Complete Book" diff --git a/docs/design-patterns/factory.md b/docs/design-patterns/factory.md index 2ab9d1b..121e454 100644 --- a/docs/design-patterns/factory.md +++ b/docs/design-patterns/factory.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Factory +description: Guide about Factory +--- # Factory Design Pattern The Factory pattern is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. @@ -473,4 +481,4 @@ public class Program - "Design Patterns: Elements of Reusable Object-Oriented Software" by Gang of Four (GoF) - [Refactoring Guru - Factory Method Pattern](https://refactoring.guru/design-patterns/factory-method) -- [Refactoring Guru - Abstract Factory Pattern](https://refactoring.guru/design-patterns/abstract-factory) \ No newline at end of file +- [Refactoring Guru - Abstract Factory Pattern](https://refactoring.guru/design-patterns/abstract-factory) diff --git a/docs/design-patterns/observer.md b/docs/design-patterns/observer.md index b15b4b9..234896d 100644 --- a/docs/design-patterns/observer.md +++ b/docs/design-patterns/observer.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Observer +description: Guide about Observer +--- # Observer Design Pattern The Observer pattern is a behavioral design pattern where an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. @@ -401,4 +409,4 @@ public class Investor : IObserver - "Design Patterns: Elements of Reusable Object-Oriented Software" by Gang of Four (GoF) - [Refactoring Guru - Observer Pattern](https://refactoring.guru/design-patterns/observer) -- [SourceMaking - Observer Pattern](https://sourcemaking.com/design_patterns/observer) \ No newline at end of file +- [SourceMaking - Observer Pattern](https://sourcemaking.com/design_patterns/observer) diff --git a/docs/design-patterns/singleton.md b/docs/design-patterns/singleton.md index 2e72e49..4f6e003 100644 --- a/docs/design-patterns/singleton.md +++ b/docs/design-patterns/singleton.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Singleton +description: Guide about Singleton +--- # Singleton Design Pattern The Singleton pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. @@ -223,4 +231,4 @@ public sealed class Singleton - "Design Patterns: Elements of Reusable Object-Oriented Software" by Gang of Four (GoF) - [Refactoring Guru - Singleton Pattern](https://refactoring.guru/design-patterns/singleton) -- [SourceMaking - Singleton Pattern](https://sourcemaking.com/design_patterns/singleton) \ No newline at end of file +- [SourceMaking - Singleton Pattern](https://sourcemaking.com/design_patterns/singleton) diff --git a/docs/devops/ci-cd.md b/docs/devops/ci-cd.md index bdaa6f5..437396e 100644 --- a/docs/devops/ci-cd.md +++ b/docs/devops/ci-cd.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Ci Cd +description: Guide about Ci Cd +--- # Continuous Integration and Continuous Deployment (CI/CD) Continuous Integration and Continuous Deployment (CI/CD) is a method to frequently deliver apps to customers by introducing automation into the stages of app development. diff --git a/docs/linux/bash-scripting.md b/docs/linux/bash-scripting.md index 3173040..6144822 100644 --- a/docs/linux/bash-scripting.md +++ b/docs/linux/bash-scripting.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Bash Scripting +description: Guide about Bash Scripting +--- # Bash Scripting Bash (Bourne Again SHell) is a command language interpreter that is widely used on various operating systems, and is the default shell on most Linux distributions. diff --git a/docs/system-design/microservices.md b/docs/system-design/microservices.md index df86b54..ab48962 100644 --- a/docs/system-design/microservices.md +++ b/docs/system-design/microservices.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Microservices +description: Guide about Microservices +--- # Microservices Architecture Microservices architecture is an architectural style that structures an application as a collection of small, loosely coupled services that can be developed, deployed, and scaled independently. diff --git a/docs/testing/unit-testing.md b/docs/testing/unit-testing.md index 600021c..c0c5cb0 100644 --- a/docs/testing/unit-testing.md +++ b/docs/testing/unit-testing.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Unit Testing +description: Guide about Unit Testing +--- # Unit Testing Unit testing is a software testing method where individual units or components of a software are tested in isolation from the rest of the system. diff --git a/i18n/es/init.txt b/i18n/init.txt similarity index 100% rename from i18n/es/init.txt rename to i18n/init.txt diff --git a/i18n/vi/README.md b/i18n/vi/README.md new file mode 100644 index 0000000..1980eb0 --- /dev/null +++ b/i18n/vi/README.md @@ -0,0 +1,53 @@ +# Tech Notes Hub + +Chào mừng đến với Tech Notes Hub! Đây là kho lưu trữ toàn diện các ghi chú kỹ thuật, đoạn mã và ví dụ bao gồm nhiều chủ đề trong phát triển phần mềm, thiết kế hệ thống và khoa học máy tính. + +## Mục đích + +Tech Notes Hub nhằm mục đích: + +- Cung cấp các giải thích rõ ràng, ngắn gọn về các khái niệm kỹ thuật quan trọng +- Cung cấp các ví dụ mã thực tế bằng nhiều ngôn ngữ lập trình +- Phục vụ như một tài liệu tham khảo cho các nhà phát triển ở mọi cấp độ kỹ năng +- Tạo ra một cơ sở kiến thức hợp tác cho cộng đồng công nghệ + +## Cấu trúc kho lưu trữ + +Kho lưu trữ được tổ chức thành các phần chính sau: + +### Algorithms (Thuật toán) +Cài đặt và giải thích về các thuật toán phổ biến, bao gồm tìm kiếm, sắp xếp, duyệt đồ thị, và nhiều hơn nữa. + +### Databases (Cơ sở dữ liệu) +Ghi chú về hệ thống cơ sở dữ liệu, tối ưu hóa truy vấn, mô hình hóa dữ liệu và các phương pháp tốt nhất cho cả cơ sở dữ liệu SQL và NoSQL. + +### Design Patterns (Mẫu thiết kế) +Giải thích chi tiết và cài đặt các mẫu thiết kế phần mềm trên nhiều ngôn ngữ lập trình. + +### DevOps +Thông tin về tích hợp liên tục, triển khai, container hóa và quản lý cơ sở hạ tầng. + +### Linux +Hướng dẫn về quản trị hệ thống Linux, lập trình shell và các công cụ dòng lệnh. + +### System Design (Thiết kế hệ thống) +Các cách tiếp cận để thiết kế các hệ thống phần mềm có khả năng mở rộng, đáng tin cậy và dễ bảo trì. + +### Testing (Kiểm thử) +Các phương pháp tốt nhất cho kiểm thử đơn vị, kiểm thử tích hợp và phát triển hướng kiểm thử. + +## Cách sử dụng kho lưu trữ này + +Mỗi phần chứa các tệp markdown với giải thích và đoạn mã. Bạn có thể: + +1. Duyệt qua các phần để tìm chủ đề quan tâm +2. Sử dụng các ví dụ mã làm tham khảo cho dự án của riêng bạn +3. Đóng góp bằng cách thêm nội dung mới hoặc cải thiện tài liệu hiện có + +## Đóng góp + +Chúng tôi hoan nghênh đóng góp từ cộng đồng! Vui lòng xem tệp [CONTRIBUTING_vi.md](../CONTRIBUTING_vi.md) của chúng tôi để biết hướng dẫn về cách đóng góp. + +## Giấy phép + +Dự án này được cấp phép theo Giấy phép MIT - xem tệp [LICENSE.txt](../LICENSE.txt) để biết chi tiết. diff --git a/i18n/vi/algorithms/graph-traversal_vi.md b/i18n/vi/algorithms/graph-traversal.md similarity index 96% rename from i18n/vi/algorithms/graph-traversal_vi.md rename to i18n/vi/algorithms/graph-traversal.md index d41c6f1..840ac1c 100644 --- a/i18n/vi/algorithms/graph-traversal_vi.md +++ b/i18n/vi/algorithms/graph-traversal.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Graph Traversal +description: Guide about Graph Traversal +--- # Các Thuật Toán Duyệt Đồ Thị (Graph Traversal Algorithms) Các thuật toán duyệt đồ thị là những kỹ thuật cơ bản được sử dụng để thăm mỗi đỉnh trong một đồ thị. Chúng là nền tảng cho nhiều thuật toán đồ thị phức tạp hơn. @@ -145,4 +153,4 @@ Cả BFS và DFS đều có độ phức tạp thời gian là O(V + E) với V ## Tài Liệu Tham Khảo 1. Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms (3rd ed.). MIT Press. -2. Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley Professional. \ No newline at end of file +2. Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley Professional. diff --git a/i18n/vi/algorithms/sorting-algorithms.md b/i18n/vi/algorithms/sorting-algorithms.md new file mode 100644 index 0000000..3eca2ab --- /dev/null +++ b/i18n/vi/algorithms/sorting-algorithms.md @@ -0,0 +1,130 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Sorting Algorithms +description: Guide about Sorting Algorithms +--- +# Thuật toán sắp xếp + +Sắp xếp là một trong những hoạt động cơ bản nhất trong khoa học máy tính. Bài viết này khám phá các thuật toán sắp xếp khác nhau, cách triển khai và đặc điểm hiệu suất của chúng. + +## Quick Sort (Sắp xếp nhanh) + +Quick Sort là một thuật toán chia để trị hoạt động bằng cách chọn một phần tử 'trục' từ mảng và phân vùng các phần tử khác thành hai mảng con theo điều kiện chúng nhỏ hơn hoặc lớn hơn trục. + +```python +def quick_sort(arr): + if len(arr) <= 1: + return arr + pivot = arr[len(arr) // 2] + left = [x for x in arr if x < pivot] + middle = [x for x in arr if x == pivot] + right = [x for x in arr if x > pivot] + return quick_sort(left) + middle + quick_sort(right) + +# Ví dụ sử dụng +arr = [3, 6, 8, 10, 1, 2, 1] +print(quick_sort(arr)) # Kết quả: [1, 1, 2, 3, 6, 8, 10] +``` + +**Độ phức tạp thời gian**: +- Trường hợp tốt nhất: O(n log n) +- Trường hợp trung bình: O(n log n) +- Trường hợp xấu nhất: O(n²) + +## Merge Sort (Sắp xếp trộn) + +Merge Sort là một thuật toán chia để trị khác, chia mảng đầu vào thành hai nửa, sắp xếp đệ quy chúng, và sau đó trộn các nửa đã sắp xếp. + +```python +def merge_sort(arr): + if len(arr) <= 1: + return arr + + mid = len(arr) // 2 + left = merge_sort(arr[:mid]) + right = merge_sort(arr[mid:]) + + return merge(left, right) + +def merge(left, right): + result = [] + i = j = 0 + + while i < len(left) and j < len(right): + if left[i] < right[j]: + result.append(left[i]) + i += 1 + else: + result.append(right[j]) + j += 1 + + result.extend(left[i:]) + result.extend(right[j:]) + return result +``` + +**Độ phức tạp thời gian**: +- Trường hợp tốt nhất: O(n log n) +- Trường hợp trung bình: O(n log n) +- Trường hợp xấu nhất: O(n log n) + +## Bubble Sort (Sắp xếp nổi bọt) + +Bubble Sort là một thuật toán đơn giản dựa trên so sánh, lặp đi lặp lại qua danh sách, so sánh các phần tử liền kề và hoán đổi chúng nếu chúng không đúng thứ tự. + +```python +def bubble_sort(arr): + n = len(arr) + for i in range(n): + # Cờ để tối ưu hóa nếu mảng đã được sắp xếp + swapped = False + + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + swapped = True + + # Nếu không có hoán đổi nào xảy ra trong lần này, mảng đã được sắp xếp + if not swapped: + break + + return arr +``` + +**Độ phức tạp thời gian**: +- Trường hợp tốt nhất: O(n) - khi mảng đã được sắp xếp +- Trường hợp trung bình: O(n²) +- Trường hợp xấu nhất: O(n²) + +## So sánh các thuật toán sắp xếp + +| Thuật toán | Độ phức tạp (Tốt nhất) | Độ phức tạp (Trung bình) | Độ phức tạp (Xấu nhất) | Độ phức tạp không gian | Ổn định | +|------------|------------------------|--------------------------|------------------------|------------------------|---------| +| Quick Sort | O(n log n) | O(n log n) | O(n²) | O(log n) | Không | +| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Có | +| Bubble Sort | O(n) | O(n²) | O(n²) | O(1) | Có | +| Insertion Sort | O(n) | O(n²) | O(n²) | O(1) | Có | +| Selection Sort | O(n²) | O(n²) | O(n²) | O(1) | Không | +| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | Không | +| Counting Sort | O(n+k) | O(n+k) | O(n+k) | O(k) | Có | +| Radix Sort | O(nk) | O(nk) | O(nk) | O(n+k) | Có | + +Trong đó: +- n là số lượng phần tử +- k là phạm vi của giá trị đầu vào + +## Khi nào sử dụng từng thuật toán + +- **Quick Sort**: Sắp xếp đa năng, hoạt động tốt cho các mảng vừa với bộ nhớ +- **Merge Sort**: Khi cần tính ổn định và yêu cầu trường hợp xấu nhất O(n log n) +- **Bubble Sort**: Mục đích giáo dục hoặc tập dữ liệu rất nhỏ +- **Insertion Sort**: Tập dữ liệu nhỏ hoặc mảng gần như đã được sắp xếp +- **Heap Sort**: Khi cần hiệu suất ổn định mà không có kịch bản xấu nhất +- **Counting/Radix Sort**: Khi phạm vi giá trị đầu vào bị giới hạn + +## Kết luận + +Việc chọn thuật toán sắp xếp phù hợp phụ thuộc vào yêu cầu cụ thể của bạn, bao gồm kích thước của tập dữ liệu, giới hạn bộ nhớ và liệu tính ổn định có quan trọng hay không. Trong thực tế, hầu hết các ngôn ngữ lập trình triển khai các thuật toán sắp xếp kết hợp kết hợp lợi ích của các phương pháp khác nhau. diff --git a/i18n/vi/databases/relational_vi.md b/i18n/vi/databases/relational.md similarity index 96% rename from i18n/vi/databases/relational_vi.md rename to i18n/vi/databases/relational.md index 6647b44..3937bf3 100644 --- a/i18n/vi/databases/relational_vi.md +++ b/i18n/vi/databases/relational.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Relational +description: Guide about Relational +--- # Cơ sở dữ liệu quan hệ Cơ sở dữ liệu quan hệ là tập hợp dữ liệu có tổ chức lưu trữ thông tin trong các bảng với hàng và cột. Chúng tuân theo mô hình quan hệ do Edgar F. Codd đề xuất vào năm 1970, nhấn mạnh mối quan hệ giữa các thực thể dữ liệu. @@ -114,4 +122,4 @@ Cơ sở dữ liệu quan hệ lý tưởng cho: - Codd, E.F. (1970). "A Relational Model of Data for Large Shared Data Banks" - Date, C.J. "An Introduction to Database Systems" -- Garcia-Molina, H., Ullman, J.D., & Widom, J. "Database Systems: The Complete Book" \ No newline at end of file +- Garcia-Molina, H., Ullman, J.D., & Widom, J. "Database Systems: The Complete Book" diff --git a/i18n/vi/design-patterns/factory_vi.md b/i18n/vi/design-patterns/factory.md similarity index 98% rename from i18n/vi/design-patterns/factory_vi.md rename to i18n/vi/design-patterns/factory.md index 63ec969..a66f1ce 100644 --- a/i18n/vi/design-patterns/factory_vi.md +++ b/i18n/vi/design-patterns/factory.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Factory +description: Guide about Factory +--- # Mẫu thiết kế Factory Mẫu Factory là một mẫu thiết kế tạo đối tượng cung cấp giao diện để tạo đối tượng trong lớp cha, nhưng cho phép các lớp con thay đổi loại đối tượng sẽ được tạo. @@ -473,4 +481,4 @@ public class Program - "Design Patterns: Elements of Reusable Object-Oriented Software" của Gang of Four (GoF) - [Refactoring Guru - Mẫu Factory Method](https://refactoring.guru/design-patterns/factory-method) -- [Refactoring Guru - Mẫu Abstract Factory](https://refactoring.guru/design-patterns/abstract-factory) \ No newline at end of file +- [Refactoring Guru - Mẫu Abstract Factory](https://refactoring.guru/design-patterns/abstract-factory) diff --git a/i18n/vi/design-patterns/observer_vi.md b/i18n/vi/design-patterns/observer.md similarity index 98% rename from i18n/vi/design-patterns/observer_vi.md rename to i18n/vi/design-patterns/observer.md index 69155cc..ffa226f 100644 --- a/i18n/vi/design-patterns/observer_vi.md +++ b/i18n/vi/design-patterns/observer.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Observer +description: Guide about Observer +--- # Mẫu thiết kế Observer Mẫu Observer là một mẫu thiết kế hành vi trong đó một đối tượng, gọi là chủ thể (subject), duy trì danh sách các phụ thuộc của nó, gọi là Observer, và thông báo cho họ tự động về bất kỳ thay đổi trạng thái nào, thường bằng cách gọi một trong các phương thức của họ. @@ -401,4 +409,4 @@ public class Investor : IObserver - "Design Patterns: Elements of Reusable Object-Oriented Software" của Gang of Four (GoF) - [Refactoring Guru - Observer Pattern](https://refactoring.guru/design-patterns/observer) -- [SourceMaking - Observer Pattern](https://sourcemaking.com/design_patterns/observer) \ No newline at end of file +- [SourceMaking - Observer Pattern](https://sourcemaking.com/design_patterns/observer) diff --git a/i18n/vi/design-patterns/singleton_vi.md b/i18n/vi/design-patterns/singleton.md similarity index 96% rename from i18n/vi/design-patterns/singleton_vi.md rename to i18n/vi/design-patterns/singleton.md index 27dd4c8..f9d06bb 100644 --- a/i18n/vi/design-patterns/singleton_vi.md +++ b/i18n/vi/design-patterns/singleton.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Singleton +description: Guide about Singleton +--- # Mẫu thiết kế Singleton Singleton là một mẫu thiết kế tạo đối tượng đảm bảo rằng một lớp chỉ có một thể hiện duy nhất và cung cấp một điểm truy cập toàn cục đến thể hiện đó. @@ -223,4 +231,4 @@ public sealed class Singleton - "Design Patterns: Elements of Reusable Object-Oriented Software" của Gang of Four (GoF) - [Refactoring Guru - Singleton Pattern](https://refactoring.guru/design-patterns/singleton) -- [SourceMaking - Singleton Pattern](https://sourcemaking.com/design_patterns/singleton) \ No newline at end of file +- [SourceMaking - Singleton Pattern](https://sourcemaking.com/design_patterns/singleton) diff --git a/i18n/vi/devops/ci-cd_vi.md b/i18n/vi/devops/ci-cd.md similarity index 97% rename from i18n/vi/devops/ci-cd_vi.md rename to i18n/vi/devops/ci-cd.md index 8b9dd04..d079247 100644 --- a/i18n/vi/devops/ci-cd_vi.md +++ b/i18n/vi/devops/ci-cd.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Ci Cd +description: Guide about Ci Cd +--- # Tích Hợp Liên Tục và Triển Khai Liên Tục (CI/CD) Tích hợp liên tục và triển khai liên tục (CI/CD) là một phương pháp để thường xuyên cung cấp ứng dụng cho khách hàng bằng cách đưa tự động hóa vào các giai đoạn phát triển ứng dụng. diff --git a/i18n/vi/linux/bash-scripting_vi.md b/i18n/vi/linux/bash-scripting.md similarity index 97% rename from i18n/vi/linux/bash-scripting_vi.md rename to i18n/vi/linux/bash-scripting.md index 329f3ff..55cd383 100644 --- a/i18n/vi/linux/bash-scripting_vi.md +++ b/i18n/vi/linux/bash-scripting.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Bash Scripting +description: Guide about Bash Scripting +--- # Lập Trình Bash Bash (Bourne Again SHell) là một ngôn ngữ thông dịch lệnh được sử dụng rộng rãi trên nhiều hệ điều hành, và là shell mặc định trên hầu hết các bản phân phối Linux. diff --git a/i18n/vi/system-design/microservices_vi.md b/i18n/vi/system-design/microservices.md similarity index 98% rename from i18n/vi/system-design/microservices_vi.md rename to i18n/vi/system-design/microservices.md index 80da511..a0259b2 100644 --- a/i18n/vi/system-design/microservices_vi.md +++ b/i18n/vi/system-design/microservices.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Microservices +description: Guide about Microservices +--- # Kiến Trúc Microservices Kiến trúc microservices là một phong cách kiến trúc cấu trúc một ứng dụng như một tập hợp các dịch vụ nhỏ, liên kết lỏng lẻo có thể được phát triển, triển khai và mở rộng độc lập. diff --git a/i18n/vi/testing/unit-testing_vi.md b/i18n/vi/testing/unit-testing.md similarity index 98% rename from i18n/vi/testing/unit-testing_vi.md rename to i18n/vi/testing/unit-testing.md index 018a504..5fa254c 100644 --- a/i18n/vi/testing/unit-testing_vi.md +++ b/i18n/vi/testing/unit-testing.md @@ -1,3 +1,11 @@ +--- +author: Tech Notes Hub +tags: 'learning, technology, programming' +update: '2025-06-06' +date: '2025-06-06' +title: Unit Testing +description: Guide about Unit Testing +--- # Kiểm Thử Đơn Vị Kiểm thử đơn vị là một phương pháp kiểm thử phần mềm trong đó các đơn vị hoặc thành phần riêng lẻ của phần mềm được kiểm tra một cách cô lập với phần còn lại của hệ thống. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..dcc75da --- /dev/null +++ b/package-lock.json @@ -0,0 +1,639 @@ +{ + "name": "tech-notes", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "glob": "^11.0.2", + "gray-matter": "^4.0.3" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", + "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..44af9e6 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "glob": "^11.0.2", + "gray-matter": "^4.0.3" + } +} diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.c b/snippets/algorithms/sorting-algorithms/sorting_algorithms.c new file mode 100644 index 0000000..05d731b --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.c @@ -0,0 +1,587 @@ +#include +#include +#include +#include + +/** + * Bubble Sort + * Time complexity: O(n^2) + */ +void bubbleSort(int arr[], int n) { + for (int i = 0; i < n - 1; i++) { + // Flag to optimize for already sorted arrays + int swapped = 0; + + for (int j = 0; j < n - i - 1; j++) { + if (arr[j] > arr[j + 1]) { + // Swap elements + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + swapped = 1; + } + } + + // If no elements were swapped in this iteration, the array is already sorted + if (swapped == 0) { + break; + } + } +} + +/** + * Selection Sort + * Time complexity: O(n^2) + */ +void selectionSort(int arr[], int n) { + for (int i = 0; i < n - 1; i++) { + // Find the smallest element in the unsorted part + int min_idx = i; + + for (int j = i + 1; j < n; j++) { + if (arr[j] < arr[min_idx]) { + min_idx = j; + } + } + + // Swap the smallest element with the first element in the unsorted part + if (min_idx != i) { + int temp = arr[i]; + arr[i] = arr[min_idx]; + arr[min_idx] = temp; + } + } +} + +/** + * Insertion Sort + * Time complexity: O(n^2) + */ +void insertionSort(int arr[], int n) { + for (int i = 1; i < n; i++) { + int key = arr[i]; + int j = i - 1; + + // Move elements greater than key to the right by one position + while (j >= 0 && arr[j] > key) { + arr[j + 1] = arr[j]; + j--; + } + + arr[j + 1] = key; + } +} + +/** + * Merge two sorted subarrays - helper function for Merge Sort + */ +void merge(int arr[], int l, int m, int r) { + int i, j, k; + int n1 = m - l + 1; + int n2 = r - m; + + // Create temporary arrays + int L[n1], R[n2]; + + // Copy data into temporary arrays + for (i = 0; i < n1; i++) { + L[i] = arr[l + i]; + } + for (j = 0; j < n2; j++) { + R[j] = arr[m + 1 + j]; + } + + // Merge the temporary arrays + i = 0; // Initial index of first subarray + j = 0; // Initial index of second subarray + k = l; // Initial index of merged subarray + + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + // Copy remaining elements of L[] if any + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + // Copy remaining elements of R[] if any + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } +} + +/** + * Merge Sort + * Time complexity: O(n log n) + */ +void mergeSort(int arr[], int l, int r) { + if (l < r) { + // Find the middle point + int m = l + (r - l) / 2; + + // Sort first and second halves + mergeSort(arr, l, m); + mergeSort(arr, m + 1, r); + + // Merge the sorted halves + merge(arr, l, m, r); + } +} + +/** + * Utility function to call mergeSort + */ +void mergeSortWrapper(int arr[], int n) { + mergeSort(arr, 0, n - 1); +} + +/** + * Partition function - helper function for Quick Sort + */ +int partition(int arr[], int low, int high) { + // Choose pivot as the last element + int pivot = arr[high]; + int i = (low - 1); // Index of the smaller element + + for (int j = low; j <= high - 1; j++) { + // If current element is less than or equal to pivot + if (arr[j] <= pivot) { + i++; // Increment index of smaller element + + // Swap arr[i] and arr[j] + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + + // Swap arr[i + 1] and arr[high] (place pivot in the correct position) + int temp = arr[i + 1]; + arr[i + 1] = arr[high]; + arr[high] = temp; + + return (i + 1); +} + +/** + * Quick Sort + * Time complexity: O(n log n) average, O(n^2) worst case + */ +void quickSort(int arr[], int low, int high) { + if (low < high) { + // pi is the partition index, arr[pi] is already in the correct position + int pi = partition(arr, low, high); + + // Recursively sort elements before and after partition + quickSort(arr, low, pi - 1); + quickSort(arr, pi + 1, high); + } +} + +/** + * Utility function to call quickSort + */ +void quickSortWrapper(int arr[], int n) { + quickSort(arr, 0, n - 1); +} + +/** + * Heapify function - helper function for Heap Sort + */ +void heapify(int arr[], int n, int i) { + int largest = i; // Initialize largest as root + int left = 2 * i + 1; // Left child index = 2*i + 1 + int right = 2 * i + 2; // Right child index = 2*i + 2 + + // If left child is greater than root + if (left < n && arr[left] > arr[largest]) { + largest = left; + } + + // If right child is greater than root + if (right < n && arr[right] > arr[largest]) { + largest = right; + } + + // If largest is not root + if (largest != i) { + // Swap i and largest + int temp = arr[i]; + arr[i] = arr[largest]; + arr[largest] = temp; + + // Heapify recursively on the affected child subtree + heapify(arr, n, largest); + } +} + +/** + * Heap Sort + * Time complexity: O(n log n) + */ +void heapSort(int arr[], int n) { + // Build heap (heapify) + for (int i = n / 2 - 1; i >= 0; i--) { + heapify(arr, n, i); + } + + // One by one extract elements from heap + for (int i = n - 1; i > 0; i--) { + // Move current root to end + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + // Call max heapify on the reduced heap + heapify(arr, i, 0); + } +} + +/** + * Counting Sort + * Time complexity: O(n + k) with k being the range of input elements + */ +void countingSort(int arr[], int n) { + // Find the maximum and minimum elements + int max = arr[0]; + int min = arr[0]; + for (int i = 1; i < n; i++) { + if (arr[i] > max) { + max = arr[i]; + } + if (arr[i] < min) { + min = arr[i]; + } + } + + int range = max - min + 1; + + // Create count array and result array + int* count = (int*)calloc(range, sizeof(int)); + int* output = (int*)malloc(n * sizeof(int)); + + // Count occurrences of each element + for (int i = 0; i < n; i++) { + count[arr[i] - min]++; + } + + // Update count[i] to contain the actual position of this value in output + for (int i = 1; i < range; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (int i = n - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + + // Copy output array to arr + for (int i = 0; i < n; i++) { + arr[i] = output[i]; + } + + // Free memory + free(count); + free(output); +} + +/** + * Utility function for Radix Sort - sorting based on the digit at position exp + */ +void countingSortForRadix(int arr[], int n, int exp) { + int output[n]; + int count[10] = {0}; // 0-9 digits + + // Count occurrences of each digit + for (int i = 0; i < n; i++) { + count[(arr[i] / exp) % 10]++; + } + + // Update count to contain the actual position of this value in output + for (int i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (int i = n - 1; i >= 0; i--) { + int digit = (arr[i] / exp) % 10; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + // Copy output array to arr + for (int i = 0; i < n; i++) { + arr[i] = output[i]; + } +} + +/** + * Radix Sort + * Time complexity: O(d * (n + b)) with d being the number of digits and b being the base + * Note: This algorithm only works with non-negative integers + */ +void radixSort(int arr[], int n) { + // Check if array is empty + if (n <= 1) return; + + // Separate array into negative and positive parts for separate handling + int hasNegative = 0; + for (int i = 0; i < n; i++) { + if (arr[i] < 0) { + hasNegative = 1; + break; + } + } + + if (hasNegative) { + // Count number of negative and positive numbers + int countNeg = 0; + for (int i = 0; i < n; i++) { + if (arr[i] < 0) countNeg++; + } + int countPos = n - countNeg; + + // Create separate arrays for negative and positive numbers + int* negArr = (int*)malloc(countNeg * sizeof(int)); + int* posArr = (int*)malloc(countPos * sizeof(int)); + + // Separate array + int negIdx = 0, posIdx = 0; + for (int i = 0; i < n; i++) { + if (arr[i] < 0) { + negArr[negIdx++] = -arr[i]; // Get absolute value + } else { + posArr[posIdx++] = arr[i]; + } + } + + // Sort negative and positive arrays using radixSort + if (countNeg > 0) radixSort(negArr, countNeg); + if (countPos > 0) radixSort(posArr, countPos); + + // Combine results + for (int i = 0; i < countNeg; i++) { + arr[i] = -negArr[countNeg - 1 - i]; // Reverse and change sign + } + for (int i = 0; i < countPos; i++) { + arr[countNeg + i] = posArr[i]; + } + + // Free memory + free(negArr); + free(posArr); + + return; + } + + // Find the largest number to know the number of digits + int max = arr[0]; + for (int i = 1; i < n; i++) { + if (arr[i] > max) { + max = arr[i]; + } + } + + // Perform counting sort for each digit + for (int exp = 1; max / exp > 0; exp *= 10) { + countingSortForRadix(arr, n, exp); + } +} + +/** + * Bucket Sort + * Time complexity: O(n + k) with k being the number of buckets + */ +void bucketSort(int arr[], int n) { + if (n <= 0) return; + + // Find the largest and smallest values + int max = arr[0]; + int min = arr[0]; + for (int i = 1; i < n; i++) { + if (arr[i] > max) max = arr[i]; + if (arr[i] < min) min = arr[i]; + } + + // Calculate the range and number of buckets + int range = max - min + 1; + int bucketCount = (n < 10) ? n : 10; // Number of buckets, maximum 10 + double bucketSize = (double)range / bucketCount; + + // Create array of buckets + int** buckets = (int**)malloc(bucketCount * sizeof(int*)); + int* bucketSizes = (int*)calloc(bucketCount, sizeof(int)); + + // Initialize buckets with initial size of 0 + for (int i = 0; i < bucketCount; i++) { + buckets[i] = (int*)malloc(n * sizeof(int)); // Maximum size is n + } + + // Distribute elements into buckets + for (int i = 0; i < n; i++) { + int bucketIndex = (int)((arr[i] - min) / bucketSize); + if (bucketIndex >= bucketCount) bucketIndex = bucketCount - 1; + buckets[bucketIndex][bucketSizes[bucketIndex]++] = arr[i]; + } + + // Sort each bucket and merge + int arrIndex = 0; + for (int i = 0; i < bucketCount; i++) { + if (bucketSizes[i] > 0) { + // Sort bucket using insertion sort + for (int j = 1; j < bucketSizes[i]; j++) { + int key = buckets[i][j]; + int k = j - 1; + while (k >= 0 && buckets[i][k] > key) { + buckets[i][k + 1] = buckets[i][k]; + k--; + } + buckets[i][k + 1] = key; + } + + // Add sorted elements from bucket to the original array + for (int j = 0; j < bucketSizes[i]; j++) { + arr[arrIndex++] = buckets[i][j]; + } + } + } + + // Free memory + for (int i = 0; i < bucketCount; i++) { + free(buckets[i]); + } + free(buckets); + free(bucketSizes); +} + +/** + * Shell Sort + * Time complexity: depends on the gap sequence, usually O(n log^2 n) + */ +void shellSort(int arr[], int n) { + // Start with large gap, then decrease + for (int gap = n/2; gap > 0; gap /= 2) { + // Perform insertion sort with gap + for (int i = gap; i < n; i++) { + // Add arr[i] to the sorted elements with gap + // Save arr[i] in temp and create a gap at position i + int temp = arr[i]; + + // Shift the sorted elements with gap until the correct position for temp is found + int j; + for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) { + arr[j] = arr[j - gap]; + } + + // Place temp (original arr[i]) in the correct position + arr[j] = temp; + } + } +} + +/** + * Utility function to print array + */ +void printArray(int arr[], int n) { + for (int i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); +} + +/** + * Utility function to copy array + */ +void copyArray(int source[], int dest[], int n) { + for (int i = 0; i < n; i++) { + dest[i] = source[i]; + } +} + +/** + * Main function to test sorting algorithms + */ +int main() { + // Test array + int arr[] = {64, 34, 25, 12, 22, 11, 90}; + int n = sizeof(arr) / sizeof(arr[0]); + int arrCopy[n]; + + printf("Original array: "); + printArray(arr, n); + + // Bubble Sort + copyArray(arr, arrCopy, n); + bubbleSort(arrCopy, n); + printf("Bubble Sort: "); + printArray(arrCopy, n); + + // Selection Sort + copyArray(arr, arrCopy, n); + selectionSort(arrCopy, n); + printf("Selection Sort: "); + printArray(arrCopy, n); + + // Insertion Sort + copyArray(arr, arrCopy, n); + insertionSort(arrCopy, n); + printf("Insertion Sort: "); + printArray(arrCopy, n); + + // Merge Sort + copyArray(arr, arrCopy, n); + mergeSortWrapper(arrCopy, n); + printf("Merge Sort: "); + printArray(arrCopy, n); + + // Quick Sort + copyArray(arr, arrCopy, n); + quickSortWrapper(arrCopy, n); + printf("Quick Sort: "); + printArray(arrCopy, n); + + // Heap Sort + copyArray(arr, arrCopy, n); + heapSort(arrCopy, n); + printf("Heap Sort: "); + printArray(arrCopy, n); + + // Counting Sort + copyArray(arr, arrCopy, n); + countingSort(arrCopy, n); + printf("Counting Sort: "); + printArray(arrCopy, n); + + // Radix Sort + copyArray(arr, arrCopy, n); + radixSort(arrCopy, n); + printf("Radix Sort: "); + printArray(arrCopy, n); + + // Bucket Sort + copyArray(arr, arrCopy, n); + bucketSort(arrCopy, n); + printf("Bucket Sort: "); + printArray(arrCopy, n); + + // Shell Sort + copyArray(arr, arrCopy, n); + shellSort(arrCopy, n); + printf("Shell Sort: "); + printArray(arrCopy, n); + + return 0; +} \ No newline at end of file diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.cpp b/snippets/algorithms/sorting-algorithms/sorting_algorithms.cpp new file mode 100644 index 0000000..773ea25 --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.cpp @@ -0,0 +1,513 @@ +#include +#include +#include +#include +#include + +/** + * Collection of popular sorting algorithms implemented in C++ + */ +class SortingAlgorithms { +public: + /** + * Bubble Sort + * Time complexity: O(n^2) + */ + static std::vector bubbleSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + int n = result.size(); + + for (int i = 0; i < n - 1; i++) { + // Flag to optimize for already sorted arrays + bool swapped = false; + + for (int j = 0; j < n - i - 1; j++) { + if (result[j] > result[j + 1]) { + // Swap elements + std::swap(result[j], result[j + 1]); + swapped = true; + } + } + + // If no elements were swapped in this loop, the array is already sorted + if (!swapped) break; + } + + return result; + } + + /** + * Selection Sort + * Time complexity: O(n^2) + */ + static std::vector selectionSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + int n = result.size(); + + for (int i = 0; i < n - 1; i++) { + // Find the minimum element in the unsorted part of the array + int minIdx = i; + + for (int j = i + 1; j < n; j++) { + if (result[j] < result[minIdx]) { + minIdx = j; + } + } + + // Swap the minimum element with the first element of the unsorted part + if (minIdx != i) { + std::swap(result[i], result[minIdx]); + } + } + + return result; + } + + /** + * Insertion Sort + * Time complexity: O(n^2) + */ + static std::vector insertionSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + int n = result.size(); + + for (int i = 1; i < n; i++) { + int key = result[i]; + int j = i - 1; + + // Move elements greater than key one position ahead + while (j >= 0 && result[j] > key) { + result[j + 1] = result[j]; + j--; + } + + result[j + 1] = key; + } + + return result; + } + + /** + * Merge Sort + * Time complexity: O(n log n) + */ + static std::vector mergeSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + + if (result.size() <= 1) return result; + + mergeSort(result, 0, result.size() - 1); + return result; + } + +private: + /** + * Helper function for Merge Sort + */ + static void mergeSort(std::vector& arr, int left, int right) { + if (left >= right) return; + + // Find the middle point + int mid = left + (right - left) / 2; + + // Sort first and second halves + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); + + // Merge the sorted halves + merge(arr, left, mid, right); + } + + /** + * Merge two sorted subarrays + */ + static void merge(std::vector& arr, int left, int mid, int right) { + // Find the sizes of two subarrays to be merged + int n1 = mid - left + 1; + int n2 = right - mid; + + // Create temporary arrays + std::vector L(n1); + std::vector R(n2); + + // Copy data into temporary arrays + for (int i = 0; i < n1; i++) { + L[i] = arr[left + i]; + } + for (int j = 0; j < n2; j++) { + R[j] = arr[mid + 1 + j]; + } + + // Merge the temporary arrays + int i = 0, j = 0; + int k = left; + + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + // Copy remaining elements of L[] if any + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + // Sao chép các phần tử còn lại của R[] nếu có + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + +public: + /** + * Quick Sort + * Time complexity: O(n log n) average, O(n^2) worst case + */ + static std::vector quickSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + + if (result.size() <= 1) return result; + + quickSort(result, 0, result.size() - 1); + return result; + } + +private: + /** + * Partition function for Quick Sort + */ + static int partition(std::vector& arr, int low, int high) { + // Select the last element as pivot + int pivot = arr[high]; + int i = low - 1; + + for (int j = low; j < high; j++) { + // If the current element is less than or equal to pivot + if (arr[j] <= pivot) { + i++; + std::swap(arr[i], arr[j]); + } + } + + std::swap(arr[i + 1], arr[high]); + return i + 1; + } + + /** + * Helper function for Quick Sort + */ + static void quickSort(std::vector& arr, int low, int high) { + if (low < high) { + // pi is the partition index, arr[pi] is already in the correct position + int pi = partition(arr, low, high); + + // Recursively sort elements before and after pivot + quickSort(arr, low, pi - 1); + quickSort(arr, pi + 1, high); + } + } + +public: + /** + * Heap Sort + * Time complexity: O(n log n) + */ + static std::vector heapSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + int n = result.size(); + + // Build heap (heapify) + for (int i = n / 2 - 1; i >= 0; i--) { + heapify(result, n, i); + } + + // One by one extract an element from heap + for (int i = n - 1; i > 0; i--) { + // Move current root to end + std::swap(result[0], result[i]); + + // Call max heapify on the reduced heap + heapify(result, i, 0); + } + + return result; + } + +private: + /** + * Heapify function for Heap Sort + */ + static void heapify(std::vector& arr, int n, int i) { + int largest = i; // Initialize largest as root + int left = 2 * i + 1; // Left child index = 2*i + 1 + int right = 2 * i + 2; // Right child index = 2*i + 2 + + // If left child is larger than root + if (left < n && arr[left] > arr[largest]) { + largest = left; + } + + // If right child is larger than root + if (right < n && arr[right] > arr[largest]) { + largest = right; + } + + // If largest is not root + if (largest != i) { + std::swap(arr[i], arr[largest]); + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } + } + +public: + /** + * Counting Sort + * Time complexity: O(n + k) with k being the range of input values + */ + static std::vector countingSort(const std::vector& arr) { + if (arr.empty()) return {}; + + // Find the maximum and minimum elements + int max = *std::max_element(arr.begin(), arr.end()); + int min = *std::min_element(arr.begin(), arr.end()); + int range = max - min + 1; + + std::vector count(range, 0); + std::vector output(arr.size()); + + // Count the occurrences of each element + for (int i = 0; i < arr.size(); i++) { + count[arr[i] - min]++; + } + + // Update count[i] to contain the actual position of this value in output + for (int i = 1; i < count.size(); i++) { + count[i] += count[i - 1]; + } + + // Build the output array + for (int i = arr.size() - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + + return output; + } + + /** + * Radix Sort + * Time complexity: O(d * (n + b)) with d being the number of digits in the largest number, b being the base + */ + static std::vector radixSort(const std::vector& arr) { + if (arr.empty()) return {}; + + // Check for negative numbers + bool hasNegative = false; + for (int num : arr) { + if (num < 0) { + hasNegative = true; + break; + } + } + + if (hasNegative) { + // Split into negative and positive lists + std::vector negatives; + std::vector positives; + + for (int num : arr) { + if (num < 0) { + negatives.push_back(-num); // Get the absolute value + } else { + positives.push_back(num); + } + } + + // Sort the absolute values of negative numbers + auto sortedNegatives = radixSort(negatives); + // Sort positive numbers + auto sortedPositives = radixSort(positives); + + // Combine: negative numbers (reversed and signed) + positive numbers + std::vector result; + for (int i = sortedNegatives.size() - 1; i >= 0; i--) { + result.push_back(-sortedNegatives[i]); + } + result.insert(result.end(), sortedPositives.begin(), sortedPositives.end()); + + return result; + } + + // Find the maximum number of digits + int max = *std::max_element(arr.begin(), arr.end()); + std::vector result = arr; + + // Perform counting sort for each digit + for (int exp = 1; max / exp > 0; exp *= 10) { + countingSortByDigit(result, exp); + } + + return result; + } + +private: + /** + * Helper function for Radix Sort - sort based on the digit at position exp + */ + static void countingSortByDigit(std::vector& arr, int exp) { + int n = arr.size(); + std::vector output(n); + std::vector count(10, 0); // 0-9 digits + + // Count the occurrences of each digit + for (int i = 0; i < n; i++) { + int digit = (arr[i] / exp) % 10; + count[digit]++; + } + + // Update count to contain the actual position + for (int i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + // Build the output array + for (int i = n - 1; i >= 0; i--) { + int digit = (arr[i] / exp) % 10; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + // Copy the output array to arr + for (int i = 0; i < n; i++) { + arr[i] = output[i]; + } + } + +public: + /** + * Bucket Sort + * Time complexity: O(n + k) with k being the number of buckets + */ + static std::vector bucketSort(const std::vector& arr, int bucketCount = 10) { + if (arr.empty()) return {}; + + // Find the maximum and minimum values + int minVal = *std::min_element(arr.begin(), arr.end()); + int maxVal = *std::max_element(arr.begin(), arr.end()); + + // Create buckets + double range = (maxVal - minVal + 1) / static_cast(bucketCount); + std::vector> buckets(bucketCount); + + // Distribute elements into buckets + for (int num : arr) { + int bucketIndex = static_cast((num - minVal) / range); + if (bucketIndex >= bucketCount) bucketIndex = bucketCount - 1; + buckets[bucketIndex].push_back(num); + } + + // Sort each bucket and concatenate + std::vector result; + for (auto& bucket : buckets) { + bucket.sort(); // Sort bucket using std::list's sort function + result.insert(result.end(), bucket.begin(), bucket.end()); + } + + return result; + } + + /** + * Shell Sort + * Time complexity: O(n log^2 n) + */ + static std::vector shellSort(const std::vector& arr) { + std::vector result = arr; // Create a copy to avoid modifying the original array + int n = result.size(); + + // Start with large gaps, then decrease + for (int gap = n/2; gap > 0; gap /= 2) { + // Perform insertion sort with gap + for (int i = gap; i < n; i++) { + // Add arr[i] to the sorted elements with gap + // Save arr[i] in temp and create a gap at position i + int temp = result[i]; + + // Shift the sorted elements with gap until the correct position for temp is found + int j; + for (j = i; j >= gap && result[j - gap] > temp; j -= gap) { + result[j] = result[j - gap]; + } + + // Place temp (original arr[i]) in the correct position + result[j] = temp; + } + } + + return result; + } +}; + +/** + * Utility function to print vector + */ +void printVector(const std::vector& arr) { + for (int num : arr) { + std::cout << num << " "; + } + std::cout << std::endl; +} + +/** + * Main function to test sorting algorithms + */ +int main() { + // Vector test + std::vector arr = {64, 34, 25, 12, 22, 11, 90}; + + std::cout << "Original array: "; + printVector(arr); + + std::cout << "Bubble Sort: "; + printVector(SortingAlgorithms::bubbleSort(arr)); + + std::cout << "Selection Sort: "; + printVector(SortingAlgorithms::selectionSort(arr)); + + std::cout << "Insertion Sort: "; + printVector(SortingAlgorithms::insertionSort(arr)); + + std::cout << "Merge Sort: "; + printVector(SortingAlgorithms::mergeSort(arr)); + + std::cout << "Quick Sort: "; + printVector(SortingAlgorithms::quickSort(arr)); + + std::cout << "Heap Sort: "; + printVector(SortingAlgorithms::heapSort(arr)); + + std::cout << "Counting Sort: "; + printVector(SortingAlgorithms::countingSort(arr)); + + std::cout << "Radix Sort: "; + printVector(SortingAlgorithms::radixSort(arr)); + + std::cout << "Bucket Sort: "; + printVector(SortingAlgorithms::bucketSort(arr)); + + std::cout << "Shell Sort: "; + printVector(SortingAlgorithms::shellSort(arr)); + + return 0; +} \ No newline at end of file diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.cs b/snippets/algorithms/sorting-algorithms/sorting_algorithms.cs new file mode 100644 index 0000000..1d1ec35 --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.cs @@ -0,0 +1,513 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SortingAlgorithms +{ + public class SortingAlgorithms + { + /// + /// Bubble Sort + /// Time complexity: O(n^2) + /// + public static int[] BubbleSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + int n = result.Length; + + for (int i = 0; i < n; i++) + { + bool swapped = false; + + for (int j = 0; j < n - i - 1; j++) + { + if (result[j] > result[j + 1]) + { + // Swap elements + int temp = result[j]; + result[j] = result[j + 1]; + result[j + 1] = temp; + swapped = true; + } + } + + // If no swapping occurred in this pass, the array is already sorted + if (!swapped) + break; + } + + return result; + } + + /// + /// Selection Sort + /// Time complexity: O(n^2) + /// + public static int[] SelectionSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + int n = result.Length; + + for (int i = 0; i < n - 1; i++) + { + // Find the minimum element in the unsorted part + int minIdx = i; + for (int j = i + 1; j < n; j++) + { + if (result[j] < result[minIdx]) + { + minIdx = j; + } + } + + // Swap the found minimum element with the first element + int temp = result[minIdx]; + result[minIdx] = result[i]; + result[i] = temp; + } + + return result; + } + + /// + /// Insertion Sort + /// Time complexity: O(n^2) + /// + public static int[] InsertionSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + int n = result.Length; + + for (int i = 1; i < n; i++) + { + int key = result[i]; + int j = i - 1; + + // Move elements greater than key one position ahead + while (j >= 0 && result[j] > key) + { + result[j + 1] = result[j]; + j--; + } + result[j + 1] = key; + } + + return result; + } + + /// + /// Merge Sort + /// Time complexity: O(n log n) + /// + public static int[] MergeSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + if (result.Length <= 1) + return result; + + return MergeSortHelper(result); + } + + private static int[] MergeSortHelper(int[] arr) + { + if (arr.Length <= 1) + return arr; + + int mid = arr.Length / 2; + int[] left = new int[mid]; + int[] right = new int[arr.Length - mid]; + + // Fill left and right subarrays + Array.Copy(arr, 0, left, 0, mid); + Array.Copy(arr, mid, right, 0, arr.Length - mid); + + left = MergeSortHelper(left); + right = MergeSortHelper(right); + + return Merge(left, right); + } + + private static int[] Merge(int[] left, int[] right) + { + int[] result = new int[left.Length + right.Length]; + int i = 0, j = 0, k = 0; + + // Merge the two arrays + while (i < left.Length && j < right.Length) + { + if (left[i] <= right[j]) + { + result[k++] = left[i++]; + } + else + { + result[k++] = right[j++]; + } + } + + // Copy remaining elements + while (i < left.Length) + { + result[k++] = left[i++]; + } + + while (j < right.Length) + { + result[k++] = right[j++]; + } + + return result; + } + + /// + /// Quick Sort + /// Time complexity: O(n log n) average, O(n^2) worst case + /// + public static int[] QuickSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + if (result.Length <= 1) + return result; + + QuickSortHelper(result, 0, result.Length - 1); + return result; + } + + private static void QuickSortHelper(int[] arr, int low, int high) + { + if (low < high) + { + // pi is the partitioning index + int pi = Partition(arr, low, high); + + // Recursively sort elements before and after partition + QuickSortHelper(arr, low, pi - 1); + QuickSortHelper(arr, pi + 1, high); + } + } + + private static int Partition(int[] arr, int low, int high) + { + int pivot = arr[high]; // Choose the last element as pivot + int i = low - 1; // Index of smaller element + + for (int j = low; j < high; j++) + { + // If current element is smaller than or equal to pivot + if (arr[j] <= pivot) + { + i++; + + // Swap arr[i] and arr[j] + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + + // Swap arr[i+1] and arr[high] (pivot) + int temp1 = arr[i + 1]; + arr[i + 1] = arr[high]; + arr[high] = temp1; + + return i + 1; + } + + /// + /// Heap Sort + /// Time complexity: O(n log n) + /// + public static int[] HeapSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + int n = result.Length; + + // Build max heap + for (int i = n / 2 - 1; i >= 0; i--) + { + Heapify(result, n, i); + } + + // Extract elements from heap one by one + for (int i = n - 1; i > 0; i--) + { + // Move current root to end + int temp = result[0]; + result[0] = result[i]; + result[i] = temp; + + // Call heapify on the reduced heap + Heapify(result, i, 0); + } + + return result; + } + + private static void Heapify(int[] arr, int n, int i) + { + int largest = i; // Initialize largest as root + int left = 2 * i + 1; // left = 2*i + 1 + int right = 2 * i + 2; // right = 2*i + 2 + + // If left child is larger than root + if (left < n && arr[left] > arr[largest]) + largest = left; + + // If right child is larger than largest so far + if (right < n && arr[right] > arr[largest]) + largest = right; + + // If largest is not root + if (largest != i) + { + int swap = arr[i]; + arr[i] = arr[largest]; + arr[largest] = swap; + + // Recursively heapify the affected sub-tree + Heapify(arr, n, largest); + } + } + + /// + /// Counting Sort + /// Time complexity: O(n + k) where k is the range of input elements + /// + public static int[] CountingSort(int[] arr) + { + if (arr.Length == 0) + return new int[0]; + + // Find the maximum and minimum element in the array + int max = arr.Max(); + int min = arr.Min(); + int range = max - min + 1; + + // Create a count array and result array + int[] count = new int[range]; + int[] output = new int[arr.Length]; + + // Store count of each element + for (int i = 0; i < arr.Length; i++) + { + count[arr[i] - min]++; + } + + // Change count[i] so that count[i] now contains the actual + // position of this element in output array + for (int i = 1; i < count.Length; i++) + { + count[i] += count[i - 1]; + } + + // Build the output array + for (int i = arr.Length - 1; i >= 0; i--) + { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + + return output; + } + + /// + /// Radix Sort + /// Time complexity: O(d * (n + b)) with d being the number of digits and b being the base + /// + public static int[] RadixSort(int[] arr) + { + if (arr.Length == 0) + return new int[0]; + + // Handle negative numbers + bool hasNegative = arr.Any(val => val < 0); + if (hasNegative) + { + // Separate into negative and positive arrays + int[] neg = arr.Where(val => val < 0).Select(val => -val).ToArray(); + int[] pos = arr.Where(val => val >= 0).ToArray(); + + // Sort absolute values of negative numbers + if (neg.Length > 0) + { + neg = RadixSort(neg); + // Reverse and negate + Array.Reverse(neg); + for (int i = 0; i < neg.Length; i++) + { + neg[i] = -neg[i]; + } + } + + // Sort positive numbers + if (pos.Length > 0) + { + pos = RadixSort(pos); + } + + // Merge negative and positive arrays + int[] result = new int[arr.Length]; + Array.Copy(neg, 0, result, 0, neg.Length); + Array.Copy(pos, 0, result, neg.Length, pos.Length); + return result; + } + + // Find the maximum number to know the number of digits + int max = arr.Max(); + + // Copy the array + int[] result = (int[])arr.Clone(); + + // Do counting sort for every digit + for (int exp = 1; max / exp > 0; exp *= 10) + { + CountingSortByDigit(result, exp); + } + + return result; + } + + private static void CountingSortByDigit(int[] arr, int exp) + { + int n = arr.Length; + int[] output = new int[n]; + int[] count = new int[10]; // Count array for digits 0-9 + + // Store count of occurrences in count[] + for (int i = 0; i < n; i++) + { + int digit = (arr[i] / exp) % 10; + count[digit]++; + } + + // Change count[i] so that count[i] now contains the actual + // position of this digit in output[] + for (int i = 1; i < 10; i++) + { + count[i] += count[i - 1]; + } + + // Build the output array + for (int i = n - 1; i >= 0; i--) + { + int digit = (arr[i] / exp) % 10; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + // Copy the output array to arr[], so that arr[] now + // contains sorted numbers according to current digit + for (int i = 0; i < n; i++) + { + arr[i] = output[i]; + } + } + + /// + /// Bucket Sort + /// Time complexity: O(n + k) where k is the number of buckets + /// + public static int[] BucketSort(int[] arr, int numBuckets = 10) + { + if (arr.Length == 0) + return new int[0]; + + // Find min and max values + int minValue = arr.Min(); + int maxValue = arr.Max(); + + // Create buckets + double bucketRange = (double)(maxValue - minValue + 1) / numBuckets; + List[] buckets = new List[numBuckets]; + for (int i = 0; i < numBuckets; i++) + { + buckets[i] = new List(); + } + + // Distribute elements into buckets + foreach (int val in arr) + { + int bucketIndex = (int)Math.Floor((val - minValue) / bucketRange); + // Handle case for max value + if (bucketIndex == numBuckets) + { + bucketIndex = numBuckets - 1; + } + buckets[bucketIndex].Add(val); + } + + // Sort individual buckets and collect them + int index = 0; + int[] result = new int[arr.Length]; + for (int i = 0; i < numBuckets; i++) + { + if (buckets[i].Count > 0) + { + // Sort each bucket + int[] bucketArray = buckets[i].ToArray(); + int[] sortedBucket = InsertionSort(bucketArray); + + // Add to result array + foreach (int val in sortedBucket) + { + result[index++] = val; + } + } + } + + return result; + } + + /// + /// Shell Sort + /// Time complexity: depends on the gap sequence, usually O(n log^2 n) + /// + public static int[] ShellSort(int[] arr) + { + int[] result = (int[])arr.Clone(); + int n = result.Length; + + // Start with a big gap, then reduce the gap + for (int gap = n / 2; gap > 0; gap /= 2) + { + // Do a gapped insertion sort for this gap size + for (int i = gap; i < n; i++) + { + // Save result[i] in temp and make a hole at position i + int temp = result[i]; + + // Shift earlier gap-sorted elements up until the correct + // location for result[i] is found + int j; + for (j = i; j >= gap && result[j - gap] > temp; j -= gap) + { + result[j] = result[j - gap]; + } + + // Put temp (the original result[i]) in its correct location + result[j] = temp; + } + } + + return result; + } + + public static void Main(string[] args) + { + // Test array + int[] testArray = { 64, 34, 25, 12, 22, 11, 90 }; + + Console.WriteLine("Original array: [{0}]", string.Join(", ", testArray)); + Console.WriteLine("Bubble Sort: [{0}]", string.Join(", ", BubbleSort(testArray))); + Console.WriteLine("Selection Sort: [{0}]", string.Join(", ", SelectionSort(testArray))); + Console.WriteLine("Insertion Sort: [{0}]", string.Join(", ", InsertionSort(testArray))); + Console.WriteLine("Merge Sort: [{0}]", string.Join(", ", MergeSort(testArray))); + Console.WriteLine("Quick Sort: [{0}]", string.Join(", ", QuickSort(testArray))); + Console.WriteLine("Heap Sort: [{0}]", string.Join(", ", HeapSort(testArray))); + Console.WriteLine("Counting Sort: [{0}]", string.Join(", ", CountingSort(testArray))); + Console.WriteLine("Radix Sort: [{0}]", string.Join(", ", RadixSort(testArray))); + Console.WriteLine("Bucket Sort: [{0}]", string.Join(", ", BucketSort(testArray, 5))); // Using 5 buckets + Console.WriteLine("Shell Sort: [{0}]", string.Join(", ", ShellSort(testArray))); + } + } +} diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.go b/snippets/algorithms/sorting-algorithms/sorting_algorithms.go new file mode 100644 index 0000000..1557ff1 --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.go @@ -0,0 +1,453 @@ +package main + +import ( + "fmt" + "math" +) + +// BubbleSort implements the bubble sort algorithm +// Time complexity: O(n^2) +func BubbleSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + n := len(result) + + for i := 0; i < n; i++ { + swapped := false + + for j := 0; j < n-i-1; j++ { + if result[j] > result[j+1] { + result[j], result[j+1] = result[j+1], result[j] + swapped = true + } + } + + // If no swapping occurred in this pass, the array is already sorted + if !swapped { + break + } + } + return result +} + +// SelectionSort implements the selection sort algorithm +// Time complexity: O(n^2) +func SelectionSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + n := len(result) + + for i := 0; i < n; i++ { + minIdx := i + for j := i + 1; j < n; j++ { + if result[j] < result[minIdx] { + minIdx = j + } + } + // Swap the found minimum element with the first element + result[i], result[minIdx] = result[minIdx], result[i] + } + return result +} + +// InsertionSort implements the insertion sort algorithm +// Time complexity: O(n^2) +func InsertionSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + n := len(result) + + for i := 1; i < n; i++ { + key := result[i] + j := i - 1 + + // Move elements of result[0..i-1], that are greater than key, + // to one position ahead of their current position + for j >= 0 && result[j] > key { + result[j+1] = result[j] + j-- + } + result[j+1] = key + } + return result +} + +// MergeSort implements the merge sort algorithm +// Time complexity: O(n log n) +func MergeSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + + if len(result) <= 1 { + return result + } + + // Recursive mergesort + return mergeSortHelper(result) +} + +func mergeSortHelper(arr []int) []int { + if len(arr) <= 1 { + return arr + } + + mid := len(arr) / 2 + left := mergeSortHelper(arr[:mid]) + right := mergeSortHelper(arr[mid:]) + + return merge(left, right) +} + +func merge(left, right []int) []int { + result := make([]int, 0, len(left)+len(right)) + i, j := 0, 0 + + for i < len(left) && j < len(right) { + if left[i] <= right[j] { + result = append(result, left[i]) + i++ + } else { + result = append(result, right[j]) + j++ + } + } + + // Append remaining elements + result = append(result, left[i:]...) + result = append(result, right[j:]...) + + return result +} + +// QuickSort implements the quick sort algorithm +// Time complexity: O(n log n) average, O(n^2) worst case +func QuickSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + + if len(result) <= 1 { + return result + } + + quickSortHelper(result, 0, len(result)-1) + return result +} + +func quickSortHelper(arr []int, low, high int) { + if low < high { + // pi is partitioning index + pi := partition(arr, low, high) + + // Recursively sort elements before and after partition + quickSortHelper(arr, low, pi-1) + quickSortHelper(arr, pi+1, high) + } +} + +func partition(arr []int, low, high int) int { + pivot := arr[high] // Choose the last element as pivot + i := low - 1 // Index of smaller element + + for j := low; j < high; j++ { + // If current element is smaller than the pivot + if arr[j] <= pivot { + i++ + arr[i], arr[j] = arr[j], arr[i] + } + } + + // Swap the pivot element with the element at (i+1) + arr[i+1], arr[high] = arr[high], arr[i+1] + return i + 1 +} + +// HeapSort implements the heap sort algorithm +// Time complexity: O(n log n) +func HeapSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + n := len(result) + + // Build max heap + for i := n/2 - 1; i >= 0; i-- { + heapify(result, n, i) + } + + // Extract elements from heap one by one + for i := n - 1; i > 0; i-- { + // Move current root to end + result[0], result[i] = result[i], result[0] + + // Call heapify on the reduced heap + heapify(result, i, 0) + } + + return result +} + +// heapify a subtree rooted with node i which is an index in arr[] +func heapify(arr []int, n, i int) { + largest := i // Initialize largest as root + left := 2*i + 1 // left = 2*i + 1 + right := 2*i + 2 // right = 2*i + 2 + + // If left child is larger than root + if left < n && arr[left] > arr[largest] { + largest = left + } + + // If right child is larger than largest so far + if right < n && arr[right] > arr[largest] { + largest = right + } + + // If largest is not root + if largest != i { + arr[i], arr[largest] = arr[largest], arr[i] + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest) + } +} + +// CountingSort implements the counting sort algorithm +// Time complexity: O(n + k) where k is the range of the non-negative key values +func CountingSort(arr []int) []int { + if len(arr) == 0 { + return []int{} + } + + result := make([]int, len(arr)) + copy(result, arr) + + // Find the maximum and minimum element in the array + max := result[0] + min := result[0] + for _, val := range result { + if val > max { + max = val + } + if val < min { + min = val + } + } + + range_of_elements := max - min + 1 + + // Create a count array to store the count of each element + count := make([]int, range_of_elements) + output := make([]int, len(result)) + + // Store the count of each element + for i := 0; i < len(result); i++ { + count[result[i]-min]++ + } + + // Store the cumulative count + for i := 1; i < len(count); i++ { + count[i] += count[i-1] + } + + // Build the output array + for i := len(result) - 1; i >= 0; i-- { + output[count[result[i]-min]-1] = result[i] + count[result[i]-min]-- + } + + return output +} + +// RadixSort implements the radix sort algorithm +// Time complexity: O(d * (n + b)) where d is the number of digits and b is the base +func RadixSort(arr []int) []int { + if len(arr) == 0 { + return []int{} + } + + // Handle negative numbers by splitting into negative and positive arrays + hasNegative := false + for _, val := range arr { + if val < 0 { + hasNegative = true + break + } + } + + if hasNegative { + neg := []int{} + pos := []int{} + + // Split into negative and positive arrays + for _, val := range arr { + if val < 0 { + neg = append(neg, -val) // Get absolute value + } else { + pos = append(pos, val) + } + } + + // Sort both arrays + if len(neg) > 0 { + neg = RadixSort(neg) + // Reverse and negate + for i, j := 0, len(neg)-1; i < j; i, j = i+1, j-1 { + neg[i], neg[j] = neg[j], neg[i] + } + for i := range neg { + neg[i] = -neg[i] + } + } + + if len(pos) > 0 { + pos = RadixSort(pos) + } + + // Merge negative and positive arrays + return append(neg, pos...) + } + + // Find the maximum number to know number of digits + max := arr[0] + for _, val := range arr { + if val > max { + max = val + } + } + + // Do counting sort for every digit + result := make([]int, len(arr)) + copy(result, arr) + exp := 1 + + // Perform counting sort for each digit + for max/exp > 0 { + countingSortByDigit(result, exp) + exp *= 10 + } + + return result +} + +func countingSortByDigit(arr []int, exp int) { + n := len(arr) + output := make([]int, n) + count := make([]int, 10) + + // Store count of occurrences in count[] + for i := 0; i < n; i++ { + digit := (arr[i] / exp) % 10 + count[digit]++ + } + + // Change count[i] so that count[i] now contains actual + // position of this digit in output[] + for i := 1; i < 10; i++ { + count[i] += count[i-1] + } + + // Build the output array + for i := n - 1; i >= 0; i-- { + digit := (arr[i] / exp) % 10 + output[count[digit]-1] = arr[i] + count[digit]-- + } + + // Copy the output array to arr[], so that arr[] now + // contains sorted numbers according to current digit + for i := 0; i < n; i++ { + arr[i] = output[i] + } +} + +// BucketSort implements the bucket sort algorithm +// Time complexity: O(n + k) where k is the number of buckets +func BucketSort(arr []int, numBuckets int) []int { + if len(arr) == 0 { + return []int{} + } + + // Find min and max values + min := arr[0] + max := arr[0] + for _, val := range arr { + if val < min { + min = val + } + if val > max { + max = val + } + } + + // Create buckets + bucketRange := float64(max-min) / float64(numBuckets) + buckets := make([][]int, numBuckets) + for i := range buckets { + buckets[i] = []int{} + } + + // Distribute elements into buckets + for _, val := range arr { + idx := int(math.Floor(float64(val-min) / bucketRange)) + // Handle edge case for max value + if idx == numBuckets { + idx = numBuckets - 1 + } + buckets[idx] = append(buckets[idx], val) + } + + // Sort individual buckets and merge them + result := []int{} + for _, bucket := range buckets { + if len(bucket) > 0 { + sortedBucket := InsertionSort(bucket) + result = append(result, sortedBucket...) + } + } + + return result +} + +// ShellSort implements the shell sort algorithm +// Time complexity: depends on the gap sequence, usually O(n log^2 n) +func ShellSort(arr []int) []int { + result := make([]int, len(arr)) + copy(result, arr) + n := len(result) + + // Start with a big gap, then reduce the gap + for gap := n / 2; gap > 0; gap /= 2 { + // Do a gapped insertion sort for this gap size + for i := gap; i < n; i++ { + // Save result[i] in temp and make a hole at position i + temp := result[i] + + // Shift earlier gap-sorted elements up until the correct + // location for result[i] is found + var j int + for j = i; j >= gap && result[j-gap] > temp; j -= gap { + result[j] = result[j-gap] + } + + // Put temp (the original result[i]) in its correct location + result[j] = temp + } + } + return result +} + +func main() { + // Test array + testArray := []int{64, 34, 25, 12, 22, 11, 90} + + fmt.Println("Original array:", testArray) + fmt.Println("Bubble Sort:", BubbleSort(testArray)) + fmt.Println("Selection Sort:", SelectionSort(testArray)) + fmt.Println("Insertion Sort:", InsertionSort(testArray)) + fmt.Println("Merge Sort:", MergeSort(testArray)) + fmt.Println("Quick Sort:", QuickSort(testArray)) + fmt.Println("Heap Sort:", HeapSort(testArray)) + fmt.Println("Counting Sort:", CountingSort(testArray)) + fmt.Println("Radix Sort:", RadixSort(testArray)) + fmt.Println("Bucket Sort:", BucketSort(testArray, 5)) // Using 5 buckets + fmt.Println("Shell Sort:", ShellSort(testArray)) +} diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.java b/snippets/algorithms/sorting-algorithms/sorting_algorithms.java new file mode 100644 index 0000000..f725b4d --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.java @@ -0,0 +1,550 @@ +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +/** + * Collection of popular sorting algorithms implemented in Java + */ +public class SortingAlgorithms { + + /** + * Bubble Sort + * Time complexity: O(n^2) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] bubbleSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + int n = result.length; + + for (int i = 0; i < n - 1; i++) { + // Flag to optimize for already sorted arrays + boolean swapped = false; + + for (int j = 0; j < n - i - 1; j++) { + if (result[j] > result[j + 1]) { + // Swap elements + int temp = result[j]; + result[j] = result[j + 1]; + result[j + 1] = temp; + swapped = true; + } + } + + // If no elements were swapped in this pass, the array is already sorted + if (!swapped) break; + } + + return result; + } + + /** + * Selection Sort + * Time complexity: O(n^2) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] selectionSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + int n = result.length; + + for (int i = 0; i < n - 1; i++) { + // Find the smallest element in the unsorted part of the array + int minIdx = i; + + for (int j = i + 1; j < n; j++) { + if (result[j] < result[minIdx]) { + minIdx = j; + } + } + + // Swap the smallest element with the first element in the unsorted part + int temp = result[minIdx]; + result[minIdx] = result[i]; + result[i] = temp; + } + + return result; + } + + /** + * Insertion Sort + * Time complexity: O(n^2) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] insertionSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + int n = result.length; + + for (int i = 1; i < n; i++) { + int key = result[i]; + int j = i - 1; + + // Move elements greater than key one position ahead + while (j >= 0 && result[j] > key) { + result[j + 1] = result[j]; + j--; + } + + result[j + 1] = key; + } + + return result; + } + + /** + * Merge Sort + * Time complexity: O(n log n) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] mergeSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + mergeSort(result, 0, result.length - 1); + return result; + } + + private static void mergeSort(int[] arr, int left, int right) { + if (left < right) { + // Find the middle point + int mid = left + (right - left) / 2; + + // Sort first and second halves + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); + + // Merge the sorted halves + merge(arr, left, mid, right); + } + } + + private static void merge(int[] arr, int left, int mid, int right) { + // Find the size of the two subarrays to merge + int n1 = mid - left + 1; + int n2 = right - mid; + + // Create temporary arrays + int[] L = new int[n1]; + int[] R = new int[n2]; + + // Copy data into temporary arrays + for (int i = 0; i < n1; i++) { + L[i] = arr[left + i]; + } + for (int j = 0; j < n2; j++) { + R[j] = arr[mid + 1 + j]; + } + + // Merge the temporary arrays + int i = 0, j = 0; + int k = left; + + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + // Copy remaining elements of L[] if any + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + // Copy remaining elements of R[] if any + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Quick Sort + * Time complexity: O(n log n) average, O(n^2) worst case + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] quickSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + quickSort(result, 0, result.length - 1); + return result; + } + + private static void quickSort(int[] arr, int low, int high) { + if (low < high) { + // pi is the partition index, arr[pi] is already in the correct position + int pi = partition(arr, low, high); + + // Recursively sort elements before and after pivot + quickSort(arr, low, pi - 1); + quickSort(arr, pi + 1, high); + } + } + + private static int partition(int[] arr, int low, int high) { + // Choose pivot as the last element + int pivot = arr[high]; + int i = low - 1; // Index of the element smaller than pivot + + for (int j = low; j < high; j++) { + // If current element is less than or equal to pivot + if (arr[j] <= pivot) { + i++; + + // Swap arr[i] and arr[j] + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + + // Swap arr[i+1] and arr[high] (place pivot in the correct position) + int temp = arr[i + 1]; + arr[i + 1] = arr[high]; + arr[high] = temp; + + return i + 1; + } + + /** + * Heap Sort + * Time complexity: O(n log n) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] heapSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + int n = result.length; + + // Build heap (heapify) + for (int i = n / 2 - 1; i >= 0; i--) { + heapify(result, n, i); + } + + // One by one extract an element from heap + for (int i = n - 1; i > 0; i--) { + // Move current root to end + int temp = result[0]; + result[0] = result[i]; + result[i] = temp; + + // Call max heapify on the reduced heap + heapify(result, i, 0); + } + + return result; + } + + private static void heapify(int[] arr, int n, int i) { + int largest = i; // Initialize largest as root + int left = 2 * i + 1; // Left child index = 2*i + 1 + int right = 2 * i + 2; // Right child index = 2*i + 2 + + // If left child is larger than root + if (left < n && arr[left] > arr[largest]) { + largest = left; + } + + // If right child is larger than root + if (right < n && arr[right] > arr[largest]) { + largest = right; + } + + // If largest is not root + if (largest != i) { + int swap = arr[i]; + arr[i] = arr[largest]; + arr[largest] = swap; + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } + } + + /** + * Counting Sort + * Time complexity: O(n + k) with k being the range of input elements + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] countingSort(int[] arr) { + if (arr.length == 0) return new int[0]; + + // Find the largest and smallest elements + int max = arr[0], min = arr[0]; + for (int i = 1; i < arr.length; i++) { + if (arr[i] > max) max = arr[i]; + if (arr[i] < min) min = arr[i]; + } + + int range = max - min + 1; + + // Create count array and output array + int[] count = new int[range]; + int[] output = new int[arr.length]; + + // Count occurrences of each element + for (int i = 0; i < arr.length; i++) { + count[arr[i] - min]++; + } + + // Update count[i] to contain the actual position of this value in output + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (int i = arr.length - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + + return output; + } + + /** + * Radix Sort + * Time complexity: O(d * (n + b)) with d being the number of digits in the largest number, b being the base + * + * @param arr Array to be sorted (only applies to non-negative integers) + * @return Sorted array + */ + public static int[] radixSort(int[] arr) { + if (arr.length == 0) return new int[0]; + + // Check for negative numbers + boolean hasNegative = false; + for (int i = 0; i < arr.length; i++) { + if (arr[i] < 0) { + hasNegative = true; + break; + } + } + + if (hasNegative) { + // Separate into negative and positive lists + List negatives = new ArrayList<>(); + List positives = new ArrayList<>(); + + for (int value : arr) { + if (value < 0) { + negatives.add(-value); // Get absolute value + } else { + positives.add(value); + } + } + + // Convert list to array + int[] negArray = new int[negatives.size()]; + for (int i = 0; i < negatives.size(); i++) { + negArray[i] = negatives.get(i); + } + + int[] posArray = new int[positives.size()]; + for (int i = 0; i < positives.size(); i++) { + posArray[i] = positives.get(i); + } + + // Sort each array + int[] sortedNegs = radixSort(negArray); + int[] sortedPos = posArray.length > 0 ? radixSort(posArray) : new int[0]; + + // Combine: negative (reverse and sign) + positive + int[] result = new int[arr.length]; + int index = 0; + + // Add negative (reverse and sign) + for (int i = sortedNegs.length - 1; i >= 0; i--) { + result[index++] = -sortedNegs[i]; + } + + // Add positive + for (int i = 0; i < sortedPos.length; i++) { + result[index++] = sortedPos[i]; + } + + return result; + } + + // Case with only non-negative numbers + int[] result = Arrays.copyOf(arr, arr.length); + + // Find the largest number to know the number of digits + int max = getMax(result); + + // Perform counting sort for each digit + for (int exp = 1; max / exp > 0; exp *= 10) { + countingSortByDigit(result, exp); + } + + return result; + } + + private static void countingSortByDigit(int[] arr, int exp) { + int n = arr.length; + int[] output = new int[n]; + int[] count = new int[10]; // 0-9 digits + + // Count occurrences of each digit + for (int i = 0; i < n; i++) { + count[(arr[i] / exp) % 10]++; + } + + // Update count to contain the actual position + for (int i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (int i = n - 1; i >= 0; i--) { + int digit = (arr[i] / exp) % 10; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + // Copy output array to arr + for (int i = 0; i < n; i++) { + arr[i] = output[i]; + } + } + + private static int getMax(int[] arr) { + int max = arr[0]; + for (int i = 1; i < arr.length; i++) { + if (arr[i] > max) { + max = arr[i]; + } + } + return max; + } + + /** + * Bucket Sort + * Time complexity: O(n + k) with k being the number of buckets + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] bucketSort(int[] arr) { + return bucketSort(arr, 5); // Default 5 elements per bucket + } + + public static int[] bucketSort(int[] arr, int bucketSize) { + if (arr.length == 0) return new int[0]; + + // Find the largest and smallest values + int minValue = arr[0]; + int maxValue = arr[0]; + + for (int i = 1; i < arr.length; i++) { + if (arr[i] < minValue) { + minValue = arr[i]; + } else if (arr[i] > maxValue) { + maxValue = arr[i]; + } + } + + // Create buckets + int bucketCount = (maxValue - minValue) / bucketSize + 1; + List> buckets = new ArrayList<>(bucketCount); + for (int i = 0; i < bucketCount; i++) { + buckets.add(new ArrayList<>()); + } + + // Distribute elements into buckets + for (int i = 0; i < arr.length; i++) { + int bucketIndex = (arr[i] - minValue) / bucketSize; + buckets.get(bucketIndex).add(arr[i]); + } + + // Sort each bucket and combine + int[] result = new int[arr.length]; + int currentIndex = 0; + + for (int i = 0; i < buckets.size(); i++) { + List bucket = buckets.get(i); + if (bucket.isEmpty()) { + continue; + } + + // Sort bucket + Collections.sort(bucket); + + // Add sorted elements from bucket to result + for (int j = 0; j < bucket.size(); j++) { + result[currentIndex++] = bucket.get(j); + } + } + + return result; + } + + /** + * Shell Sort + * Time complexity: depends on the gap sequence, typically O(n log^2 n) + * + * @param arr Array to be sorted + * @return Sorted array + */ + public static int[] shellSort(int[] arr) { + int[] result = Arrays.copyOf(arr, arr.length); + int n = result.length; + + // Start with large gap, then decrease + for (int gap = n/2; gap > 0; gap /= 2) { + // Perform insertion sort with gap + for (int i = gap; i < n; i++) { + // Add arr[i] to the sorted gap elements + // Save arr[i] in temp and create a hole at position i + int temp = result[i]; + + // Shift sorted gap elements until the correct position for temp is found + int j; + for (j = i; j >= gap && result[j - gap] > temp; j -= gap) { + result[j] = result[j - gap]; + } + + // Place temp in the correct position + result[j] = temp; + } + } + + return result; + } + + /** + * Main method to test sorting algorithms + */ + public static void main(String[] args) { + // Test array + int[] testArray = {64, 34, 25, 12, 22, 11, 90}; + + System.out.println("Original array: " + Arrays.toString(testArray)); + System.out.println("Bubble Sort: " + Arrays.toString(bubbleSort(testArray))); + System.out.println("Selection Sort: " + Arrays.toString(selectionSort(testArray))); + System.out.println("Insertion Sort: " + Arrays.toString(insertionSort(testArray))); + System.out.println("Merge Sort: " + Arrays.toString(mergeSort(testArray))); + System.out.println("Quick Sort: " + Arrays.toString(quickSort(testArray))); + System.out.println("Heap Sort: " + Arrays.toString(heapSort(testArray))); + System.out.println("Counting Sort: " + Arrays.toString(countingSort(testArray))); + System.out.println("Radix Sort: " + Arrays.toString(radixSort(testArray))); + System.out.println("Bucket Sort: " + Arrays.toString(bucketSort(testArray))); + System.out.println("Shell Sort: " + Arrays.toString(shellSort(testArray))); + } +} \ No newline at end of file diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.js b/snippets/algorithms/sorting-algorithms/sorting_algorithms.js new file mode 100644 index 0000000..03443eb --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.js @@ -0,0 +1,445 @@ +/** + * Sorting Algorithms in JavaScript + * + * This module provides implementations of various sorting algorithms. + * + * Example usage: + * node sorting_algorithms.js + */ + +/** + * Bubble Sort + * Time complexity: O(n^2) + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function bubbleSort(arr) { + const n = arr.length; + const result = [...arr]; // Create a copy to avoid modifying the original array + + for (let i = 0; i < n; i++) { + // Flag to optimize for already sorted arrays + let swapped = false; + + for (let j = 0; j < n - i - 1; j++) { + if (result[j] > result[j + 1]) { + // Swap elements + [result[j], result[j + 1]] = [result[j + 1], result[j]]; + swapped = true; + } + } + + // If no elements were swapped in this iteration, the array is already sorted + if (!swapped) break; + } + + return result; +} + +/** + * Selection Sort + * Time complexity: O(n^2) + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function selectionSort(arr) { + const n = arr.length; + const result = [...arr]; // Create a copy to avoid modifying the original array + + for (let i = 0; i < n; i++) { + // Find the smallest element in the unsorted part of the array + let minIdx = i; + + for (let j = i + 1; j < n; j++) { + if (result[j] < result[minIdx]) { + minIdx = j; + } + } + + // Swap the smallest element with the first element in the unsorted part + if (minIdx !== i) { + [result[i], result[minIdx]] = [result[minIdx], result[i]]; + } + } + + return result; +} + +/** + * Insertion Sort + * Time complexity: O(n^2) + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function insertionSort(arr) { + const n = arr.length; + const result = [...arr]; // Create a copy to avoid modifying the original array + + for (let i = 1; i < n; i++) { + const key = result[i]; + let j = i - 1; + + // Move elements greater than key one position ahead + while (j >= 0 && result[j] > key) { + result[j + 1] = result[j]; + j--; + } + + result[j + 1] = key; + } + + return result; +} + +/** + * Merge Sort + * Time complexity: O(n log n) + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function mergeSort(arr) { + // Function to merge two sorted arrays + function merge(left, right) { + const result = []; + let i = 0; + let j = 0; + + // Merge the two sorted arrays + while (i < left.length && j < right.length) { + if (left[i] <= right[j]) { + result.push(left[i++]); + } else { + result.push(right[j++]); + } + } + + // Add remaining elements + return result.concat(left.slice(i)).concat(right.slice(j)); + } + + // Merge sort function + function sort(arr) { + const n = arr.length; + + // Base case: array with 0 or 1 element + if (n <= 1) { + return arr; + } + + // Divide array into two halves + const mid = Math.floor(n / 2); + const left = arr.slice(0, mid); + const right = arr.slice(mid); + + // Recursively sort and merge + return merge(sort(left), sort(right)); + } + + return sort([...arr]); // Create a copy to avoid modifying the original array +} + +/** + * Quick Sort + * Time complexity: O(n log n) average, O(n^2) worst case + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function quickSort(arr) { + // Create a copy to avoid modifying the original array + const result = [...arr]; + + // Partition function + function partition(arr, low, high) { + // Choose pivot as the last element + const pivot = arr[high]; + let i = low - 1; + + for (let j = low; j < high; j++) { + // If current element is less than or equal to pivot + if (arr[j] <= pivot) { + i++; + // Swap elements at indices i and j + [arr[i], arr[j]] = [arr[j], arr[i]]; + } + } + + // Swap elements at indices i+1 and high (place pivot in correct position) + [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; + return i + 1; + } + + // Quick sort function + function sort(arr, low, high) { + if (low < high) { + // pi is the partition index, arr[pi] is already in correct position + const pi = partition(arr, low, high); + + // Recursively sort elements before and after pivot + sort(arr, low, pi - 1); + sort(arr, pi + 1, high); + } + return arr; + } + + return sort(result, 0, result.length - 1); +} + +/** + * Heap Sort + * Time complexity: O(n log n) + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function heapSort(arr) { + const result = [...arr]; // Create a copy to avoid modifying the original array + const n = result.length; + + // Build heap (heapify) + function heapify(arr, n, i) { + let largest = i; // Initialize largest as root + const left = 2 * i + 1; // Left child index = 2*i + 1 + const right = 2 * i + 2; // Right child index = 2*i + 2 + + // If left child is greater than root + if (left < n && arr[left] > arr[largest]) { + largest = left; + } + + // If right child is greater than root + if (right < n && arr[right] > arr[largest]) { + largest = right; + } + + // If largest is not root + if (largest !== i) { + [arr[i], arr[largest]] = [arr[largest], arr[i]]; // Swap elements + + // Recursively heapify the affected subtree + heapify(arr, n, largest); + } + } + + // Build max heap + for (let i = Math.floor(n / 2) - 1; i >= 0; i--) { + heapify(result, n, i); + } + + // One by one extract elements from heap + for (let i = n - 1; i > 0; i--) { + // Move current root to end + [result[0], result[i]] = [result[i], result[0]]; + + // Call max heapify on the reduced heap + heapify(result, i, 0); + } + + return result; +} + +/** + * Counting Sort + * Time complexity: O(n + k) with k being the range of input elements + * @param {Array} arr - Array to be sorted + * @returns {Array} Sorted array + */ +function countingSort(arr) { + if (arr.length === 0) return []; + + // Find the maximum and minimum elements + const max = Math.max(...arr); + const min = Math.min(...arr); + const range = max - min + 1; + + // Create count array and initialize with 0 + const count = new Array(range).fill(0); + const output = new Array(arr.length); + + // Count occurrences of each element + for (let i = 0; i < arr.length; i++) { + count[arr[i] - min]++; + } + + // Update count[i] to contain the actual position of this value in output + for (let i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (let i = arr.length - 1; i >= 0; i--) { + output[count[arr[i] - min] - 1] = arr[i]; + count[arr[i] - min]--; + } + + return output; +} + +/** + * Radix Sort + * Time complexity: O(d * (n + b)) with d being the number of digits and b being the base + * @param {Array} arr - Array to be sorted (only applies to non-negative integers) + * @returns {Array} Sorted array + */ +function radixSort(arr) { + if (arr.length === 0) return []; + + // Handle negative numbers + const hasNegative = arr.some(x => x < 0); + if (hasNegative) { + // Separate into negative and positive arrays + const negatives = arr.filter(x => x < 0).map(x => -x); + const positives = arr.filter(x => x >= 0); + + // Sort absolute values of negative numbers + const sortedNegatives = radixSort(negatives).map(x => -x).reverse(); + // Sort positive numbers + const sortedPositives = positives.length ? radixSort(positives) : []; + + // Combine: negative (reversed) + positive + return [...sortedNegatives, ...sortedPositives]; + } + + // Find the maximum number of digits + const max = Math.max(...arr); + let maxDigits = 0; + if (max > 0) { + maxDigits = Math.floor(Math.log10(max)) + 1; + } + + // Create a copy to avoid modifying the original array + let result = [...arr]; + + // Radix sort + for (let digit = 0; digit < maxDigits; digit++) { + // Use counting sort for each digit + const count = new Array(10).fill(0); + const output = new Array(result.length); + const divisor = Math.pow(10, digit); + + // Count occurrences of each digit + for (let i = 0; i < result.length; i++) { + const digitValue = Math.floor((result[i] / divisor) % 10); + count[digitValue]++; + } + + // Update count to contain the actual position + for (let i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + // Build output array + for (let i = result.length - 1; i >= 0; i--) { + const digitValue = Math.floor((result[i] / divisor) % 10); + output[count[digitValue] - 1] = result[i]; + count[digitValue]--; + } + + result = output; + } + + return result; +} + +/** + * Sắp xếp xô - Bucket Sort + * Độ phức tạp thời gian: O(n + k) với k là số lượng buckets + * @param {Array} arr - Mảng cần sắp xếp + * @param {number} [bucketSize=5] - Kích thước xô + * @returns {Array} Mảng đã sắp xếp + */ +function bucketSort(arr, bucketSize = 5) { + if (arr.length === 0) return []; + + // Tìm giá trị lớn nhất và nhỏ nhất + const min = Math.min(...arr); + const max = Math.max(...arr); + + // Tạo bucket + const bucketCount = Math.floor((max - min) / bucketSize) + 1; + const buckets = new Array(bucketCount); + for (let i = 0; i < bucketCount; i++) { + buckets[i] = []; + } + + // Phân phối các phần tử vào bucket + for (const num of arr) { + const bucketIndex = Math.floor((num - min) / bucketSize); + buckets[bucketIndex].push(num); + } + + // Sắp xếp từng bucket và ghép lại + const result = []; + for (const bucket of buckets) { + if (bucket.length > 0) { + // Sắp xếp từng bucket bằng insertion sort + insertionSort(bucket); + result.push(...bucket); + } + } + + return result; +} + +/** + * Sắp xếp Shell - Shell Sort + * Độ phức tạp thời gian: phụ thuộc vào dãy khoảng cách, thường là O(n log^2 n) + * @param {Array} arr - Mảng cần sắp xếp + * @returns {Array} Mảng đã sắp xếp + */ +function shellSort(arr) { + const n = arr.length; + const result = [...arr]; // Tạo bản sao để không thay đổi mảng gốc + + // Bắt đầu với khoảng cách lớn, sau đó giảm dần + for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) { + // Thực hiện insertion sort với khoảng cách gap + for (let i = gap; i < n; i++) { + // Thêm arr[i] vào các phần tử đã được sắp xếp gap + // Lưu arr[i] trong temp và tạo lỗ hổng tại vị trí i + const temp = result[i]; + + // Dịch chuyển các phần tử đã sắp xếp gap cho đến khi tìm thấy vị trí đúng cho temp + let j; + for (j = i; j >= gap && result[j - gap] > temp; j -= gap) { + result[j] = result[j - gap]; + } + + // Đặt temp vào vị trí đúng + result[j] = temp; + } + } + + return result; +} + +// Kiểm thử với một mảng +function testSortingAlgorithms() { + // Mảng test + const testArray = [64, 34, 25, 12, 22, 11, 90]; + + console.log("Mảng ban đầu:", testArray); + console.log("Bubble Sort:", bubbleSort(testArray)); + console.log("Selection Sort:", selectionSort(testArray)); + console.log("Insertion Sort:", insertionSort(testArray)); + console.log("Merge Sort:", mergeSort(testArray)); + console.log("Quick Sort:", quickSort(testArray)); + console.log("Heap Sort:", heapSort(testArray)); + console.log("Counting Sort:", countingSort(testArray)); + console.log("Radix Sort:", radixSort(testArray)); + console.log("Bucket Sort:", bucketSort(testArray)); + console.log("Shell Sort:", shellSort(testArray)); +} + +// Xuất các thuật toán +module.exports = { + bubbleSort, + selectionSort, + insertionSort, + mergeSort, + quickSort, + heapSort, + countingSort, + radixSort, + bucketSort, + shellSort, + testSortingAlgorithms +}; \ No newline at end of file diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.php b/snippets/algorithms/sorting-algorithms/sorting_algorithms.php new file mode 100644 index 0000000..a2431af --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.php @@ -0,0 +1,468 @@ + $result[$j + 1]) { + // Swap elements + $temp = $result[$j]; + $result[$j] = $result[$j + 1]; + $result[$j + 1] = $temp; + $swapped = true; + } + } + + // If no swapping occurred in this pass, the array is already sorted + if (!$swapped) { + break; + } + } + + return $result; +} + +/** + * Selection Sort + * Time complexity: O(n^2) + */ +function selectionSort($arr) { + $result = $arr; + $n = count($result); + + for ($i = 0; $i < $n - 1; $i++) { + // Find the minimum element in the unsorted part + $minIdx = $i; + for ($j = $i + 1; $j < $n; $j++) { + if ($result[$j] < $result[$minIdx]) { + $minIdx = $j; + } + } + + // Swap the found minimum element with the first element + $temp = $result[$minIdx]; + $result[$minIdx] = $result[$i]; + $result[$i] = $temp; + } + + return $result; +} + +/** + * Insertion Sort + * Time complexity: O(n^2) + */ +function insertionSort($arr) { + $result = $arr; + $n = count($result); + + for ($i = 1; $i < $n; $i++) { + $key = $result[$i]; + $j = $i - 1; + + // Move elements greater than key one position ahead + while ($j >= 0 && $result[$j] > $key) { + $result[$j + 1] = $result[$j]; + $j--; + } + $result[$j + 1] = $key; + } + + return $result; +} + +/** + * Merge Sort + * Time complexity: O(n log n) + */ +function mergeSort($arr) { + $result = $arr; + $n = count($result); + + if ($n <= 1) { + return $result; + } + + $mid = (int)($n / 2); + $left = array_slice($result, 0, $mid); + $right = array_slice($result, $mid); + + $left = mergeSort($left); + $right = mergeSort($right); + + return merge($left, $right); +} + +/** + * Helper function for merge sort + */ +function merge($left, $right) { + $result = []; + $i = $j = 0; + $leftCount = count($left); + $rightCount = count($right); + + // Merge the two arrays + while ($i < $leftCount && $j < $rightCount) { + if ($left[$i] <= $right[$j]) { + $result[] = $left[$i]; + $i++; + } else { + $result[] = $right[$j]; + $j++; + } + } + + // Add remaining elements + while ($i < $leftCount) { + $result[] = $left[$i]; + $i++; + } + + while ($j < $rightCount) { + $result[] = $right[$j]; + $j++; + } + + return $result; +} + +/** + * Quick Sort + * Time complexity: O(n log n) average, O(n^2) worst case + */ +function quickSort($arr) { + if (count($arr) <= 1) { + return $arr; + } + + $result = $arr; + quickSortHelper($result, 0, count($result) - 1); + return $result; +} + +/** + * Helper function for quick sort + */ +function quickSortHelper(&$arr, $low, $high) { + if ($low < $high) { + // pi is the partitioning index + $pi = partition($arr, $low, $high); + + // Recursively sort elements before and after partition + quickSortHelper($arr, $low, $pi - 1); + quickSortHelper($arr, $pi + 1, $high); + } +} + +/** + * Partition function for quick sort + */ +function partition(&$arr, $low, $high) { + $pivot = $arr[$high]; // Choose the last element as pivot + $i = $low - 1; // Index of smaller element + + for ($j = $low; $j < $high; $j++) { + // If current element is smaller than or equal to pivot + if ($arr[$j] <= $pivot) { + $i++; + + // Swap arr[i] and arr[j] + $temp = $arr[$i]; + $arr[$i] = $arr[$j]; + $arr[$j] = $temp; + } + } + + // Swap arr[i+1] and arr[high] (pivot) + $temp = $arr[$i + 1]; + $arr[$i + 1] = $arr[$high]; + $arr[$high] = $temp; + + return $i + 1; +} + +/** + * Heap Sort + * Time complexity: O(n log n) + */ +function heapSort($arr) { + $result = $arr; + $n = count($result); + + // Build max heap + for ($i = (int)($n / 2) - 1; $i >= 0; $i--) { + heapify($result, $n, $i); + } + + // Extract elements from heap one by one + for ($i = $n - 1; $i > 0; $i--) { + // Move current root to end + $temp = $result[0]; + $result[0] = $result[$i]; + $result[$i] = $temp; + + // Call heapify on the reduced heap + heapify($result, $i, 0); + } + + return $result; +} + +/** + * Helper function for heap sort + */ +function heapify(&$arr, $n, $i) { + $largest = $i; // Initialize largest as root + $left = 2 * $i + 1; // left = 2*i + 1 + $right = 2 * $i + 2; // right = 2*i + 2 + + // If left child is larger than root + if ($left < $n && $arr[$left] > $arr[$largest]) { + $largest = $left; + } + + // If right child is larger than largest so far + if ($right < $n && $arr[$right] > $arr[$largest]) { + $largest = $right; + } + + // If largest is not root + if ($largest != $i) { + $swap = $arr[$i]; + $arr[$i] = $arr[$largest]; + $arr[$largest] = $swap; + + // Recursively heapify the affected sub-tree + heapify($arr, $n, $largest); + } +} + +/** + * Counting Sort + * Time complexity: O(n + k) where k is the range of input elements + */ +function countingSort($arr) { + if (empty($arr)) { + return []; + } + + // Find the maximum and minimum element in the array + $max = max($arr); + $min = min($arr); + $range = $max - $min + 1; + + // Create a count array and result array + $count = array_fill(0, $range, 0); + $output = array_fill(0, count($arr), 0); + + // Store count of each element + foreach ($arr as $val) { + $count[$val - $min]++; + } + + // Change count[i] so that count[i] now contains the actual + // position of this element in output array + for ($i = 1; $i < $range; $i++) { + $count[$i] += $count[$i - 1]; + } + + // Build the output array + for ($i = count($arr) - 1; $i >= 0; $i--) { + $output[$count[$arr[$i] - $min] - 1] = $arr[$i]; + $count[$arr[$i] - $min]--; + } + + return $output; +} + +/** + * Radix Sort + * Time complexity: O(d * (n + b)) with d being the number of digits and b being the base + */ +function radixSort($arr) { + if (empty($arr)) { + return []; + } + + // Handle negative numbers + $hasNegative = false; + foreach ($arr as $val) { + if ($val < 0) { + $hasNegative = true; + break; + } + } + + if ($hasNegative) { + // Separate into negative and positive arrays + $neg = []; + $pos = []; + + foreach ($arr as $val) { + if ($val < 0) { + $neg[] = -$val; // Get absolute value + } else { + $pos[] = $val; + } + } + + // Sort absolute values of negative numbers + if (!empty($neg)) { + $neg = radixSort($neg); + // Reverse and negate + $neg = array_reverse($neg); + foreach ($neg as &$val) { + $val = -$val; + } + } + + // Sort positive numbers + if (!empty($pos)) { + $pos = radixSort($pos); + } + + // Merge negative and positive arrays + return array_merge($neg, $pos); + } + + // Find the maximum number to know the number of digits + $max = max($arr); + + // Perform counting sort for each digit + $result = $arr; + $exp = 1; + + while ((int)($max / $exp) > 0) { + $result = countingSortByDigit($result, $exp); + $exp *= 10; + } + + return $result; +} + +/** + * Helper function for radix sort + */ +function countingSortByDigit($arr, $exp) { + $n = count($arr); + $output = array_fill(0, $n, 0); + $count = array_fill(0, 10, 0); // Count array for digits 0-9 + + // Store count of occurrences in count[] + for ($i = 0; $i < $n; $i++) { + $digit = (int)(($arr[$i] / $exp) % 10); + $count[$digit]++; + } + + // Change count[i] so that count[i] now contains the actual + // position of this digit in output[] + for ($i = 1; $i < 10; $i++) { + $count[$i] += $count[$i - 1]; + } + + // Build the output array + for ($i = $n - 1; $i >= 0; $i--) { + $digit = (int)(($arr[$i] / $exp) % 10); + $output[$count[$digit] - 1] = $arr[$i]; + $count[$digit]--; + } + + return $output; +} + +/** + * Bucket Sort + * Time complexity: O(n + k) where k is the number of buckets + */ +function bucketSort($arr, $numBuckets = 10) { + if (empty($arr)) { + return []; + } + + // Find min and max values + $minValue = min($arr); + $maxValue = max($arr); + + // Create buckets + $bucketRange = ($maxValue - $minValue + 1) / $numBuckets; + $buckets = array_fill(0, $numBuckets, []); + + // Distribute elements into buckets + foreach ($arr as $val) { + $bucketIndex = (int)(($val - $minValue) / $bucketRange); + // Handle case for max value + if ($bucketIndex == $numBuckets) { + $bucketIndex = $numBuckets - 1; + } + $buckets[$bucketIndex][] = $val; + } + + // Sort individual buckets and collect them + $result = []; + foreach ($buckets as $bucket) { + if (!empty($bucket)) { + // Sort each bucket using insertion sort + $sortedBucket = insertionSort($bucket); + $result = array_merge($result, $sortedBucket); + } + } + + return $result; +} + +/** + * Shell Sort + * Time complexity: depends on the gap sequence, usually O(n log^2 n) + */ +function shellSort($arr) { + $result = $arr; + $n = count($result); + + // Start with a big gap, then reduce the gap + for ($gap = (int)($n / 2); $gap > 0; $gap = (int)($gap / 2)) { + // Do a gapped insertion sort for this gap size + for ($i = $gap; $i < $n; $i++) { + // Save result[i] in temp and make a hole at position i + $temp = $result[$i]; + + // Shift earlier gap-sorted elements up until the correct + // location for result[i] is found + $j = $i; + while ($j >= $gap && $result[$j - $gap] > $temp) { + $result[$j] = $result[$j - $gap]; + $j -= $gap; + } + + // Put temp (the original result[i]) in its correct location + $result[$j] = $temp; + } + } + + return $result; +} + +// Test with an array +$testArray = [64, 34, 25, 12, 22, 11, 90]; + +echo "Original array: " . implode(", ", $testArray) . "\n"; +echo "Bubble Sort: " . implode(", ", bubbleSort($testArray)) . "\n"; +echo "Selection Sort: " . implode(", ", selectionSort($testArray)) . "\n"; +echo "Insertion Sort: " . implode(", ", insertionSort($testArray)) . "\n"; +echo "Merge Sort: " . implode(", ", mergeSort($testArray)) . "\n"; +echo "Quick Sort: " . implode(", ", quickSort($testArray)) . "\n"; +echo "Heap Sort: " . implode(", ", heapSort($testArray)) . "\n"; +echo "Counting Sort: " . implode(", ", countingSort($testArray)) . "\n"; +echo "Radix Sort: " . implode(", ", radixSort($testArray)) . "\n"; +echo "Bucket Sort: " . implode(", ", bucketSort($testArray, 5)) . "\n"; // Using 5 buckets +echo "Shell Sort: " . implode(", ", shellSort($testArray)) . "\n"; + +?> diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.py b/snippets/algorithms/sorting-algorithms/sorting_algorithms.py new file mode 100644 index 0000000..bf1746f --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.py @@ -0,0 +1,355 @@ +def bubble_sort(arr): + """ + Bubble Sort + Time complexity: O(n^2) + """ + n = len(arr) + for i in range(n): + # Flag to optimize for already sorted arrays + swapped = False + + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + swapped = True + + # If no elements were swapped in this iteration, the array is already sorted + if not swapped: + break + + return arr + + +def selection_sort(arr): + """ + Selection Sort + Time complexity: O(n^2) + """ + n = len(arr) + + for i in range(n): + min_idx = i + + for j in range(i + 1, n): + if arr[j] < arr[min_idx]: + min_idx = j + + # Swap the smallest element with the first element in the unsorted part + arr[i], arr[min_idx] = arr[min_idx], arr[i] + + return arr + + +def insertion_sort(arr): + """ + Insertion Sort + Time complexity: O(n^2) + """ + for i in range(1, len(arr)): + key = arr[i] + j = i - 1 + + # Move elements greater than key one position ahead + while j >= 0 and arr[j] > key: + arr[j + 1] = arr[j] + j -= 1 + + arr[j + 1] = key + + return arr + + +def merge_sort(arr): + """ + Merge Sort + Time complexity: O(n log n) + """ + if len(arr) > 1: + mid = len(arr) // 2 + L = arr[:mid] + R = arr[mid:] + + # Recursively sort the first half + merge_sort(L) + + # Recursively sort the second half + merge_sort(R) + + i = j = k = 0 + + # Copy data into temporary arrays L[] and R[] + while i < len(L) and j < len(R): + if L[i] <= R[j]: + arr[k] = L[i] + i += 1 + else: + arr[k] = R[j] + j += 1 + k += 1 + + # Check if there are any remaining elements + while i < len(L): + arr[k] = L[i] + i += 1 + k += 1 + + while j < len(R): + arr[k] = R[j] + j += 1 + k += 1 + + return arr + + +def quick_sort(arr): + """ + Quick Sort + Time complexity: O(n log n) average, O(n^2) worst case + """ + if len(arr) <= 1: + return arr + + def partition(arr, low, high): + pivot = arr[high] # Choose pivot as the last element + i = low - 1 # Index of the element less than pivot + + for j in range(low, high): + # If current element is less than or equal to pivot + if arr[j] <= pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] + + arr[i + 1], arr[high] = arr[high], arr[i + 1] + return i + 1 + + def quick_sort_helper(arr, low, high): + if low < high: + # pi is the partition index, arr[pi] is already in correct position + pi = partition(arr, low, high) + + # Recursively sort elements before and after partition + quick_sort_helper(arr, low, pi - 1) + quick_sort_helper(arr, pi + 1, high) + + arr_copy = arr.copy() + quick_sort_helper(arr_copy, 0, len(arr_copy) - 1) + return arr_copy + + +def heap_sort(arr): + """ + Heap Sort + Time complexity: O(n log n) + """ + def heapify(arr, n, i): + largest = i # Initialize largest as root + left = 2 * i + 1 + right = 2 * i + 2 + + # Check if left child is greater than root + if left < n and arr[i] < arr[left]: + largest = left + + # Check if right child is greater than root + if right < n and arr[largest] < arr[right]: + largest = right + + # Change root if necessary + if largest != i: + arr[i], arr[largest] = arr[largest], arr[i] + + # Heapify the root + heapify(arr, n, largest) + + arr_copy = arr.copy() + n = len(arr_copy) + + # Build max heap + for i in range(n // 2 - 1, -1, -1): + heapify(arr_copy, n, i) + + # Extract elements from heap one by one + for i in range(n - 1, 0, -1): + arr_copy[i], arr_copy[0] = arr_copy[0], arr_copy[i] # Swap elements + heapify(arr_copy, i, 0) + + return arr_copy + + +def counting_sort(arr): + """ + Counting Sort + Time complexity: O(n + k) with k being the range of input elements + """ + # Find the maximum element in the array + if not arr: + return [] + + max_val = max(arr) + min_val = min(arr) + range_of_elements = max_val - min_val + 1 + + # Create count array and result array + count = [0] * range_of_elements + output = [0] * len(arr) + + # Count occurrences of each element + for i in range(0, len(arr)): + count[arr[i] - min_val] += 1 + + # Update count[i] to contain the actual position of this value in output + for i in range(1, len(count)): + count[i] += count[i - 1] + + # Build output array + for i in range(len(arr) - 1, -1, -1): + output[count[arr[i] - min_val] - 1] = arr[i] + count[arr[i] - min_val] -= 1 + + return output + + +def radix_sort(arr): + """ + Radix Sort + Time complexity: O(d * (n + b)) with d being the number of digits and b being the base + """ + if not arr: + return [] + + # Find the maximum number to know the number of digits + max_num = max(abs(x) for x in arr) + + # Handle negative numbers + has_negative = any(x < 0 for x in arr) + if has_negative: + # Separate into negative and positive arrays + neg = [x for x in arr if x < 0] + pos = [x for x in arr if x >= 0] + + # Sort absolute values of negative numbers + neg = [-x for x in neg] # Get absolute value + neg = radix_sort(neg) # Sort + neg = [-x for x in neg] # Reverse + neg.reverse() # Reverse + + # Sort positive numbers + pos = radix_sort(pos) if pos else [] + + # Combine: negative (reversed) + positive + return neg + pos + + # Find the number of digits + digits = 0 + while max_num > 0: + digits += 1 + max_num //= 10 + + # Counting sort for each digit + result = arr.copy() + exp = 1 + + for _ in range(digits): + # Counting sort for the digit at position 'exp' + output = [0] * len(result) + count = [0] * 10 + + for i in range(len(result)): + index = (result[i] // exp) % 10 + count[index] += 1 + + for i in range(1, 10): + count[i] += count[i - 1] + + for i in range(len(result) - 1, -1, -1): + index = (result[i] // exp) % 10 + output[count[index] - 1] = result[i] + count[index] -= 1 + + result = output + exp *= 10 + + return result + + +def bucket_sort(arr, num_buckets=10): + """ + Bucket Sort + Time complexity: O(n + k) with k being the number of buckets + """ + if not arr: + return [] + + # Find min and max + min_val = min(arr) + max_val = max(arr) + + # Create buckets + bucket_range = (max_val - min_val) / num_buckets + buckets = [[] for _ in range(num_buckets)] + + # Place elements into corresponding buckets + for i in arr: + index = int((i - min_val) / bucket_range) + # Special case for max value + if index == num_buckets: + index -= 1 + buckets[index].append(i) + + # Sort each bucket and merge + result = [] + for bucket in buckets: + insertion_sort(bucket) # Use insertion sort for each bucket + result.extend(bucket) + + return result + + +def shell_sort(arr): + """ + Shell Sort + Time complexity: depends on the gap sequence, usually O(n log^2 n) + """ + n = len(arr) + arr_copy = arr.copy() + + # Start with large gap, then decrease + gap = n // 2 + + while gap > 0: + for i in range(gap, n): + # Add arr[i] to the sorted elements with gap + # Save arr[i] in temp and create a gap at position i + temp = arr_copy[i] + + # Shift the sorted elements with gap until the correct position for temp is found + j = i + while j >= gap and arr_copy[j - gap] > temp: + arr_copy[j] = arr_copy[j - gap] + j -= gap + + # Place temp (original arr[i]) in the correct position + arr_copy[j] = temp + + # Decrease gap for the next iteration + gap //= 2 + + return arr_copy + + +# Test with an array +if __name__ == "__main__": + # Test array + test_array = [64, 34, 25, 12, 22, 11, 90] + + print("Original array:", test_array) + print("Bubble Sort:", bubble_sort(test_array)) + print("Selection Sort:", selection_sort(test_array)) + print("Insertion Sort:", insertion_sort(test_array)) + print("Merge Sort:", merge_sort(test_array.copy())) # Need to copy because merge sort modifies the original array + print("Quick Sort:", quick_sort(test_array)) + print("Heap Sort:", heap_sort(test_array)) + print("Counting Sort:", counting_sort(test_array)) + print("Radix Sort:", radix_sort(test_array)) + print("Bucket Sort:", bucket_sort(test_array)) + print("Shell Sort:", shell_sort(test_array)) \ No newline at end of file diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.rb b/snippets/algorithms/sorting-algorithms/sorting_algorithms.rb new file mode 100644 index 0000000..260983f --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.rb @@ -0,0 +1,358 @@ +# Bubble Sort +# Time complexity: O(n^2) +def bubble_sort(arr) + result = arr.clone + n = result.length + + for i in 0...n + swapped = false + + for j in 0...(n-i-1) + if result[j] > result[j+1] + result[j], result[j+1] = result[j+1], result[j] + swapped = true + end + end + + # If no swapping occurred in this pass, the array is already sorted + break unless swapped + end + + result +end + +# Selection Sort +# Time complexity: O(n^2) +def selection_sort(arr) + result = arr.clone + n = result.length + + for i in 0...n + min_idx = i + + for j in (i+1)...n + min_idx = j if result[j] < result[min_idx] + end + + # Swap the found minimum element with the first element of the unsorted part + result[i], result[min_idx] = result[min_idx], result[i] + end + + result +end + +# Insertion Sort +# Time complexity: O(n^2) +def insertion_sort(arr) + result = arr.clone + n = result.length + + for i in 1...n + key = result[i] + j = i - 1 + + # Move elements greater than key one position ahead + while j >= 0 && result[j] > key + result[j+1] = result[j] + j -= 1 + end + + result[j+1] = key + end + + result +end + +# Merge Sort +# Time complexity: O(n log n) +def merge_sort(arr) + return arr.clone if arr.length <= 1 + + mid = arr.length / 2 + left = merge_sort(arr[0...mid]) + right = merge_sort(arr[mid...arr.length]) + + merge(left, right) +end + +def merge(left, right) + result = [] + i = j = 0 + + while i < left.length && j < right.length + if left[i] <= right[j] + result << left[i] + i += 1 + else + result << right[j] + j += 1 + end + end + + # Add remaining elements + result.concat(left[i...left.length]) + result.concat(right[j...right.length]) + + result +end + +# Quick Sort +# Time complexity: O(n log n) average, O(n^2) worst case +def quick_sort(arr) + return arr.clone if arr.length <= 1 + + # Use closure to avoid modifying the original array + quick_sort_helper = lambda do |array, low, high| + if low < high + # pi is the partition index + pi = partition(array, low, high) + + # Recursively sort elements before and after partition + quick_sort_helper.call(array, low, pi - 1) + quick_sort_helper.call(array, pi + 1, high) + end + end + + result = arr.clone + quick_sort_helper.call(result, 0, result.length - 1) + result +end + +def partition(arr, low, high) + pivot = arr[high] # Choose the last element as pivot + i = low - 1 # Index of smaller element + + for j in low...high + # If current element is smaller than or equal to pivot + if arr[j] <= pivot + i += 1 + arr[i], arr[j] = arr[j], arr[i] + end + end + + # Swap the pivot element with the element at (i+1) + arr[i+1], arr[high] = arr[high], arr[i+1] + i + 1 +end + +# Heap Sort +# Time complexity: O(n log n) +def heap_sort(arr) + result = arr.clone + n = result.length + + # Build max heap + (n/2 - 1).downto(0) do |i| + heapify(result, n, i) + end + + # Extract elements from heap one by one + (n-1).downto(1) do |i| + # Move current root to end + result[0], result[i] = result[i], result[0] + + # Call heapify on the reduced heap + heapify(result, i, 0) + end + + result +end + +def heapify(arr, n, i) + largest = i # Initialize largest as root + left = 2 * i + 1 # left = 2*i + 1 + right = 2 * i + 2 # right = 2*i + 2 + + # If left child is larger than root + largest = left if left < n && arr[left] > arr[largest] + + # If right child is larger than largest so far + largest = right if right < n && arr[right] > arr[largest] + + # If largest is not root + if largest != i + arr[i], arr[largest] = arr[largest], arr[i] + + # Recursively heapify the affected sub-tree + heapify(arr, n, largest) + end +end + +# Counting Sort +# Time complexity: O(n + k) where k is the range of input elements +def counting_sort(arr) + return [] if arr.empty? + + # Find the maximum and minimum element in the array + max_val = arr.max + min_val = arr.min + range_of_elements = max_val - min_val + 1 + + # Create a count array and result array + count = Array.new(range_of_elements, 0) + output = Array.new(arr.length, 0) + + # Count occurrences of each element + arr.each { |val| count[val - min_val] += 1 } + + # Update count[i] to contain the actual position of this value in output + for i in 1...range_of_elements + count[i] += count[i-1] + end + + # Build output array + (arr.length-1).downto(0) do |i| + output[count[arr[i] - min_val] - 1] = arr[i] + count[arr[i] - min_val] -= 1 + end + + output +end + +# Radix Sort +# Time complexity: O(d * (n + b)) with d being the number of digits and b being the base +def radix_sort(arr) + return [] if arr.empty? + + # Handle negative numbers + has_negative = arr.any? { |val| val < 0 } + if has_negative + # Separate into negative and positive arrays + neg = arr.select { |val| val < 0 }.map(&:-@) # Get absolute values + pos = arr.select { |val| val >= 0 } + + # Sort absolute values of negative numbers + neg = radix_sort(neg) + neg = neg.map(&:-@).reverse # Negate and reverse + + # Sort positive numbers + pos = pos.empty? ? [] : radix_sort(pos) + + # Combine: negative (reversed) + positive + return neg + pos + end + + # Find maximum number to know number of digits + max_num = arr.max + + # Find the number of digits + digits = 0 + temp = max_num + while temp > 0 + digits += 1 + temp /= 10 + end + + # Perform counting sort for each digit + result = arr.clone + exp = 1 + + digits.times do + # Counting sort for the digit at position 'exp' + output = Array.new(result.length, 0) + count = Array.new(10, 0) + + # Store count of occurrences in count[] + result.each do |val| + digit = (val / exp) % 10 + count[digit] += 1 + end + + # Change count[i] so that count[i] now contains actual position of this digit in output[] + for i in 1...10 + count[i] += count[i-1] + end + + # Build the output array + (result.length-1).downto(0) do |i| + digit = (result[i] / exp) % 10 + output[count[digit] - 1] = result[i] + count[digit] -= 1 + end + + result = output + exp *= 10 + end + + result +end + +# Bucket Sort +# Time complexity: O(n + k) with k being the number of buckets +def bucket_sort(arr, num_buckets = 10) + return [] if arr.empty? + + # Find min and max values + min_val = arr.min + max_val = arr.max + + # Create buckets + bucket_range = (max_val - min_val).to_f / num_buckets + buckets = Array.new(num_buckets) { [] } + + # Place elements into corresponding buckets + arr.each do |val| + index = ((val - min_val) / bucket_range).to_i + # Handle case for max value + index = num_buckets - 1 if index == num_buckets + buckets[index] << val + end + + # Sort each bucket and merge + result = [] + buckets.each do |bucket| + result.concat(insertion_sort(bucket)) unless bucket.empty? + end + + result +end + +# Shell Sort +# Time complexity: depends on the gap sequence, usually O(n log^2 n) +def shell_sort(arr) + result = arr.clone + n = result.length + + # Start with a big gap, then reduce the gap + gap = n / 2 + + while gap > 0 + for i in gap...n + # Save result[i] in temp and make a hole at position i + temp = result[i] + + # Shift earlier gap-sorted elements up until the correct location for result[i] is found + j = i + while j >= gap && result[j - gap] > temp + result[j] = result[j - gap] + j -= gap + end + + # Put temp (the original result[i]) in its correct location + result[j] = temp + end + + # Reduce the gap + gap /= 2 + end + + result +end + +# Test with an array +if __FILE__ == $0 + # Test array + test_array = [64, 34, 25, 12, 22, 11, 90] + + puts "Original array: #{test_array}" + puts "Bubble Sort: #{bubble_sort(test_array)}" + puts "Selection Sort: #{selection_sort(test_array)}" + puts "Insertion Sort: #{insertion_sort(test_array)}" + puts "Merge Sort: #{merge_sort(test_array)}" + puts "Quick Sort: #{quick_sort(test_array)}" + puts "Heap Sort: #{heap_sort(test_array)}" + puts "Counting Sort: #{counting_sort(test_array)}" + puts "Radix Sort: #{radix_sort(test_array)}" + puts "Bucket Sort: #{bucket_sort(test_array)}" + puts "Shell Sort: #{shell_sort(test_array)}" +end diff --git a/snippets/algorithms/sorting-algorithms/sorting_algorithms.rs b/snippets/algorithms/sorting-algorithms/sorting_algorithms.rs new file mode 100644 index 0000000..9927e1b --- /dev/null +++ b/snippets/algorithms/sorting-algorithms/sorting_algorithms.rs @@ -0,0 +1,393 @@ +/// Bubble Sort +/// Time complexity: O(n^2) +fn bubble_sort(arr: &[i32]) -> Vec { + let mut result = arr.to_vec(); + let n = result.len(); + + for i in 0..n { + let mut swapped = false; + + for j in 0..(n - i - 1) { + if result[j] > result[j + 1] { + result.swap(j, j + 1); + swapped = true; + } + } + + // If no swapping occurred in this pass, the array is already sorted + if !swapped { + break; + } + } + + result +} + +/// Selection Sort +/// Time complexity: O(n^2) +fn selection_sort(arr: &[i32]) -> Vec { + let mut result = arr.to_vec(); + let n = result.len(); + + for i in 0..n { + let mut min_idx = i; + + for j in (i + 1)..n { + if result[j] < result[min_idx] { + min_idx = j; + } + } + + // Swap the found minimum element with the first element of the unsorted part + result.swap(i, min_idx); + } + + result +} + +/// Insertion Sort +/// Time complexity: O(n^2) +fn insertion_sort(arr: &[i32]) -> Vec { + let mut result = arr.to_vec(); + let n = result.len(); + + for i in 1..n { + let key = result[i]; + let mut j = i as i32 - 1; + + // Move elements greater than key one position ahead + while j >= 0 && result[j as usize] > key { + result[(j + 1) as usize] = result[j as usize]; + j -= 1; + } + result[(j + 1) as usize] = key; + } + + result +} + +/// Merge Sort +/// Time complexity: O(n log n) +fn merge_sort(arr: &[i32]) -> Vec { + if arr.len() <= 1 { + return arr.to_vec(); + } + + let mid = arr.len() / 2; + let left = merge_sort(&arr[0..mid]); + let right = merge_sort(&arr[mid..]); + + merge(&left, &right) +} + +fn merge(left: &[i32], right: &[i32]) -> Vec { + let mut result = Vec::with_capacity(left.len() + right.len()); + let (mut i, mut j) = (0, 0); + + while i < left.len() && j < right.len() { + if left[i] <= right[j] { + result.push(left[i]); + i += 1; + } else { + result.push(right[j]); + j += 1; + } + } + + // Add remaining elements + result.extend_from_slice(&left[i..]); + result.extend_from_slice(&right[j..]); + + result +} + +/// Quick Sort +/// Time complexity: O(n log n) average, O(n^2) worst case +fn quick_sort(arr: &[i32]) -> Vec { + if arr.len() <= 1 { + return arr.to_vec(); + } + + let mut result = arr.to_vec(); + quick_sort_helper(&mut result, 0, (result.len() - 1) as i32); + result +} + +fn quick_sort_helper(arr: &mut [i32], low: i32, high: i32) { + if low < high { + let pi = partition(arr, low, high); + + // Recursively sort elements before and after partition + quick_sort_helper(arr, low, pi - 1); + quick_sort_helper(arr, pi + 1, high); + } +} + +fn partition(arr: &mut [i32], low: i32, high: i32) -> i32 { + let pivot = arr[high as usize]; + let mut i = low - 1; + + for j in low..high { + if arr[j as usize] <= pivot { + i += 1; + arr.swap(i as usize, j as usize); + } + } + + arr.swap((i + 1) as usize, high as usize); + i + 1 +} + +/// Heap Sort +/// Time complexity: O(n log n) +fn heap_sort(arr: &[i32]) -> Vec { + let mut result = arr.to_vec(); + let n = result.len(); + + // Build max heap + for i in (0..(n / 2)).rev() { + heapify(&mut result, n, i); + } + + // Extract elements from heap one by one + for i in (1..n).rev() { + // Move current root to end + result.swap(0, i); + + // Call heapify on the reduced heap + heapify(&mut result, i, 0); + } + + result +} + +fn heapify(arr: &mut [i32], n: usize, i: usize) { + let mut largest = i; // Initialize largest as root + let left = 2 * i + 1; // left = 2*i + 1 + let right = 2 * i + 2; // right = 2*i + 2 + + // If left child is larger than root + if left < n && arr[left] > arr[largest] { + largest = left; + } + + // If right child is larger than largest so far + if right < n && arr[right] > arr[largest] { + largest = right; + } + + // If largest is not root + if largest != i { + arr.swap(i, largest); + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } +} + +/// Counting Sort +/// Time complexity: O(n + k) where k is the range of input elements +fn counting_sort(arr: &[i32]) -> Vec { + if arr.is_empty() { + return Vec::new(); + } + + // Find the maximum and minimum element in the array + let max_val = *arr.iter().max().unwrap(); + let min_val = *arr.iter().min().unwrap(); + let range = (max_val - min_val + 1) as usize; + + // Create a count array and result array + let mut count = vec![0; range]; + let mut output = vec![0; arr.len()]; + + // Store count of each element + for &val in arr { + count[(val - min_val) as usize] += 1; + } + + // Change count[i] so that count[i] now contains the actual + // position of this element in output array + for i in 1..range { + count[i] += count[i - 1]; + } + + // Build the output array + for i in (0..arr.len()).rev() { + let val = arr[i]; + output[count[(val - min_val) as usize] - 1] = val; + count[(val - min_val) as usize] -= 1; + } + + output +} + +/// Radix Sort +/// Time complexity: O(d * (n + b)) with d being the number of digits and b being the base +fn radix_sort(arr: &[i32]) -> Vec { + if arr.is_empty() { + return Vec::new(); + } + + // Handle negative numbers + let has_negative = arr.iter().any(|&val| val < 0); + if has_negative { + // Separate into negative and positive arrays + let mut neg: Vec = arr.iter() + .filter(|&&val| val < 0) + .map(|&val| -val) + .collect(); + let mut pos: Vec = arr.iter() + .filter(|&&val| val >= 0) + .copied() + .collect(); + + // Sort absolute values of negative numbers + if !neg.is_empty() { + neg = radix_sort(&neg); + // Reverse and negate + neg.reverse(); + for val in &mut neg { + *val = -*val; + } + } + + // Sort positive numbers + if !pos.is_empty() { + pos = radix_sort(&pos); + } + + // Combine: negative (reversed) + positive + neg.extend(pos); + return neg; + } + + // Find maximum number to know number of digits + let max_num = *arr.iter().max().unwrap(); + let mut result = arr.to_vec(); + let mut exp = 1; + + // Do counting sort for every digit + while max_num / exp > 0 { + counting_sort_by_digit(&mut result, exp); + exp *= 10; + } + + result +} + +fn counting_sort_by_digit(arr: &mut [i32], exp: i32) { + let n = arr.len(); + let mut output = vec![0; n]; + let mut count = vec![0; 10]; + + // Store count of occurrences in count[] + for &val in arr.iter() { + let digit = ((val / exp) % 10) as usize; + count[digit] += 1; + } + + // Change count[i] so that count[i] now contains actual + // position of this digit in output[] + for i in 1..10 { + count[i] += count[i - 1]; + } + + // Build the output array + for i in (0..n).rev() { + let digit = ((arr[i] / exp) % 10) as usize; + output[count[digit] - 1] = arr[i]; + count[digit] -= 1; + } + + // Copy the output array to arr[] + for i in 0..n { + arr[i] = output[i]; + } +} + +/// Bucket Sort +/// Time complexity: O(n + k) where k is the number of buckets +fn bucket_sort(arr: &[i32], num_buckets: usize) -> Vec { + if arr.is_empty() { + return Vec::new(); + } + + // Find min and max values + let min_val = *arr.iter().min().unwrap(); + let max_val = *arr.iter().max().unwrap(); + + // Create buckets + let bucket_range = (max_val - min_val + 1) as f64 / num_buckets as f64; + let mut buckets: Vec> = vec![Vec::new(); num_buckets]; + + // Place elements into corresponding buckets + for &val in arr { + let bucket_idx = ((val - min_val) as f64 / bucket_range) as usize; + // Handle case for max value + let idx = if bucket_idx == num_buckets { num_buckets - 1 } else { bucket_idx }; + buckets[idx].push(val); + } + + // Sort individual buckets and collect them + let mut result = Vec::new(); + for mut bucket in buckets { + if !bucket.is_empty() { + // Sort each bucket using insertion sort + bucket = insertion_sort(&bucket); + result.extend(bucket); + } + } + + result +} + +/// Shell Sort +/// Time complexity: depends on the gap sequence, usually O(n log^2 n) +fn shell_sort(arr: &[i32]) -> Vec { + let mut result = arr.to_vec(); + let n = result.len(); + + // Start with a big gap, then reduce the gap + let mut gap = n / 2; + + while gap > 0 { + for i in gap..n { + // Save result[i] in temp and make a hole at position i + let temp = result[i]; + + // Shift earlier gap-sorted elements up until the correct + // location for result[i] is found + let mut j = i; + while j >= gap && result[j - gap] > temp { + result[j] = result[j - gap]; + j -= gap; + } + + // Put temp (the original result[i]) in its correct location + result[j] = temp; + } + + // Reduce the gap + gap /= 2; + } + + result +} + +fn main() { + // Test array + let test_array = vec![64, 34, 25, 12, 22, 11, 90]; + + println!("Original array: {:?}", test_array); + println!("Bubble Sort: {:?}", bubble_sort(&test_array)); + println!("Selection Sort: {:?}", selection_sort(&test_array)); + println!("Insertion Sort: {:?}", insertion_sort(&test_array)); + println!("Merge Sort: {:?}", merge_sort(&test_array)); + println!("Quick Sort: {:?}", quick_sort(&test_array)); + println!("Heap Sort: {:?}", heap_sort(&test_array)); + println!("Counting Sort: {:?}", counting_sort(&test_array)); + println!("Radix Sort: {:?}", radix_sort(&test_array)); + println!("Bucket Sort: {:?}", bucket_sort(&test_array, 5)); // Using 5 buckets + println!("Shell Sort: {:?}", shell_sort(&test_array)); +} diff --git a/snippets/databases/.env.example b/snippets/databases/relational/.env.example similarity index 100% rename from snippets/databases/.env.example rename to snippets/databases/relational/.env.example diff --git a/snippets/databases/relational_db_examples.cs b/snippets/databases/relational/relational.cs similarity index 100% rename from snippets/databases/relational_db_examples.cs rename to snippets/databases/relational/relational.cs diff --git a/snippets/databases/sql_examples.py b/snippets/databases/relational/relational.py similarity index 100% rename from snippets/databases/sql_examples.py rename to snippets/databases/relational/relational.py diff --git a/snippets/devops/ci_cd_pipeline.sh b/snippets/devops/ci-cd/ci-cd.sh similarity index 100% rename from snippets/devops/ci_cd_pipeline.sh rename to snippets/devops/ci-cd/ci-cd.sh diff --git a/snippets/devops/init.txt b/snippets/devops/init.txt new file mode 100644 index 0000000..e69de29 diff --git a/snippets/linux/system_monitor.sh b/snippets/linux/bash-scripting/bash-scripting.sh similarity index 100% rename from snippets/linux/system_monitor.sh rename to snippets/linux/bash-scripting/bash-scripting.sh diff --git a/snippets/linux/init.txt b/snippets/linux/init.txt new file mode 100644 index 0000000..e69de29 diff --git a/snippets/system-design/init.txt b/snippets/system-design/init.txt new file mode 100644 index 0000000..e69de29 diff --git a/snippets/system-design/microservices_example.js b/snippets/system-design/microservices/microservices.js similarity index 100% rename from snippets/system-design/microservices_example.js rename to snippets/system-design/microservices/microservices.js diff --git a/snippets/testing/init.txt b/snippets/testing/init.txt new file mode 100644 index 0000000..e69de29 diff --git a/snippets/testing/unit_testing_example.js b/snippets/testing/unit-testing/unit-testing.js similarity index 100% rename from snippets/testing/unit_testing_example.js rename to snippets/testing/unit-testing/unit-testing.js diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..0b33335 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,75 @@ +# Tools for Tech Notes Hub + +This directory contains utility scripts for maintaining the Tech Notes Hub project. + +## Scripts + +### `update-frontmatter.js` + +A Node.js script that automatically updates the frontmatter (metadata) in all Markdown files in the `/docs` and `/i18n/vi` directories. + +#### Features + +- Ensures all Markdown files have consistent frontmatter +- Updates the `update` field with the current date **only if the field doesn't exists** +- Sets default values for missing fields: + - `author`: "Tech Notes Hub" + - `date`: Current date (if missing) + - `tags`: Default tags (if missing) + - `title`: Generated from filename (if missing) + - `description`: Generated from title (if missing) +- Logs include timestamps for better tracking + +#### Requirements + +- Node.js +- Dependencies: + - `gray-matter` + - `glob` + +#### Usage + +**Update all files:** + +```bash +# Install dependencies if not already installed +npm install gray-matter glob + +# Make the script executable +chmod +x tools/update-frontmatter.js + +# Run the script to update all files +node tools/update-frontmatter.js +# Or explicitly specify all files +node tools/update-frontmatter.js --all +``` + +**Update a single file manually:** + +```bash +# Update a specific file by providing the relative path from either docs/ or i18n/vi/ +node tools/update-frontmatter.js algorithms/sorting-algorithms.md + +# The script will check for the file in both directories: +# - /docs/algorithms/sorting-algorithms.md +# - /i18n/vi/algorithms/sorting-algorithms.md +``` + +#### Automation + +This script is configured to run automatically via GitHub Actions when: + +1. Any Markdown file is changed in the `/docs` or `/i18n` directories +2. Weekly on Monday at 00:00 UTC +3. Manually via the GitHub Actions interface + +The automation will commit any changes back to the repository with a commit message "chore: update markdown frontmatter [skip ci]". + +## Adding New Tools + +When adding new tools to this directory, please follow these guidelines: + +1. Create a well-documented script with clear comments +2. Update this README with information about the tool +3. Ensure the tool follows project coding standards +4. Add any necessary dependencies to the project's package.json diff --git a/tools/update-frontmatter.js b/tools/update-frontmatter.js new file mode 100755 index 0000000..ef691a1 --- /dev/null +++ b/tools/update-frontmatter.js @@ -0,0 +1,164 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const matter = require('gray-matter'); +const glob = require('glob'); + +// Default configuration for frontmatter +const DEFAULT_AUTHOR = 'Tech Notes Hub'; +const DEFAULT_TAGS = 'learning, technology, programming'; +const CURRENT_DATE = new Date().toISOString().split('T')[0]; // Format: YYYY-MM-DD + +// Path to the directories to update +const DOCS_DIR = path.join(__dirname, '..', 'docs'); +const I18N_VI_DIR = path.join(__dirname, '..', 'i18n', 'vi'); + +// Logger function with timestamp +const log = (message, type = 'info') => { + const timestamp = new Date().toISOString().replace('T', ' ').substr(0, 19); + const prefix = { + info: '📝', + success: '✅', + error: '❌', + warning: '⚠️' + }; + console.log(`${timestamp} ${prefix[type] || ''} ${message}`); +}; + +// Get all markdown files +const getMarkdownFiles = (directory) => { + return glob.sync('**/*.md', { + cwd: directory, + ignore: ['**/README.md', '**/SUMMARY.md', '**/LICENSE.md'] + }).map(file => path.join(directory, file)); +}; + +// Update frontmatter for a file +const updateFrontmatter = (filePath) => { + try { + const content = fs.readFileSync(filePath, 'utf8'); + const { data, content: markdownContent } = matter(content); + + // Update or add frontmatter fields + const updatedData = { + ...data, + author: data.author || DEFAULT_AUTHOR, + tags: data.tags || DEFAULT_TAGS, + }; + + // Only update the 'update' field if it doesn't exist + if (!data.update) { + updatedData.update = CURRENT_DATE; + } + + // If 'date' field is missing, add it + if (!data.date) { + updatedData.date = CURRENT_DATE; + } + + // If 'title' field is missing, create title from file name + if (!data.title) { + const fileName = path.basename(filePath, '.md'); + updatedData.title = fileName + .split('-') + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + } + + // If 'description' field is missing, add default description + if (!data.description) { + updatedData.description = `Guide about ${updatedData.title}`; + } + + // Create new content with updated frontmatter + const updatedContent = matter.stringify(markdownContent, updatedData); + + // Write back to file + fs.writeFileSync(filePath, updatedContent); + + log(`Updated: ${filePath}`, 'success'); + return true; + } catch (error) { + log(`Error updating ${filePath}: ${error.message}`, 'error'); + return false; + } +}; + +// Check if file exists +const fileExists = (filePath) => { + try { + return fs.existsSync(filePath); + } catch (error) { + return false; + } +}; + +// Main function to update all markdown files +const updateAllFiles = () => { + // Get all markdown files + const docsFiles = getMarkdownFiles(DOCS_DIR); + const i18nViFiles = getMarkdownFiles(I18N_VI_DIR); + const allFiles = [...docsFiles, ...i18nViFiles]; + + log(`Found ${allFiles.length} markdown files to process...`); + + // Update each file + let successCount = 0; + for (const file of allFiles) { + if (updateFrontmatter(file)) { + successCount++; + } + } + + log(`\nCompleted: ${successCount}/${allFiles.length} files updated successfully.`, 'info'); +}; + +// Function to update a single file manually +const updateSingleFile = (relativePath) => { + // Try to find the file in both directories + const docPath = path.join(DOCS_DIR, relativePath); + const i18nPath = path.join(I18N_VI_DIR, relativePath); + + if (fileExists(docPath)) { + log(`Updating file in docs directory: ${docPath}`); + updateFrontmatter(docPath); + return true; + } else if (fileExists(i18nPath)) { + log(`Updating file in i18n/vi directory: ${i18nPath}`); + updateFrontmatter(i18nPath); + return true; + } else { + log(`File not found: ${relativePath}`, 'error'); + log(`Looked in: \n ${docPath}\n ${i18nPath}`, 'warning'); + return false; + } +}; + +// Process command line arguments +const processArgs = () => { + const args = process.argv.slice(2); + + if (args.length === 0) { + // No arguments, update all files + log('No specific file provided, updating all files...'); + updateAllFiles(); + return; + } + + // First argument is the file path + const filePath = args[0]; + log(`Manual update requested for: ${filePath}`); + + if (filePath === '--all') { + // Update all files + updateAllFiles(); + } else { + // Update single file + updateSingleFile(filePath); + } +}; + +// Run script +log('Starting frontmatter update process...'); +processArgs(); diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000..fac4a7b --- /dev/null +++ b/website/README.md @@ -0,0 +1,125 @@ +# Tech Notes Hub Website + +A modern blog website built with Next.js, Tailwind CSS, shadcn UI, and i18n support for multilingual content (Vietnamese and English). + +## Features + +- **Modern UI**: Clean, minimal design with Tailwind CSS and shadcn UI components +- **Bilingual Support**: Full i18n integration with Vietnamese and English translations +- **Blog System**: Complete blog functionality with Markdown content rendering +- **Dark/Light Mode**: Theme switching with system preference detection +- **SEO Optimized**: Complete SEO setup with meta tags, OpenGraph data, dynamic sitemap.xml, robots.txt, structured metadata, canonical URLs and language alternates +- **Responsive Design**: Mobile-first approach, works on all devices + +## Tech Stack + +- [Next.js 14](https://nextjs.org/) - React framework +- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework +- [shadcn UI](https://ui.shadcn.com/) - UI component library +- [React Markdown](https://github.com/remarkjs/react-markdown) - Markdown renderer +- [i18n](https://nextjs.org/docs/app/building-your-application/routing/internationalization) - Internationalization +- [next-themes](https://github.com/pacocoursey/next-themes) - Theme management + +## Getting Started + +### Prerequisites + +- Node.js 18.17 or later +- npm or yarn + +### Installation + +1. Clone the repository + ```bash + git clone + cd website + ``` + +2. Install dependencies + ```bash + npm install + # or + yarn install + ``` + +3. Run the development server +```bash +npm run dev +# or +yarn dev +``` + +4. Open [http://localhost:3000](http://localhost:3000) with your browser to see the result + +## Project Structure + +``` +website/ +├── public/ # Static assets +├── src/ +│ ├── app/ # App router pages +│ │ ├── [locale]/ # Locale-specific routes +│ │ │ ├── blog/ # Blog pages +│ │ │ ├── about/ # About page +│ │ ├── components/ # React components +│ │ │ ├── ui/ # UI components (shadcn) +│ │ │ ├── layout/ # Layout components +│ │ │ ├── blog/ # Blog-specific components +│ │ ├── data/ # Data sources +│ │ │ ├── i18n/ # Translation files +│ │ │ ├── blog-posts.ts # Blog post data +│ │ ├── lib/ # Utility functions +│ │ │ ├── i18n/ # i18n utilities +│ │ │ ├── utils.ts # Helper functions +│ │ │ ├── types.ts # TypeScript types +├── next.config.ts # Next.js configuration +├── tailwind.config.js # Tailwind CSS configuration +``` + +## Adding Content + +### Blog Posts + +To add new blog posts, edit the `src/data/blog-posts.ts` file. Each post should follow the BlogPost interface defined in `src/lib/types.ts`. + +### Translations + +Add or edit translations in the following files: +- `src/data/i18n/en/common.json` - English translations +- `src/data/i18n/vi/common.json` - Vietnamese translations + +## Deployment + +### Build for Production + +```bash +npm run build +# or +yarn build +``` + +### Deploy to Vercel + +The easiest way to deploy the application is to use the [Vercel Platform](https://vercel.com/). + +1. Push your code to a Git repository (GitHub, GitLab, or Bitbucket) +2. Import the project to Vercel +3. Vercel will detect Next.js and configure the build settings automatically +4. Click "Deploy" + +### Other Deployment Options + +You can also deploy to other platforms like Netlify, AWS Amplify, or traditional hosting with a Node.js server. + +For static export: + +```bash +npm run build +npm run export +``` + +This will generate a static version of the site in the `out` directory that can be served by any static hosting service. + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. diff --git a/website/WEBSITE_README.md b/website/WEBSITE_README.md new file mode 100644 index 0000000..7b63ee8 --- /dev/null +++ b/website/WEBSITE_README.md @@ -0,0 +1,32 @@ +# Tech Notes Hub Blog Website + +This is the blog website component of the Tech Notes Hub project. The website is built using Next.js, Tailwind CSS, shadcn UI, and i18n support for multilingual content (Vietnamese and English). + +## Overview + +The blog website serves as a frontend for displaying technical content and notes from the Tech Notes Hub repository. It provides a modern, responsive interface for users to browse and read technical articles. + +## Getting Started + +The blog website is located in the `/website` directory. To start working with it: + +```bash +cd website +npm install +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to view the site in your browser. + +## Features + +- Modern UI built with Next.js and Tailwind CSS +- Bilingual support (Vietnamese and English) +- Dark/Light mode +- Responsive design +- SEO optimized +- Markdown content rendering + +## Documentation + +For detailed information about the blog website, including setup instructions, project structure, and deployment guidelines, please refer to the [Website README](/website/README.md) in the website directory. diff --git a/website/components.json b/website/components.json new file mode 100644 index 0000000..ffe928f --- /dev/null +++ b/website/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/website/eslint.config.mjs b/website/eslint.config.mjs new file mode 100644 index 0000000..c85fb67 --- /dev/null +++ b/website/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/website/next-seo.config.js b/website/next-seo.config.js new file mode 100644 index 0000000..f5f4328 --- /dev/null +++ b/website/next-seo.config.js @@ -0,0 +1,59 @@ +// Default SEO configuration +const defaultSEOConfig = { + titleTemplate: '%s - Tech Notes Hub', + defaultTitle: 'Tech Notes Hub', + description: 'A collection of tech notes, code snippets, and technical guides for developers', + canonical: 'https://technotes.example.com', + openGraph: { + type: 'website', + locale: 'vi_VN', + url: 'https://technotes.example.com', + siteName: 'Tech Notes Hub', + title: 'Tech Notes Hub', + description: 'A collection of tech notes, code snippets, and technical guides for developers', + images: [ + { + url: 'https://technotes.example.com/og-image.jpg', + width: 1200, + height: 630, + alt: 'Tech Notes Hub', + }, + ], + }, + twitter: { + handle: '@technotes', + site: '@technotes', + cardType: 'summary_large_image', + }, + additionalMetaTags: [ + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + name: 'author', + content: 'Tech Notes Team', + }, + { + name: 'keywords', + content: 'tech, programming, algorithms, design patterns, databases, devops, linux, system design, testing', + }, + ], + additionalLinkTags: [ + { + rel: 'icon', + href: '/favicon.ico', + }, + { + rel: 'apple-touch-icon', + href: '/apple-touch-icon.png', + sizes: '180x180', + }, + { + rel: 'manifest', + href: '/site.webmanifest', + }, + ], +}; + +export default defaultSEOConfig; diff --git a/website/next.config.js b/website/next.config.js new file mode 100644 index 0000000..e69de29 diff --git a/website/next.config.ts b/website/next.config.ts new file mode 100644 index 0000000..e59dc5b --- /dev/null +++ b/website/next.config.ts @@ -0,0 +1,61 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + reactStrictMode: true, + swcMinify: true, + images: { + domains: ['technotes.example.com'], + }, + // Configure experimental features if needed + experimental: { + // Add experimental features here when required + }, + // Add custom headers for security and caching + async headers() { + return [ + { + source: '/(.*)', + headers: [ + { + key: 'X-DNS-Prefetch-Control', + value: 'on', + }, + { + key: 'X-XSS-Protection', + value: '1; mode=block', + }, + { + key: 'X-Content-Type-Options', + value: 'nosniff', + }, + { + key: 'Referrer-Policy', + value: 'strict-origin-when-cross-origin', + }, + ], + }, + { + // Apply caching headers for static assets + source: '/(.*).(jpg|jpeg|png|gif|webp|svg|ico)', + headers: [ + { + key: 'Cache-Control', + value: 'public, max-age=31536000, immutable', + } + ], + }, + ]; + }, + // Redirect from root to default locale + async redirects() { + return [ + { + source: '/', + destination: '/en', + permanent: true, + }, + ]; + }, +}; + +export default nextConfig; diff --git a/website/package-lock.json b/website/package-lock.json new file mode 100644 index 0000000..171494e --- /dev/null +++ b/website/package-lock.json @@ -0,0 +1,9578 @@ +{ + "name": "website", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "website", + "version": "0.1.0", + "dependencies": { + "@radix-ui/react-accordion": "^1.2.11", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-navigation-menu": "^1.2.13", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-toast": "^1.2.14", + "@reduxjs/toolkit": "^2.8.2", + "@tailwindcss/typography": "^0.5.16", + "@types/react-syntax-highlighter": "^15.5.13", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "github-slugger": "^2.0.0", + "i18next": "^25.2.1", + "i18next-browser-languagedetector": "^8.1.0", + "lucide-react": "^0.513.0", + "next": "15.3.3", + "next-i18next": "^15.4.2", + "next-themes": "^0.4.6", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-i18next": "^15.5.2", + "react-markdown": "^10.1.0", + "react-redux": "^9.2.0", + "react-syntax-highlighter": "^15.6.1", + "rehype-highlight": "^7.0.2", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^4.0.1", + "shadcn-ui": "^0.9.5", + "sonner": "^2.0.5", + "tailwind-merge": "^3.3.0", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.3.3", + "tailwindcss": "^4", + "tw-animate-css": "^1.3.4", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.1.tgz", + "integrity": "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz", + "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.1", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.3.tgz", + "integrity": "sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.10.tgz", + "integrity": "sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@next/env": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.3.tgz", + "integrity": "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.3.3.tgz", + "integrity": "sha512-VKZJEiEdpKkfBmcokGjHu0vGDG+8CehGs90tBEy/IDoDDKGngeyIStt2MmE5FYNyU9BhgR7tybNWTAJY/30u+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.3.tgz", + "integrity": "sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.3.tgz", + "integrity": "sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.3.tgz", + "integrity": "sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.3.tgz", + "integrity": "sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.3.tgz", + "integrity": "sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.3.tgz", + "integrity": "sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.3.tgz", + "integrity": "sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.3.tgz", + "integrity": "sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.11.tgz", + "integrity": "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collapsible": "1.1.11", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz", + "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", + "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", + "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.13.tgz", + "integrity": "sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", + "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.14.tgz", + "integrity": "sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz", + "integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.11.0.tgz", + "integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz", + "integrity": "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz", + "integrity": "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-x64": "4.1.8", + "@tailwindcss/oxide-freebsd-x64": "4.1.8", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-x64-musl": "4.1.8", + "@tailwindcss/oxide-wasm32-wasi": "4.1.8", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.8.tgz", + "integrity": "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz", + "integrity": "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.8.tgz", + "integrity": "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.8.tgz", + "integrity": "sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.8.tgz", + "integrity": "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.8.tgz", + "integrity": "sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.8.tgz", + "integrity": "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.8.tgz", + "integrity": "sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.8.tgz", + "integrity": "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.8.tgz", + "integrity": "sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.10", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.8.tgz", + "integrity": "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.8.tgz", + "integrity": "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.8.tgz", + "integrity": "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.8", + "@tailwindcss/oxide": "4.1.8", + "postcss": "^8.4.41", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", + "license": "MIT", + "dependencies": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.58", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.58.tgz", + "integrity": "sha512-UvxetCgGwZ9HmsgGZ2tpStt6CiFU1bu28ftHWpDyfthsCt7OHXas0C7j0VgO3gBq8UHKI785wXmtcQVhLekcRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/react": { + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz", + "integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", + "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/react-syntax-highlighter": { + "version": "15.5.13", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz", + "integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.33.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.11.tgz", + "integrity": "sha512-i3/wlWjQJXMh1uiGtiv7k1EYvrrS3L1hdwmWJJiz1D8jWy726YFYPIxQWbEIVPVAgrfRR0XNlLrTQwq17cuCGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.11.tgz", + "integrity": "sha512-8XXyFvc6w6kmMmi6VYchZhjd5CDcp+Lv6Cn1YmUme0ypsZ/0Kzd+9ESrWtDrWibKPTgSteDTxp75cvBOY64FQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.11.tgz", + "integrity": "sha512-0qJBYzP8Qk24CZ05RSWDQUjdiQUeIJGfqMMzbtXgCKl/a5xa6thfC0MQkGIr55LCLd6YmMyO640ifYUa53lybQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.11.tgz", + "integrity": "sha512-1sGwpgvx+WZf0GFT6vkkOm6UJ+mlsVnjw+Yv9esK71idWeRAG3bbpkf3AoY8KIqKqmnzJExi0uKxXpakQ5Pcbg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.11.tgz", + "integrity": "sha512-D/1F/2lTe+XAl3ohkYj51NjniVly8sIqkA/n1aOND3ZMO418nl2JNU95iVa1/RtpzaKcWEsNTtHRogykrUflJg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.11.tgz", + "integrity": "sha512-7vFWHLCCNFLEQlmwKQfVy066ohLLArZl+AV/AdmrD1/pD1FlmqM+FKbtnONnIwbHtgetFUCV/SRi1q4D49aTlw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.11.tgz", + "integrity": "sha512-tYkGIx8hjWPh4zcn17jLEHU8YMmdP2obRTGkdaB3BguGHh31VCS3ywqC4QjTODjmhhNyZYkj/1Dz/+0kKvg9YA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.11.tgz", + "integrity": "sha512-6F328QIUev29vcZeRX6v6oqKxfUoGwIIAhWGD8wSysnBYFY0nivp25jdWmAb1GildbCCaQvOKEhCok7YfWkj4Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.11.tgz", + "integrity": "sha512-NqhWmiGJGdzbZbeucPZIG9Iav4lyYLCarEnxAceguMx9qlpeEF7ENqYKOwB8Zqk7/CeuYMEcLYMaW2li6HyDzQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.11.tgz", + "integrity": "sha512-J2RPIFKMdTrLtBdfR1cUMKl8Gcy05nlQ+bEs/6al7EdWLk9cs3tnDREHZ7mV9uGbeghpjo4i8neNZNx3PYUY9w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.11.tgz", + "integrity": "sha512-bDpGRerHvvHdhun7MmFUNDpMiYcJSqWckwAVVRTJf8F+RyqYJOp/mx04PDc7DhpNPeWdnTMu91oZRMV+gGaVcQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.11.tgz", + "integrity": "sha512-G9U7bVmylzRLma3cK39RBm3guoD1HOvY4o0NS4JNm37AD0lS7/xyMt7kn0JejYyc0Im8J+rH69/dXGM9DAJcSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.11.tgz", + "integrity": "sha512-7qL20SBKomekSunm7M9Fe5L93bFbn+FbHiGJbfTlp0RKhPVoJDP73vOxf1QrmJHyDPECsGWPFnKa/f8fO2FsHw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.11.tgz", + "integrity": "sha512-jisvIva8MidjI+B1lFRZZMfCPaCISePgTyR60wNT1MeQvIh5Ksa0G3gvI+Iqyj3jqYbvOHByenpa5eDGcSdoSg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.10" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.11.tgz", + "integrity": "sha512-G+H5nQZ8sRZ8ebMY6mRGBBvTEzMYEcgVauLsNHpvTUavZoCCRVP1zWkCZgOju2dW3O22+8seTHniTdl1/uLz3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.11.tgz", + "integrity": "sha512-Hfy46DBfFzyv0wgR0MMOwFFib2W2+Btc8oE5h4XlPhpelnSyA6nFxkVIyTgIXYGTdFaLoZFNn62fmqx3rjEg3A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.11.tgz", + "integrity": "sha512-7L8NdsQlCJ8T106Gbz/AjzM4QKWVsoQbKpB9bMBGcIZswUuAnJMHpvbqGW3RBqLHCIwX4XZ5fxSBHEFcK2h9wA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001721", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", + "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.42.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz", + "integrity": "sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.28.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.3.3.tgz", + "integrity": "sha512-QJLv/Ouk2vZnxL4b67njJwTLjTf7uZRltI0LL4GERYR4qMF5z08+gxkfODAeaK7TiC6o+cER91bDaEnwrTWV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "15.3.3", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.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/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "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/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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==", + "license": "MIT", + "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-to-parse5/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.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==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/i18next": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.2.1.tgz", + "integrity": "sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.1.0.tgz", + "integrity": "sha512-mHZxNx1Lq09xt5kCauZ/4bsXOEA2pfpwSoU11/QTJB+pD94iONFwp+ohqi///PwiFvjFOxe1akYCdHyFo1ng5Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-fs-backend": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.0.tgz", + "integrity": "sha512-3ZlhNoF9yxnM8pa8bWp5120/Ob6t4lVl1l/tbLmkml/ei3ud8IWySCHt2lrY5xWRlSU5D9IV2sm5bEbGuTqwTw==", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT", + "optional": true + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lucide-react": { + "version": "0.513.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.513.0.tgz", + "integrity": "sha512-CJZKq2g8Y8yN4Aq002GahSXbG2JpFv9kXwyiOAMvUBv7pxeOFHUWKB0mO7MiY4ZVFCV4aNjv2BJFq/z3DgKPQg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.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/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@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", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.4.tgz", + "integrity": "sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/next/-/next-15.3.3.tgz", + "integrity": "sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==", + "license": "MIT", + "dependencies": { + "@next/env": "15.3.3", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.3.3", + "@next/swc-darwin-x64": "15.3.3", + "@next/swc-linux-arm64-gnu": "15.3.3", + "@next/swc-linux-arm64-musl": "15.3.3", + "@next/swc-linux-x64-gnu": "15.3.3", + "@next/swc-linux-x64-musl": "15.3.3", + "@next/swc-win32-arm64-msvc": "15.3.3", + "@next/swc-win32-x64-msvc": "15.3.3", + "sharp": "^0.34.1" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-i18next": { + "version": "15.4.2", + "resolved": "https://registry.npmjs.org/next-i18next/-/next-i18next-15.4.2.tgz", + "integrity": "sha512-zgRxWf7kdXtM686ecGIBQL+Bq0+DqAhRlasRZ3vVF0TmrNTWkVhs52n//oU3Fj5O7r/xOKkECDUwfOuXVwTK/g==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + }, + { + "type": "individual", + "url": "https://locize.com" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@types/hoist-non-react-statics": "^3.3.6", + "core-js": "^3", + "hoist-non-react-statics": "^3.3.2", + "i18next-fs-backend": "^2.6.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "i18next": ">= 23.7.13", + "next": ">= 12.0.0", + "react": ">= 17.0.2", + "react-i18next": ">= 13.5.0" + } + }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-i18next": { + "version": "15.5.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.2.tgz", + "integrity": "sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-syntax-highlighter": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/react-syntax-highlighter/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/react-syntax-highlighter/node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "license": "MIT", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/refractor/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/refractor/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/refractor/node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/refractor/node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/refractor/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rehype-highlight": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.2.tgz", + "integrity": "sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-text": "^4.0.0", + "lowlight": "^3.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shadcn-ui": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/shadcn-ui/-/shadcn-ui-0.9.5.tgz", + "integrity": "sha512-dsBQWpdLLYCdSdmvOmu53nJhhWnQD1OiblhuhkI4rPYxPKTyfbmZ2NTJHWMu1fXN9PTfN6IVK5vvh+BrjHJx2g==", + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1" + }, + "bin": { + "shadcn-ui": "dist/index.js" + } + }, + "node_modules/shadcn-ui/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/sonner": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.5.tgz", + "integrity": "sha512-YwbHQO6cSso3HBXlbCkgrgzDNIhws14r4MO87Ofy+cV2X7ES4pOoAK3+veSmVTvqNx1BWUxlhPmZzP00Crk2aQ==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-js": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", + "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.8" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.0.tgz", + "integrity": "sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz", + "integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==", + "license": "MIT" + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz", + "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tw-animate-css": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.4.tgz", + "integrity": "sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unrs-resolver": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.7.11.tgz", + "integrity": "sha512-OhuAzBImFPjKNgZ2JwHMfGFUA6NSbRegd1+BPjC1Y0E6X9Y/vJ4zKeGmIMqmlYboj6cMNEwKI+xQisrg4J0HaQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.2.2" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-darwin-arm64": "1.7.11", + "@unrs/resolver-binding-darwin-x64": "1.7.11", + "@unrs/resolver-binding-freebsd-x64": "1.7.11", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.7.11", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.7.11", + "@unrs/resolver-binding-linux-arm64-gnu": "1.7.11", + "@unrs/resolver-binding-linux-arm64-musl": "1.7.11", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.7.11", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.7.11", + "@unrs/resolver-binding-linux-riscv64-musl": "1.7.11", + "@unrs/resolver-binding-linux-s390x-gnu": "1.7.11", + "@unrs/resolver-binding-linux-x64-gnu": "1.7.11", + "@unrs/resolver-binding-linux-x64-musl": "1.7.11", + "@unrs/resolver-binding-wasm32-wasi": "1.7.11", + "@unrs/resolver-binding-win32-arm64-msvc": "1.7.11", + "@unrs/resolver-binding-win32-ia32-msvc": "1.7.11", + "@unrs/resolver-binding-win32-x64-msvc": "1.7.11" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..e675786 --- /dev/null +++ b/website/package.json @@ -0,0 +1,58 @@ +{ + "name": "website", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@radix-ui/react-accordion": "^1.2.11", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-navigation-menu": "^1.2.13", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-toast": "^1.2.14", + "@reduxjs/toolkit": "^2.8.2", + "@tailwindcss/typography": "^0.5.16", + "@types/react-syntax-highlighter": "^15.5.13", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "github-slugger": "^2.0.0", + "i18next": "^25.2.1", + "i18next-browser-languagedetector": "^8.1.0", + "lucide-react": "^0.513.0", + "next": "15.3.3", + "next-i18next": "^15.4.2", + "next-themes": "^0.4.6", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-i18next": "^15.5.2", + "react-markdown": "^10.1.0", + "react-redux": "^9.2.0", + "react-syntax-highlighter": "^15.6.1", + "rehype-highlight": "^7.0.2", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^4.0.1", + "shadcn-ui": "^0.9.5", + "sonner": "^2.0.5", + "tailwind-merge": "^3.3.0", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.3.3", + "tailwindcss": "^4", + "tw-animate-css": "^1.3.4", + "typescript": "^5" + } +} diff --git a/website/pages/sitemap.xml.js b/website/pages/sitemap.xml.js new file mode 100644 index 0000000..dbe75b6 --- /dev/null +++ b/website/pages/sitemap.xml.js @@ -0,0 +1,149 @@ +import { getContentAsBlogPosts } from '@/lib/content-mapper'; + +const WEBSITE_URL = 'https://technotes.example.com'; +const LOCALES = ['en', 'vi']; + +function generateSiteMap(posts) { + return ` + + + ${LOCALES.map(locale => ` + + ${WEBSITE_URL}/${locale} + ${new Date().toISOString().split('T')[0]} + daily + 1.0 + ${LOCALES.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${LOCALES.map(locale => ` + + ${WEBSITE_URL}/${locale}/about + ${new Date().toISOString().split('T')[0]} + monthly + 0.8 + ${LOCALES.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${LOCALES.map(locale => ` + + ${WEBSITE_URL}/${locale}/privacy + ${new Date().toISOString().split('T')[0]} + monthly + 0.5 + ${LOCALES.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${LOCALES.map(locale => ` + + ${WEBSITE_URL}/${locale}/terms + ${new Date().toISOString().split('T')[0]} + monthly + 0.5 + ${LOCALES.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${LOCALES.map(locale => ` + + ${WEBSITE_URL}/${locale}/blog + ${new Date().toISOString().split('T')[0]} + daily + 0.9 + ${LOCALES.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${posts.map(post => { + // Find translations for this post + const translations = posts.filter(p => + p.slug !== post.slug && + p.relativePath === post.relativePath + ); + + return ` + + ${WEBSITE_URL}/${post.language}/blog/${post.slug} + ${post.date || new Date().toISOString().split('T')[0]} + weekly + 0.7 + ${ + // Add links to translations if they exist + translations.map(translation => ` + + `).join('') + } + + `; + }).join('')} + + `; +} + +export default function SiteMap() { + // getServerSideProps will do the heavy lifting +} + +export async function getServerSideProps({ res }) { + // Fetch all blog posts from all locales + const allPosts = []; + + for (const locale of LOCALES) { + const posts = await getContentAsBlogPosts(locale); + allPosts.push(...posts); + } + + // Generate the XML sitemap with the posts data + const sitemap = generateSiteMap(allPosts); + + res.setHeader('Content-Type', 'text/xml'); + res.write(sitemap); + res.end(); + + return { + props: {}, + }; +} diff --git a/website/postcss.config.mjs b/website/postcss.config.mjs new file mode 100644 index 0000000..c7bcb4b --- /dev/null +++ b/website/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/website/public/file.svg b/website/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/website/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/public/globe.svg b/website/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/website/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/public/next.svg b/website/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/website/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/public/og-image.jpg b/website/public/og-image.jpg new file mode 100644 index 0000000..1d053cd Binary files /dev/null and b/website/public/og-image.jpg differ diff --git a/website/public/robots.txt b/website/public/robots.txt new file mode 100644 index 0000000..e303777 --- /dev/null +++ b/website/public/robots.txt @@ -0,0 +1,25 @@ +# Allow all web crawlers +User-agent: * +Allow: / + +# Sitemap location +Sitemap: https://technotes.example.com/sitemap.xml + +# Disallow admin paths +User-agent: * +Disallow: /admin/ +Disallow: /api/ + +# Special instructions for specific bots +User-agent: Googlebot +Allow: / + +User-agent: Bingbot +Allow: / + +User-agent: Baiduspider +Disallow: / + +# Crawl-delay suggestion +User-agent: * +Crawl-delay: 10 diff --git a/website/public/sitemap.txt b/website/public/sitemap.txt new file mode 100644 index 0000000..9ef9fc0 --- /dev/null +++ b/website/public/sitemap.txt @@ -0,0 +1,10 @@ +https://technotes.example.com/en +https://technotes.example.com/vi +https://technotes.example.com/en/about +https://technotes.example.com/vi/about +https://technotes.example.com/en/blog +https://technotes.example.com/vi/blog +https://technotes.example.com/en/privacy +https://technotes.example.com/vi/privacy +https://technotes.example.com/en/terms +https://technotes.example.com/vi/terms diff --git a/website/public/vercel.svg b/website/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/website/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/public/window.svg b/website/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/website/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/app/[locale]/about/page.tsx b/website/src/app/[locale]/about/page.tsx new file mode 100644 index 0000000..6141753 --- /dev/null +++ b/website/src/app/[locale]/about/page.tsx @@ -0,0 +1,65 @@ +import { Metadata } from "next"; +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; + +export async function generateMetadata({ params }: { params: { locale: Locale } }): Promise { + const translations = await getTranslationsFromNamespaces(params.locale, ['common', 'about']); + const about = translations.about; + + return { + title: `${about.title} - ${translations.common.site.title}`, + description: translations.common.site.description, + }; +} + +interface AboutPageProps { + params: { + locale: Locale; + }; +} + +export default async function AboutPage({ params: { locale } }: AboutPageProps) { + const translations = await getTranslationsFromNamespaces(locale, ['common', 'about']); + const t = translations.common; + const about = translations.about; + + return ( +
+
+

+ {about.title} +

+ +
+

+ {about.intro} +

+ +

{about.mission.title}

+

+ {about.mission.content} +

+ +

{about.content.title}

+

+ {about.content.intro} +

+
    + {Object.entries(t.categories).map(([key, value]) => ( +
  • {value}
  • + ))} +
+ +

{about.community.title}

+

+ {about.community.content} +

+ +

{about.contact.title}

+

+ {about.contact.content} {about.contact.email}. +

+
+
+
+ ); +} diff --git a/website/src/app/[locale]/blog/[slug]/page.tsx b/website/src/app/[locale]/blog/[slug]/page.tsx new file mode 100644 index 0000000..2830411 --- /dev/null +++ b/website/src/app/[locale]/blog/[slug]/page.tsx @@ -0,0 +1,259 @@ +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; +import { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import MarkdownContent from "@/components/blog/markdown-content"; +import { getContentAsBlogPosts, findAvailableTranslations } from "@/lib/content-mapper"; +import { Globe, ChevronDown, ChevronUp, Code, CalendarClock } from "lucide-react"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import 'highlight.js/styles/github-dark.css'; +import CodeSnippet from "@/components/blog/code-snippet"; +import { generateDefaultMetadata } from '@/lib/metadata'; + +interface BlogPostPageProps { + params: { + locale: Locale; + slug: string; + }; +} + +export async function generateMetadata({ params }: BlogPostPageProps): Promise { + const locale = params.locale as Locale; + const allPosts = await getContentAsBlogPosts(params.locale); + const post = allPosts.find(post => post.slug === params.slug); + + if (!post) { + return generateDefaultMetadata({ + title: 'Post Not Found', + description: 'The blog post you are looking for does not exist.', + locale, + url: `/blog/${params.slug}`, + noIndex: true, + }); + } + + return generateDefaultMetadata({ + title: post.title, + description: post.description || `${post.title} - Tech Notes Hub`, + locale, + url: `/blog/${params.slug}`, + ogImage: post.coverImage || '/og-image.jpg', + }); +} + +export async function generateStaticParams() { + // Generate params for all locales and posts + const locales: Locale[] = ['vi', 'en']; + const params = []; + + for (const locale of locales) { + const posts = await getContentAsBlogPosts(locale); + const localeParams = posts.map(post => ({ + locale, + slug: post.slug, + })); + params.push(...localeParams); + } + + return params; +} + +export default async function BlogPostPage({ + params +}: { + params: { locale: Locale; slug: string } +}) { + const allPosts = await getContentAsBlogPosts(params.locale); + const post = allPosts.find(post => post.slug === params.slug); + + // Get translations + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + const t = translations.common; + + if (!post) { + notFound(); + } + + // Find available translations for this post + const availableTranslations = await findAvailableTranslations(params.slug); + + // Get translated category name if available + const categoryKey = post.category.toLowerCase().replace(/\s+/g, '-') as keyof typeof t.categories; + const translatedCategory = t.categories[categoryKey] || post.category; + + // Get translated source type if available + const sourceTypeKey = post.sourceType as keyof typeof t.blog.sourceTypes | undefined; + const translatedSourceType = sourceTypeKey && t.blog.sourceTypes[sourceTypeKey] + ? t.blog.sourceTypes[sourceTypeKey] + : post.sourceType; + + // Format dates according to locale + const dateFormatter = new Intl.DateTimeFormat(params.locale === 'vi' ? 'vi-VN' : 'en-US', { + year: 'numeric', + month: 'long', + day: 'numeric' + }); + + const publishDate = post.date ? dateFormatter.format(new Date(post.date)) : ''; + const updateDate = post.update ? dateFormatter.format(new Date(post.update)) : ''; + + // Add debug information for development + const debugInfo = process.env.NODE_ENV === 'development' && ( +
+

Debug Info:

+
Current Slug: {params.slug}
+
Current Locale: {params.locale}
+
Source Type: {post.sourceType}
+
Source Path: {post.sourcePath}
+
Relative Path: {post.relativePath}
+
Date: {post.date}
+
Update: {post.update}
+
+ Available Translations: +
+          {JSON.stringify(availableTranslations, null, 2)}
+        
+
+ {post.relatedSnippets && ( +
+ Related Snippets: +
+            {JSON.stringify(post.relatedSnippets.map((s) => s.filename), null, 2)}
+          
+
+ )} +
+ ); + + return ( +
+
+ + + + + {availableTranslations.length > 1 && ( +
+ + {t.blog.translatedContent}: +
+ {availableTranslations.map(translation => ( + + {t.languages[translation.locale as keyof typeof t.languages] || translation.locale.toUpperCase()} + + ))} +
+
+ )} +
+ +
+

+ {post.title} +

+
+ {`${t.blog.publishedOn} ${publishDate}`} + + {`${t.blog.by} ${post.author}`} + + {translatedCategory} + {post.sourceType && ( + <> + + {translatedSourceType} + + )} +
+ + {post.update && ( +
+ + {`${t.blog.lastUpdated || 'Last updated'}: ${updateDate}`} +
+ )} +
+ +
+ {post.coverImage && ( +
+ {post.title} +
+ )} + + + + {post.relatedSnippets && post.relatedSnippets.length > 0 && ( +
+
+ +

{t.blog.codeSnippets}

+
+ + + {post.relatedSnippets.map((snippet, index) => ( + + +
+ {snippet.filename} + + {snippet.language} + +
+
+ +
+ +
+
+
+ ))} +
+
+ )} + +
+

{t.blog.tags}:

+
+ {post.tags.map(tag => ( + + {tag} + + ))} +
+
+ + {post.sourcePath && ( +
+

{t.blog.source}:

+

+ {t.blog.sourcedFrom}: {post.sourcePath.split('/').slice(-3).join('/')} +

+
+ )} + + {process.env.NODE_ENV === 'development' && debugInfo} +
+
+ ); +} diff --git a/website/src/app/[locale]/blog/page.tsx b/website/src/app/[locale]/blog/page.tsx new file mode 100644 index 0000000..0d5925f --- /dev/null +++ b/website/src/app/[locale]/blog/page.tsx @@ -0,0 +1,272 @@ +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; +import { Metadata } from "next"; +import { getContentAsBlogPosts, getCategoriesWithCounts, CATEGORY_SLUGS } from "@/lib/content-mapper"; +import BlogCategoryFilter from "@/components/blog/category-filter"; +import { notFound } from "next/navigation"; +import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react"; +import Search from "@/components/search"; + +export async function generateMetadata({ params }: { params: { locale: Locale } }): Promise { + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + + return { + title: `${translations.common.nav.blog} - ${translations.common.site.title}`, + description: translations.common.site.description, + }; +} + +interface BlogPageProps { + params: { + locale: Locale; + }; + searchParams?: { + category?: string; + page?: string; + } +} + +const POSTS_PER_PAGE = 20; + +export default async function BlogPage({ params, searchParams }: BlogPageProps) { + const { locale } = params; + const selectedCategory = searchParams?.category || ''; + const currentPage = searchParams?.page ? parseInt(searchParams.page) : 1; + + // Get translations + const translations = await getTranslationsFromNamespaces(locale, ['common']); + const t = translations.common; + + // Get blog posts with the appropriate locale + const blogPosts = await getContentAsBlogPosts(locale); + + // Debug logging + if (process.env.NODE_ENV === 'development') { + console.log(`Total blog posts for locale ${locale}: ${blogPosts.length}`); + console.log(`Selected category: "${selectedCategory}"`); + + // Log all categories found in posts + const allCategories = new Set(blogPosts.map(post => post.category)); + console.log('Available categories in posts:', Array.from(allCategories)); + + // Log posts with design-patterns category + const designPatternPosts = blogPosts.filter(post => + post.category.toLowerCase() === 'design-patterns' || + post.category.toLowerCase() === 'design patterns' + ); + console.log(`Design pattern posts: ${designPatternPosts.length}`); + designPatternPosts.forEach(post => { + console.log(`- ${post.title} (category: "${post.category}", slug: ${post.slug})`); + }); + } + + // Filter by category if specified + const filteredPosts = selectedCategory + ? blogPosts.filter(post => { + const postCategory = post.category; + const postCategorySlug = CATEGORY_SLUGS[postCategory as keyof typeof CATEGORY_SLUGS] || + post.category.toLowerCase().replace(/\s+/g, '-'); + const searchCategory = selectedCategory.toLowerCase(); + + // Match by category slug, category name, or tags + const matchCategorySlug = postCategorySlug.toLowerCase() === searchCategory; + const matchCategoryName = post.category.toLowerCase() === searchCategory; + const matchCategoryNameWithDash = post.category.toLowerCase().replace(/\s+/g, '-') === searchCategory; + const matchTags = post.tags.some(tag => tag.toLowerCase() === searchCategory); + + if (process.env.NODE_ENV === 'development' && selectedCategory.toLowerCase() === 'design-patterns') { + console.log(`Post "${post.title}" - category: "${post.category}", slug: "${postCategorySlug}"`); + console.log(`Matches: slug=${matchCategorySlug}, name=${matchCategoryName}, name-dash=${matchCategoryNameWithDash}, tags=${matchTags}`); + } + + return matchCategorySlug || matchCategoryName || matchCategoryNameWithDash || matchTags; + }) + : blogPosts; + + // Pagination + const totalPosts = filteredPosts.length; + const totalPages = Math.ceil(totalPosts / POSTS_PER_PAGE); + const paginatedPosts = filteredPosts.slice( + (currentPage - 1) * POSTS_PER_PAGE, + currentPage * POSTS_PER_PAGE + ); + + // Get categories with counts for the sidebar + const categories = await getCategoriesWithCounts(locale); + + if (blogPosts.length === 0) { + return notFound(); + } + + // Map category names to translated versions + const translatedCategories = categories.map(category => ({ + ...category, + name: t.categories[category.id as keyof typeof t.categories] || category.name + })); + + // Generate pagination URL + const getPaginationUrl = (page: number) => { + const baseUrl = `/${locale}/blog`; + const categoryParam = selectedCategory ? `category=${selectedCategory}` : ''; + const pageParam = page > 1 ? `page=${page}` : ''; + + if (categoryParam && pageParam) { + return `${baseUrl}?${categoryParam}&${pageParam}`; + } else if (categoryParam) { + return `${baseUrl}?${categoryParam}`; + } else if (pageParam) { + return `${baseUrl}?${pageParam}`; + } + return baseUrl; + }; + + return ( +
+
+

+ {t.nav.blog} +

+

+ {t.site.description} +

+
+ +
+
+ +
+ + +
+ {paginatedPosts.length === 0 ? ( +
+

{t.blog.noPostsFound}

+

+ {t.blog.tryDifferentCategory} +

+
+ ) : ( + <> +
+ {paginatedPosts.map(post => { + // Get translated category name if available + const categoryKey = post.category.toLowerCase().replace(/\s+/g, '-') as keyof typeof t.categories; + const translatedCategory = t.categories[categoryKey] || post.category; + + // Get translated source type if available + const sourceTypeKey = post.sourceType as keyof typeof t.blog.sourceTypes | undefined; + const translatedSourceType = sourceTypeKey && t.blog.sourceTypes[sourceTypeKey] + ? t.blog.sourceTypes[sourceTypeKey] + : post.sourceType; + + return ( + + + {post.title} + + {`${t.blog.publishedOn} ${new Date(post.date).toLocaleDateString(locale === 'vi' ? 'vi-VN' : 'en-US')}`} | {translatedCategory} + + + +

{post.description}

+
+ {post.tags.map(tag => ( + + {tag} + + ))} +
+ {post.sourceType && ( +
+ + {translatedSourceType} + +
+ )} +
+ + + + + +
+ ); + })} +
+ + {/* Pagination */} + {totalPages > 1 && ( +
+ +
+ )} + + {/* Post count information */} +
+ {t.blog.showing} {(currentPage - 1) * POSTS_PER_PAGE + 1}- + {Math.min(currentPage * POSTS_PER_PAGE, totalPosts)} {t.blog.of} {totalPosts} {t.blog.posts} +
+ + )} +
+
+
+ ); +} diff --git a/website/src/app/[locale]/layout.tsx b/website/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..b862cf5 --- /dev/null +++ b/website/src/app/[locale]/layout.tsx @@ -0,0 +1,99 @@ +import { Metadata } from "next"; +import { defaultLocale, getTranslationsFromNamespaces, Locale, locales } from "@/lib/i18n/settings"; +import Header from "@/components/layout/header"; +import { Footer } from "@/components/layout/footer"; + +export async function generateMetadata({ params }: { params: { locale: string } }): Promise { + const locale = params.locale as Locale || defaultLocale; + const translations = await getTranslationsFromNamespaces(locale, ['common']); + + // Access the description directly from translations object as unknown type + const commonTranslations = translations.common as any; + const description = commonTranslations?.meta?.description || + commonTranslations?.site?.description || + 'A collection of tech notes and snippets'; + + return { + title: { + template: '%s - Tech Notes Hub', + default: 'Tech Notes Hub', + }, + description: description, + icons: { + icon: '/favicon.ico', + apple: '/apple-touch-icon.png', + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-video-preview': -1, + 'max-image-preview': 'large', + 'max-snippet': -1, + }, + }, + openGraph: { + title: 'Tech Notes Hub', + description: description, + url: `https://technotes.example.com/${locale}`, + siteName: 'Tech Notes Hub', + locale: locale, + type: 'website', + images: [ + { + url: 'https://technotes.example.com/og-image.jpg', + width: 1200, + height: 630, + alt: 'Tech Notes Hub', + }, + ], + }, + twitter: { + card: 'summary_large_image', + title: 'Tech Notes Hub', + description: description, + creator: '@technotes', + }, + alternates: { + canonical: `https://technotes.example.com/${locale}`, + languages: { + en: 'https://technotes.example.com/en', + vi: 'https://technotes.example.com/vi', + }, + }, + }; +} + +export function generateStaticParams() { + return locales.map((locale) => ({ locale })); +} + +interface RootLayoutProps { + children: React.ReactNode; + params: { + locale: string; + }; +} + +export default async function RootLayout({ + children, + params, +}: RootLayoutProps) { + // Make sure params.locale is set to default if it doesn't exist + const locale = (params?.locale as Locale) || defaultLocale; + + // Ensure getTranslationsFromNamespaces is awaited + const translations = await getTranslationsFromNamespaces(locale, ['common']); + + return ( +
+
+
+ {children} +
+
+
+ ); +} diff --git a/website/src/app/[locale]/page.tsx b/website/src/app/[locale]/page.tsx new file mode 100644 index 0000000..73d2355 --- /dev/null +++ b/website/src/app/[locale]/page.tsx @@ -0,0 +1,125 @@ +import Link from "next/link"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; +import { Metadata } from "next"; +import { getContentAsBlogPosts } from "@/lib/content-mapper"; + +export async function generateMetadata({ params }: { params: { locale: Locale } }): Promise { + const translations = await getTranslationsFromNamespaces(params.locale, ['common', 'home']); + + return { + title: translations.common.site.title, + description: translations.common.site.description, + }; +} + +interface HomePageProps { + params: { + locale: Locale; + }; +} + +export default async function HomePage({ params }: HomePageProps) { + const { locale } = params; + + // Get translations for home page + const translations = await getTranslationsFromNamespaces(locale, ['common', 'home']); + const t = translations.home; + const commonT = translations.common; + + // Get featured blog posts + const allPosts = await getContentAsBlogPosts(locale); + const featuredPosts = allPosts.slice(0, 6); // Get first 6 posts + + return ( +
+ {/* Hero Section */} +
+
+
+

+ {t.hero.title} +

+

+ {t.hero.description} +

+
+ + + + + + +
+
+
+
+ + {/* Featured Topics Section */} +
+
+
+

{t.featuredTopics.title}

+

+ {t.featuredTopics.description} +

+
+ +
+ {featuredPosts.map((post) => ( + + + {post.title} + + +

{post.description}

+
+ + + + + +
+ ))} +
+ +
+ + + +
+
+
+
+ ); +} + +const featuredTopics = [ + { + id: "web-development", + title: "Web Development", + description: "Frontend and backend technologies", + content: "Explore modern web development techniques, frameworks, and best practices for building responsive and scalable applications." + }, + { + id: "devops", + title: "DevOps", + description: "Continuous integration and deployment", + content: "Learn about DevOps methodologies, tools, and practices to improve collaboration between development and operations teams." + }, + { + id: "data-science", + title: "Data Science", + description: "Data analysis and machine learning", + content: "Dive into data science concepts, machine learning algorithms, and practical applications for extracting insights from data." + }, +]; diff --git a/website/src/app/[locale]/privacy/page.tsx b/website/src/app/[locale]/privacy/page.tsx new file mode 100644 index 0000000..4fd9cb0 --- /dev/null +++ b/website/src/app/[locale]/privacy/page.tsx @@ -0,0 +1,71 @@ +import { Metadata } from "next"; +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; + +export async function generateMetadata({ + params +}: { + params: { locale: Locale } +}): Promise { + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + const t = translations.common; + + return { + title: t.pages?.privacy?.title || 'Privacy Policy', + description: t.pages?.privacy?.introduction || 'Privacy policy for Tech Notes Hub', + }; +} + +export default async function PrivacyPolicyPage({ + params +}: { + params: { locale: Locale } +}) { + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + const t = translations.common; + + return ( +
+

+ {t.pages?.privacy?.title || 'Privacy Policy'} +

+ +
+ {t.pages?.privacy?.lastUpdated || 'Last Updated'}: {new Date('2025-06-06').toLocaleDateString(params.locale)} +
+ +
+

+ {t.pages?.privacy?.introduction || 'This Privacy Policy describes how we collect, use, and share your personal information.'} +

+ +

+ {t.pages?.privacy?.informationWeCollect || 'Information We Collect'} +

+

+ {t.pages?.privacy?.informationWeCollectText || 'When you visit our website, we may collect certain information about your device.'} +

+ +

+ {t.pages?.privacy?.howWeUseInformation || 'How We Use Your Information'} +

+

+ {t.pages?.privacy?.howWeUseInformationText || 'We use the information we collect to improve and optimize our website.'} +

+ +

+ {t.pages?.privacy?.sharingYourInformation || 'Sharing Your Information'} +

+

+ {t.pages?.privacy?.sharingYourInformationText || 'We do not share your personal information with third parties.'} +

+ +

+ {t.pages?.privacy?.yourRights || 'Your Rights'} +

+

+ {t.pages?.privacy?.yourRightsText || 'You have the right to access personal information we hold about you.'} +

+
+
+ ); +} diff --git a/website/src/app/[locale]/terms/page.tsx b/website/src/app/[locale]/terms/page.tsx new file mode 100644 index 0000000..b428046 --- /dev/null +++ b/website/src/app/[locale]/terms/page.tsx @@ -0,0 +1,78 @@ +import { Metadata } from "next"; +import { Locale, getTranslationsFromNamespaces } from "@/lib/i18n/settings"; + +export async function generateMetadata({ + params +}: { + params: { locale: Locale } +}): Promise { + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + const t = translations.common; + + return { + title: t.pages?.terms?.title || 'Terms of Service', + description: t.pages?.terms?.introduction || 'Terms of service for Tech Notes Hub', + }; +} + +export default async function TermsOfServicePage({ + params +}: { + params: { locale: Locale } +}) { + const translations = await getTranslationsFromNamespaces(params.locale, ['common']); + const t = translations.common; + + return ( +
+

+ {t.pages?.terms?.title || 'Terms of Service'} +

+ +
+ {t.pages?.terms?.lastUpdated || 'Last Updated'}: {new Date('2025-06-06').toLocaleDateString(params.locale)} +
+ +
+

+ {t.pages?.terms?.introduction || 'These Terms of Service govern your access to and use of our website.'} +

+ +

+ {t.pages?.terms?.acceptance || 'Acceptance of Terms'} +

+

+ {t.pages?.terms?.acceptanceText || 'By accessing or using our website, you agree to be bound by these Terms.'} +

+ +

+ {t.pages?.terms?.intellectualProperty || 'Intellectual Property'} +

+

+ {t.pages?.terms?.intellectualPropertyText || 'The content on our website is owned by us and protected by intellectual property laws.'} +

+ +

+ {t.pages?.terms?.userConduct || 'User Conduct'} +

+

+ {t.pages?.terms?.userConductText || 'You agree not to use our website for any illegal or unauthorized purpose.'} +

+ +

+ {t.pages?.terms?.disclaimer || 'Disclaimer'} +

+

+ {t.pages?.terms?.disclaimerText || 'Our website is provided "as is" without any warranties.'} +

+ +

+ {t.pages?.terms?.limitationOfLiability || 'Limitation of Liability'} +

+

+ {t.pages?.terms?.limitationOfLiabilityText || 'We will not be liable for any damages arising from the use of our website.'} +

+
+
+ ); +} diff --git a/website/src/app/api/robots.txt/route.ts b/website/src/app/api/robots.txt/route.ts new file mode 100644 index 0000000..5441d71 --- /dev/null +++ b/website/src/app/api/robots.txt/route.ts @@ -0,0 +1,37 @@ +const WEBSITE_URL = 'https://technotes.example.com'; + +export async function GET() { + const robotsTxt = ` +# Allow all web crawlers +User-agent: * +Allow: / + +# Sitemap location +Sitemap: ${WEBSITE_URL}/api/sitemap.xml + +# Disallow admin paths +User-agent: * +Disallow: /admin/ +Disallow: /api/ + +# Special instructions for specific bots +User-agent: Googlebot +Allow: / + +User-agent: Bingbot +Allow: / + +User-agent: Baiduspider +Disallow: / + +# Crawl-delay suggestion +User-agent: * +Crawl-delay: 10 +`.trim(); + + return new Response(robotsTxt, { + headers: { + 'Content-Type': 'text/plain', + }, + }); +} diff --git a/website/src/app/api/sitemap.xml/route.ts b/website/src/app/api/sitemap.xml/route.ts new file mode 100644 index 0000000..c33dcbc --- /dev/null +++ b/website/src/app/api/sitemap.xml/route.ts @@ -0,0 +1,143 @@ +import { getContentAsBlogPosts } from '@/lib/content-mapper'; +import { locales } from '@/lib/i18n/settings'; + +const WEBSITE_URL = 'https://technotes.example.com'; + +export async function GET() { + // Fetch all blog posts from all locales + const allPosts = []; + + for (const locale of locales) { + const posts = await getContentAsBlogPosts(locale); + allPosts.push(...posts); + } + + // Generate the XML sitemap with the posts data + const sitemap = generateSiteMap(allPosts); + + return new Response(sitemap, { + headers: { + 'Content-Type': 'text/xml', + }, + }); +} + +function generateSiteMap(posts: any[]) { + return ` + + + ${locales.map(locale => ` + + ${WEBSITE_URL}/${locale} + ${new Date().toISOString().split('T')[0]} + daily + 1.0 + ${locales.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${locales.map(locale => ` + + ${WEBSITE_URL}/${locale}/about + ${new Date().toISOString().split('T')[0]} + monthly + 0.8 + ${locales.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${locales.map(locale => ` + + ${WEBSITE_URL}/${locale}/privacy + ${new Date().toISOString().split('T')[0]} + monthly + 0.5 + ${locales.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${locales.map(locale => ` + + ${WEBSITE_URL}/${locale}/terms + ${new Date().toISOString().split('T')[0]} + monthly + 0.5 + ${locales.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${locales.map(locale => ` + + ${WEBSITE_URL}/${locale}/blog + ${new Date().toISOString().split('T')[0]} + daily + 0.9 + ${locales.map(altLocale => ` + + `).join('')} + + `).join('')} + + + ${posts.map(post => { + // Find translations for this post + const translations = posts.filter(p => + p.slug !== post.slug && + p.relativePath === post.relativePath + ); + + return ` + + ${WEBSITE_URL}/${post.language}/blog/${post.slug} + ${post.date || new Date().toISOString().split('T')[0]} + weekly + 0.7 + ${ + // Add links to translations if they exist + translations.map(translation => ` + + `).join('') + } + + `; + }).join('')} + + `; +} diff --git a/website/src/app/favicon.ico b/website/src/app/favicon.ico new file mode 100644 index 0000000..1d053cd Binary files /dev/null and b/website/src/app/favicon.ico differ diff --git a/website/src/app/globals.css b/website/src/app/globals.css new file mode 100644 index 0000000..28a8bb5 --- /dev/null +++ b/website/src/app/globals.css @@ -0,0 +1,241 @@ +@import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 5.9% 10%; + --radius: 0.5rem; + } + + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +/* Code block styling */ +.prose pre { + @apply bg-slate-950 text-slate-50 border border-slate-800; +} + +.prose code { + @apply text-slate-50; +} + +.prose .hljs { + @apply bg-transparent; +} + +/* Improve contrast for inline code */ +.prose :not(pre) > code { + @apply bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 px-1.5 py-0.5 rounded text-sm font-medium; +} + +/* Special styling for code blocks with specific languages */ +.prose pre code.language-bash::before, +.prose pre code.language-sh::before { + content: "$ "; + @apply text-slate-500; +} + +.prose pre code.language-env::before { + content: ""; +} + +/* Environment variable styling */ +.prose pre code.language-env .hljs-attr { + @apply text-green-400; +} + +.prose pre code.language-env .hljs-string { + @apply text-yellow-400; +} + +/* Add special styling for .env files */ +.prose pre.language-env, +.prose code.language-env { + @apply bg-slate-950 text-slate-100; +} + +/* Enhance visibility of environment variables */ +.language-env .hljs-name, +.language-env .hljs-attr { + @apply text-emerald-400 font-semibold; +} + +.language-env .hljs-string, +.language-env .hljs-value { + @apply text-amber-400; +} + +/* Special styling for comments in code */ +.hljs-comment { + @apply text-slate-500 italic; +} + +/* Heading link hover effect */ +.prose h1:hover .absolute, +.prose h2:hover .absolute, +.prose h3:hover .absolute, +.prose h4:hover .absolute { + @apply opacity-100; +} diff --git a/website/src/app/layout.tsx b/website/src/app/layout.tsx new file mode 100644 index 0000000..cca6ff7 --- /dev/null +++ b/website/src/app/layout.tsx @@ -0,0 +1,34 @@ +import "./globals.css"; +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import { ThemeProvider } from "@/components/layout/theme-provider"; +import { Toaster } from "sonner"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Tech Notes Hub", + description: "Center for sharing tech knowledge and technical guides", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + {children} + + + + + ); +} diff --git a/website/src/app/page.tsx b/website/src/app/page.tsx new file mode 100644 index 0000000..e68abe6 --- /dev/null +++ b/website/src/app/page.tsx @@ -0,0 +1,103 @@ +import Image from "next/image"; + +export default function Home() { + return ( +
+
+ Next.js logo +
    +
  1. + Get started by editing{" "} + + src/app/page.tsx + + . +
  2. +
  3. + Save and see your changes instantly. +
  4. +
+ + +
+ +
+ ); +} diff --git a/website/src/components/blog/category-filter.tsx b/website/src/components/blog/category-filter.tsx new file mode 100644 index 0000000..aec72ef --- /dev/null +++ b/website/src/components/blog/category-filter.tsx @@ -0,0 +1,48 @@ +"use client"; + +import { Category } from "@/lib/types"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; +import { Locale } from "@/lib/i18n/settings"; + +interface BlogCategoryFilterProps { + categories: (Category & { count: number })[]; + selectedCategory: string; + locale: Locale; + allCategoriesLabel?: string; +} + +export default function BlogCategoryFilter({ + categories, + selectedCategory, + locale, + allCategoriesLabel = "All Categories" +}: BlogCategoryFilterProps) { + return ( +
+ + {allCategoriesLabel} + + + {categories.map((category) => ( + + {category.name} + {category.count} + + ))} +
+ ); +} diff --git a/website/src/components/blog/code-snippet.tsx b/website/src/components/blog/code-snippet.tsx new file mode 100644 index 0000000..546e4ff --- /dev/null +++ b/website/src/components/blog/code-snippet.tsx @@ -0,0 +1,85 @@ +"use client"; + +import { useState } from 'react'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { Copy, Check } from 'lucide-react'; + +interface CodeSnippetProps { + language: string; + content: string; +} + +export default function CodeSnippet({ language, content }: CodeSnippetProps) { + const [copied, setCopied] = useState(false); + + // Map common file extensions to highlight.js language names + const getLanguage = (extension: string): string => { + const langMap: Record = { + 'js': 'javascript', + 'ts': 'typescript', + 'py': 'python', + 'rb': 'ruby', + 'java': 'java', + 'cs': 'csharp', + 'cpp': 'cpp', + 'c': 'c', + 'go': 'go', + 'rs': 'rust', + 'php': 'php', + 'sh': 'bash', + 'yml': 'yaml', + 'yaml': 'yaml', + 'json': 'json', + 'md': 'markdown', + 'html': 'html', + 'css': 'css', + 'scss': 'scss', + 'sql': 'sql', + 'tsx': 'tsx', + 'jsx': 'jsx', + }; + + return langMap[extension.toLowerCase()] || extension; + }; + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(content); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy text: ', err); + } + }; + + return ( +
+ + + {content} + +
+ ); +} diff --git a/website/src/components/blog/markdown-content.tsx b/website/src/components/blog/markdown-content.tsx new file mode 100644 index 0000000..543006d --- /dev/null +++ b/website/src/components/blog/markdown-content.tsx @@ -0,0 +1,179 @@ +"use client"; + +import React, { useEffect, useState } from 'react'; +import ReactMarkdown from 'react-markdown'; +import rehypeRaw from 'rehype-raw'; +import rehypeSanitize from 'rehype-sanitize'; +import rehypeHighlight from 'rehype-highlight'; +import remarkGfm from 'remark-gfm'; +import 'highlight.js/styles/github-dark.css'; +import { slug } from 'github-slugger'; +import { Copy, Check } from 'lucide-react'; + +interface MarkdownContentProps { + content: string; +} + +export default function MarkdownContent({ content }: MarkdownContentProps) { + const [copiedCode, setCopiedCode] = useState(null); + + // Handle anchor link scrolling + useEffect(() => { + // Check if there's a hash in the URL + if (window.location.hash) { + const id = window.location.hash.substring(1); + const element = document.getElementById(id); + + if (element) { + // Wait a bit for the page to fully render + setTimeout(() => { + element.scrollIntoView({ behavior: 'smooth' }); + }, 100); + } + } + }, []); + + const handleCopyCode = async (code: string) => { + try { + await navigator.clipboard.writeText(code); + setCopiedCode(code); + setTimeout(() => setCopiedCode(null), 2000); + } catch (err) { + console.error('Failed to copy code: ', err); + } + }; + + return ( +
+ { + const headingId = slug(children as string); + return ( +

+ + + # + + {children} + +

+ ); + }, + h2: ({node, children, ...props}) => { + const headingId = slug(children as string); + return ( +

+ + + # + + {children} + +

+ ); + }, + h3: ({node, children, ...props}) => { + const headingId = slug(children as string); + return ( +

+ + + # + + {children} + +

+ ); + }, + h4: ({node, children, ...props}) => { + const headingId = slug(children as string); + return ( +

+ + + # + + {children} + +

+ ); + }, + p: ({node, ...props}) =>

, + a: ({node, href, ...props}) => { + // Check if it's an anchor link + const isAnchor = href?.startsWith('#'); + return ( + + ); + }, + ul: ({node, ...props}) =>