wip: init

This commit is contained in:
taskylizard 2025-05-01 20:56:22 +00:00
parent 45d9157281
commit 2606a39f8d
No known key found for this signature in database
GPG key ID: 1820131ED1A24120
10 changed files with 1670 additions and 55 deletions

View file

@ -94,6 +94,12 @@ export default defineConfig({
replacement: fileURLToPath(
new URL('./theme/Appearance.vue', import.meta.url)
)
},
{
find: /^.*VPLocalSearchBox.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/Search.vue', import.meta.url)
)
}
]
},

View file

@ -16,6 +16,7 @@
import type { DefaultTheme } from 'vitepress'
import consola from 'consola'
import { customTokenize, customTokenProcessor } from './search'
import { transform, transformGuide } from './transformer'
// @unocss-include
@ -65,44 +66,13 @@ export const search: DefaultTheme.Config['search'] = {
},
miniSearch: {
options: {
tokenize: (text) => text.split(/[\n\r #%*,=/:;?[\]{}()&]+/u), // simplified charset: removed [-_.@] and non-english chars (diacritics etc.)
processTerm: (term, fieldName) => {
// biome-ignore lint/style/noParameterAssign: h
term = term
.trim()
.toLowerCase()
.replace(/^\.+/, '')
.replace(/\.+$/, '')
const stopWords = [
'frontmatter',
'$frontmatter.synopsis',
'and',
'about',
'but',
'now',
'the',
'with',
'you'
]
if (term.length < 2 || stopWords.includes(term)) return false
if (fieldName === 'text') {
const parts = term.split('.')
if (parts.length > 1) {
const newTerms = [term, ...parts]
.filter((t) => t.length >= 2)
.filter((t) => !stopWords.includes(t))
return newTerms
}
}
return term
}
tokenize: customTokenize,
processTerm: customTokenProcessor
},
searchOptions: {
combineWith: 'AND',
fuzzy: true,
// @ts-ignore
boostDocument: (documentId, term, storedFields: Record) => {
console.log(storedFields.titles)
const titles = (storedFields?.titles as string[])
.filter((t) => Boolean(t))
.map((t) => t.toLowerCase())
@ -153,7 +123,10 @@ export const nav: DefaultTheme.NavItem[] = [
{ text: '🔖 Bookmarks', link: 'https://github.com/fmhy/bookmarks' },
{ text: '✅ SafeGuard', link: 'https://github.com/fmhy/FMHY-SafeGuard' },
{ text: '📋 snowbin', link: 'https://pastes.fmhy.net' },
{ text: '®️ Redlib', link: 'https://redlib.fmhy.net/r/FREEMEDIAHECKYEAH/wiki/index' },
{
text: '®️ Redlib',
link: 'https://redlib.fmhy.net/r/FREEMEDIAHECKYEAH/wiki/index'
},
{ text: '🔎 SearXNG', link: 'https://searx.fmhy.net/' },
{
text: '💡 Site Hunting',

360
docs/.vitepress/search.ts Normal file
View file

@ -0,0 +1,360 @@
export const customTokenProcessor = (token: string): string | null => {
// Remove dots and normalize case before processing
const normalizedToken = token.replace(/\./g, '').toLowerCase()
const step2list: Record<string, string> = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
}
const step3list: Record<string, string> = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
}
const consonant = '[^aeiou]'
const vowel = '[aeiouy]'
const consonants = '(' + consonant + '[^aeiouy]*)'
const vowels = '(' + vowel + '[aeiou]*)'
const gt0 = new RegExp('^' + consonants + '?' + vowels + consonants)
const eq1 = new RegExp(
'^' + consonants + '?' + vowels + consonants + vowels + '?$'
)
const gt1 = new RegExp(
'^' + consonants + '?(' + vowels + consonants + '){2,}'
)
const vowelInStem = new RegExp('^' + consonants + '?' + vowel)
const consonantLike = new RegExp('^' + consonants + vowel + '[^aeiouwxy]$')
const sfxLl = /ll$/
const sfxE = /^(.+?)e$/
const sfxY = /^(.+?)y$/
const sfxIon = /^(.+?(s|t))(ion)$/
const sfxEdOrIng = /^(.+?)(ed|ing)$/
const sfxAtOrBlOrIz = /(at|bl|iz)$/
const sfxEED = /^(.+?)eed$/
const sfxS = /^.+?[^s]s$/
const sfxSsesOrIes = /^.+?(ss|i)es$/
const sfxMultiConsonantLike = /([^aeiouylsz])\1$/
const step2 =
/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/
const step3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/
const step4 =
/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/
function stemmer(value: string) {
let result = String(value).toLowerCase()
// Exit early.
if (result.length < 3) {
return result
}
/** @type {boolean} */
let firstCharacterWasLowerCaseY = false
// Detect initial `y`, make sure it never matches.
if (
result.codePointAt(0) === 121 // Lowercase Y
) {
firstCharacterWasLowerCaseY = true
result = 'Y' + result.slice(1)
}
// Step 1a.
if (sfxSsesOrIes.test(result)) {
// Remove last two characters.
result = result.slice(0, -2)
} else if (sfxS.test(result)) {
// Remove last character.
result = result.slice(0, -1)
}
/** @type {RegExpMatchArray|null} */
let match
// Step 1b.
if ((match = sfxEED.exec(result))) {
if (gt0.test(match[1])) {
// Remove last character.
result = result.slice(0, -1)
}
} else if (
(match = sfxEdOrIng.exec(result)) &&
vowelInStem.test(match[1])
) {
result = match[1]
if (sfxAtOrBlOrIz.test(result)) {
// Append `e`.
result += 'e'
} else if (sfxMultiConsonantLike.test(result)) {
// Remove last character.
result = result.slice(0, -1)
} else if (consonantLike.test(result)) {
// Append `e`.
result += 'e'
}
}
// Step 1c.
if ((match = sfxY.exec(result)) && vowelInStem.test(match[1])) {
// Remove suffixing `y` and append `i`.
result = match[1] + 'i'
}
// Step 2.
if ((match = step2.exec(result)) && gt0.test(match[1])) {
result = match[1] + step2list[match[2]]
}
// Step 3.
if ((match = step3.exec(result)) && gt0.test(match[1])) {
result = match[1] + step3list[match[2]]
}
// Step 4.
if ((match = step4.exec(result))) {
if (gt1.test(match[1])) {
result = match[1]
}
} else if ((match = sfxIon.exec(result)) && gt1.test(match[1])) {
result = match[1]
}
// Step 5.
if (
(match = sfxE.exec(result)) &&
(gt1.test(match[1]) ||
(eq1.test(match[1]) && !consonantLike.test(match[1])))
) {
result = match[1]
}
if (sfxLl.test(result) && gt1.test(result)) {
result = result.slice(0, -1)
}
// Turn initial `Y` back to `y`.
if (firstCharacterWasLowerCaseY) {
result = 'y' + result.slice(1)
}
return result
}
// adapted from these two sources
// https://gist.github.com/sebleier/554280
// https://meta.wikimedia.org/wiki/Stop_word_list/google_stop_word_list
const stopWords = new Set([
'a',
'about',
'above',
'after',
'again',
'against',
'all',
'am',
'an',
'and',
'any',
'are',
'aren',
'as',
'at',
'be',
'because',
'been',
'before',
'being',
'below',
'between',
'both',
'but',
'by',
'can',
'cannot',
'com',
'could',
'couldn',
'did',
'didn',
'do',
'does',
'doesn',
'doing',
'down',
'during',
'each',
'few',
'for',
'from',
'further',
'had',
'hadn',
'has',
'hasn',
'have',
'haven',
'having',
'he',
'her',
'here',
'hers',
'herself',
'him',
'himself',
'his',
'how',
'i',
'if',
'in',
'into',
'is',
'isn',
'it',
'its',
'itself',
'just',
'let',
'll',
'me',
'more',
'most',
'mustn',
'my',
'myself',
'no',
'nor',
'not',
'now',
'of',
'off',
'on',
'once',
'only',
'or',
'other',
'ought',
'our',
'ours',
'ourselves',
'out',
'over',
'own',
're',
's',
'same',
'shan',
'she',
'should',
'shouldn',
'so',
'some',
'such',
't',
'than',
'that',
'the',
'their',
'theirs',
'them',
'themselves',
'then',
'there',
'these',
'they',
'this',
'those',
'through',
'to',
'too',
'under',
'until',
'up',
've',
'very',
'was',
'wasn',
'we',
'were',
'weren',
'what',
'when',
'where',
'which',
'while',
'who',
'whom',
'why',
'will',
'with',
'won',
'would',
'wouldn',
'you',
'your',
'yours',
'yourself',
'yourselves'
])
return stopWords.has(normalizedToken) ? null : stemmer(normalizedToken)
}
export const customTokenize = (text: string): string[] => {
// Pre-process the text to handle dots in special cases
// This will help with cases like "V.R" to match with "vr" by removing dots
const preprocessedText = text.replace(/([A-Za-z])\.([A-Za-z])/g, '$1$2') // Remove dots between letters (like V.R -> VR)
// This regular expression matches any Unicode space or punctuation character
// Copied from https://github.com/lucaong/minisearch
// which adapted from https://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7BZ%7D%5Cp%7BP%7D&abb=on&c=on&esc=on
const SPACE_OR_PUNCTUATION =
/[\n\r -#%-*,-/:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]+/u
// Split on any space or punctuation; same as minisearch default tokenizer
// except i've corrected for the possibility for returning empty string
const tokens = preprocessedText.split(SPACE_OR_PUNCTUATION).filter(Boolean)
// Handle cases with capital letters in the middle (like "xManager" -> "x Manager")
const expandedTokens: string[] = []
for (const token of tokens) {
expandedTokens.push(token)
// If token has a capital letter in the middle, add a version with space before it
// This helps with cases like "xManager" to match with "x Manager"
const splitOnCapitals = token.replace(/([a-z])([A-Z])/g, '$1 $2')
if (splitOnCapitals !== token) {
const additionalTokens = splitOnCapitals.split(' ').filter(Boolean)
expandedTokens.push(...additionalTokens)
}
}
return expandedTokens
}

View file

@ -266,7 +266,8 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
placeholder="What a lovely wiki!"
/>
<p class="desc mb-2">
Add your Discord handle if you would like a response, or if we need more information from you, otherwise join our
Add your Discord handle if you would like a response, or if we need
more information from you, otherwise join our
<a
class="text-primary text-underline font-semibold"
href="https://rentry.co/FMHY-Invite/"

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ interface Header {
export const headers: Header = {
'adblockvpnguide.md': {
title: 'Adblocking / Privacy',
description: "Adblocking, Privacy, VPNs, Proxies, Antiviruses"
description: 'Adblocking, Privacy, VPNs, Proxies, Antiviruses'
},
'ai.md': {
title: 'Artificial Intelligence',

View file

@ -13,8 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable ts/consistent-type-imports */
declare const __VP_HASH_MAP__: Record<string, string>
declare const __VP_LOCAL_SEARCH__: boolean
declare const __ALGOLIA__: boolean
declare const __CARBON__: boolean
declare const __VUE_PROD_DEVTOOLS__: boolean
declare const __ASSETS_DIR__: string
declare module '*.vue' {
const component: import('vue').Component
import type { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}
declare module '@siteData' {
import type { SiteData } from 'vitepress'
const data: SiteData
export default data
}
declare module '@theme/index' {
import type { Theme } from 'vitepress'
const theme: Theme
export default theme
}
declare module '@localSearchIndex' {
const data: Record<string, () => Promise<{ default: string }>>
export default data
}
declare module 'mark.js/src/vanilla.js' {
import type Mark from 'mark.js'
const mark: typeof Mark
export default mark
}

View file

@ -25,14 +25,19 @@
"@headlessui/vue": "^1.7.23",
"@resvg/resvg-js": "^2.6.2",
"@vueuse/core": "^13.0.0",
"@vueuse/integrations": "^13.1.0",
"consola": "^3.2.3",
"feed": "^4.2.2",
"itty-fetcher": "^0.9.4",
"mark.js": "^8.11.1",
"markdown-it": "^14.1.0",
"minisearch": "^7.1.2",
"nitro-cors": "^0.7.1",
"nitropack": "^2.11.6",
"nprogress": "^0.2.0",
"pathe": "^2.0.1",
"reka-ui": "^2.1.1",
"stemmer": "^2.0.1",
"unocss": "66.1.0-beta.3",
"vitepress": "^1.6.3",
"vue": "^3.5.13",

152
pnpm-lock.yaml generated
View file

@ -23,6 +23,9 @@ importers:
'@vueuse/core':
specifier: ^13.0.0
version: 13.0.0(vue@3.5.13(typescript@5.8.2))
'@vueuse/integrations':
specifier: ^13.1.0
version: 13.1.0(change-case@5.4.4)(focus-trap@7.6.4)(nprogress@0.2.0)(vue@3.5.13(typescript@5.8.2))
consola:
specifier: ^3.2.3
version: 3.2.3
@ -32,6 +35,15 @@ importers:
itty-fetcher:
specifier: ^0.9.4
version: 0.9.4
mark.js:
specifier: ^8.11.1
version: 8.11.1
markdown-it:
specifier: ^14.1.0
version: 14.1.0
minisearch:
specifier: ^7.1.2
version: 7.1.2
nitro-cors:
specifier: ^0.7.1
version: 0.7.1
@ -47,6 +59,9 @@ importers:
reka-ui:
specifier: ^2.1.1
version: 2.1.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))
stemmer:
specifier: ^2.0.1
version: 2.0.1
unocss:
specifier: 66.1.0-beta.3
version: 66.1.0-beta.3(vite@5.4.14(@types/node@20.16.12)(sass@1.85.1)(terser@5.39.0))(vue@3.5.13(typescript@5.8.2))
@ -1869,6 +1884,11 @@ packages:
peerDependencies:
vue: ^3.5.0
'@vueuse/core@13.1.0':
resolution: {integrity: sha512-PAauvdRXZvTWXtGLg8cPUFjiZEddTqmogdwYpnn60t08AA5a8Q4hZokBnpTOnVNqySlFlTcRYIC8OqreV4hv3Q==}
peerDependencies:
vue: ^3.5.0
'@vueuse/integrations@12.8.2':
resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==}
peerDependencies:
@ -1910,12 +1930,57 @@ packages:
universal-cookie:
optional: true
'@vueuse/integrations@13.1.0':
resolution: {integrity: sha512-wJ6aANdUs4SOpVabChQK+uLIwxRTUAEmn1DJnflGG7Wq6yaipiRmp6as/Md201FjJnquQt8MecIPbFv8HSBeDA==}
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
vue: ^3.5.0
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
'@vueuse/metadata@12.8.2':
resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==}
'@vueuse/metadata@13.0.0':
resolution: {integrity: sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw==}
'@vueuse/metadata@13.1.0':
resolution: {integrity: sha512-+TDd7/a78jale5YbHX9KHW3cEDav1lz1JptwDvep2zSG8XjCsVE+9mHIzjTOaPbHUAk5XiE4jXLz51/tS+aKQw==}
'@vueuse/shared@12.8.2':
resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
@ -1924,6 +1989,11 @@ packages:
peerDependencies:
vue: ^3.5.0
'@vueuse/shared@13.1.0':
resolution: {integrity: sha512-IVS/qRRjhPTZ6C2/AM3jieqXACGwFZwWTdw5sNTSKk2m/ZpkuuN+ri+WCVUP8TqaKwJYt/KuMwmXspMAw8E6ew==}
peerDependencies:
vue: ^3.5.0
abbrev@3.0.0:
resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==}
engines: {node: ^18.17.0 || >=20.5.0}
@ -2307,15 +2377,6 @@ packages:
supports-color:
optional: true
debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
engines: {node: '>=6.0'}
@ -2862,6 +2923,9 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
listhen@1.9.0:
resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==}
hasBin: true
@ -2911,12 +2975,19 @@ packages:
mark.js@8.11.1:
resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
markdown-it@14.1.0:
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
hasBin: true
mdast-util-to-hast@13.2.0:
resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
mdn-data@2.12.2:
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@ -3331,6 +3402,10 @@ packages:
property-information@7.0.0:
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
quansync@0.2.8:
resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==}
@ -3590,6 +3665,10 @@ packages:
std-env@3.8.1:
resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==}
stemmer@2.0.1:
resolution: {integrity: sha512-bkWvSX2JR4nSZFfs113kd4C6X13bBBrg4fBKv2pVdzpdQI2LA5pZcWzTFNdkYsiUNl13E4EzymSRjZ0D55jBYg==}
hasBin: true
stoppable@1.1.0:
resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
engines: {node: '>=4', npm: '>=6'}
@ -3721,6 +3800,9 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
uc.micro@2.1.0:
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
ufo@1.3.2:
resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==}
@ -4268,7 +4350,7 @@ snapshots:
'@babel/traverse': 7.24.8
'@babel/types': 7.24.9
convert-source-map: 2.0.0
debug: 4.3.4
debug: 4.4.0(supports-color@9.4.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -4378,7 +4460,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.24.7
'@babel/parser': 7.24.8
'@babel/types': 7.24.9
debug: 4.3.4
debug: 4.4.0(supports-color@9.4.0)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -5686,6 +5768,13 @@ snapshots:
'@vueuse/shared': 13.0.0(vue@3.5.13(typescript@5.8.2))
vue: 3.5.13(typescript@5.8.2)
'@vueuse/core@13.1.0(vue@3.5.13(typescript@5.8.2))':
dependencies:
'@types/web-bluetooth': 0.0.21
'@vueuse/metadata': 13.1.0
'@vueuse/shared': 13.1.0(vue@3.5.13(typescript@5.8.2))
vue: 3.5.13(typescript@5.8.2)
'@vueuse/integrations@12.8.2(change-case@5.4.4)(focus-trap@7.6.4)(nprogress@0.2.0)(typescript@5.8.2)':
dependencies:
'@vueuse/core': 12.8.2(typescript@5.8.2)
@ -5698,10 +5787,22 @@ snapshots:
transitivePeerDependencies:
- typescript
'@vueuse/integrations@13.1.0(change-case@5.4.4)(focus-trap@7.6.4)(nprogress@0.2.0)(vue@3.5.13(typescript@5.8.2))':
dependencies:
'@vueuse/core': 13.1.0(vue@3.5.13(typescript@5.8.2))
'@vueuse/shared': 13.1.0(vue@3.5.13(typescript@5.8.2))
vue: 3.5.13(typescript@5.8.2)
optionalDependencies:
change-case: 5.4.4
focus-trap: 7.6.4
nprogress: 0.2.0
'@vueuse/metadata@12.8.2': {}
'@vueuse/metadata@13.0.0': {}
'@vueuse/metadata@13.1.0': {}
'@vueuse/shared@12.8.2(typescript@5.8.2)':
dependencies:
vue: 3.5.13(typescript@5.8.2)
@ -5712,6 +5813,10 @@ snapshots:
dependencies:
vue: 3.5.13(typescript@5.8.2)
'@vueuse/shared@13.1.0(vue@3.5.13(typescript@5.8.2))':
dependencies:
vue: 3.5.13(typescript@5.8.2)
abbrev@3.0.0: {}
abort-controller@3.0.0:
@ -6060,10 +6165,6 @@ snapshots:
dependencies:
ms: 2.0.0
debug@4.3.4:
dependencies:
ms: 2.1.2
debug@4.3.6:
dependencies:
ms: 2.1.2
@ -6645,6 +6746,10 @@ snapshots:
lines-and-columns@1.2.4: {}
linkify-it@5.0.0:
dependencies:
uc.micro: 2.1.0
listhen@1.9.0:
dependencies:
'@parcel/watcher': 2.5.1
@ -6717,6 +6822,15 @@ snapshots:
mark.js@8.11.1: {}
markdown-it@14.1.0:
dependencies:
argparse: 2.0.1
entities: 4.5.0
linkify-it: 5.0.0
mdurl: 2.0.0
punycode.js: 2.3.1
uc.micro: 2.1.0
mdast-util-to-hast@13.2.0:
dependencies:
'@types/hast': 3.0.4
@ -6731,6 +6845,8 @@ snapshots:
mdn-data@2.12.2: {}
mdurl@2.0.0: {}
merge-stream@2.0.0: {}
merge2@1.4.1: {}
@ -7170,6 +7286,8 @@ snapshots:
property-information@7.0.0: {}
punycode.js@2.3.1: {}
quansync@0.2.8: {}
queue-microtask@1.2.3: {}
@ -7499,6 +7617,8 @@ snapshots:
std-env@3.8.1: {}
stemmer@2.0.1: {}
stoppable@1.1.0: {}
streamx@2.22.0:
@ -7626,6 +7746,8 @@ snapshots:
typescript@5.8.2: {}
uc.micro@2.1.0: {}
ufo@1.3.2: {}
ufo@1.5.4: {}

View file

@ -13,7 +13,7 @@
"noUnusedLocals": true,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"types": ["vitepress"]
"types": ["vitepress", "vitepress/client"]
},
"exclude": ["node_modules"],
"include": [