commit 0ef209a46be20bac59b5633c6f05c0660d0bf5df
parent 0ee4b5bf1ad266461302fd1ba6c1220f4bfed791
Author: Erik Loualiche <eloualic@umn.edu>
Date: Tue, 20 May 2025 10:56:29 -0500
First commit with code
Diffstat:
21 files changed, 4645 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
@@ -24,7 +24,6 @@ jobs:
matrix:
version:
- '1.11'
- - '1.6'
- 'pre'
os:
- ubuntu-latest
diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml
@@ -0,0 +1,57 @@
+# Sample workflow for building and deploying a VitePress site to GitHub Pages
+#
+name: Documenter
+
+on:
+ # Runs on pushes targeting the `master` branch. Change this to `main` if you're
+ # using the `main` branch as the default branch.
+ push:
+ branches:
+ - master
+ tags: ['*']
+ pull_request:
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: write
+ pages: write
+ id-token: write
+ statuses: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup Julia
+ uses: julia-actions/setup-julia@v1
+ - name: Load Julia packages from cache
+ id: julia-cache
+ uses: julia-actions/cache@v2
+ - name: Build and deploy docs
+ uses: julia-actions/julia-docdeploy@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
+ DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
+ GKSwstype: "100" # for Plots.jl plots (if you have them)
+ JULIA_DEBUG: "Documenter"
+ DATADEPS_ALWAYS_ACCEPT: true
+ - name: Save Julia depot cache on cancel or failure
+ id: julia-cache-save
+ if: cancelled() || failure()
+ uses: actions/cache/save@v4
+ with:
+ path: |
+ ${{ steps.julia-cache.outputs.cache-paths }}
+ key: ${{ steps.julia-cache.outputs.cache-key }}
diff --git a/.gitignore b/.gitignore
@@ -1 +1,13 @@
+
+# ---------------------------------------------------------
+# STANDARD JULIA IGNORE
+/Manifest.toml
/Manifest*.toml
+docs/build/
+docs/node_modules
+.DS_Store
+docs/.DS_Store
+.env
+.env.gpg
+# ---------------------------------------------------------
+
diff --git a/Project.toml b/Project.toml
@@ -3,11 +3,22 @@ uuid = "36dcebb2-80bb-4116-91f4-ed9f396c4a1c"
authors = ["Erik Loualiche"]
version = "1.0.0-DEV"
+[deps]
+Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
+Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
+LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36"
+
[compat]
+Dates = "1.11.0"
+Logging = "1.11.0"
+LoggingExtras = "1.1.0"
julia = "1.6.7"
[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
+HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
+
[targets]
-test = ["Test"]
+test = ["Test", "HTTP"]
+
diff --git a/README.md b/README.md
@@ -1,3 +1,58 @@
-# BazerUtils
+# Prototypes
-[](https://github.com/eloualiche/BazerUtils.jl/actions/workflows/CI.yml?query=branch%3Amain)
+[](https://github.com/eloualiche/Prototypes.jl/actions/workflows/CI.yml)
+
+`BazerUtils.jl` is a package that assembles various functionality that I use on a frequent basis in julia.
+It is a more mature version of [`Prototypes.jl`](https://github.com/eloualiche/Prototypes.jl) where I try a bunch of things out (there is overlap).
+
+So far the package provides a one main function:
+ - [`custom_logger`](#custom-logging) is a custom logging output that builds on the standard julia logger
+
+
+## Installation
+
+`BazerUtils.jl` is a not a registered package.
+You can install it from github via
+```julia
+import Pkg
+Pkg.add(url="https://github.com/eloualiche/BazerUtils.jl")
+```
+
+
+## Usage
+
+
+### Custom Logging
+
+This one is a little niche.
+I wanted to have a custom logger that would allow me to filter messages from specific modules and redirect them to different files, which I find useful to monitor long jobs in a format that is easy to read and that I can control.
+The formatter is hard-coded to what I like but I guess I could change it easily and make it an option.
+
+Here is an example where you can create a custom logger and redirect logging to different files.
+See the doc for more [examples](https://eloualiche.github.io/BazerUtils.jl/dev/man/logger_guide)
+```julia
+custom_logger(
+ "./log/build_stable_sample_multiplier"; # prefix of log-file being generated
+ file_loggers=[:warn, :debug], # which file logger to deploy
+
+ filtered_modules_all=[:HTTP], # filtering messages across all loggers from specific modules
+ filtered_modules_specific=[:TranscodingStreams], # filtering messages for stdout and info from specific modules
+
+ displaysize=(50,100), # how much to show
+ log_format=:log4j, # how to format the log for files
+ log_format_stdout = :pretty, # how to format the log for the repl
+
+ create_log_files=true, # if false all logs are written to a single file
+ overwrite=true, # overwrite old logs
+
+ );
+```
+
+
+## Other stuff
+
+
+See my other package
+ - [BazerData.jl](https://github.com/eloualiche/BazerData.jl) which groups together data wrangling functions.
+ - [FinanceRoutines.jl](https://github.com/eloualiche/FinanceRoutines.jl) which is more focused and centered on working with financial data.
+ - [TigerFetch.jl](https://github.com/eloualiche/TigerFetch.jl) which simplifies downloading shape files from the Census.
diff --git a/docs/Manifest.toml b/docs/Manifest.toml
@@ -0,0 +1,320 @@
+# This file is machine-generated - editing it directly is not advised
+
+julia_version = "1.11.5"
+manifest_format = "2.0"
+project_hash = "e89c0bcba17a78547342e3d4fd78c0f63c0ad74e"
+
+[[deps.ANSIColoredPrinters]]
+git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c"
+uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9"
+version = "0.0.1"
+
+[[deps.AbstractTrees]]
+git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177"
+uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
+version = "0.4.5"
+
+[[deps.ArgTools]]
+uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
+version = "1.1.2"
+
+[[deps.Artifacts]]
+uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
+version = "1.11.0"
+
+[[deps.Base64]]
+uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
+version = "1.11.0"
+
+[[deps.CodecZlib]]
+deps = ["TranscodingStreams", "Zlib_jll"]
+git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9"
+uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
+version = "0.7.8"
+
+[[deps.Dates]]
+deps = ["Printf"]
+uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
+version = "1.11.0"
+
+[[deps.DocInventories]]
+deps = ["CodecZlib", "Downloads", "TOML"]
+git-tree-sha1 = "e97cfa8680a39396924dcdca4b7ff1014ed5c499"
+uuid = "43dc2714-ed3b-44b5-b226-857eda1aa7de"
+version = "1.0.0"
+
+[[deps.DocStringExtensions]]
+git-tree-sha1 = "e7b7e6f178525d17c720ab9c081e4ef04429f860"
+uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
+version = "0.9.4"
+
+[[deps.Documenter]]
+deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"]
+git-tree-sha1 = "6c182d0bd94142d7cbc3ae8a1e74668f15d0dd65"
+uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
+version = "1.11.4"
+
+[[deps.DocumenterVitepress]]
+deps = ["ANSIColoredPrinters", "Base64", "DocInventories", "DocStringExtensions", "Documenter", "IOCapture", "Markdown", "NodeJS_20_jll", "REPL", "TOML"]
+git-tree-sha1 = "ad8874057da904afb1917557e7222b263981d2ed"
+uuid = "4710194d-e776-4893-9690-8d956a29c365"
+version = "0.2.1"
+
+ [deps.DocumenterVitepress.extensions]
+ DocumenterVitepressDocumenterCitationsExt = "DocumenterCitations"
+
+ [deps.DocumenterVitepress.weakdeps]
+ DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
+
+[[deps.Downloads]]
+deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
+uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
+version = "1.6.0"
+
+[[deps.Expat_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl"]
+git-tree-sha1 = "d55dffd9ae73ff72f1c0482454dcf2ec6c6c4a63"
+uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
+version = "2.6.5+0"
+
+[[deps.FileWatching]]
+uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
+version = "1.11.0"
+
+[[deps.Git]]
+deps = ["Git_jll", "JLLWrappers", "OpenSSH_jll"]
+git-tree-sha1 = "2230a9cc32394b11a3b3aa807a382e3bbab1198c"
+uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2"
+version = "1.4.0"
+
+[[deps.Git_jll]]
+deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"]
+git-tree-sha1 = "2f6d6f7e6d6de361865d4394b802c02fc944fc7c"
+uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb"
+version = "2.49.0+0"
+
+[[deps.IOCapture]]
+deps = ["Logging", "Random"]
+git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770"
+uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
+version = "0.2.5"
+
+[[deps.InteractiveUtils]]
+deps = ["Markdown"]
+uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
+version = "1.11.0"
+
+[[deps.JLLWrappers]]
+deps = ["Artifacts", "Preferences"]
+git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6"
+uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
+version = "1.7.0"
+
+[[deps.JSON]]
+deps = ["Dates", "Mmap", "Parsers", "Unicode"]
+git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
+uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
+version = "0.21.4"
+
+[[deps.LazilyInitializedFields]]
+git-tree-sha1 = "0f2da712350b020bc3957f269c9caad516383ee0"
+uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf"
+version = "1.3.0"
+
+[[deps.LibCURL]]
+deps = ["LibCURL_jll", "MozillaCACerts_jll"]
+uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
+version = "0.6.4"
+
+[[deps.LibCURL_jll]]
+deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
+uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
+version = "8.6.0+0"
+
+[[deps.LibGit2]]
+deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
+uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
+version = "1.11.0"
+
+[[deps.LibGit2_jll]]
+deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
+uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
+version = "1.7.2+0"
+
+[[deps.LibSSH2_jll]]
+deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
+uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
+version = "1.11.0+1"
+
+[[deps.Libdl]]
+uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
+version = "1.11.0"
+
+[[deps.Libiconv_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl"]
+git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809"
+uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
+version = "1.18.0+0"
+
+[[deps.Logging]]
+uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
+version = "1.11.0"
+
+[[deps.Markdown]]
+deps = ["Base64"]
+uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
+version = "1.11.0"
+
+[[deps.MarkdownAST]]
+deps = ["AbstractTrees", "Markdown"]
+git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899"
+uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391"
+version = "0.1.2"
+
+[[deps.MbedTLS_jll]]
+deps = ["Artifacts", "Libdl"]
+uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
+version = "2.28.6+0"
+
+[[deps.Mmap]]
+uuid = "a63ad114-7e13-5084-954f-fe012c677804"
+version = "1.11.0"
+
+[[deps.MozillaCACerts_jll]]
+uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
+version = "2023.12.12"
+
+[[deps.NetworkOptions]]
+uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
+version = "1.2.0"
+
+[[deps.NodeJS_20_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl"]
+git-tree-sha1 = "0b1b4a83773cfdefa5d9dc0322e4c0624ce88b5b"
+uuid = "c7aee132-11e1-519c-8219-0a43005e73c2"
+version = "20.12.2+0"
+
+[[deps.OpenSSH_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll", "Zlib_jll"]
+git-tree-sha1 = "cb7acd5d10aff809b4d0191dfe1956c2edf35800"
+uuid = "9bd350c2-7e96-507f-8002-3f2e150b4e1b"
+version = "10.0.1+0"
+
+[[deps.OpenSSL_jll]]
+deps = ["Artifacts", "JLLWrappers", "Libdl"]
+git-tree-sha1 = "9216a80ff3682833ac4b733caa8c00390620ba5d"
+uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
+version = "3.5.0+0"
+
+[[deps.PCRE2_jll]]
+deps = ["Artifacts", "Libdl"]
+uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15"
+version = "10.42.0+1"
+
+[[deps.Parsers]]
+deps = ["Dates", "PrecompileTools", "UUIDs"]
+git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810"
+uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
+version = "2.8.3"
+
+[[deps.Pkg]]
+deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"]
+uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
+version = "1.11.0"
+weakdeps = ["REPL"]
+
+ [deps.Pkg.extensions]
+ REPLExt = "REPL"
+
+[[deps.PrecompileTools]]
+deps = ["Preferences"]
+git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
+uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
+version = "1.2.1"
+
+[[deps.Preferences]]
+deps = ["TOML"]
+git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
+uuid = "21216c6a-2e73-6563-6e65-726566657250"
+version = "1.4.3"
+
+[[deps.Printf]]
+deps = ["Unicode"]
+uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
+version = "1.11.0"
+
+[[deps.REPL]]
+deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"]
+uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
+version = "1.11.0"
+
+[[deps.Random]]
+deps = ["SHA"]
+uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
+version = "1.11.0"
+
+[[deps.RegistryInstances]]
+deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"]
+git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51"
+uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3"
+version = "0.1.0"
+
+[[deps.SHA]]
+uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
+version = "0.7.0"
+
+[[deps.Serialization]]
+uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
+version = "1.11.0"
+
+[[deps.Sockets]]
+uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
+version = "1.11.0"
+
+[[deps.StyledStrings]]
+uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b"
+version = "1.11.0"
+
+[[deps.TOML]]
+deps = ["Dates"]
+uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
+version = "1.0.3"
+
+[[deps.Tar]]
+deps = ["ArgTools", "SHA"]
+uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
+version = "1.10.0"
+
+[[deps.Test]]
+deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
+uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
+version = "1.11.0"
+
+[[deps.TranscodingStreams]]
+git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
+uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
+version = "0.11.3"
+
+[[deps.UUIDs]]
+deps = ["Random", "SHA"]
+uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
+version = "1.11.0"
+
+[[deps.Unicode]]
+uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
+version = "1.11.0"
+
+[[deps.Zlib_jll]]
+deps = ["Libdl"]
+uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
+version = "1.2.13+1"
+
+[[deps.nghttp2_jll]]
+deps = ["Artifacts", "Libdl"]
+uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
+version = "1.59.0+0"
+
+[[deps.p7zip_jll]]
+deps = ["Artifacts", "Libdl"]
+uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
+version = "17.4.0+2"
diff --git a/docs/Project.toml b/docs/Project.toml
@@ -0,0 +1,3 @@
+[deps]
+Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
+DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365"
diff --git a/docs/make.jl b/docs/make.jl
@@ -0,0 +1,57 @@
+#!/usr/bin/env julia
+
+
+push!(LOAD_PATH, "../src/")
+# import Pkg; Pkg.develop("../src")
+# locally : julia --color=yes --project make.jl
+
+# --
+using BazerUtils
+using Documenter
+using DocumenterVitepress
+
+# --
+makedocs(
+ # format = Documenter.HTML(),
+ format = DocumenterVitepress.MarkdownVitepress(
+ repo = "https://github.com/eloualiche/BazerUtils.jl",
+ ),
+ repo = Remotes.GitHub("eloualiche", "BazerUtils.jl"),
+ sitename = "BazerUtils.jl",
+ modules = [BazerUtils],
+ authors = "Erik Loualiche",
+ pages=[
+ "Home" => "index.md",
+ "Manual" => [
+ "man/logger_guide.md",
+ ],
+ # "Demos" => [
+ # ],
+ "Library" => [
+ "lib/public.md",
+ "lib/internals.md"
+ ]
+ ]
+)
+
+
+deploydocs(;
+ repo = "github.com/eloualiche/BazerUtils.jl",
+ target = "build", # this is where Vitepress stores its output
+ devbranch = "main",
+ branch = "gh-pages",
+ push_preview = true,
+)
+
+
+# deploydocs(;
+# repo = "github.com/eloualiche/Prototypes.jl",
+# devbranch = "build",
+# )
+
+# deploydocs(;
+# repo = "github.com/eloualiche/Prototypes.jl",
+# target = "build",
+# branch = "gh-pages",
+# )
+
diff --git a/docs/package-lock.json b/docs/package-lock.json
@@ -0,0 +1,2797 @@
+{
+ "name": "docs",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "@nolebase/vitepress-plugin-enhanced-readabilities": "^2.14.0",
+ "markdown-it": "^14.1.0",
+ "markdown-it-footnote": "^4.0.0",
+ "markdown-it-mathjax3": "^4.3.2",
+ "vitepress": "^1.6.3",
+ "vitepress-plugin-tabs": "^0.6.0"
+ }
+ },
+ "node_modules/@algolia/autocomplete-core": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz",
+ "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==",
+ "dependencies": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.17.7",
+ "@algolia/autocomplete-shared": "1.17.7"
+ }
+ },
+ "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz",
+ "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "search-insights": ">= 1 < 3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz",
+ "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-shared": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz",
+ "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.25.0.tgz",
+ "integrity": "sha512-1pfQulNUYNf1Tk/svbfjfkLBS36zsuph6m+B6gDkPEivFmso/XnRgwDvjAx80WNtiHnmeNjIXdF7Gos8+OLHqQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.25.0.tgz",
+ "integrity": "sha512-AFbG6VDJX/o2vDd9hqncj1B6B4Tulk61mY0pzTtzKClyTDlNP0xaUiEKhl6E7KO9I/x0FJF5tDCm0Hn6v5x18A==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.25.0.tgz",
+ "integrity": "sha512-il1zS/+Rc6la6RaCdSZ2YbJnkQC6W1wiBO8+SH+DE6CPMWBU6iDVzH0sCKSAtMWl9WBxoN6MhNjGBnCv9Yy2bA==",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.25.0.tgz",
+ "integrity": "sha512-blbjrUH1siZNfyCGeq0iLQu00w3a4fBXm0WRIM0V8alcAPo7rWjLbMJMrfBtzL9X5ic6wgxVpDADXduGtdrnkw==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.25.0.tgz",
+ "integrity": "sha512-aywoEuu1NxChBcHZ1pWaat0Plw7A8jDMwjgRJ00Mcl7wGlwuPt5dJ/LTNcg3McsEUbs2MBNmw0ignXBw9Tbgow==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.25.0.tgz",
+ "integrity": "sha512-a/W2z6XWKjKjIW1QQQV8PTTj1TXtaKx79uR3NGBdBdGvVdt24KzGAaN7sCr5oP8DW4D3cJt44wp2OY/fZcPAVA==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.25.0.tgz",
+ "integrity": "sha512-9rUYcMIBOrCtYiLX49djyzxqdK9Dya/6Z/8sebPn94BekT+KLOpaZCuc6s0Fpfq7nx5J6YY5LIVFQrtioK9u0g==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.25.0.tgz",
+ "integrity": "sha512-jJeH/Hk+k17Vkokf02lkfYE4A+EJX+UgnMhTLR/Mb+d1ya5WhE+po8p5a/Nxb6lo9OLCRl6w3Hmk1TX1e9gVbQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.25.0.tgz",
+ "integrity": "sha512-Ls3i1AehJ0C6xaHe7kK9vPmzImOn5zBg7Kzj8tRYIcmCWVyuuFwCIsbuIIz/qzUf1FPSWmw0TZrGeTumk2fqXg==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.25.0.tgz",
+ "integrity": "sha512-79sMdHpiRLXVxSjgw7Pt4R1aNUHxFLHiaTDnN2MQjHwJ1+o3wSseb55T9VXU4kqy3m7TUme3pyRhLk5ip/S4Mw==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.25.0.tgz",
+ "integrity": "sha512-JLaF23p1SOPBmfEqozUAgKHQrGl3z/Z5RHbggBu6s07QqXXcazEsub5VLonCxGVqTv6a61AAPr8J1G5HgGGjEw==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.25.0.tgz",
+ "integrity": "sha512-rtzXwqzFi1edkOF6sXxq+HhmRKDy7tz84u0o5t1fXwz0cwx+cjpmxu/6OQKTdOJFS92JUYHsG51Iunie7xbqfQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.25.0.tgz",
+ "integrity": "sha512-ZO0UKvDyEFvyeJQX0gmZDQEvhLZ2X10K+ps6hViMo1HgE2V8em00SwNsQ+7E/52a+YiBkVWX61pJJJE44juDMQ==",
+ "dependencies": {
+ "@algolia/client-common": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
+ "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
+ "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@docsearch/css": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz",
+ "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz",
+ "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==",
+ "dependencies": {
+ "@docsearch/react": "3.8.2",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/react": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz",
+ "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.2",
+ "algoliasearch": "^5.14.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@iconify-json/carbon": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@iconify-json/carbon/-/carbon-1.2.8.tgz",
+ "integrity": "sha512-6xh4YiFBz6qoSnB3XMe23WvjTJroDFXB17J1MbiT7nATFe+70+em1acRXr8hgP/gYpwFMHFc4IvjA/IPTPnTzg==",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify-json/icon-park-outline": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@iconify-json/icon-park-outline/-/icon-park-outline-1.2.2.tgz",
+ "integrity": "sha512-7VkMWOZTIMNkC9+oAL4I5kVlVC5Pq3nQpruZ4E3cLyKaeV95gaUrEilUkvGW71fgsFYCBWAmOZ3KpM4ux0j0zA==",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify-json/octicon": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@iconify-json/octicon/-/octicon-1.2.6.tgz",
+ "integrity": "sha512-7VlYHNjvkwAb8JGlJX+/rfmudQormGG1n8peyf+zfSnrgQOSBTTCaQIHvWjfOMsU/KRa8CZx5dvQe5dpMTHC1w==",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify-json/simple-icons": {
+ "version": "1.2.35",
+ "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.35.tgz",
+ "integrity": "sha512-PAHZZn6P5ToHMhmEeeh/O96E/Ep4PctN44N64dWYbDasEvbVoN6x62m+Doz8au0SVS4/zYEMAsDO6TdO9ep84Q==",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="
+ },
+ "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=="
+ },
+ "node_modules/@nolebase/ui": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/@nolebase/ui/-/ui-2.17.0.tgz",
+ "integrity": "sha512-t0zr9FiUMju7W/iL/BzX+JuZZz0UgAC1ZMN4VKAOtRIUaQhPjE3LZMqfOrrsWhKNT8uTY7CVIcIzSulPuAe1og==",
+ "dependencies": {
+ "@iconify-json/octicon": "^1.2.5",
+ "less": "^4.3.0",
+ "vue": "^3.5.13"
+ },
+ "peerDependencies": {
+ "vitepress": "^1.5.0 || ^2.0.0-alpha.1"
+ }
+ },
+ "node_modules/@nolebase/vitepress-plugin-enhanced-readabilities": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/@nolebase/vitepress-plugin-enhanced-readabilities/-/vitepress-plugin-enhanced-readabilities-2.17.0.tgz",
+ "integrity": "sha512-3vSSK/sz9X3pnLFxch7o/WdQ7wOtxun16Jw6OnYxyS7tmGc7oLhR1GJaGBMkGCIkz8RX0Dwic4+HaExWZBPM/A==",
+ "dependencies": {
+ "@iconify-json/carbon": "^1.2.8",
+ "@iconify-json/icon-park-outline": "^1.2.2",
+ "@nolebase/ui": "^2.17.0",
+ "less": "^4.3.0"
+ },
+ "peerDependencies": {
+ "vitepress": "^1.5.0 || ^2.0.0-alpha.1"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.0.tgz",
+ "integrity": "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.0.tgz",
+ "integrity": "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.0.tgz",
+ "integrity": "sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.0.tgz",
+ "integrity": "sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.0.tgz",
+ "integrity": "sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.0.tgz",
+ "integrity": "sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.0.tgz",
+ "integrity": "sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.0.tgz",
+ "integrity": "sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.0.tgz",
+ "integrity": "sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.0.tgz",
+ "integrity": "sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.0.tgz",
+ "integrity": "sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.0.tgz",
+ "integrity": "sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.0.tgz",
+ "integrity": "sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.0.tgz",
+ "integrity": "sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.0.tgz",
+ "integrity": "sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.0.tgz",
+ "integrity": "sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.0.tgz",
+ "integrity": "sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.0.tgz",
+ "integrity": "sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.0.tgz",
+ "integrity": "sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.0.tgz",
+ "integrity": "sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@shikijs/core": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz",
+ "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==",
+ "dependencies": {
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.4"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz",
+ "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^3.1.0"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz",
+ "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz",
+ "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz",
+ "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz",
+ "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
+ },
+ "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==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
+ },
+ "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=="
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="
+ },
+ "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=="
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.14.tgz",
+ "integrity": "sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==",
+ "dependencies": {
+ "@babel/parser": "^7.27.2",
+ "@vue/shared": "3.5.14",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.14.tgz",
+ "integrity": "sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.14",
+ "@vue/shared": "3.5.14"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.14.tgz",
+ "integrity": "sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==",
+ "dependencies": {
+ "@babel/parser": "^7.27.2",
+ "@vue/compiler-core": "3.5.14",
+ "@vue/compiler-dom": "3.5.14",
+ "@vue/compiler-ssr": "3.5.14",
+ "@vue/shared": "3.5.14",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.17",
+ "postcss": "^8.5.3",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.14.tgz",
+ "integrity": "sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.14",
+ "@vue/shared": "3.5.14"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.6",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.6.tgz",
+ "integrity": "sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.6"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.6",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.6.tgz",
+ "integrity": "sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.6",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.6",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.6.tgz",
+ "integrity": "sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.14.tgz",
+ "integrity": "sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==",
+ "dependencies": {
+ "@vue/shared": "3.5.14"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.14.tgz",
+ "integrity": "sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.14",
+ "@vue/shared": "3.5.14"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.14.tgz",
+ "integrity": "sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.14",
+ "@vue/runtime-core": "3.5.14",
+ "@vue/shared": "3.5.14",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.14.tgz",
+ "integrity": "sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.14",
+ "@vue/shared": "3.5.14"
+ },
+ "peerDependencies": {
+ "vue": "3.5.14"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.14.tgz",
+ "integrity": "sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ=="
+ },
+ "node_modules/@vueuse/core": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz",
+ "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/integrations": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz",
+ "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==",
+ "dependencies": {
+ "@vueuse/core": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz",
+ "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz",
+ "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==",
+ "dependencies": {
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz",
+ "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==",
+ "engines": {
+ "node": ">=14.6"
+ }
+ },
+ "node_modules/algoliasearch": {
+ "version": "5.25.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.25.0.tgz",
+ "integrity": "sha512-n73BVorL4HIwKlfJKb4SEzAYkR3Buwfwbh+MYxg2mloFph2fFGV58E90QTzdbfzWrLn4HE5Czx/WTjI8fcHaMg==",
+ "dependencies": {
+ "@algolia/client-abtesting": "5.25.0",
+ "@algolia/client-analytics": "5.25.0",
+ "@algolia/client-common": "5.25.0",
+ "@algolia/client-insights": "5.25.0",
+ "@algolia/client-personalization": "5.25.0",
+ "@algolia/client-query-suggestions": "5.25.0",
+ "@algolia/client-search": "5.25.0",
+ "@algolia/ingestion": "1.25.0",
+ "@algolia/monitoring": "1.25.0",
+ "@algolia/recommend": "5.25.0",
+ "@algolia/requester-browser-xhr": "5.25.0",
+ "@algolia/requester-fetch": "5.25.0",
+ "@algolia/requester-node-http": "5.25.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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=="
+ },
+ "node_modules/birpc": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz",
+ "integrity": "sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "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==",
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "dependencies": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
+ "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
+ "dependencies": {
+ "css-select": "^4.3.0",
+ "css-what": "^6.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
+ "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+ "dependencies": {
+ "is-what": "^3.14.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/dom-serializer/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex-xs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
+ "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "optional": true,
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escape-goat": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz",
+ "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/focus-trap": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.4.tgz",
+ "integrity": "sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==",
+ "dependencies": {
+ "tabbable": "^6.2.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "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==",
+ "optional": true
+ },
+ "node_modules/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/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==",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
+ },
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+ "optional": true,
+ "bin": {
+ "image-size": "bin/image-size.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
+ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
+ },
+ "node_modules/juice": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/juice/-/juice-8.1.0.tgz",
+ "integrity": "sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==",
+ "dependencies": {
+ "cheerio": "1.0.0-rc.10",
+ "commander": "^6.1.0",
+ "mensch": "^0.3.4",
+ "slick": "^1.12.2",
+ "web-resource-inliner": "^6.0.1"
+ },
+ "bin": {
+ "juice": "bin/juice"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/less": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz",
+ "integrity": "sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==",
+ "dependencies": {
+ "copy-anything": "^2.0.1",
+ "parse-node-version": "^1.0.1",
+ "tslib": "^2.3.0"
+ },
+ "bin": {
+ "lessc": "bin/lessc"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "optionalDependencies": {
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "make-dir": "^2.1.0",
+ "mime": "^1.4.1",
+ "needle": "^3.1.0",
+ "source-map": "~0.6.0"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dependencies": {
+ "uc.micro": "^2.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==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "optional": true,
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="
+ },
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it-footnote": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-4.0.0.tgz",
+ "integrity": "sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ=="
+ },
+ "node_modules/markdown-it-mathjax3": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz",
+ "integrity": "sha512-TX3GW5NjmupgFtMJGRauioMbbkGsOXAAt1DZ/rzzYmTHqzkO1rNAdiMD4NiruurToPApn2kYy76x02QN26qr2w==",
+ "dependencies": {
+ "juice": "^8.0.0",
+ "mathjax-full": "^3.2.0"
+ }
+ },
+ "node_modules/mathjax-full": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
+ "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
+ "dependencies": {
+ "esm": "^3.2.25",
+ "mhchemparser": "^4.1.0",
+ "mj-context-menu": "^0.6.1",
+ "speech-rule-engine": "^4.0.6"
+ }
+ },
+ "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==",
+ "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/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
+ },
+ "node_modules/mensch": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz",
+ "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g=="
+ },
+ "node_modules/mhchemparser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
+ "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
+ },
+ "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"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^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"
+ }
+ ]
+ },
+ "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"
+ }
+ ],
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.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"
+ }
+ ]
+ },
+ "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"
+ }
+ ]
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "optional": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minisearch": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.2.tgz",
+ "integrity": "sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA=="
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+ },
+ "node_modules/mj-context-menu": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
+ "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
+ },
+ "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"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/needle": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz",
+ "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "sax": "^1.2.4"
+ },
+ "bin": {
+ "needle": "bin/needle"
+ },
+ "engines": {
+ "node": ">= 4.4.x"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/oniguruma-to-es": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz",
+ "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==",
+ "dependencies": {
+ "emoji-regex-xs": "^1.0.0",
+ "regex": "^6.0.1",
+ "regex-recursion": "^6.0.2"
+ }
+ },
+ "node_modules/parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.26.6",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.6.tgz",
+ "integrity": "sha512-5SRRBinwpwkaD+OqlBDeITlRgvd8I8QlxHJw9AxSdMNV6O+LodN9nUyYGpSF7sadHjs6RzeFShMexC6DbtWr9g==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "optional": true
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz",
+ "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-recursion": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz",
+ "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-utilities": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
+ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
+ },
+ "node_modules/rollup": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.0.tgz",
+ "integrity": "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==",
+ "dependencies": {
+ "@types/estree": "1.0.7"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.41.0",
+ "@rollup/rollup-android-arm64": "4.41.0",
+ "@rollup/rollup-darwin-arm64": "4.41.0",
+ "@rollup/rollup-darwin-x64": "4.41.0",
+ "@rollup/rollup-freebsd-arm64": "4.41.0",
+ "@rollup/rollup-freebsd-x64": "4.41.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.41.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.41.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.41.0",
+ "@rollup/rollup-linux-arm64-musl": "4.41.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.41.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.41.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.41.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.41.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.41.0",
+ "@rollup/rollup-linux-x64-gnu": "4.41.0",
+ "@rollup/rollup-linux-x64-musl": "4.41.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.41.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.41.0",
+ "@rollup/rollup-win32-x64-msvc": "4.41.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "optional": true
+ },
+ "node_modules/sax": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+ "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
+ "optional": true
+ },
+ "node_modules/search-insights": {
+ "version": "2.17.3",
+ "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
+ "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
+ "peer": true
+ },
+ "node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/shiki": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz",
+ "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/langs": "2.5.0",
+ "@shikijs/themes": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/slick": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz",
+ "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/speech-rule-engine": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.1.2.tgz",
+ "integrity": "sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==",
+ "dependencies": {
+ "@xmldom/xmldom": "0.9.8",
+ "commander": "13.1.0",
+ "wicked-good-xpath": "1.3.0"
+ },
+ "bin": {
+ "sre": "bin/sre"
+ }
+ },
+ "node_modules/speech-rule-engine/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/superjson/node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/superjson/node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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=="
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ },
+ "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==",
+ "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==",
+ "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==",
+ "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==",
+ "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==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/valid-data-url": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz",
+ "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.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==",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.19",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
+ "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.3.tgz",
+ "integrity": "sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==",
+ "dependencies": {
+ "@docsearch/css": "3.8.2",
+ "@docsearch/js": "3.8.2",
+ "@iconify-json/simple-icons": "^1.2.21",
+ "@shikijs/core": "^2.1.0",
+ "@shikijs/transformers": "^2.1.0",
+ "@shikijs/types": "^2.1.0",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.2.1",
+ "@vue/devtools-api": "^7.7.0",
+ "@vue/shared": "^3.5.13",
+ "@vueuse/core": "^12.4.0",
+ "@vueuse/integrations": "^12.4.0",
+ "focus-trap": "^7.6.4",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.1",
+ "shiki": "^2.1.0",
+ "vite": "^5.4.14",
+ "vue": "^3.5.13"
+ },
+ "bin": {
+ "vitepress": "bin/vitepress.js"
+ },
+ "peerDependencies": {
+ "markdown-it-mathjax3": "^4",
+ "postcss": "^8"
+ },
+ "peerDependenciesMeta": {
+ "markdown-it-mathjax3": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress-plugin-tabs": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/vitepress-plugin-tabs/-/vitepress-plugin-tabs-0.6.0.tgz",
+ "integrity": "sha512-35mQUbI6lcVrLj0PpwautXm8LiV6Gz5ZDlklVRf/0KDd6gGs8HaZztqOxdffnzCiKIFLURBx930xq28it9jQTg==",
+ "peerDependencies": {
+ "vitepress": "^1.0.0",
+ "vue": "^3.3.8"
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.14",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.14.tgz",
+ "integrity": "sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.14",
+ "@vue/compiler-sfc": "3.5.14",
+ "@vue/runtime-dom": "3.5.14",
+ "@vue/server-renderer": "3.5.14",
+ "@vue/shared": "3.5.14"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/web-resource-inliner": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz",
+ "integrity": "sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "escape-goat": "^3.0.0",
+ "htmlparser2": "^5.0.0",
+ "mime": "^2.4.6",
+ "node-fetch": "^2.6.0",
+ "valid-data-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/domhandler": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
+ "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
+ "dependencies": {
+ "domelementtype": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/htmlparser2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz",
+ "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^3.3.0",
+ "domutils": "^2.4.2",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/htmlparser2?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/wicked-good-xpath": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
+ "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
+ },
+ "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==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/docs/package.json b/docs/package.json
@@ -0,0 +1,15 @@
+{
+ "scripts": {
+ "docs:dev": "vitepress dev build/.documenter",
+ "docs:build": "vitepress build build/.documenter",
+ "docs:preview": "vitepress preview build/.documenter"
+ },
+ "dependencies": {
+ "@nolebase/vitepress-plugin-enhanced-readabilities": "^2.14.0",
+ "markdown-it": "^14.1.0",
+ "markdown-it-footnote": "^4.0.0",
+ "markdown-it-mathjax3": "^4.3.2",
+ "vitepress": "^1.6.3",
+ "vitepress-plugin-tabs": "^0.6.0"
+ }
+}
diff --git a/docs/src/components/AuthorBadge.vue b/docs/src/components/AuthorBadge.vue
@@ -0,0 +1,139 @@
+<template>
+ <a
+ v-if="link"
+ :href="link"
+ class="badge-link"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ <span class="badge-container">
+ <span class="badge-label">Author</span>
+ <span class="author-badge" :style="{ backgroundColor: getColor(author) }">
+ <img :src="getAvatarUrl" :alt="author" :class="{ 'platform-avatar': !props.avatar }" class="author-avatar">
+ {{ author }}
+ </span>
+ </span>
+ </a>
+ <span v-else class="badge-container">
+ <span class="badge-label">Author</span>
+ <span class="author-badge" :style="{ backgroundColor: getColor(author) }">
+ <img :src="getAvatarUrl" :alt="author" :class="{ 'platform-avatar': !props.avatar }" class="author-avatar">
+ {{ author }}
+ </span>
+ </span>
+</template>
+
+<script setup>
+import { computed } from 'vue'
+
+const props = defineProps({
+ author: {
+ type: String,
+ required: true
+ },
+ avatar: {
+ type: String,
+ default: ''
+ },
+ platform: {
+ type: String,
+ default: 'user'
+ },
+ link: {
+ type: String,
+ default: ''
+ }
+})
+
+// Platform avatars mapping
+const platformAvatars = {
+ github: 'https://img.icons8.com/ios-filled/50/github.png',
+ gitlab: 'https://img.icons8.com/ios-filled/50/gitlab.png',
+ x: 'https://img.icons8.com/ios/50/twitterx--v2.png',
+ linkedin: 'https://img.icons8.com/ios-filled/50/linkedin.png',
+ bluesky: 'https://img.icons8.com/material-sharp/48/bluesky.png',
+ mastodon: 'https://img.icons8.com/windows/64/mastodon.png',
+ user: 'https://img.icons8.com/windows/64/user.png'
+}
+
+const getAvatarUrl = computed(() => {
+ // If custom avatar is provided, use it
+ if (props.avatar) {
+ return props.avatar
+ }
+ // If platform is specified, use platform avatar
+ if (props.platform && platformAvatars[props.platform.toLowerCase()]) {
+ return platformAvatars[props.platform.toLowerCase()]
+ }
+ // Default to user avatar
+ return platformAvatars.user
+})
+
+// Color function remains the same
+const getColor = (name) => {
+ const colors = [
+ '#3eaf7c', // green
+ '#476582', // blue
+ '#c53e3e', // red
+ '#986801', // orange
+ '#8957e5' // purple
+ ]
+ const hash = name.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
+ return colors[hash % colors.length]
+}
+</script>
+
+<style scoped>
+.badge-container {
+ display: inline-flex;
+ height: 20px;
+ line-height: 24px;
+ font-size: 12px;
+ font-weight: 500;
+ border-radius: 5px;
+ margin-right: 0.5rem;
+ margin-bottom: 0.5rem;
+ overflow: hidden;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
+ vertical-align: middle;
+}
+
+.badge-label {
+ padding: 0 8px;
+ background-color: #555;
+ color: white;
+ display: flex;
+ align-items: center;
+}
+
+.author-badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 0 8px;
+ color: white;
+}
+
+.author-avatar {
+ width: 15px;
+ height: 15px;
+ border-radius: 50%;
+ margin-right: 0.25rem;
+ margin-left: -0.25rem;
+}
+.platform-avatar {
+ filter: brightness(0) invert(1);
+}
+.badge-link {
+ text-decoration: none;
+ color: inherit;
+}
+
+.badge-link:hover .author-badge {
+ opacity: 0.9;
+}
+
+.badge-link:hover .badge-container {
+ box-shadow: 0 0 0 1.25px rgba(248, 248, 247, 0.4);
+ transition: all 0.2s ease;
+}
+</style>+
\ No newline at end of file
diff --git a/docs/src/components/Authors.vue b/docs/src/components/Authors.vue
@@ -0,0 +1,28 @@
+<template>
+ <div class="authors-container">
+ <AuthorBadge
+ v-for="author in pageAuthors"
+ :key="author.name"
+ :author="author.name"
+ :avatar="author.avatar"
+ :platform="author.platform"
+ :link="author.link"
+ />
+ </div>
+ </template>
+
+ <script setup>
+ import { useData } from 'vitepress'
+
+ const { frontmatter } = useData()
+ const pageAuthors = frontmatter.value.authors || []
+ </script>
+
+ <style scoped>
+ .authors-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin: 1rem 0;
+ }
+ </style>+
\ No newline at end of file
diff --git a/docs/src/components/VersionPicker.vue b/docs/src/components/VersionPicker.vue
@@ -0,0 +1,116 @@
+<!-- Adapted from https://github.com/MakieOrg/Makie.jl/blob/master/docs/src/.vitepress/theme/VersionPicker.vue -->
+
+<script setup lang="ts">
+import { ref, onMounted, computed} from 'vue'
+import { useData } from 'vitepress'
+import VPNavBarMenuGroup from 'vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue'
+import VPNavScreenMenuGroup from 'vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue'
+
+declare global {
+ interface Window {
+ DOC_VERSIONS?: string[];
+ DOCUMENTER_CURRENT_VERSION?: string;
+ }
+}
+
+const absoluteRoot = __DEPLOY_ABSPATH__;
+const absoluteOrigin = (typeof window === 'undefined' ? '' : window.location.origin) + absoluteRoot;
+
+const props = defineProps<{ screenMenu?: boolean }>();
+const versions = ref<Array<{ text: string, link: string, class?: string }>>([]);
+const currentVersion = ref('Versions');
+const isClient = ref(false);
+const { site } = useData();
+
+const isLocalBuild = () => {
+ return typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');
+};
+
+const waitForScriptsToLoad = () => {
+ return new Promise<boolean>((resolve) => {
+ if (isLocalBuild() || typeof window === 'undefined') {
+ resolve(false);
+ return;
+ }
+ const checkInterval = setInterval(() => {
+ if (window.DOC_VERSIONS && window.DOCUMENTER_CURRENT_VERSION) {
+ clearInterval(checkInterval);
+ resolve(true);
+ }
+ }, 100);
+ setTimeout(() => {
+ clearInterval(checkInterval);
+ resolve(false);
+ }, 5000);
+ });
+};
+
+const loadVersions = async () => {
+ if (typeof window === 'undefined') return;
+
+ try {
+ if (isLocalBuild()) {
+ versions.value = [{ text: 'dev', link: '/' }];
+ currentVersion.value = 'dev';
+ } else {
+ const scriptsLoaded = await waitForScriptsToLoad();
+
+ if (scriptsLoaded && window.DOC_VERSIONS && window.DOCUMENTER_CURRENT_VERSION) {
+ const allVersions = new Set([...window.DOC_VERSIONS, window.DOCUMENTER_CURRENT_VERSION]);
+ versions.value = Array.from(allVersions).map(v => ({
+ text: v,
+ link: `${absoluteOrigin}/${v}/`
+ }));
+ currentVersion.value = window.DOCUMENTER_CURRENT_VERSION;
+ } else {
+ versions.value = [{ text: 'dev', link: `${absoluteOrigin}/dev/` }];
+ currentVersion.value = 'dev';
+ }
+ }
+ } catch (error) {
+ console.warn('Error loading versions:', error);
+ versions.value = [{ text: 'dev', link: `${absoluteOrigin}/dev/` }];
+ currentVersion.value = 'dev';
+ }
+ isClient.value = true;
+};
+
+const versionItems = computed(() => {
+ return versions.value.map((v) => ({
+ text: v.text,
+ link: v.link
+ }));
+});
+
+onMounted(() => {
+ if (typeof window !== 'undefined') {
+ currentVersion.value = window.DOCUMENTER_CURRENT_VERSION ?? 'Versions';
+ loadVersions();
+ }
+});
+</script>
+
+<template>
+ <template v-if="isClient">
+ <VPNavBarMenuGroup
+ v-if="!screenMenu && versions.length > 0"
+ :item="{ text: currentVersion, items: versionItems }"
+ class="VPVersionPicker"
+ />
+ <VPNavScreenMenuGroup
+ v-else-if="screenMenu && versions.length > 0"
+ :text="currentVersion"
+ :items="versionItems"
+ class="VPVersionPicker"
+ />
+ </template>
+</template>
+
+<style scoped>
+.VPVersionPicker :deep(button .text) {
+ color: var(--vp-c-text-1) !important;
+}
+.VPVersionPicker:hover :deep(button .text) {
+ color: var(--vp-c-text-2) !important;
+}
+</style>+
\ No newline at end of file
diff --git a/docs/src/index.md b/docs/src/index.md
@@ -0,0 +1,4 @@
+# BazerUtils.jl
+
+Utility functions for everyday julia.
+
diff --git a/docs/src/lib/internals.md b/docs/src/lib/internals.md
@@ -0,0 +1,8 @@
+# Package Internals
+
+## `BazerUtils` Module
+
+```@autodocs
+Modules = [BazerUtils]
+Public = false
+```
diff --git a/docs/src/lib/public.md b/docs/src/lib/public.md
@@ -0,0 +1,8 @@
+# Public Interface
+
+## `BazerUtils` Module
+
+```@autodocs
+Modules = [BazerUtils]
+Private = false
+```
diff --git a/docs/src/man/logger_guide.md b/docs/src/man/logger_guide.md
@@ -0,0 +1,135 @@
+# Logging
+
+The function `custom_logger` is a wrapper over the `Logging.jl` and `LoggingExtras.jl` libraries.
+I made them such that I could fine tune the type of log I use repeatedly across projects.
+
+The things I find most useful:
+
+1. four different log files for each different level of logging from *error* to *debug*
+2. pretty (to me) formatting for stdout but also an option to have `log4j` style formatting in the files
+3. filtering out messages of verbose packages (`TranscodingStreams`, etc...) which sometimes slows down julia because of excessive logging.
+
+There are still a few things that might be useful down the line:
+(1) a catch-all log file where filters do not apply; (2) filtering out specific functions of packages;
+
+Overall this is working fine for me.
+
+## Basic usage
+
+Say at the beginning of a script you would have something like:
+```julia
+using BazerUtils
+custom_logger("/tmp/log_test";
+ filtered_modules_all=[:StatsModels, :TranscodingStreams, :Parquet2],
+ create_log_files=true,
+ overwrite=true,
+ log_format = :log4j);
+
+┌ Info: Creating four different files for logging ...
+│ ⮑ /tmp/log_test_error.log
+│ /tmp/log_test_warn.log
+│ /tmp/log_test_info.log
+└ /tmp/log_test_debug.log
+```
+
+The REPL will see all messages above debug level:
+```julia
+> @error "This is an error level message"
+┌ [08:28:08 2025-02-12] ERROR | @ Main[REPL[17]:1]
+└ This is an error level message
+
+> @warn "This is an warn level message"
+┌ [08:28:08 2025-02-12] WARN | @ Main[REPL[18]:1]
+└ This is an warn level message
+
+> @info "This is an info level message"
+┌ [08:28:08 2025-02-12] INFO | @ Main[REPL[19]:1]
+└ This is an info level message
+
+> @debug "This is an debug level message"
+
+```
+Then each of the respective log-levels will be redirected to the individual files and if the log4j option was specified they will look like something like this
+```log4j
+2025-02-12 08:28:08 ERROR Main[REPL[17]:1] - This is an error level message
+2025-02-12 08:28:08 WARN Main[REPL[18]:1] - This is an warn level message
+2025-02-12 08:28:08 INFO Main[REPL[19]:1] - This is an info level message
+2025-02-12 08:28:08 DEBUG Main[REPL[20]:1] - This is an debug level message
+```
+
+
+## Options
+
+### Formatting
+
+The `log_format` is `log4j` by default (only for the files).
+The only other option for now is `pretty` which uses the format I wrote for the REPL; note that it is a little cumbersome for files especially since you have to make sure your editor has the ansi interpreter on.
+
+### Files
+
+The default is to create one file for each level.
+There is an option to only create one file for each level and keep things a little tidier in your directories:
+```julia
+> custom_logger("/tmp/log_test";
+ create_log_files=false, overwrite=true, log_format = :log4j);
+
+┌ [08:37:03 2025-02-12] INFO | @ Prototypes[/Users/loulou/Dropbox/projects_code/julia_packages/Prototypes/src/CustomLogger.jl:44]
+│ Only one sink provided ...
+└ All logs will be written without differentiation on /tmp/log_test
+
+> @error "This is an error level message"
+> @warn "This is an warn level message"
+> @info "This is an info level message"
+> @debug "This is an debug level message"
+```
+
+And then the file `/tmp/log_test` has the following:
+```log4j
+2025-02-12 08:37:29 ERROR Main[REPL[22]:1] - This is an error level message
+2025-02-12 08:37:29 WARN Main[REPL[23]:1] - This is an warn level message
+2025-02-12 08:37:29 INFO Main[REPL[24]:1] - This is an info level message
+2025-02-12 08:37:29 DEBUG Main[REPL[25]:1] - This is an debug level message
+```
+
+Now imagine you want to keep the same log file but for a different script.
+You can use the same logger option with the `overwrite=false` option:
+```julia
+> custom_logger("/tmp/log_test";
+ create_log_files=false, overwrite=false, log_format = :log4j);
+
+> @error "This is an error level message from a different script and new logger"
+```
+
+### Filtering
+
+- `filtered_modules_specific::Vector{Symbol}=nothing`: which modules do you want to filter out of logging (only for info and stdout)
+ Some packages just write too much log ... filter them out but still be able to check them out in other logs
+- `filtered_modules_all::Vector{Symbol}=nothing`: which modules do you want to filter out of logging (across all logs)
+ Examples could be TranscodingStreams (noticed that it writes so much to logs that it sometimes slows down I/O)
+
+
+## Other
+
+For `log4j` I do modify the message string to fit on one line.
+You will find that the "\n" is now replaced by " | "; I guess I could have an option for which character delimitates lines, but this seems too fussy.
+
+I am trying to have a path shortener that would allow to reduce the path of the function to a fixed size.
+The cost is that path will no longer be "clickable" but we would keep things tidy as messages will all start at the same column.
+(see the `shorten_path_str` function).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BazerUtils.jl b/src/BazerUtils.jl
@@ -1,5 +1,25 @@
module BazerUtils
-# Write your package code here.
+
+# --------------------------------------------------------------------------------------------------
+import Dates: format, now, Dates, ISODateTimeFormat
+import Logging: global_logger, Logging, Logging.Debug, Logging.Info, Logging.Warn, AbstractLogger
+import LoggingExtras: ConsoleLogger, EarlyFilteredLogger, FileLogger, FormatLogger,
+ MinLevelLogger, TeeLogger, TransformerLogger
+
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+# Import functions
+include("CustomLogger.jl")
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+# List of exported functions
+export custom_logger
+# --------------------------------------------------------------------------------------------------
+
end
diff --git a/src/CustomLogger.jl b/src/CustomLogger.jl
@@ -0,0 +1,649 @@
+# --------------------------------------------------------------------------------------------------
+
+# CustomLogger.jl
+
+# Function to create a custom logger
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+# Exported function
+# custom_logger
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+abstract type LogSink end
+
+# Helper function to get filenames
+function get_log_filenames(filename::AbstractString;
+ file_loggers::Vector{Symbol}=[:error, :warn, :info, :debug],
+ create_files::Bool=false)
+
+ if create_files
+ files = map(f -> "$(filename)_$(string(f)).log", file_loggers)
+ # files = ["$(filename)_error.log", "$(filename)_warn.log",
+ # "$(filename)_info.log", "$(filename)_debug.log"]
+ else
+ files = repeat([filename], 4)
+ end
+ return files
+end
+
+function get_log_filenames(files::Vector{<:AbstractString})
+ length(files) > 4 && (@warn "Please provide adequate number of logs (4 for sinks)")
+ length(files) < 4 && throw(ArgumentError("Must provide at least 4 file paths"))
+ return files[1:min(4, length(files))]
+end
+
+struct FileSink <: LogSink
+ files::Vector{String}
+ ios::Vector{IO}
+
+ function FileSink(filename::AbstractString;
+ file_loggers::Vector{Symbol}=[:error, :warn, :info, :debug],
+ create_files::Bool=false)
+
+ files = get_log_filenames(filename; file_loggers=file_loggers, create_files=create_files)
+ if create_files
+ @info "Creating $(length(files)) different files for logging ... \n \u2B91\t$(join(files, "\n\t"))"
+ else
+ @info "Only one sink provided ... \n\tAll logs will be written without differentiation on $filename"
+ end
+ ios = [open(f, "a") for f in files]
+ new(files, ios)
+ end
+
+ function FileSink(files::Vector{<:AbstractString})
+ actual_files = get_log_filenames(files)
+ ios = [open(f, "a") for f in actual_files]
+ new(actual_files, ios)
+ end
+end
+
+# Add finalizer to handle cleanup
+function Base.close(sink::FileSink)
+ foreach(close, sink.ios)
+end
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+"""
+ custom_logger(filename; kw...)
+
+# Arguments
+- `filename::AbstractString`: base name for the log files
+- `output_dir::AbstractString=./log/`: name of directory where log files are written
+- `filtered_modules_specific::Vector{Symbol}=nothing`: which modules do you want to filter out of logging (only for info and stdout)
+ Some packages just write too much log ... filter them out but still be able to check them out in other logs
+- `filtered_modules_all::Vector{Symbol}=nothing`: which modules do you want to filter out of logging (across all logs)
+ Examples could be TranscodingStreams (noticed that it writes so much to logs that it sometimes slows down I/O)
+- `file_loggers::Union{Symbol, Vector{Symbol}}=[:error, :warn, :info, :debug]`: which file logger to register
+- `log_date_format::AbstractString="yyyy-mm-dd"`: time stamp format at beginning of each logged lines for dates
+- `log_time_format::AbstractString="HH:MM:SS"`: time stamp format at beginning of each logged lines for times
+- `displaysize::Tuple{Int,Int}=(50,100)`: how much to show on log (same for all logs for now!)
+- `log_format::Symbol=:log4j`: how to format the log files; I have added an option for pretty (all or nothing for now)
+- `log_format_stdout::Symbol=:pretty`: how to format the stdout; default is pretty
+- `overwrite::Bool=false`: do we overwrite previously created log files
+
+The custom_logger function creates four files in `output_dir` for four different levels of logging:
+ from least to most verbose: `filename.info.log.jl`, `filename.warn.log.jl`, `filename.debug.log.jl`, `filename.full.log.jl`
+The debug logging offers the option to filter messages from specific packages (some packages are particularly verbose) using the `filter` optional argument
+The full logging gets all of the debug without any of the filters.
+Info and warn log the standard info and warning level logging messages.
+
+Note that the default **overwrites** old log files (specify overwrite=false to avoid this).
+
+"""
+function custom_logger(
+ sink::LogSink;
+ filtered_modules_specific::Union{Nothing, Vector{Symbol}}=nothing,
+ filtered_modules_all::Union{Nothing, Vector{Symbol}}=nothing,
+ file_loggers::Union{Symbol, Vector{Symbol}}=[:error, :warn, :info, :debug],
+ log_date_format::AbstractString="yyyy-mm-dd",
+ log_time_format::AbstractString="HH:MM:SS",
+ displaysize::Tuple{Int,Int}=(50,100),
+ log_format::Symbol=:log4j,
+ log_format_stdout::Symbol=:pretty,
+ shorten_path::Symbol=:relative_path,
+ verbose::Bool=false)
+
+ # warning if some non imported get filtered ...
+ imported_modules = filter((x) -> typeof(getfield(Main, x)) <: Module && x ≠ :Main,
+ names(Main, imported=true))
+ all_filters = filter(x->!isnothing(x), unique([filtered_modules_specific; filtered_modules_all]))
+ catch_nonimported = map(x -> x ∈ imported_modules, all_filters)
+ if !(reduce(&, catch_nonimported)) && verbose
+ @warn "Some non (directly) imported modules are being filtered ... $(join(string.(all_filters[.!catch_nonimported]), ", "))"
+ end
+
+ # Filter functions
+ function create_absolute_filter(modules)
+ return function(log)
+ if isnothing(modules)
+ return true
+ else
+ module_name = string(log._module)
+ # Check if the module name starts with any of the filtered module names
+ # some modules did not get filtered because of submodules...
+ # Note: we might catch too many modules here so keep it in mind if something does not show up in log
+ for m in modules
+ if startswith(module_name, string(m))
+ return false # Filter out if matches
+ end
+ end
+ return true # Keep if no matches
+ end
+ end
+ end
+ module_absolute_message_filter = create_absolute_filter(filtered_modules_all)
+
+ function create_specific_filter(modules)
+ return function(log)
+ if isnothing(modules)
+ return true
+ else
+ module_name = string(log._module)
+ # Check if the module name starts with any of the filtered module names
+ # some modules did not get filtered because of submodules...
+ # Note: we might catch too many modules here so keep it in mind if something does not show up in log
+ for m in modules
+ if startswith(module_name, string(m))
+ return false # Filter out if matches
+ end
+ end
+ return true # Keep if no matches
+ end
+ end
+ end
+ module_specific_message_filter = create_absolute_filter(all_filters)
+
+
+ format_log_stdout = (io,log_record)->custom_format(io, log_record;
+ displaysize=displaysize,
+ log_date_format=log_date_format,
+ log_time_format=log_time_format,
+ log_format=log_format_stdout)
+
+ format_log_file = (io,log_record)->custom_format(io, log_record;
+ displaysize=displaysize,
+ log_date_format=log_date_format,
+ log_time_format=log_time_format,
+ log_format=log_format,
+ shorten_path=shorten_path)
+
+ # Create demux_logger using sink's IO streams
+ # demux_logger = TeeLogger(
+ # MinLevelLogger(
+ # EarlyFilteredLogger(module_absolute_message_filter, # error
+ # FormatLogger(format_log_file, sink.ios[1])),
+ # Logging.Error),
+ # MinLevelLogger(
+ # EarlyFilteredLogger(module_absolute_message_filter, # warn
+ # FormatLogger(format_log_file, sink.ios[2])),
+ # Logging.Warn),
+ # MinLevelLogger(
+ # EarlyFilteredLogger(module_specific_message_filter, # info
+ # FormatLogger(format_log_file, sink.ios[3])),
+ # Logging.Info),
+ # MinLevelLogger(
+ # EarlyFilteredLogger(module_absolute_message_filter, # debug
+ # FormatLogger(format_log_file, sink.ios[4])),
+ # Logging.Debug),
+ # MinLevelLogger(
+ # EarlyFilteredLogger(module_specific_message_filter, # stdout
+ # FormatLogger(format_log_stdout, stdout)),
+ # Logging.Info)
+ # )
+ demux_logger = create_demux_logger(sink, file_loggers,
+ module_absolute_message_filter, module_specific_message_filter, format_log_file, format_log_stdout)
+
+
+
+ global_logger(demux_logger)
+
+
+ return demux_logger
+end
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+# Convenience constructor that creates appropriate sink
+function custom_logger(
+ filename::Union{AbstractString, Vector{AbstractString}};
+ create_log_files::Bool=false,
+ overwrite::Bool=false,
+ create_dir::Bool=false,
+ file_loggers::Union{Symbol, Vector{Symbol}}=[:error, :warn, :info, :debug],
+ kwargs...)
+
+ file_loggers_array = file_loggers isa Symbol ? [file_loggers] : file_loggers
+
+ files = get_log_filenames(filename;
+ file_loggers=file_loggers_array, create_files=create_log_files)
+
+ # create directory if needed and bool true
+ # returns an error if directory does not exist and bool false
+ log_dir = unique(dirname.(files))
+ if create_dir && !isdir(log_dir)
+ @warn "Creating directory for logs ... $(join(log_dir, ", "))"
+ mkpath.(log_dir)
+ elseif !isdir(log_dir)
+ @error "Directory for logs does not exist ... $(join(log_dir, ", "))"
+ end
+ # Handle cleanup if needed
+ overwrite && foreach(f -> rm(f, force=true), files)
+ # Create sink
+ sink = FileSink(filename;
+ file_loggers=file_loggers_array, create_files=create_log_files)
+ # Call main logger function
+ custom_logger(sink; file_loggers=file_loggers, kwargs...)
+end
+
+
+# version for starting julia in batch mode
+function custom_logger(;
+ kwargs...)
+
+ if abspath(PROGRAM_FILE) == @__FILE__ # true if not in REPL
+ custom_logger(@__FILE__;
+ kwargs...)
+ else
+ @error "Could not get proper filename for logger ... filename = $(@__FILE__)"
+ end
+
+end
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+function create_demux_logger(sink,
+ file_loggers::Union{Symbol, Vector{Symbol}},
+ module_absolute_message_filter,
+ module_specific_message_filter,
+ format_log_file,
+ format_log_stdout)
+
+ # Convert single symbol to vector for consistency
+ loggers_to_include = file_loggers isa Symbol ? [file_loggers] : file_loggers
+
+ logger_configs = Dict(
+ :error => (1, module_absolute_message_filter, Logging.Error),
+ :warn => (2, module_absolute_message_filter, Logging.Warn),
+ :info => (3, module_specific_message_filter, Logging.Info),
+ :debug => (4, module_absolute_message_filter, Logging.Debug)
+ )
+
+ logger_list = []
+
+ io_index = 1
+ for logger_key in loggers_to_include
+ if haskey(logger_configs, logger_key)
+ if io_index > length(sink.ios)
+ error("Not enough IO streams in sink for logger: $logger_key")
+ end
+
+ _, message_filter, log_level = logger_configs[logger_key]
+
+ file_logger = MinLevelLogger(
+ EarlyFilteredLogger(message_filter,
+ FormatLogger(format_log_file, sink.ios[io_index])),
+ log_level)
+
+ push!(logger_list, file_logger)
+ io_index += 1
+ else
+ @warn "Unknown logger type: $logger_key"
+ end
+ end
+
+ # Always include stdout logger
+ stdout_logger = MinLevelLogger(
+ EarlyFilteredLogger(module_specific_message_filter,
+ FormatLogger(format_log_stdout, stdout)),
+ Logging.Info)
+
+ push!(logger_list, stdout_logger)
+
+ # Create and return the TeeLogger
+ return TeeLogger(logger_list...)
+
+end
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+# Custom format function with box-drawing characters for wrap-around effect
+# TODO should rewrite for multiple dispatch with different types for log_format
+function custom_format(io, log_record::NamedTuple;
+ displaysize::Tuple{Int,Int}=(50,100),
+ log_date_format::AbstractString="yyyy-mm-dd",
+ log_time_format::AbstractString="HH:MM:SS",
+ log_format::Symbol=:pretty, # available pretty or log4j
+ shorten_path::Symbol=:relative_path # see function below tried to emulate p10k
+ )
+
+ # -- format the message!!!
+ formatted_message = reformat_msg(log_record; displaysize=displaysize)
+
+ if log_format == :pretty
+
+ prefix_continuation_line = "│ "
+ prefix_last_line = "└ "
+
+ (first_line, message_lines) = format_pretty(log_record;
+ log_date_format=log_date_format, log_time_format=log_time_format)
+
+ println(io, "$first_line")
+ for (index, line) in enumerate(message_lines)
+ if index < length(message_lines)
+ println(io, "$prefix_continuation_line$line")
+ else # Last line
+ println(io, "$prefix_last_line$line")
+ end
+ end
+
+ elseif log_format == :log4j
+ log_entry = log_record |>
+ str -> format_log4j(str, shorten_path=shorten_path) |> msg_to_singline
+ println(io, log_entry)
+ elseif log_format == :syslog
+ log_entry = log_record |> format_syslog |> msg_to_singline
+ println(io, log_entry)
+ end
+
+
+end
+
+
+# --- general functions
+"""
+ reformat_msg
+ # we view strings as simple and everything else as complex
+"""
+function reformat_msg(log_record;
+ displaysize::Tuple{Int,Int}=(50,100),
+ log_format::Symbol=:pretty)::AbstractString
+
+ if log_record.message isa AbstractString
+ return log_record.message
+ else
+ buf = IOBuffer()
+ if log_format == :pretty
+ show(IOContext(buf, :limit=>true, :compact=>true, :color=>true, :displaysize=>displaysize),
+ "text/plain", log_record.message)
+ else # log_format == :log4j
+ show(IOContext(buf, :limit => true, :compact => true, :displaysize => (50, 100)),
+ "text/plain", log_record.message)
+ end
+ formatted_message = String(take!(buf))
+ end
+ return formatted_message
+end
+
+
+function msg_to_singline(message::AbstractString)::AbstractString
+ message |>
+ str -> replace(str, r"\"\"\"[\r\n\s]*(.+?)[\r\n\s]*\"\"\""s => s"\1") |>
+ str -> replace(str, r"\n\s*" => " | ") |>
+ str -> replace(str, r"\|\s*\|" => "|") |>
+ str -> replace(str, r"\s*\|\s*" => " | ") |>
+ str -> replace(str, r"\|\s*$" => "") |>
+ strip
+end
+
+
+# --- pretty format
+function format_pretty(log_record::NamedTuple;
+ log_date_format::AbstractString="yyyy-mm-dd",
+ log_time_format::AbstractString="HH:MM:SS",
+ )::Tuple{AbstractString, Vector{AbstractString}}
+
+ BOLD = "\033[1m"
+ EMPH = "\033[2m"
+ RESET = "\033[0m"
+ T = now()
+
+ date = format(T, log_date_format)
+ time = format(T, log_time_format)
+ timestamp = "$BOLD$time$RESET $EMPH$date$RESET" # Apply bold only to the time
+ log_level = log_record.level
+ level = string(log_level)
+ color = get_color(log_level)
+ module_name = log_record._module
+ file = log_record.file
+ line = log_record.line
+ source_info = " @ $module_name[$file:$line]"
+ # Prepare the first part of the message prefix
+ first_line = "┌ [$timestamp] $color$level\033[0m | $source_info"
+
+ formatted_message = reformat_msg(log_record, log_format=:pretty)
+
+ message_lines = split(formatted_message, "\n")
+
+ return (first_line, message_lines)
+
+end
+
+# --- log4j format
+function format_log4j(log_record::NamedTuple;
+ shorten_path::Symbol=:relative_path)::AbstractString
+
+ timestamp = format(now(), "yyyy-mm-dd HH:MM:SS")
+ log_level = rpad(uppercase(string(log_record.level)), 5)
+ module_name = nameof(log_record._module)
+ file = shorten_path_str(log_record.file; strategy=shorten_path)
+ prefix = shorten_path == :relative_path ? "[$(pwd())] " : ""
+ line = log_record.line
+ formatted_message = reformat_msg(log_record, log_format=:log4j)
+
+ log_entry = "$prefix$timestamp $log_level $module_name[$file:$line] $(replace(formatted_message, "\n" => " | "))"
+
+ return log_entry
+
+end
+
+# --- syslog format!
+# ----- for syslog mapping of severity!
+const syslog_severity_map = Dict( # look at get color to get something nicer than a string call
+ "Info" => 6, # Informational
+ "Warn" => 4, # Warning
+ "Error" => 3, # Error
+ "Debug" => 7 # Debugging
+ )
+# ----- where are the binaries!
+const julia_bin = Base.julia_cmd().exec[1]
+
+"""
+ format_syslog
+"""
+function format_syslog(log_record::NamedTuple)::AbstractString
+
+ timestamp = Dates.format(now(), ISODateTimeFormat)
+ file = log_record.file
+ severity = get(syslog_severity_map, string(log_record.level), 6) # Default to INFO
+ facility = 1 # User-level messages
+ pri = (facility * 8) + severity
+ hostname = gethostname()
+ pid = getpid()
+ # msg_id = haskey(log_record.metadata, "msg_id") ? log_record.metadata["msg_id"] : "-" # TODO
+ app_name = julia_bin
+ # msg_id = metadata["msg_id"] if haskey(metadata, "msg_id") else "-"
+ msg_id = "-"
+ # # Format structured data
+ # structured_data = ""
+ # if !isempty(metadata)
+ # structured_data = "[" * join(["exp@32473 $(k)=\"$(v)\"" for (k, v) in metadata if k != "msg_id"], " ") * "]"
+ # else
+ structured_data = "-"
+ # end
+ formatted_message = reformat_msg(log_record, log_format=:syslog)
+
+ # we put everything on one line for clear logging ...
+ log_entry = "<$pri>1 $timestamp $hostname $app_name $pid $msg_id $structured_data $(replace(formatted_message, "\n" => " | "))"
+ # Print the log entry println(io, log_entry)
+ return log_entry
+
+end
+
+# --- pretty format
+#-- colors for pretty
+function get_color(level)
+
+ RESET = "\033[0m"
+ BOLD = "\033[1m"
+ # ITALIC =
+ LIGHT_BLUE = "\033[94m"
+ RED = "\033[31m"
+ GREEN = "\033[32m"
+ YELLOW = "\033[33m"
+
+ return level == Logging.Debug ? LIGHT_BLUE : # Use light blue for Debug
+ level == Logging.Info ? GREEN :
+ level == Logging.Warn ? "$YELLOW$BOLD" :
+ level == Logging.Error ? "$RED$BOLD" :
+ RESET # Default to no specific color
+end
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+"""
+ shorten_path_str(path::AbstractString; max_length::Int=40, strategy::Symbol=:truncate_middle)
+
+Shorten a file path string to a specified maximum length using various strategies.
+
+# Arguments
+- `path::AbstractString`: The input path to be shortened
+- `max_length::Int=40`: Maximum desired length of the output path
+- `strategy::Symbol=:truncate_middle`: Strategy to use for shortening. Options:
+ * `:no`: Return path unchanged
+ * `:truncate_middle`: Truncate middle of path components while preserving start/end
+ * `:truncate_to_last`: Keep only the last n components of the path
+ * `:truncate_from_right`: Progressively remove characters from right side of components
+ * `:truncate_to_unique`: Reduce components to unique prefixes
+
+# Returns
+- `String`: The shortened path
+
+# Examples
+```julia
+# Using different strategies
+julia> shorten_path_str("/very/long/path/to/file.txt", max_length=20)
+"/very/…/path/to/file.txt"
+
+julia> shorten_path_str("/usr/local/bin/program", strategy=:truncate_to_last, max_length=20)
+"/bin/program"
+
+julia> shorten_path_str("/home/user/documents/very_long_filename.txt", strategy=:truncate_middle)
+"/home/user/doc…ents/very_…name.txt"
+```
+"""
+function shorten_path_str(path::AbstractString;
+ max_length::Int=40,
+ strategy::Symbol=:truncate_middle
+ )::AbstractString
+
+ if strategy == :no
+ return path
+ elseif strategy == :relative_path
+ return "./" * relpath(path, pwd())
+ end
+
+ # Return early if path is already short enough
+ if length(path) ≤ max_length
+ return path
+ end
+
+ # Split path into components
+ parts = split(path, '/')
+ is_absolute = startswith(path, '/')
+
+ # Handle empty path or root directory
+ if isempty(parts) || (length(parts) == 1 && isempty(parts[1]))
+ return is_absolute ? "/" : ""
+ end
+
+ # Remove empty strings from split
+ parts = filter(!isempty, parts)
+
+ if strategy == :truncate_to_last
+ # Keep only the last few components
+ n = 2 # number of components to keep
+ if length(parts) > n
+ shortened = parts[end-n+1:end]
+ result = join(shortened, "/")
+ return is_absolute ? "/$result" : result
+ end
+
+ elseif strategy == :truncate_middle
+ # For each component, truncate the middle if it's too long
+ function shorten_component(comp::AbstractString; max_comp_len::Int=10)
+ if length(comp) ≤ max_comp_len
+ return comp
+ end
+ keep = max_comp_len ÷ 2 - 1
+ return string(comp[1:keep], "…", comp[end-keep+1:end])
+ end
+
+ shortened = map(p -> shorten_component(p), parts)
+ result = join(shortened, "/")
+ if length(result) > max_length
+ # If still too long, drop some middle directories
+ middle_start = length(parts) ÷ 3
+ middle_end = 2 * length(parts) ÷ 3
+ shortened = [parts[1:middle_start]..., "…", parts[middle_end:end]...]
+ result = join(shortened, "/")
+ end
+ return is_absolute ? "/$result" : result
+
+ elseif strategy == :truncate_from_right
+ # Start removing characters from right side of each component
+ shortened = copy(parts)
+ while join(shortened, "/") |> length > max_length && any(length.(shortened) .> 3)
+ # Find longest component
+ idx = argmax(length.(shortened))
+ if length(shortened[idx]) > 3
+ shortened[idx] = shortened[idx][1:end-1]
+ end
+ end
+ result = join(shortened, "/")
+ return is_absolute ? "/$result" : result
+
+ elseif strategy == :truncate_to_unique
+ # Simplified unique prefix strategy
+ function unique_prefix(str::AbstractString, others::Vector{String}; min_len::Int=1)
+ for len in min_len:length(str)
+ prefix = str[1:len]
+ if !any(s -> s != str && startswith(s, prefix), others)
+ return prefix
+ end
+ end
+ return str
+ end
+
+ # Get unique prefixes for each component
+ shortened = String[]
+ for (i, part) in enumerate(parts)
+ if i == 1 || i == length(parts)
+ push!(shortened, part)
+ else
+ prefix = unique_prefix(part, String.(parts))
+ push!(shortened, prefix)
+ end
+ end
+
+ result = join(shortened, "/")
+ return is_absolute ? "/$result" : result
+ end
+
+ # Default fallback: return truncated original path
+ return string(path[1:max_length-3], "…")
+end
+# --------------------------------------------------------------------------------------------------
+
+
+
+
diff --git a/test/UnitTests/customlogger.jl b/test/UnitTests/customlogger.jl
@@ -0,0 +1,181 @@
+@testset "CustomLogger" begin
+
+ function get_log_names(logger_in)
+ log_paths = map(l -> l.logger.logger.stream, logger_in.loggers) |>
+ (s -> filter(x -> x isa IOStream, s)) |>
+ (s -> map(x -> x.name, s)) |>
+ (s -> map(x -> match(r"<file (.+)>", x)[1], s))
+ return unique(string.(log_paths))
+ end
+
+ function close_logger(logger::TeeLogger; remove_files::Bool=false)
+ # Get filenames before closing
+ filenames = get_log_names(logger)
+
+ # Close all IOStreams
+ for min_logger in logger.loggers
+ stream = min_logger.logger.logger.stream
+ if stream isa IOStream
+ close(stream)
+ end
+ end
+ remove_files && rm.(filenames) # Optionally remove the files
+
+ # Reset to default logger
+ global_logger(ConsoleLogger(stderr))
+ end
+
+ log_path = joinpath.(tempdir(), "log")
+
+ # -- logger with everything in one place ...
+ logger_single = custom_logger(
+ log_path;
+ overwrite=true)
+ @error "ERROR MESSAGE"
+ @warn "WARN MESSAGE"
+ @info "INFO MESSAGE"
+ @debug "DEBUG MESSAGE"
+ log_file = get_log_names(logger_single)[1]
+ log_content = read(log_file, String)
+ @test contains(log_content, "ERROR MESSAGE")
+ @test contains(log_content, "WARN MESSAGE")
+ @test contains(log_content, "INFO MESSAGE")
+ @test contains(log_content, "DEBUG MESSAGE")
+ close_logger(logger_single, remove_files=true)
+
+ # -- logger across multiple files ...
+ logger_multiple = custom_logger(
+ log_path;
+ overwrite=true, create_log_files=true)
+ log_files = get_log_names(logger_multiple)
+ @error "ERROR MESSAGE"
+ @warn "WARN MESSAGE"
+ @info "INFO MESSAGE"
+ @debug "DEBUG MESSAGE"
+ log_content = read.(log_files, String)
+ @test contains(log_content[1], "ERROR MESSAGE")
+ @test contains(log_content[2], "WARN MESSAGE")
+ @test contains(log_content[3], "INFO MESSAGE")
+ @test contains(log_content[4], "DEBUG MESSAGE")
+ rm.(log_files)
+
+ # -- logger with absolute filtering
+ logger_multiple = custom_logger(
+ log_path;
+ overwrite=true, create_log_files=true,
+ filtered_modules_all=[:HTTP],
+ ) ;
+ log_files = get_log_names(logger_multiple)
+ HTTP.get("http://example.com");
+ log_content = read.(log_files, String)
+ @test countlines(log_files[1]) == 0
+ @test countlines(log_files[2]) == 0
+ @test countlines(log_files[3]) == 0
+ @test countlines(log_files[4]) != 0 # TranscodingStreams write here
+ @test !contains(log_content[4], r"HTTP"i)
+
+ # -- logger with specific filtering
+ logger_multiple = custom_logger(
+ log_path;
+ overwrite=true, create_log_files=true,
+ filtered_modules_specific=[:HTTP],
+ filtered_modules_all=[:TranscodingStreams],
+ ) ;
+ log_files = get_log_names(logger_multiple)
+ HTTP.get("http://example.com");
+ log_content = read.(log_files, String)
+ @test countlines(log_files[1]) == 0
+ @test countlines(log_files[2]) == 0
+ @test countlines(log_files[3]) == 0; # this is getting filtered out
+ @test countlines(log_files[4]) != 0 # TranscodingStreams write here
+ @test contains(log_content[4], r"HTTP"i)
+
+
+ # -- logger with formatting
+ logger_single = custom_logger(
+ log_path;
+ log_format=:log4j,
+ overwrite=true)
+ @error "ERROR MESSAGE"
+ @warn "WARN MESSAGE"
+ @info "INFO MESSAGE"
+ @debug "DEBUG MESSAGE"
+ log_file = get_log_names(logger_single)[1]
+ log_content = read(log_file, String)
+ @test contains(log_content, r"ERROR .* ERROR MESSAGE")
+ @test contains(log_content, r"WARN .* WARN MESSAGE")
+ @test contains(log_content, r"INFO .* INFO MESSAGE")
+ @test contains(log_content, r"DEBUG .* DEBUG MESSAGE")
+ close_logger(logger_single, remove_files=true)
+
+ # -- logger with formatting and truncation
+ logger_single = custom_logger(
+ log_path;
+ log_format=:log4j,
+ shorten_path=:truncate_middle,
+ overwrite=true)
+ @error "ERROR MESSAGE"
+ @warn "WARN MESSAGE"
+ @info "INFO MESSAGE"
+ @debug "DEBUG MESSAGE"
+ HTTP.get("http://example.com");
+ log_file = get_log_names(logger_single)[1]
+ log_content = read(log_file, String)
+ # println(log_content)
+ @test contains(log_content, r"ERROR .* ERROR MESSAGE")
+ @test contains(log_content, r"WARN .* WARN MESSAGE")
+ @test contains(log_content, r"INFO .* INFO MESSAGE")
+ @test contains(log_content, r"DEBUG .* DEBUG MESSAGE")
+ @test contains(log_content, "…")
+ close_logger(logger_single, remove_files=true)
+
+ # -- syslog logger
+ logger_single = custom_logger(
+ log_path;
+ log_format=:syslog,
+ shorten_path=:truncate_middle,
+ overwrite=true)
+ @error "ERROR MESSAGE"
+ @warn "WARN MESSAGE"
+ @info "INFO MESSAGE"
+ @debug "DEBUG MESSAGE"
+ HTTP.get("http://example.com");
+ log_file = get_log_names(logger_single)[1]
+ log_content = read(log_file, String)
+ # println(log_content)
+ # we should test for the lines
+ log_lines = split(log_content, "\n")
+ @test all(map(contains("ERROR"), filter(contains("<11>"), log_lines)))
+ @test all(map(contains("WARN"), filter(contains("<12>"), log_lines)))
+ @test all(map(contains("INFO"), filter(contains("<14>"), log_lines)))
+ @test any(map(contains("DEBUG"), filter(contains("<15>"), log_lines)))
+ close_logger(logger_single, remove_files=true)
+
+ # -- logger to only one file sink
+ log_path = joinpath.(tempdir(), "log")
+ logger_single = custom_logger(
+ log_path;
+ create_log_files=true, overwrite=true,
+ file_loggers = [:debug, :info])
+ @debug "DEBUG MESSAGE"
+ @info "INFO MESSAGE"
+ log_file = get_log_names(logger_single)
+ log_content = read.(log_file, String)
+ @test contains.(log_content, r"DEBUG .* DEBUG MESSAGE") == [true, false]
+ @test contains.(log_content, r"INFO .* INFO MESSAGE") == [true, true]
+ close_logger(logger_single, remove_files=true)
+
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/runtests.jl b/test/runtests.jl
@@ -1,6 +1,27 @@
+# --------------------------------------------------------------------------------------------------
using BazerUtils
using Test
-@testset "BazerUtils.jl" begin
- # Write your tests here.
+import Logging: global_logger
+import LoggingExtras: ConsoleLogger, TeeLogger
+import HTTP
+
+const testsuite = [
+ "customlogger"
+]
+
+# --------------------------------------------------------------------------------------------------
+
+
+# --------------------------------------------------------------------------------------------------
+printstyled("Running tests:\n", color=:blue, bold=true)
+
+@testset verbose=true "BazerUtils.jl" begin
+ for test in testsuite
+ println("\033[1m\033[32m → RUNNING\033[0m: $(test)")
+ include("UnitTests/$test.jl")
+ println("\033[1m\033[32m PASSED\033[0m")
+ end
end
+# --------------------------------------------------------------------------------------------------
+