mirror of
https://github.com/ArthurDanjou/artchat.git
synced 2026-01-14 15:54:03 +01:00
feat(infinite-canvas): add infinite canvas component with drag and zoom functionality
- Implemented InfiniteCanvas.vue for rendering an infinite canvas with drag and zoom capabilities. - Created useInfiniteCanvas composable for managing canvas state and interactions. - Added useImagePreloader composable for preloading images and videos. - Introduced constants for physics, touch interactions, viewport settings, and zoom defaults. - Developed utility functions for touch handling and media type detection. - Defined TypeScript types for canvas items, grid items, and composables. - Registered components and composables in the Nuxt module. - Added screenshot generation functionality for content files. - Updated package.json to include capture-website dependency.
This commit is contained in:
@@ -45,10 +45,15 @@ defineShortcuts({
|
|||||||
t: () => toggleDark({ clientX: window.innerWidth / 2, clientY: window.innerHeight }),
|
t: () => toggleDark({ clientX: window.innerWidth / 2, clientY: window.innerHeight }),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isMobile = computed(() => {
|
||||||
|
if (!import.meta.client)
|
||||||
|
return false
|
||||||
|
return isMobileDevice(navigator.userAgent, window.innerWidth)
|
||||||
|
})
|
||||||
const activeElement = useActiveElement()
|
const activeElement = useActiveElement()
|
||||||
watch(openMessageModal, async () => {
|
watch(openMessageModal, async () => {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
if (activeElement.value instanceof HTMLElement) {
|
if (activeElement.value instanceof HTMLElement && isMobile.value) {
|
||||||
activeElement.value.blur()
|
activeElement.value.blur()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ const { t } = useI18n()
|
|||||||
</h1>
|
</h1>
|
||||||
<p class="text-center flex gap-0.5">
|
<p class="text-center flex gap-0.5">
|
||||||
{{ t('error.main') }}
|
{{ t('error.main') }}
|
||||||
<NuxtLink href="/" class="sofia flex items-center group">
|
|
||||||
<span class="duration-300 underline-offset-2 font-semibold text-md text-black dark:text-white underline decoration-gray-300 dark:decoration-neutral-700 group-hover:decoration-black dark:group-hover:decoration-white">
|
|
||||||
{{ t('error.redirect') }}
|
|
||||||
</span>
|
|
||||||
</NuxtLink>
|
|
||||||
</p>
|
</p>
|
||||||
|
<NuxtLink href="/" class="sofia flex items-center group">
|
||||||
|
<span class="duration-300 underline-offset-2 font-semibold text-md text-black dark:text-white underline decoration-gray-300 dark:decoration-neutral-700 group-hover:decoration-black dark:group-hover:decoration-white">
|
||||||
|
{{ t('error.redirect') }}
|
||||||
|
</span>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,263 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { CanvasItem } from '~~/modules/infinite-canvas/types'
|
||||||
|
|
||||||
|
const { data, error } = await useAsyncData(`canva`, async () => {
|
||||||
|
const items: CanvasItem[] = []
|
||||||
|
|
||||||
|
const projects = await queryCollection('projects')
|
||||||
|
.select('title', 'description', 'cover', 'tags', 'slug', 'canva')
|
||||||
|
.all()
|
||||||
|
|
||||||
|
projects.forEach((project) => {
|
||||||
|
if (!project.cover)
|
||||||
|
return
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
title: project.title,
|
||||||
|
description: project.description || '',
|
||||||
|
image: `/projects/${project.cover}`,
|
||||||
|
link: `/projects/${project.slug}`,
|
||||||
|
tags: project.tags || [],
|
||||||
|
height: project.canva?.height ?? 270,
|
||||||
|
width: project.canva?.width ?? 480,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const writings = await queryCollection('writings')
|
||||||
|
.select('title', 'description', 'cover', 'slug', 'tags', 'canva')
|
||||||
|
.all()
|
||||||
|
|
||||||
|
writings.forEach((writing) => {
|
||||||
|
if (!writing.cover)
|
||||||
|
return
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
title: writing.title,
|
||||||
|
description: writing.description || '',
|
||||||
|
image: `/writings/${writing.cover}`,
|
||||||
|
link: `/writings/${writing.slug}`,
|
||||||
|
tags: writing.tags || [],
|
||||||
|
height: writing.canva?.height ?? 270,
|
||||||
|
width: writing.canva?.width ?? 480,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return items
|
||||||
|
})
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const isMobile = computed(() => {
|
||||||
|
if (!import.meta.client)
|
||||||
|
return false
|
||||||
|
return isMobileDevice(navigator.userAgent, window.innerWidth)
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
function handleItemClick(item: CanvasItem) {
|
||||||
|
if (import.meta.client) {
|
||||||
|
router.push(item.link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUrls = computed(() => data.value?.map(item => item.cover))
|
||||||
|
|
||||||
|
const loaderProgress = ref(0)
|
||||||
|
const showLoader = ref(true)
|
||||||
|
const isImagesLoaded = ref(false)
|
||||||
|
|
||||||
|
const hoveredItemIndex = ref<number | null>(null)
|
||||||
|
|
||||||
|
const { startPreloading } = useImagePreloader({
|
||||||
|
images: imageUrls.value || [],
|
||||||
|
onProgress: (newProgress) => {
|
||||||
|
loaderProgress.value = newProgress
|
||||||
|
},
|
||||||
|
onComplete: () => {
|
||||||
|
isImagesLoaded.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
showLoader.value = false
|
||||||
|
}, 500)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const canvasRef = ref<any>(null)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
startPreloading()
|
||||||
|
nextTick(() => {
|
||||||
|
if (canvasRef.value?.updateDimensions) {
|
||||||
|
canvasRef.value.updateDimensions()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Prevent browser navigation gestures
|
||||||
|
if (import.meta.client) {
|
||||||
|
document.documentElement.style.overscrollBehavior = 'none'
|
||||||
|
document.body.style.overscrollBehavior = 'none'
|
||||||
|
document.body.style.touchAction = 'manipulation'
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div />
|
<main v-if="data" class="canvas-page relative h-screen w-screen overflow-hidden" style="touch-action: none; overscroll-behavior: none;">
|
||||||
|
<Canvas
|
||||||
|
ref="canvasRef"
|
||||||
|
:items="data || []"
|
||||||
|
:base-gap="50"
|
||||||
|
:zoom-options="{
|
||||||
|
minZoom: 0.4,
|
||||||
|
maxZoom: 2.2,
|
||||||
|
zoomFactor: 1.08,
|
||||||
|
enableCtrl: true,
|
||||||
|
enableMeta: true,
|
||||||
|
enableAlt: true,
|
||||||
|
}"
|
||||||
|
class="absolute inset-0"
|
||||||
|
@item-click="handleItemClick"
|
||||||
|
>
|
||||||
|
<template #default="{ item, index, onItemClick }">
|
||||||
|
<Motion
|
||||||
|
:initial="{
|
||||||
|
opacity: 0,
|
||||||
|
filter: 'blur(20px)',
|
||||||
|
scale: 0.8,
|
||||||
|
}"
|
||||||
|
:animate="isImagesLoaded ? {
|
||||||
|
opacity: 1,
|
||||||
|
filter: 'blur(0px)',
|
||||||
|
scale: 1,
|
||||||
|
} : {
|
||||||
|
opacity: 0,
|
||||||
|
filter: 'blur(20px)',
|
||||||
|
scale: 0.8,
|
||||||
|
}"
|
||||||
|
:transition="{
|
||||||
|
duration: 0.8,
|
||||||
|
delay: isImagesLoaded ? Math.random() * 0.8 : 0,
|
||||||
|
ease: 'easeOut',
|
||||||
|
}"
|
||||||
|
class="group relative size-full select-none overflow-hidden hover:scale-105 active:scale-95 transition-all duration-300"
|
||||||
|
:class="[
|
||||||
|
isMobile ? 'cursor-default' : 'cursor-pointer',
|
||||||
|
index % 2 === 0 ? 'rotate-1' : '-rotate-1',
|
||||||
|
]"
|
||||||
|
data-canvas-item
|
||||||
|
@click="onItemClick"
|
||||||
|
@mouseenter="hoveredItemIndex = index"
|
||||||
|
@mouseleave="hoveredItemIndex = null"
|
||||||
|
>
|
||||||
|
<div class="absolute inset-0 rounded-2xl bg-gradient-to-br p-1 border-2 border-default/50">
|
||||||
|
<div class="relative size-full overflow-hidden rounded-xl">
|
||||||
|
<video
|
||||||
|
v-if="item && isVideo(item.image)"
|
||||||
|
:src="item.image"
|
||||||
|
class="size-full object-cover"
|
||||||
|
autoplay
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
playsinline
|
||||||
|
:draggable="false"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else-if="item"
|
||||||
|
:src="item.image"
|
||||||
|
:alt="item.title"
|
||||||
|
class="size-full object-cover"
|
||||||
|
:draggable="false"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- Item details overlay -->
|
||||||
|
<Motion
|
||||||
|
v-if="!isMobile"
|
||||||
|
:initial="{ opacity: 0, scale: 0.95 }"
|
||||||
|
:animate="hoveredItemIndex === index ? {
|
||||||
|
opacity: 1,
|
||||||
|
scale: 1,
|
||||||
|
transformOrigin: 'bottom left',
|
||||||
|
} : {
|
||||||
|
opacity: 0,
|
||||||
|
scale: 0.95,
|
||||||
|
transformOrigin: 'bottom left',
|
||||||
|
}"
|
||||||
|
:transition="{
|
||||||
|
duration: 0.2,
|
||||||
|
ease: 'easeOut',
|
||||||
|
}"
|
||||||
|
class="absolute inset-0 flex flex-col justify-end bg-gradient-to-t from-black/90 via-black/60 to-transparent backdrop-blur-[2px] p-4 rounded-xl"
|
||||||
|
>
|
||||||
|
<Motion
|
||||||
|
:initial="{ y: 20, opacity: 0 }"
|
||||||
|
:animate="hoveredItemIndex === index ? {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
} : {
|
||||||
|
y: 20,
|
||||||
|
opacity: 0,
|
||||||
|
}"
|
||||||
|
:transition="{
|
||||||
|
duration: 0.25,
|
||||||
|
delay: 0.05,
|
||||||
|
ease: 'easeOut',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="flex items-start gap-2">
|
||||||
|
<div class="flex-1">
|
||||||
|
<h3 class="font-medium text-white mb-1 line-clamp-2 leading-tight">
|
||||||
|
{{ item?.title }}
|
||||||
|
</h3>
|
||||||
|
<p
|
||||||
|
v-if="item?.description"
|
||||||
|
class="text-sm text-white/85 line-clamp-2"
|
||||||
|
>
|
||||||
|
{{ item.description }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<UIcon name="i-heroicons-arrow-top-right-on-square" class="size-4 text-white/70 flex-shrink-0 mt-0.5" />
|
||||||
|
</div>
|
||||||
|
</Motion>
|
||||||
|
</Motion>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Motion>
|
||||||
|
</template>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
<div v-if="canvasRef" class="fixed bottom-2 right-2 sm:bottom-4 sm:right-4 pointer-events-none">
|
||||||
|
<CanvasMinimap
|
||||||
|
:items="data || []"
|
||||||
|
:grid-items="canvasRef.gridItems || []"
|
||||||
|
:offset="canvasRef.offset || { x: 0, y: 0 }"
|
||||||
|
:zoom="canvasRef.zoom || 1"
|
||||||
|
:container-dimensions="canvasRef.containerDimensions || { width: 0, height: 0 }"
|
||||||
|
:canvas-bounds="canvasRef.canvasBounds || { width: 0, height: 0 }"
|
||||||
|
class="scale-85 sm:scale-100 origin-bottom-right"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pointer-events-none absolute bottom-2 left-2 sm:bottom-4 sm:left-4 z-40 flex flex-col gap-2">
|
||||||
|
<div class="rounded-lg bg-default/80 px-3 py-2 text-highlighted backdrop-blur-sm">
|
||||||
|
<p class="text-xs opacity-75">
|
||||||
|
<span class="sm:hidden">{{ data?.length }} items</span><span class="hidden sm:inline">Click items to open links • {{ data?.length }} items</span>
|
||||||
|
<span v-if="canvasRef?.zoom" class="ml-2 opacity-60">
|
||||||
|
• {{ Math.round((canvasRef.zoom || 1) * 100) }}%
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:block rounded-lg bg-default/80 px-3 py-2 text-highlighted backdrop-blur-sm">
|
||||||
|
<p class="text-xs opacity-75">
|
||||||
|
Hold Ctrl/⌘/Alt + scroll to zoom (40%-220%)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CanvasLoader
|
||||||
|
:progress="loaderProgress"
|
||||||
|
:is-visible="showLoader"
|
||||||
|
:title="t('canva.title')"
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
<main v-else>
|
||||||
|
{{ error }}
|
||||||
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ const route = useRoute()
|
|||||||
const { data: project } = await useAsyncData(`projects/${route.params.slug}`, () =>
|
const { data: project } = await useAsyncData(`projects/${route.params.slug}`, () =>
|
||||||
queryCollection('projects').path(`/projects/${route.params.slug}`).first())
|
queryCollection('projects').path(`/projects/${route.params.slug}`).first())
|
||||||
|
|
||||||
|
if (!project.value) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 404,
|
||||||
|
statusMessage: `Project "${route.params.slug}" not found`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: project.value?.title,
|
title: project.value?.title,
|
||||||
description: project.value?.description,
|
description: project.value?.description,
|
||||||
@@ -11,7 +18,7 @@ useSeoMeta({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main v-if="project" class="mt-8 md:mt-16 md:mb-36 mb-20">
|
<UContainer v-if="project" class="mt-8 md:mt-16 md:mb-36 mb-20">
|
||||||
<PostAlert class="mb-8" />
|
<PostAlert class="mb-8" />
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-end justify-between gap-2 flex-wrap">
|
<div class="flex items-end justify-between gap-2 flex-wrap">
|
||||||
@@ -51,7 +58,7 @@ useSeoMeta({
|
|||||||
/>
|
/>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
<PostFooter />
|
<PostFooter />
|
||||||
</main>
|
</UContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ const route = useRoute()
|
|||||||
const { data: writing } = await useAsyncData(`writings/${route.params.slug}`, () =>
|
const { data: writing } = await useAsyncData(`writings/${route.params.slug}`, () =>
|
||||||
queryCollection('writings').path(`/writings/${route.params.slug}`).first())
|
queryCollection('writings').path(`/writings/${route.params.slug}`).first())
|
||||||
|
|
||||||
|
if (!writing.value) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 404,
|
||||||
|
statusMessage: `Writing "${route.params.slug}" not found`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: writing.value?.title,
|
title: writing.value?.title,
|
||||||
description: writing.value?.description,
|
description: writing.value?.description,
|
||||||
|
|||||||
147
bun.lock
147
bun.lock
@@ -23,6 +23,7 @@
|
|||||||
"@vercel/speed-insights": "^1.2.0",
|
"@vercel/speed-insights": "^1.2.0",
|
||||||
"@vueuse/motion": "^3.0.3",
|
"@vueuse/motion": "^3.0.3",
|
||||||
"better-sqlite3": "^12.2.0",
|
"better-sqlite3": "^12.2.0",
|
||||||
|
"capture-website": "^4.2.0",
|
||||||
"eslint": "^9.0.0",
|
"eslint": "^9.0.0",
|
||||||
"nuxt": "^4.1.0",
|
"nuxt": "^4.1.0",
|
||||||
"rehype-katex": "^7.0.1",
|
"rehype-katex": "^7.0.1",
|
||||||
@@ -219,6 +220,16 @@
|
|||||||
|
|
||||||
"@floating-ui/vue": ["@floating-ui/vue@1.1.9", "", { "dependencies": { "@floating-ui/dom": "^1.7.4", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ=="],
|
"@floating-ui/vue": ["@floating-ui/vue@1.1.9", "", { "dependencies": { "@floating-ui/dom": "^1.7.4", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ=="],
|
||||||
|
|
||||||
|
"@ghostery/adblocker": ["@ghostery/adblocker@2.11.6", "", { "dependencies": { "@ghostery/adblocker-content": "^2.11.6", "@ghostery/adblocker-extended-selectors": "^2.11.6", "@ghostery/url-parser": "^1.3.0", "@remusao/guess-url-type": "^2.1.0", "@remusao/small": "^2.1.0", "@remusao/smaz": "^2.2.0", "tldts-experimental": "^7.0.12" } }, "sha512-fUkLvWDObCMjjwUHw0/jt3N11wT7FBWJVFUXsUN4Do7J3Henp63JZQw1RYv2Y15NT0idVERR9IhbjJdd3/w48w=="],
|
||||||
|
|
||||||
|
"@ghostery/adblocker-content": ["@ghostery/adblocker-content@2.11.6", "", { "dependencies": { "@ghostery/adblocker-extended-selectors": "^2.11.6" } }, "sha512-K+hJR27fYpRGoUQnza2p0BmN86htN1ASoRxF73mAdf1CNDSyfPNCNlpoKt83Z9CbYBdEglXOWItazB9hRMs7gw=="],
|
||||||
|
|
||||||
|
"@ghostery/adblocker-extended-selectors": ["@ghostery/adblocker-extended-selectors@2.11.6", "", {}, "sha512-jFKNwwWYYxMHaIqGCLO/sR8oRBcGcVD3bCLPZ9wLBoTMTtCnwdXRlMxWwnNi7Bw5PSw7aw8w6hcEfHdcbdU+Qw=="],
|
||||||
|
|
||||||
|
"@ghostery/adblocker-puppeteer": ["@ghostery/adblocker-puppeteer@2.11.6", "", { "dependencies": { "@ghostery/adblocker": "^2.11.6", "@ghostery/adblocker-content": "^2.11.6", "tldts-experimental": "^7.0.12" }, "peerDependencies": { "puppeteer": ">5" } }, "sha512-Hncfvucl1VkVHpvC1r/H4G4eEHfrhs3VYrOvVU7bHrlw12lPwvzUF+hiQuduIzH1kxyrowRHdMgDA5Nx5x8h/g=="],
|
||||||
|
|
||||||
|
"@ghostery/url-parser": ["@ghostery/url-parser@1.3.0", "", { "dependencies": { "tldts-experimental": "^7.0.8" } }, "sha512-FEzdSeiva0Mt3bR4xePFzthhjT4IzvA5QTvS1xXkNyLpMGeq40mb3V2fSs0ZItRaP9IybZthDfHUSbQ1HLdx4Q=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||||
@@ -491,6 +502,20 @@
|
|||||||
|
|
||||||
"@poppinss/exception": ["@poppinss/exception@1.2.2", "", {}, "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg=="],
|
"@poppinss/exception": ["@poppinss/exception@1.2.2", "", {}, "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg=="],
|
||||||
|
|
||||||
|
"@puppeteer/browsers": ["@puppeteer/browsers@2.6.1", "", { "dependencies": { "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg=="],
|
||||||
|
|
||||||
|
"@remusao/guess-url-type": ["@remusao/guess-url-type@2.1.0", "", {}, "sha512-zI3dlTUxpjvx2GCxp9nLOSK5yEIqDCpxlAVGwb2Y49RKkS72oeNaxxo+VWS5+XQ5+Mf8Zfp9ZXIlk+G5eoEN8A=="],
|
||||||
|
|
||||||
|
"@remusao/small": ["@remusao/small@2.1.0", "", {}, "sha512-Y1kyjZp7JU7dXdyOdxHVNfoTr1XLZJTyQP36/esZUU/WRWq9XY0PV2HsE3CsIHuaTf4pvgWv2pvzvnZ//UHIJQ=="],
|
||||||
|
|
||||||
|
"@remusao/smaz": ["@remusao/smaz@2.2.0", "", { "dependencies": { "@remusao/smaz-compress": "^2.2.0", "@remusao/smaz-decompress": "^2.2.0" } }, "sha512-eSd3Qs0ELP/e7tU1SI5RWXcCn9KjDgvBY+KtWbL4i2QvvHhJOfdIt4v0AA3S5BbLWAr5dCEC7C4LUfogDm6q/Q=="],
|
||||||
|
|
||||||
|
"@remusao/smaz-compress": ["@remusao/smaz-compress@2.2.0", "", { "dependencies": { "@remusao/trie": "^2.1.0" } }, "sha512-TXpTPgILRUYOt2rEe0+9PC12xULPvBqeMpmipzB9A7oM4fa9Ztvy9lLYzPTd7tiQEeoNa1pmxihpKfJtsxnM/w=="],
|
||||||
|
|
||||||
|
"@remusao/smaz-decompress": ["@remusao/smaz-decompress@2.2.0", "", {}, "sha512-ERAPwxPaA0/yg4hkNU7T2S+lnp9jj1sApcQMtOyROvOQyo+Zuh6Hn/oRcXr8mmjlYzyRaC7E6r3mT1nrdHR6pg=="],
|
||||||
|
|
||||||
|
"@remusao/trie": ["@remusao/trie@2.1.0", "", {}, "sha512-Er3Q8q0/2OcCJPQYJOPLmCuqO0wu7cav3SPtpjlxSbjFi1x+A1pZkkLD6c9q2rGEkGW/tkrRzfrhNMt8VQjzXg=="],
|
||||||
|
|
||||||
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-beta.34", "", { "os": "android", "cpu": "arm64" }, "sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA=="],
|
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-beta.34", "", { "os": "android", "cpu": "arm64" }, "sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA=="],
|
||||||
|
|
||||||
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.34", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ=="],
|
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.34", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ=="],
|
||||||
@@ -655,6 +680,8 @@
|
|||||||
|
|
||||||
"@tanstack/vue-virtual": ["@tanstack/vue-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "vue": "^2.7.0 || ^3.0.0" } }, "sha512-vhF7kEU9EXWXh+HdAwKJ2m3xaOnTTmgcdXcF2pim8g4GvI7eRrk2YRuV5nUlZnd/NbCIX4/Ja2OZu5EjJL06Ww=="],
|
"@tanstack/vue-virtual": ["@tanstack/vue-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "vue": "^2.7.0 || ^3.0.0" } }, "sha512-vhF7kEU9EXWXh+HdAwKJ2m3xaOnTTmgcdXcF2pim8g4GvI7eRrk2YRuV5nUlZnd/NbCIX4/Ja2OZu5EjJL06Ww=="],
|
||||||
|
|
||||||
|
"@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
|
||||||
|
|
||||||
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
|
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
|
||||||
|
|
||||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
|
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
|
||||||
@@ -685,6 +712,8 @@
|
|||||||
|
|
||||||
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="],
|
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="],
|
||||||
|
|
||||||
|
"@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.42.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/type-utils": "8.42.0", "@typescript-eslint/utils": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.42.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.42.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/type-utils": "8.42.0", "@typescript-eslint/utils": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.42.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.42.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.42.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg=="],
|
||||||
@@ -855,6 +884,8 @@
|
|||||||
|
|
||||||
"ast-kit": ["ast-kit@2.1.2", "", { "dependencies": { "@babel/parser": "^7.28.0", "pathe": "^2.0.3" } }, "sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g=="],
|
"ast-kit": ["ast-kit@2.1.2", "", { "dependencies": { "@babel/parser": "^7.28.0", "pathe": "^2.0.3" } }, "sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g=="],
|
||||||
|
|
||||||
|
"ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="],
|
||||||
|
|
||||||
"ast-walker-scope": ["ast-walker-scope@0.8.2", "", { "dependencies": { "@babel/parser": "^7.28.3", "ast-kit": "^2.1.2" } }, "sha512-3pYeLyDZ6nJew9QeBhS4Nly02269Dkdk32+zdbbKmL6n4ZuaGorwwA+xx12xgOciA8BF1w9x+dlH7oUkFTW91w=="],
|
"ast-walker-scope": ["ast-walker-scope@0.8.2", "", { "dependencies": { "@babel/parser": "^7.28.3", "ast-kit": "^2.1.2" } }, "sha512-3pYeLyDZ6nJew9QeBhS4Nly02269Dkdk32+zdbbKmL6n4ZuaGorwwA+xx12xgOciA8BF1w9x+dlH7oUkFTW91w=="],
|
||||||
|
|
||||||
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
||||||
@@ -881,6 +912,8 @@
|
|||||||
|
|
||||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||||
|
|
||||||
|
"basic-ftp": ["basic-ftp@5.0.5", "", {}, "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg=="],
|
||||||
|
|
||||||
"better-sqlite3": ["better-sqlite3@12.2.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ=="],
|
"better-sqlite3": ["better-sqlite3@12.2.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ=="],
|
||||||
|
|
||||||
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
||||||
@@ -903,7 +936,7 @@
|
|||||||
|
|
||||||
"browserslist": ["browserslist@4.25.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="],
|
"browserslist": ["browserslist@4.25.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="],
|
||||||
|
|
||||||
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||||
|
|
||||||
"buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="],
|
"buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="],
|
||||||
|
|
||||||
@@ -925,6 +958,8 @@
|
|||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001739", "", {}, "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001739", "", {}, "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA=="],
|
||||||
|
|
||||||
|
"capture-website": ["capture-website@4.2.0", "", { "dependencies": { "@ghostery/adblocker-puppeteer": "^2.1.1", "file-url": "^4.0.0", "puppeteer": "^23.10.0", "tough-cookie": "^5.0.0" } }, "sha512-EmkSn36CXTC8tUsS6aNmvvsdpfVTYYkuRp7U5bV9gcJwcDbqqA5c0Op/iskYPKtDdOkuVp61mjn/LLywX0h7cw=="],
|
||||||
|
|
||||||
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
@@ -945,6 +980,8 @@
|
|||||||
|
|
||||||
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
||||||
|
|
||||||
|
"chromium-bidi": ["chromium-bidi@0.11.0", "", { "dependencies": { "mitt": "3.0.1", "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-6CJWHkNRoyZyjV9Rwv2lYONZf1Xm0IuDyNq97nwSsxxP3wf5Bwy15K5rOvVKMtJ127jJBmxFUanSAOjgFRxgrA=="],
|
||||||
|
|
||||||
"ci-info": ["ci-info@4.3.0", "", {}, "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ=="],
|
"ci-info": ["ci-info@4.3.0", "", {}, "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ=="],
|
||||||
|
|
||||||
"citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
|
"citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
|
||||||
@@ -1001,6 +1038,8 @@
|
|||||||
|
|
||||||
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
||||||
|
|
||||||
|
"cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="],
|
||||||
|
|
||||||
"crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="],
|
"crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="],
|
||||||
|
|
||||||
"crc32-stream": ["crc32-stream@6.0.0", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" } }, "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g=="],
|
"crc32-stream": ["crc32-stream@6.0.0", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" } }, "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g=="],
|
||||||
@@ -1035,6 +1074,8 @@
|
|||||||
|
|
||||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
|
||||||
|
|
||||||
"db0": ["db0@0.3.2", "", { "peerDependencies": { "@electric-sql/pglite": "*", "@libsql/client": "*", "better-sqlite3": "*", "drizzle-orm": "*", "mysql2": "*", "sqlite3": "*" }, "optionalPeers": ["@electric-sql/pglite", "@libsql/client", "better-sqlite3", "drizzle-orm", "mysql2", "sqlite3"] }, "sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw=="],
|
"db0": ["db0@0.3.2", "", { "peerDependencies": { "@electric-sql/pglite": "*", "@libsql/client": "*", "better-sqlite3": "*", "drizzle-orm": "*", "mysql2": "*", "sqlite3": "*" }, "optionalPeers": ["@electric-sql/pglite", "@libsql/client", "better-sqlite3", "drizzle-orm", "mysql2", "sqlite3"] }, "sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw=="],
|
||||||
|
|
||||||
"de-indent": ["de-indent@1.0.2", "", {}, "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="],
|
"de-indent": ["de-indent@1.0.2", "", {}, "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="],
|
||||||
@@ -1059,6 +1100,8 @@
|
|||||||
|
|
||||||
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
|
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
|
||||||
|
|
||||||
|
"degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="],
|
||||||
|
|
||||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
||||||
|
|
||||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||||
@@ -1075,6 +1118,8 @@
|
|||||||
|
|
||||||
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
|
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
|
||||||
|
|
||||||
|
"devtools-protocol": ["devtools-protocol@0.0.1367902", "", {}, "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg=="],
|
||||||
|
|
||||||
"dfa": ["dfa@1.2.0", "", {}, "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="],
|
"dfa": ["dfa@1.2.0", "", {}, "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="],
|
||||||
|
|
||||||
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
|
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
|
||||||
@@ -1137,6 +1182,10 @@
|
|||||||
|
|
||||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||||
|
|
||||||
|
"env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
|
||||||
|
|
||||||
|
"error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="],
|
||||||
|
|
||||||
"error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="],
|
"error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="],
|
||||||
|
|
||||||
"errx": ["errx@0.1.0", "", {}, "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q=="],
|
"errx": ["errx@0.1.0", "", {}, "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q=="],
|
||||||
@@ -1239,6 +1288,8 @@
|
|||||||
|
|
||||||
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
||||||
|
|
||||||
|
"extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="],
|
||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
|
|
||||||
"fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
|
"fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
|
||||||
@@ -1255,12 +1306,16 @@
|
|||||||
|
|
||||||
"fault": ["fault@2.0.1", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ=="],
|
"fault": ["fault@2.0.1", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ=="],
|
||||||
|
|
||||||
|
"fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
|
||||||
|
|
||||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||||
|
|
||||||
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
|
||||||
|
|
||||||
|
"file-url": ["file-url@4.0.0", "", {}, "sha512-vRCdScQ6j3Ku6Kd7W1kZk9c++5SqD6Xz5Jotrjr/nkY714M14RFHy/AAVA2WQvpsqVAVgTbDrYyBpU205F0cLw=="],
|
||||||
|
|
||||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||||
|
|
||||||
"find-up": ["find-up@7.0.0", "", { "dependencies": { "locate-path": "^7.2.0", "path-exists": "^5.0.0", "unicorn-magic": "^0.1.0" } }, "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g=="],
|
"find-up": ["find-up@7.0.0", "", { "dependencies": { "locate-path": "^7.2.0", "path-exists": "^5.0.0", "unicorn-magic": "^0.1.0" } }, "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g=="],
|
||||||
@@ -1307,6 +1362,8 @@
|
|||||||
|
|
||||||
"get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
|
"get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
|
||||||
|
|
||||||
|
"get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="],
|
||||||
|
|
||||||
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
||||||
|
|
||||||
"git-up": ["git-up@8.1.1", "", { "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^9.2.0" } }, "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g=="],
|
"git-up": ["git-up@8.1.1", "", { "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^9.2.0" } }, "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g=="],
|
||||||
@@ -1397,6 +1454,8 @@
|
|||||||
|
|
||||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||||
|
|
||||||
|
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
||||||
|
|
||||||
"http-shutdown": ["http-shutdown@1.2.2", "", {}, "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw=="],
|
"http-shutdown": ["http-shutdown@1.2.2", "", {}, "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw=="],
|
||||||
|
|
||||||
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||||
@@ -1425,6 +1484,8 @@
|
|||||||
|
|
||||||
"ioredis": ["ioredis@5.7.0", "", { "dependencies": { "@ioredis/commands": "^1.3.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g=="],
|
"ioredis": ["ioredis@5.7.0", "", { "dependencies": { "@ioredis/commands": "^1.3.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g=="],
|
||||||
|
|
||||||
|
"ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="],
|
||||||
|
|
||||||
"ipx": ["ipx@2.1.1", "", { "dependencies": { "@fastify/accept-negotiator": "^1.1.0", "citty": "^0.1.5", "consola": "^3.2.3", "defu": "^6.1.4", "destr": "^2.0.2", "etag": "^1.8.1", "h3": "^1.10.0", "image-meta": "^0.2.0", "listhen": "^1.5.6", "ofetch": "^1.3.3", "pathe": "^1.1.2", "sharp": "^0.32.6", "svgo": "^3.2.0", "ufo": "^1.3.2", "unstorage": "^1.10.1", "xss": "^1.0.14" }, "bin": { "ipx": "bin/ipx.mjs" } }, "sha512-XuM9FEGOT+/45mfAWZ5ykwkZ/oE7vWpd1iWjRffMWlwAYIRzb/xD6wZhQ4BzmPMX6Ov5dqK0wUyD0OEN9oWT6g=="],
|
"ipx": ["ipx@2.1.1", "", { "dependencies": { "@fastify/accept-negotiator": "^1.1.0", "citty": "^0.1.5", "consola": "^3.2.3", "defu": "^6.1.4", "destr": "^2.0.2", "etag": "^1.8.1", "h3": "^1.10.0", "image-meta": "^0.2.0", "listhen": "^1.5.6", "ofetch": "^1.3.3", "pathe": "^1.1.2", "sharp": "^0.32.6", "svgo": "^3.2.0", "ufo": "^1.3.2", "unstorage": "^1.10.1", "xss": "^1.0.14" }, "bin": { "ipx": "bin/ipx.mjs" } }, "sha512-XuM9FEGOT+/45mfAWZ5ykwkZ/oE7vWpd1iWjRffMWlwAYIRzb/xD6wZhQ4BzmPMX6Ov5dqK0wUyD0OEN9oWT6g=="],
|
||||||
|
|
||||||
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
|
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
|
||||||
@@ -1435,7 +1496,7 @@
|
|||||||
|
|
||||||
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
|
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
|
||||||
|
|
||||||
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
|
"is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
|
||||||
|
|
||||||
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
||||||
|
|
||||||
@@ -1497,6 +1558,8 @@
|
|||||||
|
|
||||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||||
|
|
||||||
|
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
|
||||||
|
|
||||||
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
|
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
|
||||||
|
|
||||||
"json-schema-to-typescript": ["json-schema-to-typescript@15.0.4", "", { "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.5.5", "@types/json-schema": "^7.0.15", "@types/lodash": "^4.17.7", "is-glob": "^4.0.3", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "minimist": "^1.2.8", "prettier": "^3.2.5", "tinyglobby": "^0.2.9" }, "bin": { "json2ts": "dist/src/cli.js" } }, "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ=="],
|
"json-schema-to-typescript": ["json-schema-to-typescript@15.0.4", "", { "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.5.5", "@types/json-schema": "^7.0.15", "@types/lodash": "^4.17.7", "is-glob": "^4.0.3", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "minimist": "^1.2.8", "prettier": "^3.2.5", "tinyglobby": "^0.2.9" }, "bin": { "json2ts": "dist/src/cli.js" } }, "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ=="],
|
||||||
@@ -1555,6 +1618,8 @@
|
|||||||
|
|
||||||
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
|
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
|
||||||
|
|
||||||
|
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||||
|
|
||||||
"listhen": ["listhen@1.9.0", "", { "dependencies": { "@parcel/watcher": "^2.4.1", "@parcel/watcher-wasm": "^2.4.1", "citty": "^0.1.6", "clipboardy": "^4.0.0", "consola": "^3.2.3", "crossws": ">=0.2.0 <0.4.0", "defu": "^6.1.4", "get-port-please": "^3.1.2", "h3": "^1.12.0", "http-shutdown": "^1.2.2", "jiti": "^2.1.2", "mlly": "^1.7.1", "node-forge": "^1.3.1", "pathe": "^1.1.2", "std-env": "^3.7.0", "ufo": "^1.5.4", "untun": "^0.1.3", "uqr": "^0.1.2" }, "bin": { "listen": "bin/listhen.mjs", "listhen": "bin/listhen.mjs" } }, "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg=="],
|
"listhen": ["listhen@1.9.0", "", { "dependencies": { "@parcel/watcher": "^2.4.1", "@parcel/watcher-wasm": "^2.4.1", "citty": "^0.1.6", "clipboardy": "^4.0.0", "consola": "^3.2.3", "crossws": ">=0.2.0 <0.4.0", "defu": "^6.1.4", "get-port-please": "^3.1.2", "h3": "^1.12.0", "http-shutdown": "^1.2.2", "jiti": "^2.1.2", "mlly": "^1.7.1", "node-forge": "^1.3.1", "pathe": "^1.1.2", "std-env": "^3.7.0", "ufo": "^1.5.4", "untun": "^0.1.3", "uqr": "^0.1.2" }, "bin": { "listen": "bin/listhen.mjs", "listhen": "bin/listhen.mjs" } }, "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg=="],
|
||||||
|
|
||||||
"load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="],
|
"load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="],
|
||||||
@@ -1745,6 +1810,8 @@
|
|||||||
|
|
||||||
"natural-orderby": ["natural-orderby@5.0.0", "", {}, "sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg=="],
|
"natural-orderby": ["natural-orderby@5.0.0", "", {}, "sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg=="],
|
||||||
|
|
||||||
|
"netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
|
||||||
|
|
||||||
"nitropack": ["nitropack@2.12.5", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.0", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^0.30.1", "archiver": "^7.0.1", "c12": "^3.2.0", "chokidar": "^4.0.3", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.1.0", "crossws": "^0.3.5", "db0": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^9.0.0", "esbuild": "^0.25.9", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.7", "globby": "^14.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.4", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.7.0", "jiti": "^2.5.1", "klona": "^2.0.6", "knitwork": "^1.2.0", "listhen": "^1.9.0", "magic-string": "^0.30.18", "magicast": "^0.3.5", "mime": "^4.0.7", "mlly": "^1.8.0", "node-fetch-native": "^1.6.7", "node-mock-http": "^1.0.2", "ofetch": "^1.4.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "pretty-bytes": "^7.0.1", "radix3": "^1.1.2", "rollup": "^4.50.0", "rollup-plugin-visualizer": "^6.0.3", "scule": "^1.3.0", "semver": "^7.7.2", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.0", "source-map": "^0.7.6", "std-env": "^3.9.0", "ufo": "^1.6.1", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.4.1", "unenv": "2.0.0-rc.20", "unimport": "^5.2.0", "unplugin-utils": "^0.3.0", "unstorage": "^1.17.0", "untyped": "^2.0.0", "unwasm": "^0.3.11", "youch": "4.1.0-beta.8", "youch-core": "^0.3.3" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-KDTFhATOzqWHXFZkNlAH9J989Wibpl6s38eaYZj/Km2GbcUBLdcDxL4x7vd9pHWhD1Yk1u5oLh8+MsqJeQ7GMA=="],
|
"nitropack": ["nitropack@2.12.5", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.0", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^0.30.1", "archiver": "^7.0.1", "c12": "^3.2.0", "chokidar": "^4.0.3", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.1.0", "crossws": "^0.3.5", "db0": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^9.0.0", "esbuild": "^0.25.9", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.7", "globby": "^14.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.4", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.7.0", "jiti": "^2.5.1", "klona": "^2.0.6", "knitwork": "^1.2.0", "listhen": "^1.9.0", "magic-string": "^0.30.18", "magicast": "^0.3.5", "mime": "^4.0.7", "mlly": "^1.8.0", "node-fetch-native": "^1.6.7", "node-mock-http": "^1.0.2", "ofetch": "^1.4.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "pretty-bytes": "^7.0.1", "radix3": "^1.1.2", "rollup": "^4.50.0", "rollup-plugin-visualizer": "^6.0.3", "scule": "^1.3.0", "semver": "^7.7.2", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.0", "source-map": "^0.7.6", "std-env": "^3.9.0", "ufo": "^1.6.1", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.4.1", "unenv": "2.0.0-rc.20", "unimport": "^5.2.0", "unplugin-utils": "^0.3.0", "unstorage": "^1.17.0", "untyped": "^2.0.0", "unwasm": "^0.3.11", "youch": "4.1.0-beta.8", "youch-core": "^0.3.3" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-KDTFhATOzqWHXFZkNlAH9J989Wibpl6s38eaYZj/Km2GbcUBLdcDxL4x7vd9pHWhD1Yk1u5oLh8+MsqJeQ7GMA=="],
|
||||||
|
|
||||||
"node-abi": ["node-abi@3.77.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ=="],
|
"node-abi": ["node-abi@3.77.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ=="],
|
||||||
@@ -1815,6 +1882,10 @@
|
|||||||
|
|
||||||
"p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="],
|
"p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="],
|
||||||
|
|
||||||
|
"pac-proxy-agent": ["pac-proxy-agent@7.2.0", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.5" } }, "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA=="],
|
||||||
|
|
||||||
|
"pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="],
|
||||||
|
|
||||||
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
|
||||||
|
|
||||||
"package-manager-detector": ["package-manager-detector@1.3.0", "", {}, "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ=="],
|
"package-manager-detector": ["package-manager-detector@1.3.0", "", {}, "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ=="],
|
||||||
@@ -1829,6 +1900,8 @@
|
|||||||
|
|
||||||
"parse-imports-exports": ["parse-imports-exports@0.2.4", "", { "dependencies": { "parse-statements": "1.0.11" } }, "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ=="],
|
"parse-imports-exports": ["parse-imports-exports@0.2.4", "", { "dependencies": { "parse-statements": "1.0.11" } }, "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ=="],
|
||||||
|
|
||||||
|
"parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
|
||||||
|
|
||||||
"parse-path": ["parse-path@7.1.0", "", { "dependencies": { "protocols": "^2.0.0" } }, "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw=="],
|
"parse-path": ["parse-path@7.1.0", "", { "dependencies": { "protocols": "^2.0.0" } }, "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw=="],
|
||||||
|
|
||||||
"parse-statements": ["parse-statements@1.0.11", "", {}, "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA=="],
|
"parse-statements": ["parse-statements@1.0.11", "", {}, "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA=="],
|
||||||
@@ -1853,6 +1926,8 @@
|
|||||||
|
|
||||||
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
|
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
|
||||||
|
|
||||||
|
"pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
||||||
|
|
||||||
"perfect-debounce": ["perfect-debounce@2.0.0", "", {}, "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow=="],
|
"perfect-debounce": ["perfect-debounce@2.0.0", "", {}, "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow=="],
|
||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
@@ -1941,16 +2016,26 @@
|
|||||||
|
|
||||||
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
||||||
|
|
||||||
|
"progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
|
||||||
|
|
||||||
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
||||||
|
|
||||||
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
||||||
|
|
||||||
"protocols": ["protocols@2.0.2", "", {}, "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ=="],
|
"protocols": ["protocols@2.0.2", "", {}, "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ=="],
|
||||||
|
|
||||||
|
"proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="],
|
||||||
|
|
||||||
|
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
||||||
|
|
||||||
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
|
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
|
"puppeteer": ["puppeteer@23.11.1", "", { "dependencies": { "@puppeteer/browsers": "2.6.1", "chromium-bidi": "0.11.0", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1367902", "puppeteer-core": "23.11.1", "typed-query-selector": "^2.12.0" }, "bin": { "puppeteer": "lib/cjs/puppeteer/node/cli.js" } }, "sha512-53uIX3KR5en8l7Vd8n5DUv90Ae9QDQsyIthaUFVzwV6yU750RjqRznEtNMBT20VthqAdemnJN+hxVdmMHKt7Zw=="],
|
||||||
|
|
||||||
|
"puppeteer-core": ["puppeteer-core@23.11.1", "", { "dependencies": { "@puppeteer/browsers": "2.6.1", "chromium-bidi": "0.11.0", "debug": "^4.4.0", "devtools-protocol": "0.0.1367902", "typed-query-selector": "^2.12.0", "ws": "^8.18.0" } }, "sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg=="],
|
||||||
|
|
||||||
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
|
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
@@ -2095,12 +2180,18 @@
|
|||||||
|
|
||||||
"slugify": ["slugify@1.6.6", "", {}, "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw=="],
|
"slugify": ["slugify@1.6.6", "", {}, "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw=="],
|
||||||
|
|
||||||
|
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
|
||||||
|
|
||||||
"smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="],
|
"smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="],
|
||||||
|
|
||||||
"socket.io-client": ["socket.io-client@4.8.1", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" } }, "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ=="],
|
"socket.io-client": ["socket.io-client@4.8.1", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" } }, "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ=="],
|
||||||
|
|
||||||
"socket.io-parser": ["socket.io-parser@4.2.4", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" } }, "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew=="],
|
"socket.io-parser": ["socket.io-parser@4.2.4", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" } }, "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew=="],
|
||||||
|
|
||||||
|
"socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
|
||||||
|
|
||||||
|
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
|
||||||
|
|
||||||
"source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
"source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
@@ -2185,6 +2276,8 @@
|
|||||||
|
|
||||||
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
|
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
|
||||||
|
|
||||||
|
"through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="],
|
||||||
|
|
||||||
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
|
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
|
||||||
|
|
||||||
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
||||||
@@ -2193,6 +2286,12 @@
|
|||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
||||||
|
|
||||||
|
"tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="],
|
||||||
|
|
||||||
|
"tldts-core": ["tldts-core@7.0.12", "", {}, "sha512-3K76aXywJFduGRsOYoY5JzINLs/WMlOkeDwPL+8OCPq2Rh39gkSDtWAxdJQlWjpun/xF/LHf29yqCi6VC/rHDA=="],
|
||||||
|
|
||||||
|
"tldts-experimental": ["tldts-experimental@7.0.12", "", { "dependencies": { "tldts-core": "^7.0.12" } }, "sha512-riDDp/JrJJuh/2GV1Tgg6OnOwcWlgleBKi4/xkhd0DW7tvvmNjmWXCh2nj7Z2G1k9S/AGN4RiiPRbvhGJUCxeg=="],
|
||||||
|
|
||||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||||
|
|
||||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||||
@@ -2203,6 +2302,8 @@
|
|||||||
|
|
||||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||||
|
|
||||||
|
"tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="],
|
||||||
|
|
||||||
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
|
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
|
||||||
|
|
||||||
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||||
@@ -2225,12 +2326,16 @@
|
|||||||
|
|
||||||
"type-level-regexp": ["type-level-regexp@0.1.17", "", {}, "sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg=="],
|
"type-level-regexp": ["type-level-regexp@0.1.17", "", {}, "sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg=="],
|
||||||
|
|
||||||
|
"typed-query-selector": ["typed-query-selector@2.12.0", "", {}, "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||||
|
|
||||||
"ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="],
|
"ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="],
|
||||||
|
|
||||||
"ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="],
|
"ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="],
|
||||||
|
|
||||||
|
"unbzip2-stream": ["unbzip2-stream@1.4.3", "", { "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="],
|
||||||
|
|
||||||
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
||||||
|
|
||||||
"unctx": ["unctx@2.4.1", "", { "dependencies": { "acorn": "^8.14.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.17", "unplugin": "^2.1.0" } }, "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg=="],
|
"unctx": ["unctx@2.4.1", "", { "dependencies": { "acorn": "^8.14.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.17", "unplugin": "^2.1.0" } }, "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg=="],
|
||||||
@@ -2385,6 +2490,8 @@
|
|||||||
|
|
||||||
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||||
|
|
||||||
|
"yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
|
||||||
|
|
||||||
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
|
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
|
||||||
|
|
||||||
"youch": ["youch@4.1.0-beta.11", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-sQi6PERyO/mT8w564ojOVeAlYTtVQmC2GaktQAf+IdI75/GKIggosBuvyVXvEV+FATAT6RbLdIjFoiIId4ozoQ=="],
|
"youch": ["youch@4.1.0-beta.11", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-sQi6PERyO/mT8w564ojOVeAlYTtVQmC2GaktQAf+IdI75/GKIggosBuvyVXvEV+FATAT6RbLdIjFoiIId4ozoQ=="],
|
||||||
@@ -2499,6 +2606,10 @@
|
|||||||
|
|
||||||
"@poppinss/dumper/supports-color": ["supports-color@10.2.0", "", {}, "sha512-5eG9FQjEjDbAlI5+kdpdyPIBMRH4GfTVDGREVupaZHmVoppknhM29b/S9BkQz7cathp85BVgRi/As3Siln7e0Q=="],
|
"@poppinss/dumper/supports-color": ["supports-color@10.2.0", "", {}, "sha512-5eG9FQjEjDbAlI5+kdpdyPIBMRH4GfTVDGREVupaZHmVoppknhM29b/S9BkQz7cathp85BVgRi/As3Siln7e0Q=="],
|
||||||
|
|
||||||
|
"@puppeteer/browsers/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"@puppeteer/browsers/tar-fs": ["tar-fs@3.1.0", "", { "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0" } }, "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w=="],
|
||||||
|
|
||||||
"@rollup/plugin-commonjs/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"@rollup/plugin-commonjs/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
"@rollup/plugin-inject/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"@rollup/plugin-inject/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
@@ -2557,12 +2668,14 @@
|
|||||||
|
|
||||||
"aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
"ast-types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
"bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
"c12/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
"c12/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
||||||
|
|
||||||
|
"chromium-bidi/zod": ["zod@3.23.8", "", {}, "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="],
|
||||||
|
|
||||||
"clean-regexp/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
"clean-regexp/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
||||||
|
|
||||||
"cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
"cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
@@ -2597,12 +2710,18 @@
|
|||||||
|
|
||||||
"eslint-plugin-yml/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
"eslint-plugin-yml/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"extract-zip/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
||||||
|
|
||||||
"fast-glob/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
"fast-glob/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"framer-motion/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"framer-motion/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"get-uri/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="],
|
"global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="],
|
||||||
@@ -2617,6 +2736,8 @@
|
|||||||
|
|
||||||
"http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
|
"http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
|
||||||
|
|
||||||
|
"http-proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"https-proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
"https-proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"ioredis/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
"ioredis/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
@@ -2665,6 +2786,8 @@
|
|||||||
|
|
||||||
"nuxt-component-meta/@nuxt/kit": ["@nuxt/kit@4.1.0", "", { "dependencies": { "c12": "^3.2.0", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.7", "ignore": "^7.0.5", "jiti": "^2.5.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.2", "std-env": "^3.9.0", "tinyglobby": "^0.2.14", "ufo": "^1.6.1", "unctx": "^2.4.1", "unimport": "^5.2.0", "untyped": "^2.0.0" } }, "sha512-QY6wgano7szNP5hLUKNeZTLdx009F2n+a8L9M4Wzk1jhubvENc81jLWHAnaJOogRpqMeEqZcjHRfqTx+J1/lfQ=="],
|
"nuxt-component-meta/@nuxt/kit": ["@nuxt/kit@4.1.0", "", { "dependencies": { "c12": "^3.2.0", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.7", "ignore": "^7.0.5", "jiti": "^2.5.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.2", "std-env": "^3.9.0", "tinyglobby": "^0.2.14", "ufo": "^1.6.1", "unctx": "^2.4.1", "unimport": "^5.2.0", "untyped": "^2.0.0" } }, "sha512-QY6wgano7szNP5hLUKNeZTLdx009F2n+a8L9M4Wzk1jhubvENc81jLWHAnaJOogRpqMeEqZcjHRfqTx+J1/lfQ=="],
|
||||||
|
|
||||||
|
"pac-proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
||||||
|
|
||||||
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||||
@@ -2685,8 +2808,16 @@
|
|||||||
|
|
||||||
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
||||||
|
|
||||||
|
"proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||||
|
|
||||||
|
"puppeteer-core/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||||
|
|
||||||
|
"readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
||||||
|
|
||||||
"readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
|
"readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
|
||||||
|
|
||||||
"regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="],
|
"regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="],
|
||||||
@@ -2709,10 +2840,14 @@
|
|||||||
|
|
||||||
"simple-git/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
"simple-git/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"simple-swizzle/is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
|
||||||
|
|
||||||
"socket.io-client/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
"socket.io-client/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
||||||
|
|
||||||
"socket.io-parser/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
"socket.io-parser/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
||||||
|
|
||||||
|
"socks-proxy-agent/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||||
|
|
||||||
"string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
"string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
@@ -2733,6 +2868,8 @@
|
|||||||
|
|
||||||
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
||||||
|
|
||||||
|
"tldts/tldts-core": ["tldts-core@6.1.86", "", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="],
|
||||||
|
|
||||||
"toml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"toml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
"unimport/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
"unimport/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
||||||
@@ -2765,6 +2902,8 @@
|
|||||||
|
|
||||||
"yaml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"yaml-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
|
"yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||||
|
|
||||||
"@intlify/vue-i18n-extensions/vue-i18n/@intlify/core-base": ["@intlify/core-base@10.0.8", "", { "dependencies": { "@intlify/message-compiler": "10.0.8", "@intlify/shared": "10.0.8" } }, "sha512-FoHslNWSoHjdUBLy35bpm9PV/0LVI/DSv9L6Km6J2ad8r/mm0VaGg06C40FqlE8u2ADcGUM60lyoU7Myo4WNZQ=="],
|
"@intlify/vue-i18n-extensions/vue-i18n/@intlify/core-base": ["@intlify/core-base@10.0.8", "", { "dependencies": { "@intlify/message-compiler": "10.0.8", "@intlify/shared": "10.0.8" } }, "sha512-FoHslNWSoHjdUBLy35bpm9PV/0LVI/DSv9L6Km6J2ad8r/mm0VaGg06C40FqlE8u2ADcGUM60lyoU7Myo4WNZQ=="],
|
||||||
@@ -2793,6 +2932,8 @@
|
|||||||
|
|
||||||
"@nuxtjs/i18n/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
"@nuxtjs/i18n/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
||||||
|
"@puppeteer/browsers/tar-fs/tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
|
|
||||||
"cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
"cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ export const collections = {
|
|||||||
tags: z.array(z.string()),
|
tags: z.array(z.string()),
|
||||||
cover: z.string(),
|
cover: z.string(),
|
||||||
favorite: z.boolean().optional(),
|
favorite: z.boolean().optional(),
|
||||||
|
canva: z.object({
|
||||||
|
height: z.number().default(270),
|
||||||
|
width: z.number().default(480),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
writings: defineCollection({
|
writings: defineCollection({
|
||||||
@@ -26,6 +30,10 @@ export const collections = {
|
|||||||
readingTime: z.number(),
|
readingTime: z.number(),
|
||||||
cover: z.string().optional(),
|
cover: z.string().optional(),
|
||||||
tags: z.array(z.string()),
|
tags: z.array(z.string()),
|
||||||
|
canva: z.object({
|
||||||
|
height: z.number().default(270),
|
||||||
|
width: z.number().default(480),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
usesCategories: defineCollection({
|
usesCategories: defineCollection({
|
||||||
|
|||||||
@@ -203,5 +203,8 @@
|
|||||||
"copy": "Copy link"
|
"copy": "Copy link"
|
||||||
},
|
},
|
||||||
"top": "Go to top"
|
"top": "Go to top"
|
||||||
|
},
|
||||||
|
"canva": {
|
||||||
|
"title": "Loading the canva ..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,5 +203,8 @@
|
|||||||
},
|
},
|
||||||
"top": "Ir arriba"
|
"top": "Ir arriba"
|
||||||
},
|
},
|
||||||
"alert": "Por falta de tiempo, no tuve tiempo para traducir este contenido al francés. Gracias por su comprensión."
|
"alert": "Por falta de tiempo, no tuve tiempo para traducir este contenido al francés. Gracias por su comprensión.",
|
||||||
|
"canva": {
|
||||||
|
"title": "Cargando el lienzo ..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,5 +203,8 @@
|
|||||||
"copy": "Copier le lien"
|
"copy": "Copier le lien"
|
||||||
},
|
},
|
||||||
"top": "Remonter en haut"
|
"top": "Remonter en haut"
|
||||||
|
},
|
||||||
|
"canva": {
|
||||||
|
"title": "Chargement du canva..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
modules/infinite-canvas/components/CanvasLoader.vue
Normal file
116
modules/infinite-canvas/components/CanvasLoader.vue
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { LoaderProps } from '../types'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<LoaderProps>(), {
|
||||||
|
title: 'Loading Canvas',
|
||||||
|
description: 'Preparing your visual journey...',
|
||||||
|
})
|
||||||
|
|
||||||
|
const RADIUS = 45
|
||||||
|
const CIRCUMFERENCE = 2 * Math.PI * RADIUS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate progress percentage for display
|
||||||
|
*/
|
||||||
|
const percent = computed(() => Math.round(props.progress * 100))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate stroke dash offset for circular progress
|
||||||
|
*/
|
||||||
|
const dashOffset = computed(() => CIRCUMFERENCE * (1 - props.progress))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation props for the content reveal
|
||||||
|
*/
|
||||||
|
const contentAnimation = {
|
||||||
|
initial: { opacity: 0, y: 20 },
|
||||||
|
animate: { opacity: 1, y: 0 },
|
||||||
|
transition: { duration: 0.5, delay: 0.2 },
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if loading is complete
|
||||||
|
*/
|
||||||
|
const isComplete = computed(() => props.progress >= 1)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Transition
|
||||||
|
enter-active-class="transition-all duration-500 ease-out"
|
||||||
|
leave-active-class="transition-all duration-700 ease-out"
|
||||||
|
enter-from-class="opacity-0"
|
||||||
|
enter-to-class="opacity-100"
|
||||||
|
leave-from-class="opacity-100"
|
||||||
|
leave-to-class="opacity-0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="isVisible"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center bg-default"
|
||||||
|
>
|
||||||
|
<div class="pointer-events-none fixed inset-0 size-full overflow-hidden">
|
||||||
|
<div class="noise pointer-events-none absolute inset-[-200%] size-[400%] bg-[url('/noise.png')] opacity-[4%]" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative flex flex-col items-center space-y-8">
|
||||||
|
<div class="relative">
|
||||||
|
<svg
|
||||||
|
class="size-24 -rotate-90 transform"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
cx="50"
|
||||||
|
cy="50"
|
||||||
|
:r="RADIUS"
|
||||||
|
fill="none"
|
||||||
|
stroke="rgba(255, 255, 255, 0.1)"
|
||||||
|
stroke-width="2"
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
cx="50"
|
||||||
|
cy="50"
|
||||||
|
:r="RADIUS"
|
||||||
|
fill="none"
|
||||||
|
stroke="rgba(255, 255, 255, 0.8)"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
:stroke-dasharray="CIRCUMFERENCE"
|
||||||
|
:stroke-dashoffset="dashOffset"
|
||||||
|
class="transition-all duration-300 ease-out"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class="absolute inset-0 flex items-center justify-center">
|
||||||
|
<span class="text-xl font-medium text-highlighted">
|
||||||
|
{{ percent }}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<Motion v-bind="contentAnimation">
|
||||||
|
<h2 class="text-2xl font-light text-highlighted mb-2">
|
||||||
|
{{ title }}
|
||||||
|
</h2>
|
||||||
|
<p class="text-sm text-highlighted/60">
|
||||||
|
{{ description }}
|
||||||
|
</p>
|
||||||
|
</Motion>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex space-x-2">
|
||||||
|
<div
|
||||||
|
v-for="i in 3"
|
||||||
|
:key="i"
|
||||||
|
class="size-2 rounded-full bg-inverted/40"
|
||||||
|
:class="{ 'animate-pulse': !isComplete }"
|
||||||
|
:style="{ animationDelay: `${i * 0.2}s` }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pointer-events-none absolute inset-0">
|
||||||
|
<div class="absolute left-1/2 top-1/2 size-96 -translate-x-1/2 -translate-y-1/2 rounded-full bg-inverted/5 blur-3xl" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</template>
|
||||||
116
modules/infinite-canvas/components/CanvasMinimap.vue
Normal file
116
modules/infinite-canvas/components/CanvasMinimap.vue
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { MinimapProps } from '../types'
|
||||||
|
|
||||||
|
const props = defineProps<MinimapProps>()
|
||||||
|
|
||||||
|
const MINIMAP_SIZE = 120
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the scale factor to fit canvas in minimap
|
||||||
|
*/
|
||||||
|
const scale = computed(() => {
|
||||||
|
const { width, height } = props.canvasBounds
|
||||||
|
return Math.min(MINIMAP_SIZE / width, MINIMAP_SIZE / height)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actual minimap dimensions after scaling
|
||||||
|
*/
|
||||||
|
const dimensions = computed(() => ({
|
||||||
|
width: props.canvasBounds.width * scale.value,
|
||||||
|
height: props.canvasBounds.height * scale.value,
|
||||||
|
}))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Positioning to center the minimap content
|
||||||
|
*/
|
||||||
|
const centerOffset = computed(() => ({
|
||||||
|
x: (MINIMAP_SIZE - dimensions.value.width) / 2,
|
||||||
|
y: (MINIMAP_SIZE - dimensions.value.height) / 2,
|
||||||
|
}))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform grid items to minimap coordinates with proper scaling
|
||||||
|
*/
|
||||||
|
const items = computed(() =>
|
||||||
|
props.gridItems.map(item => ({
|
||||||
|
index: item.index,
|
||||||
|
x: item.position.x * scale.value,
|
||||||
|
y: item.position.y * scale.value,
|
||||||
|
width: Math.max(2, item.width * scale.value),
|
||||||
|
height: Math.max(2, item.height * scale.value),
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate viewport rectangle in minimap space
|
||||||
|
*/
|
||||||
|
const viewport = computed(() => {
|
||||||
|
const { width, height } = props.containerDimensions
|
||||||
|
const { zoom } = props
|
||||||
|
|
||||||
|
// Canvas coordinates of current viewport
|
||||||
|
const viewX = -props.offset.x / zoom
|
||||||
|
const viewY = -props.offset.y / zoom
|
||||||
|
const viewWidth = width / zoom
|
||||||
|
const viewHeight = height / zoom
|
||||||
|
|
||||||
|
// Convert to minimap coordinates
|
||||||
|
const x = viewX * scale.value
|
||||||
|
const y = viewY * scale.value
|
||||||
|
const w = viewWidth * scale.value
|
||||||
|
const h = viewHeight * scale.value
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: Math.max(0, Math.min(dimensions.value.width - w, x)),
|
||||||
|
y: Math.max(0, Math.min(dimensions.value.height - h, y)),
|
||||||
|
width: Math.min(dimensions.value.width, w),
|
||||||
|
height: Math.min(dimensions.value.height, h),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="relative overflow-hidden rounded-lg border border-default bg-default/40 p-2 backdrop-blur-sm shadow-lg">
|
||||||
|
<!-- Minimap container -->
|
||||||
|
<div
|
||||||
|
class="relative"
|
||||||
|
:style="{ width: `${MINIMAP_SIZE}px`, height: `${MINIMAP_SIZE}px` }"
|
||||||
|
>
|
||||||
|
<!-- Centered minimap content -->
|
||||||
|
<div
|
||||||
|
class="absolute bg-muted/50"
|
||||||
|
:style="{
|
||||||
|
left: `${centerOffset.x}px`,
|
||||||
|
top: `${centerOffset.y}px`,
|
||||||
|
width: `${dimensions.width}px`,
|
||||||
|
height: `${dimensions.height}px`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!-- Items with real shapes -->
|
||||||
|
<div
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.index"
|
||||||
|
class="absolute bg-accented border border-inverted/30 rounded-sm"
|
||||||
|
:style="{
|
||||||
|
width: `${item.width}px`,
|
||||||
|
height: `${item.height}px`,
|
||||||
|
left: `${item.x}px`,
|
||||||
|
top: `${item.y}px`,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Viewport indicator -->
|
||||||
|
<div
|
||||||
|
class="absolute border border-primary bg-primary/10"
|
||||||
|
:style="{
|
||||||
|
left: `${viewport.x}px`,
|
||||||
|
top: `${viewport.y}px`,
|
||||||
|
width: `${viewport.width}px`,
|
||||||
|
height: `${viewport.height}px`,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
142
modules/infinite-canvas/components/InfiniteCanvas.vue
Normal file
142
modules/infinite-canvas/components/InfiniteCanvas.vue
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<script setup lang="ts" generic="T extends CanvasItem">
|
||||||
|
import type { CanvasItem, InfiniteCanvasEmits, InfiniteCanvasProps } from '../types'
|
||||||
|
import { useInfiniteCanvas } from '../composables/useInfiniteCanvas'
|
||||||
|
import { PHYSICS } from '../constants'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<InfiniteCanvasProps<T>>(), {
|
||||||
|
baseGap: 40,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<InfiniteCanvasEmits<T>>()
|
||||||
|
|
||||||
|
const containerRef = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
const {
|
||||||
|
offset,
|
||||||
|
zoom,
|
||||||
|
visibleItems,
|
||||||
|
gridItems,
|
||||||
|
containerDimensions,
|
||||||
|
canvasBounds,
|
||||||
|
canClick,
|
||||||
|
updateDimensions,
|
||||||
|
handlePointerDown: handlePointerDownCore,
|
||||||
|
handlePointerMove: handlePointerMoveCore,
|
||||||
|
handlePointerUp: handlePointerUpCore,
|
||||||
|
handleWheel,
|
||||||
|
handleTouchStart,
|
||||||
|
handleTouchMove,
|
||||||
|
handleTouchEnd,
|
||||||
|
navigateTo,
|
||||||
|
} = useInfiniteCanvas({
|
||||||
|
items: props.items as CanvasItem[],
|
||||||
|
baseGap: props.baseGap,
|
||||||
|
zoomOptions: props.zoomOptions,
|
||||||
|
containerRef,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Track drag state for click handling
|
||||||
|
const isCurrentlyDragging = ref(false)
|
||||||
|
const dragStartPosition = ref<{ x: number, y: number }>({ x: 0, y: 0 })
|
||||||
|
const totalDragDistance = ref(0)
|
||||||
|
|
||||||
|
function handlePointerDown(event: PointerEvent) {
|
||||||
|
handlePointerDownCore(event.clientX, event.clientY)
|
||||||
|
isCurrentlyDragging.value = false
|
||||||
|
dragStartPosition.value = { x: event.clientX, y: event.clientY }
|
||||||
|
totalDragDistance.value = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePointerMove(event: PointerEvent) {
|
||||||
|
const currentPos = { x: event.clientX, y: event.clientY }
|
||||||
|
const distance = Math.sqrt(
|
||||||
|
(currentPos.x - dragStartPosition.value.x) ** 2
|
||||||
|
+ (currentPos.y - dragStartPosition.value.y) ** 2,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (distance > PHYSICS.DRAG_THRESHOLD) {
|
||||||
|
isCurrentlyDragging.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
totalDragDistance.value = distance
|
||||||
|
handlePointerMoveCore(event.clientX, event.clientY)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePointerUp(event: PointerEvent) {
|
||||||
|
handlePointerUpCore(event.clientX, event.clientY)
|
||||||
|
|
||||||
|
if (isCurrentlyDragging.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
isCurrentlyDragging.value = false
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleItemClick(item: T | undefined, index: number) {
|
||||||
|
if (item && canClick.value && !isCurrentlyDragging.value && totalDragDistance.value <= PHYSICS.DRAG_THRESHOLD) {
|
||||||
|
emit('itemClick', item, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
updateDimensions()
|
||||||
|
useResizeObserver(containerRef, updateDimensions)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
offset,
|
||||||
|
zoom,
|
||||||
|
visibleItems,
|
||||||
|
gridItems,
|
||||||
|
containerDimensions,
|
||||||
|
canvasBounds,
|
||||||
|
updateDimensions,
|
||||||
|
navigateTo,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="containerRef"
|
||||||
|
class="relative size-full overflow-hidden touch-none select-none"
|
||||||
|
style="touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;"
|
||||||
|
@pointerdown="handlePointerDown"
|
||||||
|
@pointermove="handlePointerMove"
|
||||||
|
@pointerup="handlePointerUp"
|
||||||
|
@pointercancel="handlePointerUp"
|
||||||
|
@wheel="handleWheel"
|
||||||
|
@touchstart="handleTouchStart"
|
||||||
|
@touchmove="handleTouchMove"
|
||||||
|
@touchend="handleTouchEnd"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute transform-gpu will-change-transform"
|
||||||
|
:style="{
|
||||||
|
transform: `translate3d(${offset.x}px, ${offset.y}px, 0) scale(${zoom})`,
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
perspective: '1000px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(gridItem, visibleIndex) in visibleItems"
|
||||||
|
:key="gridItem.index"
|
||||||
|
class="absolute transform-gpu will-change-transform"
|
||||||
|
:style="{
|
||||||
|
left: `${gridItem.position.x}px`,
|
||||||
|
top: `${gridItem.position.y}px`,
|
||||||
|
width: `${gridItem.width}px`,
|
||||||
|
height: `${gridItem.height}px`,
|
||||||
|
backfaceVisibility: 'hidden',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
v-if="props.items[gridItem.index]"
|
||||||
|
:item="props.items[gridItem.index]"
|
||||||
|
:index="gridItem.index"
|
||||||
|
:visible-index
|
||||||
|
:on-item-click="() => handleItemClick(props.items[gridItem.index], gridItem.index)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
116
modules/infinite-canvas/composables/useImagePreloader.ts
Normal file
116
modules/infinite-canvas/composables/useImagePreloader.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/* eslint-disable ts/no-use-before-define */
|
||||||
|
/**
|
||||||
|
* @fileoverview Composable for preloading images and videos
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ImagePreloaderOptions, UseImagePreloaderReturn } from '../types'
|
||||||
|
import { isVideo } from '../utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preloads a single media file (image or video)
|
||||||
|
* @param src Media URL to preload
|
||||||
|
* @returns Promise that resolves when loaded
|
||||||
|
*/
|
||||||
|
function preloadMedia(src: string): Promise<void> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (isVideo(src)) {
|
||||||
|
const video = document.createElement('video')
|
||||||
|
video.preload = 'metadata'
|
||||||
|
video.muted = true
|
||||||
|
|
||||||
|
const handleLoad = () => {
|
||||||
|
video.removeEventListener('loadedmetadata', handleLoad)
|
||||||
|
video.removeEventListener('error', handleError)
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleError = () => {
|
||||||
|
video.removeEventListener('loadedmetadata', handleLoad)
|
||||||
|
video.removeEventListener('error', handleError)
|
||||||
|
resolve() // Don't reject to avoid breaking the flow
|
||||||
|
}
|
||||||
|
|
||||||
|
video.addEventListener('loadedmetadata', handleLoad)
|
||||||
|
video.addEventListener('error', handleError)
|
||||||
|
video.src = src
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const img = new Image()
|
||||||
|
|
||||||
|
const handleLoad = () => {
|
||||||
|
img.removeEventListener('load', handleLoad)
|
||||||
|
img.removeEventListener('error', handleError)
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleError = () => {
|
||||||
|
img.removeEventListener('load', handleLoad)
|
||||||
|
img.removeEventListener('error', handleError)
|
||||||
|
resolve() // Don't reject to avoid breaking the flow
|
||||||
|
}
|
||||||
|
|
||||||
|
img.addEventListener('load', handleLoad)
|
||||||
|
img.addEventListener('error', handleError)
|
||||||
|
img.src = src
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composable for preloading multiple media files with progress tracking
|
||||||
|
* @param options Configuration options
|
||||||
|
* @returns Preloader state and controls
|
||||||
|
*/
|
||||||
|
export function useImagePreloader(options: ImagePreloaderOptions): UseImagePreloaderReturn {
|
||||||
|
const { images, onProgress, onComplete } = options
|
||||||
|
|
||||||
|
const progress = ref(0)
|
||||||
|
const loadedCount = ref(0)
|
||||||
|
const isLoading = ref(true)
|
||||||
|
const isComplete = ref(false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates progress and triggers callbacks
|
||||||
|
*/
|
||||||
|
const updateProgress = () => {
|
||||||
|
const newProgress = loadedCount.value / images.length
|
||||||
|
progress.value = newProgress
|
||||||
|
onProgress?.(newProgress)
|
||||||
|
|
||||||
|
if (loadedCount.value === images.length) {
|
||||||
|
isComplete.value = true
|
||||||
|
isLoading.value = false
|
||||||
|
onComplete?.()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the preloading process for all media files
|
||||||
|
*/
|
||||||
|
const startPreloading = async () => {
|
||||||
|
if (images.length === 0) {
|
||||||
|
progress.value = 1
|
||||||
|
isComplete.value = true
|
||||||
|
isLoading.value = false
|
||||||
|
onComplete?.()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preload all media in parallel with individual progress tracking
|
||||||
|
const preloadPromises = images.map(async (src) => {
|
||||||
|
await preloadMedia(src)
|
||||||
|
loadedCount.value++
|
||||||
|
updateProgress()
|
||||||
|
})
|
||||||
|
|
||||||
|
await Promise.all(preloadPromises)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
progress: readonly(progress),
|
||||||
|
loadedCount: readonly(loadedCount),
|
||||||
|
isLoading: readonly(isLoading),
|
||||||
|
isComplete: readonly(isComplete),
|
||||||
|
startPreloading,
|
||||||
|
}
|
||||||
|
}
|
||||||
576
modules/infinite-canvas/composables/useInfiniteCanvas.ts
Normal file
576
modules/infinite-canvas/composables/useInfiniteCanvas.ts
Normal file
@@ -0,0 +1,576 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Main composable for infinite canvas functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type {
|
||||||
|
GridItem,
|
||||||
|
Position,
|
||||||
|
UseInfiniteCanvasOptions,
|
||||||
|
UseInfiniteCanvasReturn,
|
||||||
|
} from '../types'
|
||||||
|
import { PHYSICS, TOUCH, VIEWPORT, ZOOM_DEFAULTS } from '../constants'
|
||||||
|
import { clamp, getTouchCenter, getTouchDistance } from '../utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an infinite canvas with drag, zoom, and virtualization support
|
||||||
|
* @param options Configuration options
|
||||||
|
* @returns Canvas state and event handlers
|
||||||
|
*/
|
||||||
|
export function useInfiniteCanvas(options: UseInfiniteCanvasOptions): UseInfiniteCanvasReturn {
|
||||||
|
const { items, baseGap = 40, zoomOptions, containerRef } = options
|
||||||
|
|
||||||
|
// Canvas state
|
||||||
|
const offset = ref<Position>({ x: 0, y: 0 })
|
||||||
|
const velocity = ref<Position>({ x: 0, y: 0 })
|
||||||
|
const zoom = ref(1)
|
||||||
|
const containerDimensions = ref({ width: 0, height: 0 })
|
||||||
|
|
||||||
|
// Interaction state
|
||||||
|
const isDragging = ref(false)
|
||||||
|
const justFinishedDragging = ref(false)
|
||||||
|
const dragStart = ref<Position>({ x: 0, y: 0 })
|
||||||
|
const dragStartOffset = ref<Position>({ x: 0, y: 0 })
|
||||||
|
const totalDragDistance = ref(0)
|
||||||
|
const dragStartTime = ref(0)
|
||||||
|
|
||||||
|
// Touch state
|
||||||
|
const isPinching = ref(false)
|
||||||
|
const initialPinchDistance = ref(0)
|
||||||
|
const initialPinchZoom = ref(1)
|
||||||
|
const pinchCenter = ref<Position & { canvasX?: number, canvasY?: number }>({ x: 0, y: 0 })
|
||||||
|
const touchStartTime = ref(0)
|
||||||
|
const wasPinching = ref(false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate canvas bounds based on item count
|
||||||
|
*/
|
||||||
|
const canvasBounds = computed(() => {
|
||||||
|
const canvasSize = Math.max(4000, items.length * 100)
|
||||||
|
return {
|
||||||
|
width: canvasSize,
|
||||||
|
height: canvasSize,
|
||||||
|
centerX: canvasSize / 2,
|
||||||
|
centerY: canvasSize / 2,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check collision between two positioned items
|
||||||
|
*/
|
||||||
|
const checkCollision = (
|
||||||
|
pos1: Position,
|
||||||
|
size1: { width: number, height: number },
|
||||||
|
pos2: Position,
|
||||||
|
size2: { width: number, height: number },
|
||||||
|
): boolean => {
|
||||||
|
const gap = baseGap
|
||||||
|
return !(
|
||||||
|
pos1.x + size1.width + gap < pos2.x
|
||||||
|
|| pos2.x + size2.width + gap < pos1.x
|
||||||
|
|| pos1.y + size1.height + gap < pos2.y
|
||||||
|
|| pos2.y + size2.height + gap < pos1.y
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a valid position for an item using spiral placement
|
||||||
|
*/
|
||||||
|
const findValidPosition = (index: number, placedItems: GridItem[]): Position => {
|
||||||
|
const { centerX = 0, centerY = 0 } = canvasBounds.value
|
||||||
|
const itemWidth = items[index]?.width || 300
|
||||||
|
const itemHeight = items[index]?.height || 300
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
return {
|
||||||
|
x: centerX - itemWidth / 2,
|
||||||
|
y: centerY - itemHeight / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let radius = 200
|
||||||
|
const maxRadius = 2000
|
||||||
|
const angleStep = 0.5
|
||||||
|
|
||||||
|
while (radius < maxRadius) {
|
||||||
|
for (let angle = 0; angle < Math.PI * 2; angle += angleStep) {
|
||||||
|
const x = centerX + Math.cos(angle) * radius - itemWidth / 2
|
||||||
|
const y = centerY + Math.sin(angle) * radius - itemHeight / 2
|
||||||
|
const newPosition = { x, y }
|
||||||
|
|
||||||
|
const hasCollision = placedItems.some(placedItem =>
|
||||||
|
checkCollision(
|
||||||
|
newPosition,
|
||||||
|
{ width: itemWidth, height: itemHeight },
|
||||||
|
placedItem.position,
|
||||||
|
{ width: placedItem.width, height: placedItem.height },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!hasCollision) {
|
||||||
|
return newPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radius += 150
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x: centerX, y: centerY }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate positions for all grid items
|
||||||
|
*/
|
||||||
|
const gridItems = computed<GridItem[]>(() => {
|
||||||
|
const placedItems: GridItem[] = []
|
||||||
|
|
||||||
|
return items.map((item, index) => {
|
||||||
|
const position = findValidPosition(index, placedItems)
|
||||||
|
const gridItem: GridItem = {
|
||||||
|
position,
|
||||||
|
index,
|
||||||
|
width: item.width || 300,
|
||||||
|
height: item.height || 300,
|
||||||
|
}
|
||||||
|
placedItems.push(gridItem)
|
||||||
|
return gridItem
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constrain offset to canvas bounds
|
||||||
|
*/
|
||||||
|
const constrainOffset = (newOffset: Position): Position => {
|
||||||
|
const { width, height } = containerDimensions.value
|
||||||
|
const { width: canvasWidth, height: canvasHeight } = canvasBounds.value
|
||||||
|
const currentZoom = zoom.value
|
||||||
|
|
||||||
|
const maxOffsetX = width - canvasWidth * currentZoom
|
||||||
|
const maxOffsetY = height - canvasHeight * currentZoom
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: clamp(newOffset.x, maxOffsetX, 0),
|
||||||
|
y: clamp(newOffset.y, maxOffsetY, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throttled visible items calculation to reduce flickering during zoom
|
||||||
|
*/
|
||||||
|
const _visibleItemsCache = ref<GridItem[]>([])
|
||||||
|
let _lastVisibleItemsUpdate = 0
|
||||||
|
|
||||||
|
const calculateVisibleItems = () => {
|
||||||
|
const { width, height } = containerDimensions.value
|
||||||
|
const currentZoom = zoom.value
|
||||||
|
|
||||||
|
// Increase buffer during pinching to reduce flickering
|
||||||
|
const baseBuffer = isPinching.value
|
||||||
|
? VIEWPORT.BASE_BUFFER * 1.5
|
||||||
|
: VIEWPORT.BASE_BUFFER
|
||||||
|
|
||||||
|
const buffer = Math.max(
|
||||||
|
VIEWPORT.MIN_BUFFER,
|
||||||
|
baseBuffer / Math.max(currentZoom, 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
const viewportLeft = (-offset.value.x) / currentZoom - buffer
|
||||||
|
const viewportRight = (-offset.value.x + width) / currentZoom + buffer
|
||||||
|
const viewportTop = (-offset.value.y) / currentZoom - buffer
|
||||||
|
const viewportBottom = (-offset.value.y + height) / currentZoom + buffer
|
||||||
|
|
||||||
|
const maxVisibleItems = Math.min(
|
||||||
|
VIEWPORT.MAX_VISIBLE_ITEMS,
|
||||||
|
Math.ceil(VIEWPORT.VISIBLE_ITEMS_FACTOR / currentZoom),
|
||||||
|
)
|
||||||
|
|
||||||
|
const visibleItemsList = gridItems.value.filter((gridItem) => {
|
||||||
|
const itemRight = gridItem.position.x + gridItem.width
|
||||||
|
const itemBottom = gridItem.position.y + gridItem.height
|
||||||
|
|
||||||
|
return (
|
||||||
|
gridItem.position.x < viewportRight
|
||||||
|
&& itemRight > viewportLeft
|
||||||
|
&& gridItem.position.y < viewportBottom
|
||||||
|
&& itemBottom > viewportTop
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (visibleItemsList.length > maxVisibleItems) {
|
||||||
|
const centerX = (-offset.value.x + width / 2) / currentZoom
|
||||||
|
const centerY = (-offset.value.y + height / 2) / currentZoom
|
||||||
|
|
||||||
|
return visibleItemsList
|
||||||
|
.map(item => ({
|
||||||
|
...item,
|
||||||
|
distanceToCenter: Math.sqrt(
|
||||||
|
(item.position.x + item.width / 2 - centerX) ** 2
|
||||||
|
+ (item.position.y + item.height / 2 - centerY) ** 2,
|
||||||
|
),
|
||||||
|
}))
|
||||||
|
.sort((a, b) => a.distanceToCenter - b.distanceToCenter)
|
||||||
|
.slice(0, maxVisibleItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibleItemsList
|
||||||
|
}
|
||||||
|
|
||||||
|
const visibleItems = computed(() => {
|
||||||
|
const now = Date.now()
|
||||||
|
const updateDelay = isPinching.value ? 50 : 16 // Throttle more during pinching for stability
|
||||||
|
|
||||||
|
// Throttle updates during rapid changes to reduce flickering
|
||||||
|
if (now - _lastVisibleItemsUpdate > updateDelay || !isPinching.value) {
|
||||||
|
_lastVisibleItemsUpdate = now
|
||||||
|
const newVisibleItems = calculateVisibleItems()
|
||||||
|
|
||||||
|
// During pinching, only update if there's a significant change
|
||||||
|
if (isPinching.value) {
|
||||||
|
const currentCount = _visibleItemsCache.value.length
|
||||||
|
const newCount = newVisibleItems.length
|
||||||
|
const changeThreshold = Math.max(2, Math.floor(currentCount * 0.1))
|
||||||
|
|
||||||
|
if (Math.abs(newCount - currentCount) >= changeThreshold) {
|
||||||
|
_visibleItemsCache.value = newVisibleItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_visibleItemsCache.value = newVisibleItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _visibleItemsCache.value
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Center the view on the canvas
|
||||||
|
*/
|
||||||
|
const centerView = () => {
|
||||||
|
const { width, height } = containerDimensions.value
|
||||||
|
const { centerX = 0, centerY = 0 } = canvasBounds.value
|
||||||
|
|
||||||
|
offset.value = {
|
||||||
|
x: -centerX + width / 2,
|
||||||
|
y: -centerY + height / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update container dimensions and center view if needed
|
||||||
|
*/
|
||||||
|
const updateDimensions = () => {
|
||||||
|
if (containerRef.value) {
|
||||||
|
const rect = containerRef.value.getBoundingClientRect()
|
||||||
|
containerDimensions.value = { width: rect.width, height: rect.height }
|
||||||
|
|
||||||
|
if (offset.value.x === 0 && offset.value.y === 0 && rect.width > 0) {
|
||||||
|
centerView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation loop for momentum
|
||||||
|
*/
|
||||||
|
const animate = () => {
|
||||||
|
if (Math.abs(velocity.value.x) > PHYSICS.MIN_VELOCITY
|
||||||
|
|| Math.abs(velocity.value.y) > PHYSICS.MIN_VELOCITY) {
|
||||||
|
offset.value = constrainOffset({
|
||||||
|
x: offset.value.x + velocity.value.x,
|
||||||
|
y: offset.value.y + velocity.value.y,
|
||||||
|
})
|
||||||
|
|
||||||
|
velocity.value.x *= PHYSICS.FRICTION
|
||||||
|
velocity.value.y *= PHYSICS.FRICTION
|
||||||
|
|
||||||
|
requestAnimationFrame(animate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event handlers
|
||||||
|
const handlePointerDown = (clientX: number, clientY: number) => {
|
||||||
|
dragStart.value = { x: clientX, y: clientY }
|
||||||
|
dragStartOffset.value = { ...offset.value }
|
||||||
|
totalDragDistance.value = 0
|
||||||
|
dragStartTime.value = Date.now()
|
||||||
|
isDragging.value = false
|
||||||
|
justFinishedDragging.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePointerMove = (clientX: number, clientY: number) => {
|
||||||
|
if (dragStart.value.x === 0 && dragStart.value.y === 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
const deltaX = clientX - dragStart.value.x
|
||||||
|
const deltaY = clientY - dragStart.value.y
|
||||||
|
|
||||||
|
totalDragDistance.value = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
|
||||||
|
|
||||||
|
if (totalDragDistance.value > PHYSICS.DRAG_THRESHOLD) {
|
||||||
|
isDragging.value = true
|
||||||
|
|
||||||
|
offset.value = constrainOffset({
|
||||||
|
x: dragStartOffset.value.x + deltaX,
|
||||||
|
y: dragStartOffset.value.y + deltaY,
|
||||||
|
})
|
||||||
|
|
||||||
|
velocity.value = { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePointerUp = (clientX: number, clientY: number) => {
|
||||||
|
if (isDragging.value) {
|
||||||
|
const deltaTime = Date.now() - dragStartTime.value
|
||||||
|
const deltaX = clientX - dragStart.value.x
|
||||||
|
const deltaY = clientY - dragStart.value.y
|
||||||
|
|
||||||
|
if (deltaTime > 0 && totalDragDistance.value > PHYSICS.DRAG_THRESHOLD) {
|
||||||
|
const velocityMultiplier = Math.min(deltaTime, 100) / 100
|
||||||
|
velocity.value = {
|
||||||
|
x: (deltaX / deltaTime) * 16 * velocityMultiplier,
|
||||||
|
y: (deltaY / deltaTime) * 16 * velocityMultiplier,
|
||||||
|
}
|
||||||
|
animate()
|
||||||
|
}
|
||||||
|
|
||||||
|
justFinishedDragging.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
justFinishedDragging.value = false
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
isDragging.value = false
|
||||||
|
dragStart.value = { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleWheel = (event: WheelEvent) => {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
const opts = zoomOptions || {}
|
||||||
|
const minZoom = opts.minZoom ?? ZOOM_DEFAULTS.MIN
|
||||||
|
const maxZoom = opts.maxZoom ?? ZOOM_DEFAULTS.MAX
|
||||||
|
const zoomFactor = opts.zoomFactor ?? ZOOM_DEFAULTS.FACTOR
|
||||||
|
const zoomFactorOut = 1 / zoomFactor
|
||||||
|
|
||||||
|
const isZoomModifier = (
|
||||||
|
(opts.enableCtrl !== false && event.ctrlKey)
|
||||||
|
|| (opts.enableMeta !== false && event.metaKey)
|
||||||
|
|| (opts.enableAlt !== false && event.altKey)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isZoomModifier) {
|
||||||
|
const newZoom = clamp(
|
||||||
|
zoom.value * (event.deltaY > 0 ? zoomFactorOut : zoomFactor),
|
||||||
|
minZoom,
|
||||||
|
maxZoom,
|
||||||
|
)
|
||||||
|
|
||||||
|
const rect = containerRef.value?.getBoundingClientRect()
|
||||||
|
if (rect) {
|
||||||
|
const mouseX = event.clientX - rect.left
|
||||||
|
const mouseY = event.clientY - rect.top
|
||||||
|
|
||||||
|
const oldZoom = zoom.value
|
||||||
|
const pointX = (mouseX - offset.value.x) / oldZoom
|
||||||
|
const pointY = (mouseY - offset.value.y) / oldZoom
|
||||||
|
|
||||||
|
zoom.value = newZoom
|
||||||
|
|
||||||
|
offset.value = constrainOffset({
|
||||||
|
x: mouseX - pointX * newZoom,
|
||||||
|
y: mouseY - pointY * newZoom,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zoom.value = newZoom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset.value = constrainOffset({
|
||||||
|
x: offset.value.x - event.deltaX,
|
||||||
|
y: offset.value.y - event.deltaY,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity.value = { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
const navigateTo = (position: Position) => {
|
||||||
|
const { width, height } = containerDimensions.value
|
||||||
|
offset.value = constrainOffset({
|
||||||
|
x: -position.x + width / 2,
|
||||||
|
y: -position.y + height / 2,
|
||||||
|
})
|
||||||
|
velocity.value = { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touch handlers
|
||||||
|
const handleTouchStart = (event: TouchEvent) => {
|
||||||
|
// Only prevent default for multi-touch to allow single touch scrolling
|
||||||
|
if (event.touches.length > 1) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
const touches = Array.from(event.touches)
|
||||||
|
touchStartTime.value = Date.now()
|
||||||
|
wasPinching.value = false
|
||||||
|
|
||||||
|
if (touches.length === 1 && touches[0]) {
|
||||||
|
const [touch] = touches
|
||||||
|
handlePointerDown(touch.clientX, touch.clientY)
|
||||||
|
isPinching.value = false
|
||||||
|
}
|
||||||
|
else if (touches.length === 2 && touches[0] && touches[1]) {
|
||||||
|
const [touch1, touch2] = touches
|
||||||
|
isPinching.value = true
|
||||||
|
wasPinching.value = true
|
||||||
|
initialPinchDistance.value = getTouchDistance(touch1, touch2)
|
||||||
|
initialPinchZoom.value = zoom.value
|
||||||
|
|
||||||
|
const rect = containerRef.value?.getBoundingClientRect()
|
||||||
|
if (rect) {
|
||||||
|
const center = getTouchCenter(touch1, touch2)
|
||||||
|
// Store the center in canvas coordinates (accounting for current transform)
|
||||||
|
const canvasX = (center.x - rect.left - offset.value.x) / zoom.value
|
||||||
|
const canvasY = (center.y - rect.top - offset.value.y) / zoom.value
|
||||||
|
pinchCenter.value = {
|
||||||
|
x: center.x - rect.left,
|
||||||
|
y: center.y - rect.top,
|
||||||
|
canvasX,
|
||||||
|
canvasY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isDragging.value = false
|
||||||
|
velocity.value = { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastTouchMoveCall = 0
|
||||||
|
const handleTouchMove = (event: TouchEvent) => {
|
||||||
|
// Prevent default only for multi-touch (pinch/zoom)
|
||||||
|
if (event.touches.length > 1) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = Date.now()
|
||||||
|
// Reduce throttling during pinch for smoother zoom
|
||||||
|
const throttleDelay = isPinching.value
|
||||||
|
? 8 // More frequent updates during pinch
|
||||||
|
: (zoom.value > ZOOM_DEFAULTS.HIGH_ZOOM_THRESHOLD
|
||||||
|
? TOUCH.THROTTLE_MS_HIGH_ZOOM
|
||||||
|
: TOUCH.THROTTLE_MS)
|
||||||
|
|
||||||
|
if (now - lastTouchMoveCall < throttleDelay)
|
||||||
|
return
|
||||||
|
lastTouchMoveCall = now
|
||||||
|
|
||||||
|
const touches = Array.from(event.touches)
|
||||||
|
|
||||||
|
if (touches.length === 1 && !isPinching.value && touches[0]) {
|
||||||
|
const [touch] = touches
|
||||||
|
handlePointerMove(touch.clientX, touch.clientY)
|
||||||
|
}
|
||||||
|
else if (touches.length === 2 && isPinching.value && touches[0] && touches[1]) {
|
||||||
|
const [touch1, touch2] = touches
|
||||||
|
const currentDistance = getTouchDistance(touch1, touch2)
|
||||||
|
const distanceChange = currentDistance - initialPinchDistance.value
|
||||||
|
|
||||||
|
if (Math.abs(distanceChange) > TOUCH.PINCH_THRESHOLD) {
|
||||||
|
const opts = zoomOptions || {}
|
||||||
|
const minZoom = opts.minZoom ?? ZOOM_DEFAULTS.MIN
|
||||||
|
const maxZoom = opts.maxZoom ?? ZOOM_DEFAULTS.MAX
|
||||||
|
|
||||||
|
const zoomFactor = 1 + (distanceChange / initialPinchDistance.value) * 1.2
|
||||||
|
const newZoom = clamp(initialPinchZoom.value * zoomFactor, minZoom, maxZoom)
|
||||||
|
|
||||||
|
// Use the stored canvas coordinates if available for more stable zooming
|
||||||
|
let pointX, pointY
|
||||||
|
if (pinchCenter.value.canvasX !== undefined && pinchCenter.value.canvasY !== undefined) {
|
||||||
|
pointX = pinchCenter.value.canvasX
|
||||||
|
pointY = pinchCenter.value.canvasY
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Fallback to the old method
|
||||||
|
const oldZoom = zoom.value
|
||||||
|
pointX = (pinchCenter.value.x - offset.value.x) / oldZoom
|
||||||
|
pointY = (pinchCenter.value.y - offset.value.y) / oldZoom
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch zoom and offset updates to reduce flickering
|
||||||
|
const newOffset = constrainOffset({
|
||||||
|
x: pinchCenter.value.x - pointX * newZoom,
|
||||||
|
y: pinchCenter.value.y - pointY * newZoom,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Apply changes in a single frame
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
zoom.value = newZoom
|
||||||
|
offset.value = newOffset
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTouchEnd = (event: TouchEvent) => {
|
||||||
|
// Only prevent default if we were handling multi-touch
|
||||||
|
if (wasPinching.value || isPinching.value) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
const touches = Array.from(event.touches)
|
||||||
|
const touchDuration = Date.now() - touchStartTime.value
|
||||||
|
|
||||||
|
if (touches.length === 0) {
|
||||||
|
if (isPinching.value || wasPinching.value) {
|
||||||
|
isPinching.value = false
|
||||||
|
wasPinching.value = false
|
||||||
|
// Force a clean update of visible items after pinching ends
|
||||||
|
setTimeout(() => {
|
||||||
|
_visibleItemsCache.value = calculateVisibleItems()
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const changedTouches = Array.from(event.changedTouches)
|
||||||
|
const [touch] = changedTouches
|
||||||
|
if (touch) {
|
||||||
|
if (touchDuration < TOUCH.TAP_DURATION
|
||||||
|
&& totalDragDistance.value <= TOUCH.TAP_DISTANCE) {
|
||||||
|
isDragging.value = false
|
||||||
|
justFinishedDragging.value = false
|
||||||
|
totalDragDistance.value = 0
|
||||||
|
}
|
||||||
|
handlePointerUp(touch.clientX, touch.clientY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (touches.length === 1 && isPinching.value && touches[0]) {
|
||||||
|
isPinching.value = false
|
||||||
|
const [touch] = touches
|
||||||
|
handlePointerDown(touch.clientX, touch.clientY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const canClick = computed(() =>
|
||||||
|
!justFinishedDragging.value
|
||||||
|
&& !isPinching.value
|
||||||
|
&& totalDragDistance.value <= PHYSICS.DRAG_THRESHOLD,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
offset: readonly(offset),
|
||||||
|
zoom: readonly(zoom),
|
||||||
|
visibleItems,
|
||||||
|
gridItems,
|
||||||
|
containerDimensions: readonly(containerDimensions),
|
||||||
|
canvasBounds: readonly(canvasBounds),
|
||||||
|
canClick: readonly(canClick),
|
||||||
|
updateDimensions,
|
||||||
|
handlePointerDown,
|
||||||
|
handlePointerMove,
|
||||||
|
handlePointerUp,
|
||||||
|
handleWheel,
|
||||||
|
handleTouchStart,
|
||||||
|
handleTouchMove,
|
||||||
|
handleTouchEnd,
|
||||||
|
navigateTo,
|
||||||
|
}
|
||||||
|
}
|
||||||
55
modules/infinite-canvas/constants/index.ts
Normal file
55
modules/infinite-canvas/constants/index.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Physics constants for drag and scroll behavior
|
||||||
|
*/
|
||||||
|
export const PHYSICS = {
|
||||||
|
/** Minimum velocity threshold for momentum animation */
|
||||||
|
MIN_VELOCITY: 0.1,
|
||||||
|
/** Friction coefficient for momentum decay */
|
||||||
|
FRICTION: 0.92,
|
||||||
|
/** Minimum distance to register as drag (px) */
|
||||||
|
DRAG_THRESHOLD: 5,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Touch interaction constants
|
||||||
|
*/
|
||||||
|
export const TOUCH = {
|
||||||
|
/** Minimum distance to register as pinch gesture (px) */
|
||||||
|
PINCH_THRESHOLD: 10,
|
||||||
|
/** Throttle delay for touch events at normal zoom (ms) */
|
||||||
|
THROTTLE_MS: 16,
|
||||||
|
/** Throttle delay for touch events at high zoom (ms) */
|
||||||
|
THROTTLE_MS_HIGH_ZOOM: 32,
|
||||||
|
/** Maximum tap duration (ms) */
|
||||||
|
TAP_DURATION: 300,
|
||||||
|
/** Maximum tap movement distance (px) */
|
||||||
|
TAP_DISTANCE: 10,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Viewport and performance constants
|
||||||
|
*/
|
||||||
|
export const VIEWPORT = {
|
||||||
|
/** Base buffer around viewport for item culling (px) */
|
||||||
|
BASE_BUFFER: 300,
|
||||||
|
/** Minimum buffer size (px) */
|
||||||
|
MIN_BUFFER: 100,
|
||||||
|
/** Maximum visible items */
|
||||||
|
MAX_VISIBLE_ITEMS: 100,
|
||||||
|
/** Base visible items calculation factor */
|
||||||
|
VISIBLE_ITEMS_FACTOR: 120,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default zoom configuration
|
||||||
|
*/
|
||||||
|
export const ZOOM_DEFAULTS = {
|
||||||
|
/** Minimum zoom level (40%) */
|
||||||
|
MIN: 0.4,
|
||||||
|
/** Maximum zoom level (220%) */
|
||||||
|
MAX: 2.2,
|
||||||
|
/** Zoom factor per step */
|
||||||
|
FACTOR: 1.08,
|
||||||
|
/** High zoom threshold for performance optimizations */
|
||||||
|
HIGH_ZOOM_THRESHOLD: 1.5,
|
||||||
|
} as const
|
||||||
110
modules/infinite-canvas/index.ts
Normal file
110
modules/infinite-canvas/index.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Nuxt module for infinite canvas functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { addComponent, addImports, createResolver, defineNuxtModule } from '@nuxt/kit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module configuration options
|
||||||
|
*/
|
||||||
|
export interface ModuleOptions {
|
||||||
|
/** Component name prefix (default: '') */
|
||||||
|
prefix?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infinite Canvas Nuxt Module
|
||||||
|
*
|
||||||
|
* Provides components and composables for creating infinite, zoomable canvases
|
||||||
|
* with drag interactions, touch support, and performance optimizations.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* // nuxt.config.ts
|
||||||
|
* export default defineNuxtConfig({
|
||||||
|
* modules: ['./modules/infinite-canvas']
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export default defineNuxtModule<ModuleOptions>({
|
||||||
|
meta: {
|
||||||
|
name: '@nuxt/infinite-canvas',
|
||||||
|
configKey: 'infiniteCanvas',
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
prefix: '',
|
||||||
|
},
|
||||||
|
setup(options, nuxt) {
|
||||||
|
const resolver = createResolver(import.meta.url)
|
||||||
|
|
||||||
|
// Register components
|
||||||
|
addComponent({
|
||||||
|
name: `${options.prefix}Canvas`,
|
||||||
|
filePath: resolver.resolve('./components/InfiniteCanvas.vue'),
|
||||||
|
export: 'default',
|
||||||
|
})
|
||||||
|
|
||||||
|
addComponent({
|
||||||
|
name: `${options.prefix}CanvasMinimap`,
|
||||||
|
filePath: resolver.resolve('./components/CanvasMinimap.vue'),
|
||||||
|
export: 'default',
|
||||||
|
})
|
||||||
|
|
||||||
|
addComponent({
|
||||||
|
name: `${options.prefix}CanvasLoader`,
|
||||||
|
filePath: resolver.resolve('./components/CanvasLoader.vue'),
|
||||||
|
export: 'default',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Register composables
|
||||||
|
addImports([
|
||||||
|
{
|
||||||
|
name: 'useInfiniteCanvas',
|
||||||
|
from: resolver.resolve('./composables/useInfiniteCanvas'),
|
||||||
|
as: 'useInfiniteCanvas',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'useImagePreloader',
|
||||||
|
from: resolver.resolve('./composables/useImagePreloader'),
|
||||||
|
as: 'useImagePreloader',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Register utilities (optional, for advanced usage)
|
||||||
|
addImports([
|
||||||
|
{
|
||||||
|
name: 'getTouchDistance',
|
||||||
|
from: resolver.resolve('./utils'),
|
||||||
|
as: 'getTouchDistance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'getTouchCenter',
|
||||||
|
from: resolver.resolve('./utils'),
|
||||||
|
as: 'getTouchCenter',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isVideo',
|
||||||
|
from: resolver.resolve('./utils'),
|
||||||
|
as: 'isVideo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isMobileDevice',
|
||||||
|
from: resolver.resolve('./utils'),
|
||||||
|
as: 'isMobileDevice',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Add type definitions
|
||||||
|
nuxt.hook('prepare:types', (options) => {
|
||||||
|
options.references.push({
|
||||||
|
path: resolver.resolve('./types'),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
declare module '@nuxt/schema' {
|
||||||
|
interface NuxtConfig {
|
||||||
|
infiniteCanvas?: ModuleOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
221
modules/infinite-canvas/types/index.ts
Normal file
221
modules/infinite-canvas/types/index.ts
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview Type definitions for the Infinite Canvas module
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic item that can be displayed on the canvas
|
||||||
|
*/
|
||||||
|
export interface CanvasItem {
|
||||||
|
/** URL to the image or video */
|
||||||
|
image: string
|
||||||
|
/** Display title */
|
||||||
|
title: string
|
||||||
|
/** External link URL */
|
||||||
|
link: string
|
||||||
|
/** Item width in pixels (optional, defaults to 300) */
|
||||||
|
width?: number
|
||||||
|
/** Item height in pixels (optional, defaults to 300) */
|
||||||
|
height?: number
|
||||||
|
/** Additional properties */
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D coordinate position
|
||||||
|
*/
|
||||||
|
export interface Position {
|
||||||
|
/** X coordinate */
|
||||||
|
x: number
|
||||||
|
/** Y coordinate */
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grid item with position and dimensions
|
||||||
|
*/
|
||||||
|
export interface GridItem {
|
||||||
|
/** Position on the canvas */
|
||||||
|
position: Position
|
||||||
|
/** Index in the original items array */
|
||||||
|
index: number
|
||||||
|
/** Item width in pixels */
|
||||||
|
width: number
|
||||||
|
/** Item height in pixels */
|
||||||
|
height: number
|
||||||
|
/** Whether the item is currently visible (computed) */
|
||||||
|
isVisible?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zoom configuration options
|
||||||
|
*/
|
||||||
|
export interface ZoomOptions {
|
||||||
|
/** Minimum zoom level (default: 0.4) */
|
||||||
|
minZoom?: number
|
||||||
|
/** Maximum zoom level (default: 2.2) */
|
||||||
|
maxZoom?: number
|
||||||
|
/** Zoom factor per step (default: 1.08) */
|
||||||
|
zoomFactor?: number
|
||||||
|
/** Enable Ctrl key for zooming (default: true) */
|
||||||
|
enableCtrl?: boolean
|
||||||
|
/** Enable Meta key for zooming (default: true) */
|
||||||
|
enableMeta?: boolean
|
||||||
|
/** Enable Alt key for zooming (default: true) */
|
||||||
|
enableAlt?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Canvas boundaries and dimensions
|
||||||
|
*/
|
||||||
|
export interface CanvasBounds {
|
||||||
|
/** Canvas width in pixels */
|
||||||
|
width: number
|
||||||
|
/** Canvas height in pixels */
|
||||||
|
height: number
|
||||||
|
/** Center X coordinate (computed) */
|
||||||
|
centerX?: number
|
||||||
|
/** Center Y coordinate (computed) */
|
||||||
|
centerY?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container dimensions
|
||||||
|
*/
|
||||||
|
export interface ContainerDimensions {
|
||||||
|
/** Container width in pixels */
|
||||||
|
width: number
|
||||||
|
/** Container height in pixels */
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for the useInfiniteCanvas composable
|
||||||
|
*/
|
||||||
|
export interface UseInfiniteCanvasOptions {
|
||||||
|
/** Array of items to display */
|
||||||
|
items: CanvasItem[]
|
||||||
|
/** Minimum gap between items in pixels (default: 40) */
|
||||||
|
baseGap?: number
|
||||||
|
/** Zoom configuration */
|
||||||
|
zoomOptions?: ZoomOptions
|
||||||
|
/** Reference to the container element */
|
||||||
|
containerRef: Ref<HTMLElement | null>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return type of the useInfiniteCanvas composable
|
||||||
|
*/
|
||||||
|
export interface UseInfiniteCanvasReturn {
|
||||||
|
/** Current canvas offset */
|
||||||
|
offset: Readonly<Ref<Position>>
|
||||||
|
/** Current zoom level */
|
||||||
|
zoom: Readonly<Ref<number>>
|
||||||
|
/** Currently visible items */
|
||||||
|
visibleItems: ComputedRef<GridItem[]>
|
||||||
|
/** All positioned grid items */
|
||||||
|
gridItems: ComputedRef<GridItem[]>
|
||||||
|
/** Container dimensions */
|
||||||
|
containerDimensions: Readonly<Ref<ContainerDimensions>>
|
||||||
|
/** Canvas boundaries */
|
||||||
|
canvasBounds: Readonly<Ref<CanvasBounds>>
|
||||||
|
/** Whether clicks are allowed (not dragging) */
|
||||||
|
canClick: Readonly<Ref<boolean>>
|
||||||
|
/** Update container dimensions */
|
||||||
|
updateDimensions: () => void
|
||||||
|
/** Handle pointer down events */
|
||||||
|
handlePointerDown: (clientX: number, clientY: number) => void
|
||||||
|
/** Handle pointer move events */
|
||||||
|
handlePointerMove: (clientX: number, clientY: number) => void
|
||||||
|
/** Handle pointer up events */
|
||||||
|
handlePointerUp: (clientX: number, clientY: number) => void
|
||||||
|
/** Handle wheel events */
|
||||||
|
handleWheel: (event: WheelEvent) => void
|
||||||
|
/** Handle touch start events */
|
||||||
|
handleTouchStart: (event: TouchEvent) => void
|
||||||
|
/** Handle touch move events */
|
||||||
|
handleTouchMove: (event: TouchEvent) => void
|
||||||
|
/** Handle touch end events */
|
||||||
|
handleTouchEnd: (event: TouchEvent) => void
|
||||||
|
/** Navigate to a specific position */
|
||||||
|
navigateTo: (position: Position) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for the image preloader
|
||||||
|
*/
|
||||||
|
export interface ImagePreloaderOptions {
|
||||||
|
/** Array of image/video URLs to preload */
|
||||||
|
images: string[]
|
||||||
|
/** Progress callback (0-1) */
|
||||||
|
onProgress?: (progress: number) => void
|
||||||
|
/** Completion callback */
|
||||||
|
onComplete?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return type of the useImagePreloader composable
|
||||||
|
*/
|
||||||
|
export interface UseImagePreloaderReturn {
|
||||||
|
/** Loading progress (0-1) */
|
||||||
|
progress: Readonly<Ref<number>>
|
||||||
|
/** Number of loaded items */
|
||||||
|
loadedCount: Readonly<Ref<number>>
|
||||||
|
/** Whether currently loading */
|
||||||
|
isLoading: Readonly<Ref<boolean>>
|
||||||
|
/** Whether loading is complete */
|
||||||
|
isComplete: Readonly<Ref<boolean>>
|
||||||
|
/** Start the preloading process */
|
||||||
|
startPreloading: () => Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Props for the minimap component
|
||||||
|
*/
|
||||||
|
export interface MinimapProps {
|
||||||
|
/** Canvas items */
|
||||||
|
items: CanvasItem[]
|
||||||
|
/** Grid items with positions */
|
||||||
|
gridItems: GridItem[]
|
||||||
|
/** Current canvas offset */
|
||||||
|
offset: Position
|
||||||
|
/** Current zoom level */
|
||||||
|
zoom: number
|
||||||
|
/** Container dimensions */
|
||||||
|
containerDimensions: ContainerDimensions
|
||||||
|
/** Canvas boundaries */
|
||||||
|
canvasBounds: CanvasBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Props for the loader component
|
||||||
|
*/
|
||||||
|
export interface LoaderProps {
|
||||||
|
/** Loading progress (0-1) */
|
||||||
|
progress: number
|
||||||
|
/** Whether the loader is visible */
|
||||||
|
isVisible: boolean
|
||||||
|
/** Optional title */
|
||||||
|
title?: string
|
||||||
|
/** Optional description */
|
||||||
|
description?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Props for the InfiniteCanvas component
|
||||||
|
*/
|
||||||
|
export interface InfiniteCanvasProps<T = any> {
|
||||||
|
/** Array of items to display */
|
||||||
|
items: T[]
|
||||||
|
/** Minimum gap between items (default: 40) */
|
||||||
|
baseGap?: number
|
||||||
|
/** Zoom configuration */
|
||||||
|
zoomOptions?: ZoomOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events emitted by the InfiniteCanvas component
|
||||||
|
*/
|
||||||
|
export interface InfiniteCanvasEmits<T = any> {
|
||||||
|
/** Emitted when an item is clicked */
|
||||||
|
itemClick: [item: T, index: number]
|
||||||
|
}
|
||||||
73
modules/infinite-canvas/utils/index.ts
Normal file
73
modules/infinite-canvas/utils/index.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Calculates the distance between two touch points
|
||||||
|
* @param touch1 First touch point
|
||||||
|
* @param touch2 Second touch point
|
||||||
|
* @returns Distance in pixels
|
||||||
|
*/
|
||||||
|
export function getTouchDistance(touch1: Touch, touch2: Touch): number {
|
||||||
|
const dx = touch1.clientX - touch2.clientX
|
||||||
|
const dy = touch1.clientY - touch2.clientY
|
||||||
|
return Math.sqrt(dx * dx + dy * dy)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the center point between two touches
|
||||||
|
* @param touch1 First touch point
|
||||||
|
* @param touch2 Second touch point
|
||||||
|
* @returns Center coordinates
|
||||||
|
*/
|
||||||
|
export function getTouchCenter(touch1: Touch, touch2: Touch): { x: number, y: number } {
|
||||||
|
return {
|
||||||
|
x: (touch1.clientX + touch2.clientX) / 2,
|
||||||
|
y: (touch1.clientY + touch2.clientY) / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a throttled version of a function
|
||||||
|
* @param func Function to throttle
|
||||||
|
* @param delay Delay in milliseconds
|
||||||
|
* @returns Throttled function
|
||||||
|
*/
|
||||||
|
export function throttle<T extends(...args: any[]) => any>(func: T, delay: number): T {
|
||||||
|
let lastCall = 0
|
||||||
|
return ((...args: any[]) => {
|
||||||
|
const now = Date.now()
|
||||||
|
if (now - lastCall >= delay) {
|
||||||
|
lastCall = now
|
||||||
|
return func(...args)
|
||||||
|
}
|
||||||
|
}) as T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a file URL is a video based on its extension
|
||||||
|
* @param url File URL to check
|
||||||
|
* @returns True if the file is a video
|
||||||
|
*/
|
||||||
|
export function isVideo(url: string): boolean {
|
||||||
|
const extension = url.split('.').pop()?.toLowerCase()
|
||||||
|
return ['mp4', 'webm', 'mov'].includes(extension || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects if the current device is mobile
|
||||||
|
* @param userAgent Navigator user agent string
|
||||||
|
* @param windowWidth Current window width
|
||||||
|
* @returns True if device is mobile
|
||||||
|
*/
|
||||||
|
export function isMobileDevice(userAgent: string = '', windowWidth: number = 0): boolean {
|
||||||
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
|
||||||
|
|| windowWidth <= 768
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps a value between min and max
|
||||||
|
* @param value Value to clamp
|
||||||
|
* @param min Minimum value
|
||||||
|
* @param max Maximum value
|
||||||
|
* @returns Clamped value
|
||||||
|
*/
|
||||||
|
export function clamp(value: number, min: number, max: number): number {
|
||||||
|
return Math.max(min, Math.min(max, value))
|
||||||
|
}
|
||||||
59
modules/screenshots.ts
Normal file
59
modules/screenshots.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
|
import { existsSync } from 'node:fs'
|
||||||
|
import { defineNuxtModule } from '@nuxt/kit'
|
||||||
|
import captureWebsite from 'capture-website'
|
||||||
|
import { join } from 'pathe'
|
||||||
|
|
||||||
|
interface ContentFile {
|
||||||
|
id?: string
|
||||||
|
body?: {
|
||||||
|
items: TemplateItem[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TemplateItem {
|
||||||
|
name: string
|
||||||
|
url?: string
|
||||||
|
screenshotUrl?: string
|
||||||
|
screenshotOptions?: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineNuxtModule((_, nuxt) => {
|
||||||
|
nuxt.hook('content:file:afterParse', async ({ content: file }: { content: ContentFile }) => {
|
||||||
|
if (file.id?.includes('works/')) {
|
||||||
|
const template = file as TemplateItem
|
||||||
|
const url = template.screenshotUrl || template.url
|
||||||
|
if (!url) {
|
||||||
|
console.error(`Work ${template.name} has no "url" or "screenshotUrl" to take a screenshot from`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (template.screenshotUrl)
|
||||||
|
return
|
||||||
|
|
||||||
|
const name = template.name.toLowerCase().replace(/\s/g, '-')
|
||||||
|
// eslint-disable-next-line node/prefer-global/process
|
||||||
|
const filename = join(process.cwd(), 'public/assets/works', `${name}.png`)
|
||||||
|
|
||||||
|
if (existsSync(filename))
|
||||||
|
return
|
||||||
|
|
||||||
|
console.log(`Generating screenshot for work ${template.name} hitting ${url}...`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await captureWebsite.file(url, filename, {
|
||||||
|
...(template.screenshotOptions || {
|
||||||
|
darkMode: true,
|
||||||
|
}),
|
||||||
|
launchOptions: {
|
||||||
|
headless: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`Screenshot for ${template.name} generated successfully`)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error(`Error generating screenshot for ${template.name}:`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
"@vercel/speed-insights": "^1.2.0",
|
"@vercel/speed-insights": "^1.2.0",
|
||||||
"@vueuse/motion": "^3.0.3",
|
"@vueuse/motion": "^3.0.3",
|
||||||
"better-sqlite3": "^12.2.0",
|
"better-sqlite3": "^12.2.0",
|
||||||
|
"capture-website": "^4.2.0",
|
||||||
"eslint": "^9.0.0",
|
"eslint": "^9.0.0",
|
||||||
"nuxt": "^4.1.0",
|
"nuxt": "^4.1.0",
|
||||||
"rehype-katex": "^7.0.1",
|
"rehype-katex": "^7.0.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user