flash cards working (rudimentary)
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s

This commit is contained in:
ryan 2025-10-01 20:19:31 -07:00
parent 6ff2012e26
commit 461e6c2754
11 changed files with 664 additions and 471 deletions

431
hindki/package-lock.json generated
View File

@ -32,23 +32,23 @@
"license": "MIT"
},
"node_modules/@astrojs/internal-helpers": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.2.tgz",
"integrity": "sha512-KCkCqR3Goym79soqEtbtLzJfqhTWMyVaizUi35FLzgGSzBotSw8DB1qwsu7U96ihOJgYhDk2nVPz+3LnXPeX6g==",
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.3.tgz",
"integrity": "sha512-6Pl0bQEIChuW5wqN7jdKrzWfCscW2rG/Cz+fzt4PhSQX2ivBpnhXgFUCs0M3DCYvjYHnPVG2W36X5rmFjZ62sw==",
"license": "MIT"
},
"node_modules/@astrojs/markdown-remark": {
"version": "6.3.6",
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.6.tgz",
"integrity": "sha512-bwylYktCTsLMVoCOEHbn2GSUA3c5KT/qilekBKA3CBng0bo1TYjNZPr761vxumRk9kJGqTOtU+fgCAp5Vwokug==",
"version": "6.3.7",
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.7.tgz",
"integrity": "sha512-KXGdq6/BC18doBCYXp08alHlWChH0hdD2B1qv9wIyOHbvwI5K6I7FhSta8dq1hBQNdun8YkKPR013D/Hm8xd0g==",
"license": "MIT",
"dependencies": {
"@astrojs/internal-helpers": "0.7.2",
"@astrojs/internal-helpers": "0.7.3",
"@astrojs/prism": "3.3.0",
"github-slugger": "^2.0.0",
"hast-util-from-html": "^2.0.3",
"hast-util-to-text": "^4.0.2",
"import-meta-resolve": "^4.1.0",
"import-meta-resolve": "^4.2.0",
"js-yaml": "^4.1.0",
"mdast-util-definitions": "^6.0.0",
"rehype-raw": "^7.0.0",
@ -57,8 +57,8 @@
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.2",
"remark-smartypants": "^3.0.2",
"shiki": "^3.2.1",
"smol-toml": "^1.3.4",
"shiki": "^3.12.2",
"smol-toml": "^1.4.2",
"unified": "^11.0.5",
"unist-util-remove-position": "^5.0.0",
"unist-util-visit": "^5.0.0",
@ -67,12 +67,12 @@
}
},
"node_modules/@astrojs/mdx": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.5.tgz",
"integrity": "sha512-YB3Hhsvl1BxyY0ARe1OrnVzLNKDPXAz9epYvmL+MQ8A85duSsSLQaO3GHB6/qZJKNoLmP6PptOtCONCKkbhPeQ==",
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.6.tgz",
"integrity": "sha512-jH04tYgaqLfq3To42+z1oEcXrXUzo3BxZ4fTkb+7BEmOJkQ9/c3iIixFEC+x0GgE8lJb4SuEDGldpAv7+1yY8A==",
"license": "MIT",
"dependencies": {
"@astrojs/markdown-remark": "6.3.6",
"@astrojs/markdown-remark": "6.3.7",
"@mdx-js/mdx": "^3.1.1",
"acorn": "^8.15.0",
"es-module-lexer": "^1.7.0",
@ -107,12 +107,6 @@
"astro": "^5.7.0"
}
},
"node_modules/@astrojs/node/node_modules/@astrojs/internal-helpers": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.3.tgz",
"integrity": "sha512-6Pl0bQEIChuW5wqN7jdKrzWfCscW2rG/Cz+fzt4PhSQX2ivBpnhXgFUCs0M3DCYvjYHnPVG2W36X5rmFjZ62sw==",
"license": "MIT"
},
"node_modules/@astrojs/prism": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz",
@ -126,9 +120,9 @@
}
},
"node_modules/@astrojs/react": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.3.1.tgz",
"integrity": "sha512-Jhv35TsDHuQLvwof2z10P3g1s9wIR4UN9jE7O4NZBJNXOt/+qk+L0rY9th4SX7VzccKmRltUGxAhI1cXH52gXw==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.4.0.tgz",
"integrity": "sha512-RzblkVImAFdV1C0AWsSWzS70Z0FMtW2p0XXkNYu3QePfyVJta3JIy8m8jY8271etaCZtpFjsE2UaiHGZIBm6nw==",
"license": "MIT",
"dependencies": {
"@vitejs/plugin-react": "^4.7.0",
@ -265,15 +259,6 @@
"url": "https://opencollective.com/babel"
}
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
@ -306,24 +291,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-globals": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
@ -1636,9 +1603,9 @@
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.0.tgz",
"integrity": "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz",
"integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==",
"cpu": [
"arm"
],
@ -1649,9 +1616,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.0.tgz",
"integrity": "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz",
"integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==",
"cpu": [
"arm64"
],
@ -1662,9 +1629,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.0.tgz",
"integrity": "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz",
"integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==",
"cpu": [
"arm64"
],
@ -1675,9 +1642,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.0.tgz",
"integrity": "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz",
"integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==",
"cpu": [
"x64"
],
@ -1688,9 +1655,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.0.tgz",
"integrity": "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz",
"integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==",
"cpu": [
"arm64"
],
@ -1701,9 +1668,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.0.tgz",
"integrity": "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz",
"integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==",
"cpu": [
"x64"
],
@ -1714,9 +1681,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.0.tgz",
"integrity": "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz",
"integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==",
"cpu": [
"arm"
],
@ -1727,9 +1694,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.0.tgz",
"integrity": "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz",
"integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==",
"cpu": [
"arm"
],
@ -1740,9 +1707,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.0.tgz",
"integrity": "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz",
"integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==",
"cpu": [
"arm64"
],
@ -1753,9 +1720,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.0.tgz",
"integrity": "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz",
"integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==",
"cpu": [
"arm64"
],
@ -1766,9 +1733,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.0.tgz",
"integrity": "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz",
"integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==",
"cpu": [
"loong64"
],
@ -1779,9 +1746,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.0.tgz",
"integrity": "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz",
"integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==",
"cpu": [
"ppc64"
],
@ -1792,9 +1759,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.0.tgz",
"integrity": "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz",
"integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==",
"cpu": [
"riscv64"
],
@ -1805,9 +1772,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.0.tgz",
"integrity": "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz",
"integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==",
"cpu": [
"riscv64"
],
@ -1818,9 +1785,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.0.tgz",
"integrity": "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz",
"integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==",
"cpu": [
"s390x"
],
@ -1831,9 +1798,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.0.tgz",
"integrity": "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz",
"integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==",
"cpu": [
"x64"
],
@ -1844,9 +1811,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.0.tgz",
"integrity": "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz",
"integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==",
"cpu": [
"x64"
],
@ -1857,9 +1824,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.0.tgz",
"integrity": "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz",
"integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==",
"cpu": [
"arm64"
],
@ -1870,9 +1837,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.0.tgz",
"integrity": "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz",
"integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==",
"cpu": [
"arm64"
],
@ -1883,9 +1850,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.0.tgz",
"integrity": "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz",
"integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==",
"cpu": [
"ia32"
],
@ -1896,9 +1863,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.0.tgz",
"integrity": "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz",
"integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==",
"cpu": [
"x64"
],
@ -1909,9 +1876,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.0.tgz",
"integrity": "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz",
"integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==",
"cpu": [
"x64"
],
@ -2145,18 +2112,18 @@
}
},
"node_modules/@types/node": {
"version": "24.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz",
"integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
"version": "24.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.6.1.tgz",
"integrity": "sha512-ljvjjs3DNXummeIaooB4cLBKg2U6SPI6Hjra/9rRIy7CpM0HpLtG9HptkMKAb4HYWy5S7HUvJEuWgr/y0U8SHw==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.12.0"
"undici-types": "~7.13.0"
}
},
"node_modules/@types/react": {
"version": "19.1.13",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz",
"integrity": "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==",
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.0.tgz",
"integrity": "sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==",
"license": "MIT",
"peer": true,
"dependencies": {
@ -2164,13 +2131,13 @@
}
},
"node_modules/@types/react-dom": {
"version": "19.1.9",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz",
"integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==",
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.0.0"
"@types/react": "^19.2.0"
}
},
"node_modules/@types/sax": {
@ -2382,14 +2349,14 @@
}
},
"node_modules/astro": {
"version": "5.13.9",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.13.9.tgz",
"integrity": "sha512-vwnJ9Db/X35G3n7F2KgcAAsQ7Du00s0ZFvB+Sx0w7Jl4fwit4+mHJbL4U2ZFxIo9tU07oZEey/2g1Awom7i0LQ==",
"version": "5.14.1",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.14.1.tgz",
"integrity": "sha512-gPa8NY7/lP8j8g81iy8UwANF3+aukKRWS68IlthZQNgykpg80ne6lbHOp6FErYycxQ1TUhgEfkXVDQZAoJx8Bg==",
"license": "MIT",
"dependencies": {
"@astrojs/compiler": "^2.12.2",
"@astrojs/internal-helpers": "0.7.2",
"@astrojs/markdown-remark": "6.3.6",
"@astrojs/internal-helpers": "0.7.3",
"@astrojs/markdown-remark": "6.3.7",
"@astrojs/telemetry": "3.3.0",
"@capsizecss/unpack": "^2.4.0",
"@oslojs/encoding": "^1.1.0",
@ -2536,6 +2503,18 @@
"astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0"
}
},
"node_modules/astro/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@ -2582,9 +2561,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz",
"integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==",
"version": "2.8.10",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.10.tgz",
"integrity": "sha512-uLfgBi+7IBNay8ECBO2mVMGZAc1VgZWEChxm4lv+TobGdG82LnXMjuNGo/BSSZZL4UmkWhxEHP2f5ziLNwGWMA==",
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.js"
@ -2673,9 +2652,9 @@
}
},
"node_modules/browserslist": {
"version": "4.26.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz",
"integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==",
"version": "4.26.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz",
"integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==",
"funding": [
{
"type": "opencollective",
@ -2692,9 +2671,9 @@
],
"license": "MIT",
"dependencies": {
"baseline-browser-mapping": "^2.8.3",
"caniuse-lite": "^1.0.30001741",
"electron-to-chromium": "^1.5.218",
"baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746",
"electron-to-chromium": "^1.5.227",
"node-releases": "^2.0.21",
"update-browserslist-db": "^1.1.3"
},
@ -2718,9 +2697,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001743",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz",
"integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==",
"version": "1.0.30001746",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001746.tgz",
"integrity": "sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==",
"funding": [
{
"type": "opencollective",
@ -3033,9 +3012,9 @@
"license": "MIT"
},
"node_modules/detect-libc": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz",
"integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz",
"integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@ -3122,9 +3101,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
"version": "1.5.223",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.223.tgz",
"integrity": "sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==",
"version": "1.5.228",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz",
"integrity": "sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==",
"license": "ISC"
},
"node_modules/emoji-regex": {
@ -3143,9 +3122,9 @@
}
},
"node_modules/entities": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
@ -4195,10 +4174,13 @@
}
},
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
}
},
"node_modules/magic-string": {
"version": "0.30.19",
@ -4255,18 +4237,6 @@
"integrity": "sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==",
"license": "MIT"
},
"node_modules/markdown-it/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/markdown-table": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
@ -5738,6 +5708,18 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5/node_modules/entities": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@ -5924,9 +5906,9 @@
}
},
"node_modules/react": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
"peer": true,
"engines": {
@ -5934,16 +5916,16 @@
}
},
"node_modules/react-dom": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.26.0"
"scheduler": "^0.27.0"
},
"peerDependencies": {
"react": "^19.1.1"
"react": "^19.2.0"
}
},
"node_modules/react-refresh": {
@ -6337,9 +6319,9 @@
}
},
"node_modules/rollup": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz",
"integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==",
"version": "4.52.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz",
"integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==",
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
@ -6352,28 +6334,28 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.52.0",
"@rollup/rollup-android-arm64": "4.52.0",
"@rollup/rollup-darwin-arm64": "4.52.0",
"@rollup/rollup-darwin-x64": "4.52.0",
"@rollup/rollup-freebsd-arm64": "4.52.0",
"@rollup/rollup-freebsd-x64": "4.52.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.0",
"@rollup/rollup-linux-arm-musleabihf": "4.52.0",
"@rollup/rollup-linux-arm64-gnu": "4.52.0",
"@rollup/rollup-linux-arm64-musl": "4.52.0",
"@rollup/rollup-linux-loong64-gnu": "4.52.0",
"@rollup/rollup-linux-ppc64-gnu": "4.52.0",
"@rollup/rollup-linux-riscv64-gnu": "4.52.0",
"@rollup/rollup-linux-riscv64-musl": "4.52.0",
"@rollup/rollup-linux-s390x-gnu": "4.52.0",
"@rollup/rollup-linux-x64-gnu": "4.52.0",
"@rollup/rollup-linux-x64-musl": "4.52.0",
"@rollup/rollup-openharmony-arm64": "4.52.0",
"@rollup/rollup-win32-arm64-msvc": "4.52.0",
"@rollup/rollup-win32-ia32-msvc": "4.52.0",
"@rollup/rollup-win32-x64-gnu": "4.52.0",
"@rollup/rollup-win32-x64-msvc": "4.52.0",
"@rollup/rollup-android-arm-eabi": "4.52.3",
"@rollup/rollup-android-arm64": "4.52.3",
"@rollup/rollup-darwin-arm64": "4.52.3",
"@rollup/rollup-darwin-x64": "4.52.3",
"@rollup/rollup-freebsd-arm64": "4.52.3",
"@rollup/rollup-freebsd-x64": "4.52.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.3",
"@rollup/rollup-linux-arm-musleabihf": "4.52.3",
"@rollup/rollup-linux-arm64-gnu": "4.52.3",
"@rollup/rollup-linux-arm64-musl": "4.52.3",
"@rollup/rollup-linux-loong64-gnu": "4.52.3",
"@rollup/rollup-linux-ppc64-gnu": "4.52.3",
"@rollup/rollup-linux-riscv64-gnu": "4.52.3",
"@rollup/rollup-linux-riscv64-musl": "4.52.3",
"@rollup/rollup-linux-s390x-gnu": "4.52.3",
"@rollup/rollup-linux-x64-gnu": "4.52.3",
"@rollup/rollup-linux-x64-musl": "4.52.3",
"@rollup/rollup-openharmony-arm64": "4.52.3",
"@rollup/rollup-win32-arm64-msvc": "4.52.3",
"@rollup/rollup-win32-ia32-msvc": "4.52.3",
"@rollup/rollup-win32-x64-gnu": "4.52.3",
"@rollup/rollup-win32-x64-msvc": "4.52.3",
"fsevents": "~2.3.2"
}
},
@ -6401,22 +6383,19 @@
"license": "ISC"
},
"node_modules/scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
"license": "MIT",
"peer": true
},
"node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/send": {
@ -6495,6 +6474,18 @@
"@img/sharp-win32-x64": "0.34.4"
}
},
"node_modules/sharp/node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/shiki": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-3.13.0.tgz",
@ -6773,9 +6764,9 @@
}
},
"node_modules/typescript": {
"version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0",
"peer": true,
"bin": {
@ -6811,9 +6802,9 @@
"license": "MIT"
},
"node_modules/undici-types": {
"version": "7.12.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz",
"integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==",
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz",
"integrity": "sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==",
"license": "MIT"
},
"node_modules/unicode-properties": {
@ -7098,6 +7089,12 @@
}
}
},
"node_modules/unstorage/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",

View File

@ -1,27 +1,9 @@
import React, { useState, useEffect } from 'react';
interface VocabWord {
english: string;
hindi: string;
gender?: string;
type?: string;
note?: string;
examples?: Array<{
english: string;
hindi: string;
note?: string;
}>;
see_also?: string[];
}
interface VocabCategory {
slug: string;
about: string;
words: VocabWord[];
}
import type { VocabList, VocabWord } from '@/types/types';
import { z } from 'zod';
export default function AddVocabForm() {
const [categories, setCategories] = useState<VocabCategory[]>([]);
const [categories, setCategories] = useState<VocabList[]>([]);
const [selectedCategory, setSelectedCategory] = useState('');
const [loading, setLoading] = useState(false);
const [categoriesLoading, setCategoriesLoading] = useState(true);
@ -32,11 +14,11 @@ export default function AddVocabForm() {
const [formData, setFormData] = useState<VocabWord>({
english: '',
hindi: '',
gender: '',
type: 'noun',
note: '',
examples: [],
see_also: [],
gender: undefined,
note: undefined,
examples: undefined,
see_also: undefined,
});
const englishInputRef = React.useRef<HTMLInputElement>(null);
@ -163,7 +145,7 @@ export default function AddVocabForm() {
setFormData({
english: '',
hindi: '',
gender: '',
gender: undefined,
type: currentType, // Keep the last used type
note: '',
examples: [],
@ -343,8 +325,13 @@ export default function AddVocabForm() {
<label htmlFor="gender">Gender (for nouns):</label>
<select
id="gender"
value={formData.gender}
onChange={(e) => setFormData({ ...formData, gender: e.target.value })}
value={formData.gender ?? ''}
onChange={(e) => {
// Use genderSchema from VocabWord type
const genderSchema = z.enum(['m', 'f']).optional();
const parsed = genderSchema.safeParse(e.target.value === '' ? undefined : e.target.value);
setFormData({ ...formData, gender: parsed.success ? parsed.data : undefined });
}}
>
<option value="">N/A</option>
<option value="m">Masculine (m)</option>

View File

@ -1,41 +1,50 @@
import React, { useState, useEffect } from "react";
import type { VocabWord } from "@/types/types";
import { useState, useEffect } from "react";
import { highlight } from "@/lib/markdown";
export default function FlashCard(word: any) {
// Get state of all checkboxes on page
const [numCheckedBoxes, setNumCheckedBoxes] = useState(0);
const updateCheckboxCount = () => {
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
const checkedBoxes = Array.from(checkboxes).filter(
(checkbox) => (checkbox as HTMLInputElement).checked,
export default function FlashCard({ word }: { word: VocabWord }) {
const options = [
{
front: word.english,
back: word.hindi
},
{
front: word.hindi,
back: word.english
}].concat(
word.examples
? word.examples.flatMap(example => [
{
front: highlight(example.english, word.english),
back: highlight(example.hindi, word.hindi)
},
{
front: highlight(example.hindi, word.hindi),
back: highlight(example.english, word.english)
}
])
: []
);
setNumCheckedBoxes(checkedBoxes.length);
};
const [randomCard, setRandomCard] = useState(() => options[Math.floor(Math.random() * options.length)]);
const [isFlipped, setIsFlipped] = useState(false);
useEffect(() => {
// Initial count
updateCheckboxCount();
setRandomCard(options[Math.floor(Math.random() * options.length)]);
setIsFlipped(false);
}, [word]);
// Listen for checkbox changes
const handleCheckboxChange = (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.type === "checkbox") {
updateCheckboxCount();
}
};
// Add event listener to the document to catch all checkbox changes
document.addEventListener("change", handleCheckboxChange);
// Cleanup event listener on unmount
return () => {
document.removeEventListener("change", handleCheckboxChange);
};
}, []);
function flipCard() {
setIsFlipped(!isFlipped);
}
console.log(options);
return (
<div className="flash-card">
<h2>Word</h2>
<p dangerouslySetInnerHTML={{
__html: isFlipped ? randomCard.back : randomCard.front
}} />
<button onClick={() => flipCard()}>Flip</button>
</div>
);
}

View File

@ -0,0 +1,87 @@
import { useState, useEffect } from "react";
import type { VocabList, VocabWord } from "@/types/types";
import FlashCard from "./FlashCard";
export default function FlashCardActivity({ vocabList }: { vocabList: VocabList[] }) {
const [currentWord, setCurrentWord] = useState<VocabWord | null>(null);
const [numFilteredWords, setNumFilteredWords] = useState(0);
const getSelectedFilters = () => {
const categoryCheckboxes = document.querySelectorAll<HTMLInputElement>(
'input[data-filter="category"]'
);
const typeCheckboxes = document.querySelectorAll<HTMLInputElement>(
'input[data-filter="type"]'
);
const selectedCategories = Array.from(categoryCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const selectedTypes = Array.from(typeCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
return { selectedCategories, selectedTypes };
};
const getFilteredWords = () => {
const { selectedCategories, selectedTypes } = getSelectedFilters();
const filteredWords = vocabList
.filter(list => selectedCategories.includes(list.slug))
.flatMap(list => list.words)
.filter(word => selectedTypes.includes(word.type));
if (filteredWords.length === 0) {
alert("No words match the selected filters.");
return;
}
return filteredWords;
};
const getRandomWord = () => {
const filteredWords = getFilteredWords();
const randomIndex = Math.floor(Math.random() * filteredWords!.length);
setCurrentWord(filteredWords![randomIndex]);
setNumFilteredWords(filteredWords!.length);
};
const updateFilteredWordsCount = () => {
const filteredWords = getFilteredWords();
if (filteredWords) {
setNumFilteredWords(filteredWords.length);
}
};
useEffect(() => {
// Initialize with a random word
getRandomWord();
// Listen for checkbox changes anywhere in the document
const handleCheckboxChange = (event: Event) => {
const target = event.target as HTMLElement;
if (target.tagName === 'INPUT' && (target as HTMLInputElement).type === 'checkbox') {
updateFilteredWordsCount();
}
};
document.addEventListener('change', handleCheckboxChange);
return () => {
document.removeEventListener('change', handleCheckboxChange);
};
}, []);
return (
<div className="flash-card-activity">
{currentWord && (
<FlashCard word={currentWord} />
)}
<button onClick={getRandomWord}>Next</button>
<div>
{numFilteredWords} words match the selected filters.
</div>
</div>
);
}

View File

@ -1,7 +1,8 @@
---
import Default from '@astrojs/starlight/components/PageSidebar.astro';
const isLearningPage = Astro.locals.starlightRoute.id === 'learn';
import Default from "@astrojs/starlight/components/PageSidebar.astro";
import MobileTableOfContents from "@astrojs/starlight/components/MobileTableOfContents.astro";
import { Icon } from "@astrojs/starlight/components";
const isLearningPage = Astro.locals.starlightRoute.id === "learn";
import { getCollection } from "astro:content";
@ -20,40 +21,48 @@ const types = Array.from(typesSet).sort();
{
isLearningPage ? (
<>
<div class="lg:sl-hidden">
Help we're on mobile
</div>
<div class="right-sidebar-panel sl-hidden lg:sl-block">
<div class="sl-container">
<div class="lg:sl-hidden">Filters</div>
<div class="right-sidebar-panel sl-hidden lg:sl-block">
<div class="sl-container">
<div class="filters">
<div class="category-filters">
<h2>Categories</h2>
<!-- Check boxes for each category -->
{
categories.map((category) => (
<div class="filter">
<input type="checkbox" id={category.id} name={category.id} value={category.id} checked />
<label for={category.id}>{category.id}</label>
<div class="category-filters">
<h2>Categories</h2>
{/* Check boxes for each category */}
{categories.map((category) => (
<div class="filter">
<input
data-filter="category"
type="checkbox"
id={category.id}
name={category.id}
value={category.id}
checked
/>
<label for={category.id}>{category.id}</label>
</div>
))}
</div>
))
}
</div>
<!-- Check boxes for each type of word -->
<div class="type-filters">
<h2>Types</h2>
{
types.map((type) => (
<div class="filter">
<input type="checkbox" id={type} name={type} value={type} checked />
<label for={type}>{type}</label>
{/* Check boxes for each type of word */}
<div class="type-filters">
<h2>Types</h2>
{types.map((type) => (
<div class="filter">
<input
data-filter="type"
type="checkbox"
id={type}
name={type}
value={type}
checked
/>
<label for={type}>{type}</label>
</div>
))}
</div>
))
}
</div>
</div>
</div>
</div>
</>
</div>
</div>
</div>
</>
) : (
<Default>
<slot />
@ -62,24 +71,24 @@ const types = Array.from(typesSet).sort();
}
<style>
.filters {
display: flex;
gap: 2em;
margin-bottom: 1em;
}
.sl-container{
padding: 1rem var(--sl-sidebar-pad-x);
}
.category-filters, .type-filters {
.filters {
display: flex;
gap: 2em;
margin-bottom: 1em;
}
.sl-container {
padding: 1rem 2em;
}
.category-filters,
.type-filters {
margin-top: 0;
display: flex;
flex-direction: column;
gap: 0.5em;
}
.filter {
display: flex;
align-items: center;
gap: 0.5em;
}
display: flex;
flex-direction: column;
gap: 0.5em;
}
.filter {
display: flex;
align-items: center;
gap: 0.5em;
}
</style>

View File

@ -1,97 +1,109 @@
---
import {Aside, Badge, Icon} from '@astrojs/starlight/components';
import AnchorHeading from '@astrojs/starlight/components/AnchorHeading.astro';
import markdownit from 'markdown-it'
import markdownItMark from 'markdown-it-mark'
const md = markdownit().use(markdownItMark);
import { Aside, Badge, Icon } from "@astrojs/starlight/components";
import AnchorHeading from "@astrojs/starlight/components/AnchorHeading.astro";
import { render, renderInline, highlight } from "@/lib/markdown";
interface Props {
word: {
english: string;
hindi: string;
gender?: "m" | "f";
note?: string;
examples?: Array<{
hindi: string;
english: string;
hindi: string;
gender?: "m" | "f";
note?: string;
}>
see_also?: string[];
tags?: string[];
}
examples?: Array<{
hindi: string;
english: string;
note?: string;
}>;
see_also?: string[];
tags?: string[];
};
}
const {word}: Props = Astro.props;
const { word }: Props = Astro.props;
const gender_lookup: Record<"m" | "f", ["note" | "tip", string]> = {
"m": ["note", "masculine"],
"f": ["tip", "feminine"],
m: ["note", "masculine"],
f: ["tip", "feminine"],
};
function renderInline(rawText:string){
// Swap double-dash for em-dash
const text = rawText.replace(/---/g, '&mdash;').replace(/--/g, '&ndash;');
return md.renderInline(text);
}
function render(rawText:string){
// Swap double-dash for em-dash
const text = rawText.replace(/---/g, '&mdash;').replace(/--/g, '&ndash;');
return md.render(text);
}
function highlight(text: string, term: string) {
const terms = term.split(',').map(t => t.trim()).filter(Boolean);
const regex = new RegExp(`(${terms.map(t => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})`, 'gi');
const parts = text.split(regex);
return renderInline(parts.map((part) => regex.test(part) ? `**${part}**` : part).join(''));
}
---
<li id={word.hindi} class="word-entry">
<AnchorHeading level="4" id={word.hindi} class="word-heading" style="font-weight: normal;">
{word.hindi} <Icon name="right-arrow" class="icon-inline" /><span>{word.english}</span>
{word.gender && <Badge variant={gender_lookup[word.gender][0]} text={gender_lookup[word.gender][1]} class="gender-badge"/>}
</AnchorHeading>
{word.note &&
<div set:html={render(word.note)}></div>
}
{
word.examples &&(
<>
<p>For example,</p>
<ol>
{word.examples.map((e) => (
<li class="word-examples">
<AnchorHeading
level="4"
id={word.hindi}
class="word-heading"
style="font-weight: normal;"
>
{word.hindi}
<Icon name="right-arrow" class="icon-inline" /><span
>{word.english}</span
>
{
word.gender && (
<Badge
variant={gender_lookup[word.gender][0]}
text={gender_lookup[word.gender][1]}
class="gender-badge"
/>
)
}
</AnchorHeading>
{word.note && <div set:html={render(word.note)} />}
{
word.examples && (
<>
<p>For example,</p>
<ol>
{word.examples.map((e) => (
<li class="word-examples">
<p>
<span
set:html={highlight(e.hindi, word.hindi)}
/>{" "}
<Icon name="right-arrow" class="icon-inline" />{" "}
<span
set:html={highlight(
e.english,
word.english,
)}
/>
</p>
{e.note && (
<Aside type="note" title="Note">
<p
set:html={highlight(e.note, word.hindi)}
/>
</Aside>
)}
</li>
))}
</ol>
</>
)
}
{
word.see_also && (
<p>
<span set:html={highlight(e.hindi, word.hindi)}></span> <Icon name="right-arrow" class="icon-inline" /> <span set:html={highlight(e.english, word.english)}></span>
</p>
{e.note && (
<Aside type="note" title="Note">
<p set:html={highlight(e.note, word.hindi)}></p>
</Aside>
)}
</li>
))}
</ol>
</> )}
{ word.see_also && (
<p><b>See also:</b>
{ word.see_also.map((ref, i) => (
<>
<span set:html={renderInline(ref)}></span>{ i < word.see_also!.length - 1 ? "; " : '' }
</>
)) }
</p>
)}
{ word.tags && (
<p>
{
word.tags.map((tag, i) => (
<b>See also:</b>
{word.see_also.map((ref, i) => (
<>
<Badge text={tag} class="tag-badge"/>{ i < word.tags!.length - 1 ? " " : '' }
<span set:html={renderInline(ref)} />
{i < word.see_also!.length - 1 ? "; " : ""}
</>
))
}
</p>
)}
))}
</p>
)
}
{
word.tags && (
<p>
{word.tags.map((tag, i) => (
<>
<Badge text={tag} class="tag-badge" />
{i < word.tags!.length - 1 ? " " : ""}
</>
))}
</p>
)
}
</li>

View File

@ -3,33 +3,13 @@ import { docsLoader } from "@astrojs/starlight/loaders";
import { docsSchema } from "@astrojs/starlight/schema";
import { file } from "astro/loaders";
import { z } from "zod";
import type { VocabWord, VocabList } from "@/types/types";
import { vocabWordSchema, vocabListSchema } from "@/types/types";
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
vocabList: defineCollection({
loader: file("src/vocab_list.yaml"),
schema: z.object({
about: z.string().optional(),
words: z.array(
z.object({
type: z.string(),
english: z.string(),
hindi: z.string(),
gender: z.enum(["m", "f"]).optional(),
note: z.string().optional(),
examples: z
.array(
z.object({
english: z.string(),
hindi: z.string(),
note: z.string().optional(),
}),
)
.optional(),
see_also: z.array(z.string()).optional(),
tags: z.array(z.string()).optional(),
}),
),
}),
schema: vocabListSchema,
}),
};

View File

@ -0,0 +1,21 @@
import markdownit from 'markdown-it'
import markdownItMark from 'markdown-it-mark'
const md = markdownit().use(markdownItMark);
export function renderInline(rawText: string) {
// Swap double-dash for em-dash
const text = rawText.replace(/---/g, '&mdash;').replace(/--/g, '&ndash;');
return md.renderInline(text);
}
export function render(rawText: string) {
// Swap double-dash for em-dash
const text = rawText.replace(/---/g, '&mdash;').replace(/--/g, '&ndash;');
return md.render(text);
}
export function highlight(text: string, term: string) {
const terms = term.split(',').map(t => t.trim()).filter(Boolean);
const regex = new RegExp(`(${terms.map(t => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})`, 'gi');
const parts = text.split(regex);
return renderInline(parts.map((part) => regex.test(part) ? `**${part}**` : part).join(''));
}

View File

@ -1,15 +1,20 @@
---
import FlashCardActivity from "@/components/FlashCardActivity";
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
import FlashCard from "@/components/FlashCard";
const checkboxes = 3;
import { getCollection } from "astro:content";
const vocabListCollection = await getCollection("vocabList");
const vocabList = vocabListCollection.map((category) => ({
...category.data,
slug: category.id,
}));
---
<StarlightPage
frontmatter={{
title: "Learning Mode ${checkboxes} checked",
title: "Flash Cards",
tableOfContents: true,
prev: false,
}}
>
<FlashCard word="test" client:load />
<FlashCardActivity vocabList={vocabList} client:load />
</StarlightPage>

View File

@ -76,7 +76,8 @@
font-style: normal;
font-display: swap;
unicode-range:
U+0900-097F, U+200C-200D; /* Devanagari block + zero-width joiners */
U+0900-097F, U+200C-200D;
/* Devanagari block + zero-width joiners */
}
@font-face {
@ -130,10 +131,14 @@
--sl-font: var(--font-sans);
/* Light theme - warm paper-like background */
--sl-color-bg: #fefcf8; /* Warm off-white, like aged paper */
--sl-color-bg-nav: #faf8f4; /* Slightly darker for navigation */
--sl-color-bg-sidebar: #f8f6f2; /* Even softer for sidebar */
--sl-color-bg-inline-code: #f4f2ee; /* Subtle for inline code */
--sl-color-bg: #fefcf8;
/* Warm off-white, like aged paper */
--sl-color-bg-nav: #faf8f4;
/* Slightly darker for navigation */
--sl-color-bg-sidebar: #f8f6f2;
/* Even softer for sidebar */
--sl-color-bg-inline-code: #f4f2ee;
/* Subtle for inline code */
/* Custom accent color */
--sl-color-accent: #336699;
@ -151,12 +156,14 @@
/* Dark theme overrides */
[data-theme="dark"] {
--sl-color-bg: #1a1814; /* Dark warm background */
--sl-color-bg: #1a1814;
/* Dark warm background */
--sl-color-bg-nav: #1e1c18;
--sl-color-bg-sidebar: #16140f;
--sl-color-bg-inline-code: #2a2620;
--sl-color-accent: #5ba3c4; /* Warmer blue-teal for dark theme */
--sl-color-accent: #5ba3c4;
/* Warmer blue-teal for dark theme */
--sl-color-accent-low: #5ba3c4;
--sl-color-accent-high: #6bb4d5;
--sl-color-text-invert: #1a1814;
@ -179,7 +186,8 @@ blockquote,
.prose,
.sl-markdown-content {
font-family: var(--font-serif);
font-size: 1.25rem; /* 18px, up from default 16px */
font-size: 1.25rem;
/* 18px, up from default 16px */
}
/* UI elements remain sans-serif */
@ -222,6 +230,7 @@ h6,
vertical-align: middle;
font-family: var(--font-sans);
}
.tag-badge {
font-family: var(--font-sans);
background: transparent;
@ -243,6 +252,7 @@ h6,
text-decoration: none;
color: var(--sl-color-accent);
}
.sl-markdown-content a:hover,
.tagline a:hover {
text-decoration: underline;
@ -257,33 +267,55 @@ mark {
}
/* Override the exact Starlight rule that's causing issues */
.sl-markdown-content
[yaml-editor]
:not(a, strong, em, del, span, input, code, br)
+ :not(a, strong, em, del, span, input, code, br, :where(.not-content *)) {
.sl-markdown-content [yaml-editor] :not(a, strong, em, del, span, input, code, br)+ :not(a, strong, em, del, span, input, code, br, :where(.not-content *)) {
margin-top: 0 !important;
}
/* Also target if the YAMLEditor itself is within sl-markdown-content */
.sl-markdown-content
:not(a, strong, em, del, span, input, code, br)
+ [yaml-editor]:not(
a,
strong,
em,
del,
span,
input,
code,
br,
:where(.not-content *)
) {
.sl-markdown-content :not(a, strong, em, del, span, input, code, br)+[yaml-editor]:not(a,
strong,
em,
del,
span,
input,
code,
br,
:where(.not-content *)) {
margin-top: 0 !important;
}
/* .sl-container {
max-width: 100%;
} */
.flash-card-activity {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
}
.flash-card {
border: 1px solid var(--sl-color-border);
border-radius: 8px;
padding: 1.5rem;
background-color: var(--sl-color-bg-inline-code);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.flash-card button {
float: right;
margin-top: 1rem;
padding: 0.5rem 1rem;
background-color: var(--sl-color-accent);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.flash-card p {
font-size: 1.5em;
line-height: 1.5;
}
/* =================================================================
LANGUAGE-SPECIFIC STYLES
@ -308,9 +340,11 @@ mark {
.serif {
font-family: var(--font-serif);
}
.sans {
font-family: var(--font-sans);
}
.devanagari-font {
font-family: var(--font-devanagari);
}
@ -319,15 +353,19 @@ mark {
.font-light {
font-weight: 300;
}
.font-regular {
font-weight: 400;
}
.font-semibold {
font-weight: 600;
}
.font-bold {
font-weight: 700;
}
.font-black {
font-weight: 900;
}
@ -337,14 +375,17 @@ mark {
font-family: var(--font-serif);
font-weight: 400;
}
.serif-bold {
font-family: var(--font-serif);
font-weight: 700;
}
.sans-regular {
font-family: var(--font-sans);
font-weight: 400;
}
.sans-bold {
font-family: var(--font-sans);
font-weight: 700;
@ -355,18 +396,22 @@ mark {
font-family: var(--font-devanagari);
font-weight: 300;
}
.hindi-regular {
font-family: var(--font-devanagari);
font-weight: 400;
}
.hindi-semibold {
font-family: var(--font-devanagari);
font-weight: 600;
}
.hindi-bold {
font-family: var(--font-devanagari);
font-weight: 700;
}
.hindi-black {
font-family: var(--font-devanagari);
font-weight: 900;
@ -377,14 +422,17 @@ mark {
font-family: var(--font-serif);
font-weight: 400;
}
.minion-bold {
font-family: var(--font-serif);
font-weight: 700;
}
.myriad-regular {
font-family: var(--font-sans);
font-weight: 400;
}
.myriad-bold {
font-family: var(--font-sans);
font-weight: 700;

View File

@ -1,10 +1,48 @@
// Export interfaces and types
import { z } from "zod";
export interface VocabWord {
type: "noun" | "verb" | "adjective" | "adverb" | "phrase" | "other";
english: string;
hindi: string;
gender?: "m" | "f";
type: string;
gender?: "m" | "f" | undefined;
note?: string;
examples?: Array<{
english: string;
hindi: string;
note?: string;
}>;
see_also?: string[];
}
export interface VocabCategory {
export interface VocabList {
slug: string;
about: string;
words: VocabWord[];
}
export const vocabWordSchema = z.object({
english: z.string(),
hindi: z.string(),
type: z.string(),
gender: z.enum(["m", "f"]).optional(),
note: z.string().optional(),
examples: z
.array(
z.object({
english: z.string(),
hindi: z.string(),
note: z.string().optional(),
})
)
.optional(),
see_also: z.array(z.string()).optional(),
});
export type VocabWordSchema = z.infer<typeof vocabWordSchema>;
export const vocabListSchema = z.object({
slug: z.string(),
about: z.string(),
words: z.array(vocabWordSchema),
});
export type VocabListSchema = z.infer<typeof vocabListSchema>;