mirror of
				https://github.com/mmahdium/TorrentMax.git
				synced 2025-11-04 02:58:13 +01:00 
			
		
		
		
	Finished API integration
This commit is contained in:
		
							
								
								
									
										110
									
								
								app/components/MagnetCard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								app/components/MagnetCard.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  name: string;
 | 
			
		||||
  totalTrackers: number;
 | 
			
		||||
  magnetUrl: string;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const copied = ref(false);
 | 
			
		||||
 | 
			
		||||
function copyMagnet() {
 | 
			
		||||
  navigator.clipboard.writeText(decodeURIComponent(props.magnetUrl));
 | 
			
		||||
  copied.value = true;
 | 
			
		||||
  setTimeout(() => (copied.value = false), 2000);
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="w-full max-w-2xl mx-auto ">
 | 
			
		||||
    <div class="rounded-2xl border bg-base-100 shadow-lg p-6 space-y-4">
 | 
			
		||||
      <!-- Title and trackers -->
 | 
			
		||||
      <div class="flex items-center justify-between">
 | 
			
		||||
        <h2 class="text-lg font-semibold wrap-break-word flex-1">
 | 
			
		||||
          {{ name }}
 | 
			
		||||
        </h2>
 | 
			
		||||
        <span class="badge badge-outline whitespace-nowrap ml-3">
 | 
			
		||||
          {{ totalTrackers }} trackers
 | 
			
		||||
        </span>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <!-- Magnet link with copy -->
 | 
			
		||||
      <div class="form-control">
 | 
			
		||||
        <label class="label">
 | 
			
		||||
          <span class="label-text font-medium">Maxed Out Magnet Link</span>
 | 
			
		||||
        </label>
 | 
			
		||||
        <div class="flex items-center gap-2">
 | 
			
		||||
          <input
 | 
			
		||||
            type="url"
 | 
			
		||||
            :value="decodeURIComponent(props.magnetUrl)"
 | 
			
		||||
            readonly
 | 
			
		||||
            class="input input-bordered w-full font-medium text-xs"
 | 
			
		||||
          />
 | 
			
		||||
          <button
 | 
			
		||||
          v-auto-animate
 | 
			
		||||
            class="btn btn-square btn-primary text-accent"
 | 
			
		||||
            @click="copyMagnet"
 | 
			
		||||
            :title="copied ? 'Copied!' : 'Copy magnet link'"
 | 
			
		||||
          >
 | 
			
		||||
            <!-- Default copy icon -->
 | 
			
		||||
            <svg v-if="!copied" xmlns="http://www.w3.org/2000/svg" fill="none"
 | 
			
		||||
                 viewBox="0 0 24 24" stroke-width="1.5"
 | 
			
		||||
                 stroke="currentColor" class="size-6">
 | 
			
		||||
              <path stroke-linecap="round" stroke-linejoin="round"
 | 
			
		||||
                    d="M15.666 3.888A2.25 2.25 0 0 0 13.5 
 | 
			
		||||
                       2.25h-3c-1.03 0-1.9.693-2.166 
 | 
			
		||||
                       1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 
 | 
			
		||||
                       0 0 1-.75.75H9a.75.75 0 0 
 | 
			
		||||
                       1-.75-.75v0c0-.212.03-.418.084-.612m7.332 
 | 
			
		||||
                       0c.646.049 1.288.11 1.927.184 1.1.128 
 | 
			
		||||
                       1.907 1.077 1.907 2.185V19.5a2.25 
 | 
			
		||||
                       2.25 0 0 1-2.25 2.25H6.75A2.25 
 | 
			
		||||
                       2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 
 | 
			
		||||
                       1.907-2.185a48.208 48.208 0 0 1 
 | 
			
		||||
                       1.927-.184" />
 | 
			
		||||
            </svg>
 | 
			
		||||
 | 
			
		||||
            <!-- Success icon -->
 | 
			
		||||
            <svg v-else xmlns="http://www.w3.org/2000/svg" fill="none"
 | 
			
		||||
                 viewBox="0 0 24 24" stroke-width="1.5"
 | 
			
		||||
                 stroke="currentColor" class="size-6">
 | 
			
		||||
              <path stroke-linecap="round" stroke-linejoin="round"
 | 
			
		||||
                    d="M11.35 3.836c-.065.21-.1.433-.1.664 
 | 
			
		||||
                       0 .414.336.75.75.75h4.5a.75.75 
 | 
			
		||||
                       0 0 0 .75-.75 2.25 2.25 0 0 
 | 
			
		||||
                       0-.1-.664m-5.8 0A2.251 2.251 
 | 
			
		||||
                       0 0 1 13.5 2.25H15c1.012 0 
 | 
			
		||||
                       1.867.668 2.15 1.586m-5.8 
 | 
			
		||||
                       0c-.376.023-.75.05-1.124.08C9.095 
 | 
			
		||||
                       4.01 8.25 4.973 8.25 6.108V8.25m8.9-4.414c.376.023.75.05 
 | 
			
		||||
                       1.124.08 1.131.094 1.976 1.057 
 | 
			
		||||
                       1.976 2.192V16.5A2.25 2.25 
 | 
			
		||||
                       0 0 1 18 18.75h-2.25m-7.5-10.5H4.875c-.621 
 | 
			
		||||
                       0-1.125.504-1.125 1.125v11.25c0 
 | 
			
		||||
                       .621.504 1.125 1.125 1.125h9.75c.621 
 | 
			
		||||
                       0 1.125-.504 1.125-1.125V18.75m-7.5-10.5h6.375c.621 
 | 
			
		||||
                       0 1.125.504 1.125 1.125v9.375m-8.25-3 
 | 
			
		||||
                       1.5 1.5 3-3.75" />
 | 
			
		||||
            </svg>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <!-- Info alert -->
 | 
			
		||||
      <div class="alert alert-soft mt-2">
 | 
			
		||||
        <svg xmlns="http://www.w3.org/2000/svg" fill="none"
 | 
			
		||||
             viewBox="0 0 24 24"
 | 
			
		||||
             class="stroke-current shrink-0 w-6 h-6">
 | 
			
		||||
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
 | 
			
		||||
                d="M13 16h-1v-4h-1m1-4h.01M21 
 | 
			
		||||
                   12a9 9 0 11-18 0 9 9 0 0118 
 | 
			
		||||
                   0z"/>
 | 
			
		||||
        </svg>
 | 
			
		||||
        <span>
 | 
			
		||||
          This magnet link has been enriched with additional trackers for better availability.
 | 
			
		||||
        </span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
							
								
								
									
										87
									
								
								app/components/SearchBar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								app/components/SearchBar.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(["submit"]);
 | 
			
		||||
 | 
			
		||||
const magnetUrl = ref("");
 | 
			
		||||
const error = ref("");
 | 
			
		||||
 | 
			
		||||
function isMagnetLink(url: string): boolean {
 | 
			
		||||
  const magnetRegex =
 | 
			
		||||
    /^magnet:\?xt=urn:btih:(?:[A-F0-9]{40}|[A-Z2-7]{32})(?:&[a-z0-9]+=[^&]*)*$/i;
 | 
			
		||||
  return magnetRegex.test(url.trim());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleSubmit() {
 | 
			
		||||
  if (!isMagnetLink(magnetUrl.value)) {
 | 
			
		||||
    error.value = "Invalid magnet URL";
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  error.value = "";
 | 
			
		||||
  emit("submit", magnetUrl.value);
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="w-full">
 | 
			
		||||
    <div
 | 
			
		||||
      class="flex items-center w-full rounded-2xl shadow-lg px-4 py-2 transition-all duration-500 focus-within:ring-2"
 | 
			
		||||
      :class="
 | 
			
		||||
        error
 | 
			
		||||
          ? 'border-2 border-red-500 bg-base-200'
 | 
			
		||||
          : 'border border-primary bg-base-100 focus-within:ring-primary'
 | 
			
		||||
      "
 | 
			
		||||
    >
 | 
			
		||||
      <!-- Left icon -->
 | 
			
		||||
      <svg
 | 
			
		||||
        xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
        fill="none"
 | 
			
		||||
        viewBox="0 0 24 24"
 | 
			
		||||
        stroke-width="1.5"
 | 
			
		||||
        stroke="currentColor"
 | 
			
		||||
        class="size-5 mr-3 transition-colors duration-500"
 | 
			
		||||
        :class="error ? 'text-red-500' : 'text-gray-400'"
 | 
			
		||||
      >
 | 
			
		||||
        <path
 | 
			
		||||
          stroke-linecap="round"
 | 
			
		||||
          stroke-linejoin="round"
 | 
			
		||||
          d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
 | 
			
		||||
        />
 | 
			
		||||
      </svg>
 | 
			
		||||
 | 
			
		||||
      <!-- Input -->
 | 
			
		||||
      <input
 | 
			
		||||
        v-model="magnetUrl"
 | 
			
		||||
        type="text"
 | 
			
		||||
        placeholder="Enter magnet URL"
 | 
			
		||||
        class="flex-1 bg-transparent outline-none text-base"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <!-- Right circular button -->
 | 
			
		||||
      <button
 | 
			
		||||
        class="ml-3 w-10 h-10 flex items-center justify-center rounded-full bg-primary text-accent hover:scale-110 transition-transform duration-300 shadow-md"
 | 
			
		||||
        @click="handleSubmit"
 | 
			
		||||
      >
 | 
			
		||||
        <svg
 | 
			
		||||
          xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
          fill="none"
 | 
			
		||||
          viewBox="0 0 24 24"
 | 
			
		||||
          stroke-width="1.5"
 | 
			
		||||
          stroke="currentColor"
 | 
			
		||||
          class="size-5"
 | 
			
		||||
        >
 | 
			
		||||
          <path
 | 
			
		||||
            stroke-linecap="round"
 | 
			
		||||
            stroke-linejoin="round"
 | 
			
		||||
            d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z"
 | 
			
		||||
          />
 | 
			
		||||
        </svg>
 | 
			
		||||
      </button>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Error text -->
 | 
			
		||||
    <p v-motion-fade v-if="error" class="mt-2 text-sm text-red-500">
 | 
			
		||||
      {{ error }}
 | 
			
		||||
    </p>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -1,201 +1,104 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, onMounted, onUnmounted } from 'vue'
 | 
			
		||||
import { useMotion } from '@vueuse/motion'
 | 
			
		||||
import MagnetCard from "~/components/MagnetCard.vue";
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
const magnetInput = ref('')
 | 
			
		||||
const isLoading = ref(false)
 | 
			
		||||
 | 
			
		||||
// Light bar particles
 | 
			
		||||
interface Particle {
 | 
			
		||||
  id: number;
 | 
			
		||||
  x: number;
 | 
			
		||||
  y: number;
 | 
			
		||||
  opacity: number;
 | 
			
		||||
  speed: number;
 | 
			
		||||
  size: number;
 | 
			
		||||
  symbol: string;
 | 
			
		||||
interface MaxedMagnetResponse {
 | 
			
		||||
  totalTrackers: number;
 | 
			
		||||
  name?: string;
 | 
			
		||||
  id: string;
 | 
			
		||||
  maxedMagnet: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const particles = ref<Particle[]>([])
 | 
			
		||||
const maxedMagnet = ref<MaxedMagnetResponse | null>(null);
 | 
			
		||||
const error = ref<string | null>(null);
 | 
			
		||||
const loading = ref(false);
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  if (process.client) {
 | 
			
		||||
    initializeParticles()
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
async function getMaxedMagnetUrl(magnet: string) {
 | 
			
		||||
  error.value = null; // Clear any previous error
 | 
			
		||||
  loading.value = true; // Set loading to true
 | 
			
		||||
 | 
			
		||||
const symbols = ['✦', '✧', '★', '●', '◈', '◇', '◈']
 | 
			
		||||
  try {
 | 
			
		||||
    const response = await fetch("/api/magnet", {
 | 
			
		||||
      method: "POST",
 | 
			
		||||
      headers: {
 | 
			
		||||
        "Content-Type": "application/json",
 | 
			
		||||
      },
 | 
			
		||||
      body: JSON.stringify({ magnet }),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
const initializeParticles = () => {
 | 
			
		||||
  if (typeof window === 'undefined') return
 | 
			
		||||
  
 | 
			
		||||
  const particleCount = 20
 | 
			
		||||
  particles.value = []
 | 
			
		||||
  
 | 
			
		||||
  for (let i = 0; i < particleCount; i++) {
 | 
			
		||||
    particles.value.push({
 | 
			
		||||
      id: i,
 | 
			
		||||
      x: Math.random() * window.innerWidth,
 | 
			
		||||
      y: Math.random() * 60, // Start from top area where light bar is
 | 
			
		||||
      opacity: Math.random() * 0.4 + 0.2,
 | 
			
		||||
      speed: Math.random() * 0.8 + 0.2,
 | 
			
		||||
      size: Math.random() * 8 + 4,
 | 
			
		||||
      symbol: symbols[Math.floor(Math.random() * symbols.length)]
 | 
			
		||||
    })
 | 
			
		||||
    if (!response.ok) {
 | 
			
		||||
      const errorData = await response.json().catch(() => ({}));
 | 
			
		||||
      error.value =
 | 
			
		||||
        errorData.message || `HTTP error! status: ${response.status}`;
 | 
			
		||||
      console.error("API error:", error.value);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  // Start animation
 | 
			
		||||
  animateParticles()
 | 
			
		||||
    maxedMagnet.value = await response.json();
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    error.value =
 | 
			
		||||
      err instanceof Error ? err.message : "An unknown error occurred";
 | 
			
		||||
    console.error("Network error:", err);
 | 
			
		||||
  } finally {
 | 
			
		||||
    loading.value = false; // Reset loading state
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
let animationFrameId: number
 | 
			
		||||
 | 
			
		||||
const animateParticles = () => {
 | 
			
		||||
  particles.value.forEach(particle => {
 | 
			
		||||
    // Move particles down
 | 
			
		||||
    particle.y += particle.speed
 | 
			
		||||
    
 | 
			
		||||
    // Reset particles that go off screen
 | 
			
		||||
    if (particle.y > window.innerHeight) {
 | 
			
		||||
      particle.y = Math.random() * 20
 | 
			
		||||
      particle.x = Math.random() * window.innerWidth
 | 
			
		||||
}
 | 
			
		||||
  })
 | 
			
		||||
  
 | 
			
		||||
  // Continue animation
 | 
			
		||||
  animationFrameId = requestAnimationFrame(animateParticles)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const addTrackers = async () => {
 | 
			
		||||
  if (!magnetInput.value.trim()) return
 | 
			
		||||
  
 | 
			
		||||
  isLoading.value = true
 | 
			
		||||
  // Simulate API call
 | 
			
		||||
  await new Promise(resolve => setTimeout(resolve, 1500))
 | 
			
		||||
  isLoading.value = false
 | 
			
		||||
  
 | 
			
		||||
  // Here you would implement the actual tracker addition logic
 | 
			
		||||
  console.log('Adding trackers to:', magnetInput.value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clean up animation on component unmount
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
  if (animationFrameId) {
 | 
			
		||||
    cancelAnimationFrame(animationFrameId)
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="min-h-screen bg-black text-white overflow-hidden relative">
 | 
			
		||||
    <!-- Single expanding radial gradient for seamless light -->
 | 
			
		||||
    <div 
 | 
			
		||||
      v-motion
 | 
			
		||||
      :initial="{ width: '0px', height: '0px', top: '-20%', left: '50%', transform: 'translateX(-50%)' }"
 | 
			
		||||
      :visibleOnce="{ 
 | 
			
		||||
        width: '200vw', 
 | 
			
		||||
        height: '200vh', 
 | 
			
		||||
        transition: { duration: 3000, ease: 'cubic-bezier(0.3, 0.7, 0.4, 1.0)' } 
 | 
			
		||||
      }"
 | 
			
		||||
      class="absolute z-0 opacity-40"
 | 
			
		||||
      :style="{
 | 
			
		||||
        background: 'radial-gradient(circle at 50% 20%, rgba(59, 130, 246, 0.5), rgba(139, 92, 246, 0.25) 20%, transparent 50%)',
 | 
			
		||||
        'background-size': '100% 100%',
 | 
			
		||||
        'background-repeat': 'no-repeat'
 | 
			
		||||
      }"
 | 
			
		||||
    ></div>
 | 
			
		||||
    <!-- Additional bright center glow -->
 | 
			
		||||
    <div 
 | 
			
		||||
      v-motion
 | 
			
		||||
      :initial="{ opacity: 0 }"
 | 
			
		||||
      :visibleOnce="{ opacity: 0.5, transition: { duration: 500, delay: 300 } }"
 | 
			
		||||
      class="absolute top-[-10%] left-1/2 transform -translate-x-1/2 w-80 h-80 rounded-full bg-blue-400 blur-3xl z-0"
 | 
			
		||||
    ></div>
 | 
			
		||||
    
 | 
			
		||||
    <!-- Falling particles -->
 | 
			
		||||
    <div class="absolute inset-0 z-0">
 | 
			
		||||
      <div 
 | 
			
		||||
        v-for="particle in particles" 
 | 
			
		||||
        :key="particle.id"
 | 
			
		||||
        class="absolute text-blue-300/60 text-lg font-bold select-none pointer-events-none"
 | 
			
		||||
        :style="{
 | 
			
		||||
          left: particle.x + 'px',
 | 
			
		||||
          top: particle.y + 'px',
 | 
			
		||||
          opacity: particle.opacity,
 | 
			
		||||
          fontSize: particle.size + 'px',
 | 
			
		||||
          transform: 'translate(-50%, -50%)'
 | 
			
		||||
        }"
 | 
			
		||||
      >
 | 
			
		||||
        {{ particle.symbol }}
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Content -->
 | 
			
		||||
    <div class="relative z-10 min-h-screen flex flex-col items-center justify-center p-6">
 | 
			
		||||
      <!-- Title with subtle fade in -->
 | 
			
		||||
      <div 
 | 
			
		||||
        v-motion
 | 
			
		||||
        :initial="{ opacity: 0 }"
 | 
			
		||||
        :visibleOnce="{ opacity: 1, transition: { duration: 1000 } }"
 | 
			
		||||
        class="text-center mb-10"
 | 
			
		||||
      >
 | 
			
		||||
        <h1 class="text-4xl md:text-6xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-500 mb-4 tracking-tight">
 | 
			
		||||
          TorrentMax
 | 
			
		||||
        </h1>
 | 
			
		||||
        <p class="text-gray-400 max-w-md mx-auto">
 | 
			
		||||
          Maximize your torrents with premium tracker integration
 | 
			
		||||
  <div class="flex flex-col min-h-screen bg-base-300">
 | 
			
		||||
    <div class="grow flex items-start justify-center pt-40 px-4">
 | 
			
		||||
      <div class="w-full max-w-2xl space-y-6">
 | 
			
		||||
        <div class="hero">
 | 
			
		||||
          <div class="hero-content text-center">
 | 
			
		||||
            <div class="max-w-md">
 | 
			
		||||
              <h1 class="text-5xl font-bold drop-shadow-xl">TorrentMax</h1>
 | 
			
		||||
              <p class="py-6">
 | 
			
		||||
                Paste a magnet link below and TorrentMax will enrich it with
 | 
			
		||||
                additional trackers
 | 
			
		||||
              </p>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <SearchBar @submit="getMaxedMagnetUrl" />
 | 
			
		||||
 | 
			
		||||
      <!-- Input and Button -->
 | 
			
		||||
        <!-- Loading indicator -->
 | 
			
		||||
        <div
 | 
			
		||||
        v-motion
 | 
			
		||||
        :initial="{ opacity: 0 }"
 | 
			
		||||
        :visibleOnce="{ opacity: 1, transition: { duration: 1000, delay: 300 } }"
 | 
			
		||||
        class="w-full max-w-2xl flex flex-col sm:flex-row gap-4"
 | 
			
		||||
          v-motion-fade
 | 
			
		||||
          v-if="loading"
 | 
			
		||||
          class="flex justify-center items-center p-8"
 | 
			
		||||
        >
 | 
			
		||||
        <textarea
 | 
			
		||||
          v-model="magnetInput"
 | 
			
		||||
          placeholder="Enter magnet link or .torrent file content..."
 | 
			
		||||
          class="flex-grow px-6 py-4 rounded-xl bg-gray-800/50 backdrop-blur-sm border border-gray-700 focus:border-blue-400 focus:ring-2 focus:ring-blue-500/30 text-white placeholder-gray-500 min-h-[60px] max-h-[120px] resize-none shadow-inner focus:shadow-blue-500/10 focus:shadow-lg transition-all duration-300"
 | 
			
		||||
          rows="1"
 | 
			
		||||
        ></textarea>
 | 
			
		||||
        <button
 | 
			
		||||
          @click="addTrackers"
 | 
			
		||||
          :disabled="isLoading"
 | 
			
		||||
          class="px-8 py-4 bg-gradient-to-r from-blue-600 to-purple-600 rounded-xl font-medium text-white shadow-lg shadow-blue-500/20 hover:shadow-blue-500/40 hover:from-blue-500 hover:to-purple-600 transition-all duration-500 disabled:opacity-50 flex items-center justify-center whitespace-nowrap"
 | 
			
		||||
        >
 | 
			
		||||
          <span v-if="!isLoading" class="flex items-center">
 | 
			
		||||
            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 | 
			
		||||
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
 | 
			
		||||
            </svg>
 | 
			
		||||
            Max It Out
 | 
			
		||||
          </span>
 | 
			
		||||
          <span v-else class="flex items-center">
 | 
			
		||||
            <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
 | 
			
		||||
              <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
 | 
			
		||||
              <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
 | 
			
		||||
            </svg>
 | 
			
		||||
            Processing...
 | 
			
		||||
          </span>
 | 
			
		||||
        </button>
 | 
			
		||||
          <span class="loading loading-infinity loading-lg"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
      <div class="mt-10 text-center text-sm text-gray-600">
 | 
			
		||||
        <p>Your torrents will be enhanced with premium trackers for maximum performance</p>
 | 
			
		||||
        <!-- Error message display -->
 | 
			
		||||
        <div v-if="error && !loading" class="max-w-2xl mx-auto p-4">
 | 
			
		||||
          <div class="alert alert-error">
 | 
			
		||||
            <svg
 | 
			
		||||
              xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
              class="stroke-current shrink-0 h-6 w-6"
 | 
			
		||||
              fill="none"
 | 
			
		||||
              viewBox="0 0 24 24"
 | 
			
		||||
            >
 | 
			
		||||
              <path
 | 
			
		||||
                stroke-linecap="round"
 | 
			
		||||
                stroke-linejoin="round"
 | 
			
		||||
                stroke-width="2"
 | 
			
		||||
                d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
 | 
			
		||||
              />
 | 
			
		||||
            </svg>
 | 
			
		||||
            <span>{{ error }}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <MagnetCard
 | 
			
		||||
          v-motion-fade
 | 
			
		||||
          v-if="maxedMagnet && !loading"
 | 
			
		||||
          :name="maxedMagnet.name || 'Unknown Torrent'"
 | 
			
		||||
          :total-trackers="maxedMagnet.totalTrackers"
 | 
			
		||||
          :magnet-url="maxedMagnet.maxedMagnet"
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
/* Simple fade in animation */
 | 
			
		||||
@keyframes fadeIn {
 | 
			
		||||
  from { opacity: 0; }
 | 
			
		||||
  to { opacity: 1; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fade-in {
 | 
			
		||||
  animation: fadeIn 1s ease-in-out;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,2 +1,4 @@
 | 
			
		||||
@import "tailwindcss";
 | 
			
		||||
@plugin "daisyui";
 | 
			
		||||
@plugin "daisyui" {
 | 
			
		||||
  themes: lemonade --default, abyss --prefersdark;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import tailwindcss from "@tailwindcss/vite";
 | 
			
		||||
export default defineNuxtConfig({
 | 
			
		||||
  compatibilityDate: '2025-07-15',
 | 
			
		||||
  devtools: { enabled: true },
 | 
			
		||||
  modules: ['@nuxt/eslint','@vueuse/motion/nuxt'],
 | 
			
		||||
  modules: ['@nuxt/eslint','@vueuse/motion/nuxt','@formkit/auto-animate/nuxt'],
 | 
			
		||||
  vite: {
 | 
			
		||||
    plugins: [tailwindcss()],
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
    "postinstall": "nuxt prepare"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@formkit/auto-animate": "^0.9.0",
 | 
			
		||||
    "@nuxt/eslint": "1.10.0",
 | 
			
		||||
    "@tailwindcss/vite": "^4.1.16",
 | 
			
		||||
    "@vueuse/motion": "^3.0.3",
 | 
			
		||||
@@ -19,5 +20,8 @@
 | 
			
		||||
    "tailwindcss": "^4.1.16",
 | 
			
		||||
    "vue": "^3.5.22",
 | 
			
		||||
    "vue-router": "^4.6.3"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "typescript": "^5.9.3"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										328
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										328
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -8,15 +8,18 @@ importers:
 | 
			
		||||
 | 
			
		||||
  .:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@formkit/auto-animate':
 | 
			
		||||
        specifier: ^0.9.0
 | 
			
		||||
        version: 0.9.0
 | 
			
		||||
      '@nuxt/eslint':
 | 
			
		||||
        specifier: 1.10.0
 | 
			
		||||
        version: 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
        version: 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.3.5)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
      '@tailwindcss/vite':
 | 
			
		||||
        specifier: ^4.1.16
 | 
			
		||||
        version: 4.1.16(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
      '@vueuse/motion':
 | 
			
		||||
        specifier: ^3.0.3
 | 
			
		||||
        version: 3.0.3(magicast@0.5.0)(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
        version: 3.0.3(magicast@0.3.5)(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      daisyui:
 | 
			
		||||
        specifier: ^5.3.10
 | 
			
		||||
        version: 5.3.10
 | 
			
		||||
@@ -25,7 +28,7 @@ importers:
 | 
			
		||||
        version: 9.38.0(jiti@2.6.1)
 | 
			
		||||
      nuxt:
 | 
			
		||||
        specifier: ^4.2.0
 | 
			
		||||
        version: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
        version: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
      tailwindcss:
 | 
			
		||||
        specifier: ^4.1.16
 | 
			
		||||
        version: 4.1.16
 | 
			
		||||
@@ -35,6 +38,10 @@ importers:
 | 
			
		||||
      vue-router:
 | 
			
		||||
        specifier: ^4.6.3
 | 
			
		||||
        version: 4.6.3(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
    devDependencies:
 | 
			
		||||
      typescript:
 | 
			
		||||
        specifier: ^5.9.3
 | 
			
		||||
        version: 5.9.3
 | 
			
		||||
 | 
			
		||||
packages:
 | 
			
		||||
 | 
			
		||||
@@ -363,8 +370,8 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
 | 
			
		||||
    engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/compat@1.4.0':
 | 
			
		||||
    resolution: {integrity: sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==}
 | 
			
		||||
  '@eslint/compat@1.4.1':
 | 
			
		||||
    resolution: {integrity: sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      eslint: ^8.40 || 9
 | 
			
		||||
@@ -376,8 +383,8 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/config-helpers@0.4.1':
 | 
			
		||||
    resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==}
 | 
			
		||||
  '@eslint/config-helpers@0.4.2':
 | 
			
		||||
    resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/config-inspector@1.3.0':
 | 
			
		||||
@@ -390,6 +397,10 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/core@0.17.0':
 | 
			
		||||
    resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/eslintrc@3.3.1':
 | 
			
		||||
    resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
@@ -402,10 +413,13 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@eslint/plugin-kit@0.4.0':
 | 
			
		||||
    resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==}
 | 
			
		||||
  '@eslint/plugin-kit@0.4.1':
 | 
			
		||||
    resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
 | 
			
		||||
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 | 
			
		||||
 | 
			
		||||
  '@formkit/auto-animate@0.9.0':
 | 
			
		||||
    resolution: {integrity: sha512-VhP4zEAacXS3dfTpJpJ88QdLqMTcabMg0jwpOSxZ/VzfQVfl3GkZSCZThhGC5uhq/TxPHPzW0dzr4H9Bb1OgKA==}
 | 
			
		||||
 | 
			
		||||
  '@humanfs/core@0.19.1':
 | 
			
		||||
    resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
 | 
			
		||||
    engines: {node: '>=18.18.0'}
 | 
			
		||||
@@ -425,6 +439,14 @@ packages:
 | 
			
		||||
  '@ioredis/commands@1.4.0':
 | 
			
		||||
    resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==}
 | 
			
		||||
 | 
			
		||||
  '@isaacs/balanced-match@4.0.1':
 | 
			
		||||
    resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
 | 
			
		||||
    engines: {node: 20 || >=22}
 | 
			
		||||
 | 
			
		||||
  '@isaacs/brace-expansion@5.0.0':
 | 
			
		||||
    resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
 | 
			
		||||
    engines: {node: 20 || >=22}
 | 
			
		||||
 | 
			
		||||
  '@isaacs/cliui@8.0.2':
 | 
			
		||||
    resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
 | 
			
		||||
    engines: {node: '>=12'}
 | 
			
		||||
@@ -1006,8 +1028,8 @@ packages:
 | 
			
		||||
      rollup:
 | 
			
		||||
        optional: true
 | 
			
		||||
 | 
			
		||||
  '@rollup/plugin-replace@6.0.2':
 | 
			
		||||
    resolution: {integrity: sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==}
 | 
			
		||||
  '@rollup/plugin-replace@6.0.3':
 | 
			
		||||
    resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==}
 | 
			
		||||
    engines: {node: '>=14.0.0'}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
 | 
			
		||||
@@ -1669,8 +1691,8 @@ packages:
 | 
			
		||||
  base64-js@1.5.1:
 | 
			
		||||
    resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
 | 
			
		||||
 | 
			
		||||
  baseline-browser-mapping@2.8.20:
 | 
			
		||||
    resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==}
 | 
			
		||||
  baseline-browser-mapping@2.8.21:
 | 
			
		||||
    resolution: {integrity: sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==}
 | 
			
		||||
    hasBin: true
 | 
			
		||||
 | 
			
		||||
  bindings@1.5.0:
 | 
			
		||||
@@ -1898,8 +1920,8 @@ packages:
 | 
			
		||||
    engines: {node: '>=4'}
 | 
			
		||||
    hasBin: true
 | 
			
		||||
 | 
			
		||||
  cssnano-preset-default@7.0.9:
 | 
			
		||||
    resolution: {integrity: sha512-tCD6AAFgYBOVpMBX41KjbvRh9c2uUjLXRyV7KHSIrwHiq5Z9o0TFfUCoM3TwVrRsRteN3sVXGNvjVNxYzkpTsA==}
 | 
			
		||||
  cssnano-preset-default@7.0.10:
 | 
			
		||||
    resolution: {integrity: sha512-6ZBjW0Lf1K1Z+0OKUAUpEN62tSXmYChXWi2NAA0afxEVsj9a+MbcB1l5qel6BHJHmULai2fCGRthCeKSFbScpA==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -1910,8 +1932,8 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  cssnano@7.1.1:
 | 
			
		||||
    resolution: {integrity: sha512-fm4D8ti0dQmFPeF8DXSAA//btEmqCOgAc/9Oa3C1LW94h5usNrJEfrON7b4FkPZgnDEn6OUs5NdxiJZmAtGOpQ==}
 | 
			
		||||
  cssnano@7.1.2:
 | 
			
		||||
    resolution: {integrity: sha512-HYOPBsNvoiFeR1eghKD5C3ASm64v9YVyJB4Ivnl2gqKoQYvjjN/G0rztvKQq8OxocUtC6sjqY8jwYngIB4AByA==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -2144,8 +2166,8 @@ packages:
 | 
			
		||||
      eslint-import-resolver-node:
 | 
			
		||||
        optional: true
 | 
			
		||||
 | 
			
		||||
  eslint-plugin-jsdoc@61.1.10:
 | 
			
		||||
    resolution: {integrity: sha512-ACsczYGax1Iu9zRBiG176I66cgL2nRt1TbMgE9TAzxoGKfBD9PjhA//K/JKk3uBk25RsYHj3TqMaAiy913IpEA==}
 | 
			
		||||
  eslint-plugin-jsdoc@61.1.11:
 | 
			
		||||
    resolution: {integrity: sha512-c+NQQOFd+ZTjFt0pfFMB8OTumExg0vf8mlJsOtLj6qTDGewtLh7bhwoDgBg6rIiTziYc8N4u4dYmSdAIn0yTEQ==}
 | 
			
		||||
    engines: {node: '>=20.11.0'}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
 | 
			
		||||
@@ -2829,8 +2851,8 @@ packages:
 | 
			
		||||
  magicast@0.3.5:
 | 
			
		||||
    resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
 | 
			
		||||
 | 
			
		||||
  magicast@0.5.0:
 | 
			
		||||
    resolution: {integrity: sha512-D0cxqnb8DpO66P4LkD9ME6a4AhRK6A+xprXksD5vtsJN6G4zbzdI10vDaWCIyj3eLwjNZrQxUYB20FDhKrMEKQ==}
 | 
			
		||||
  magicast@0.5.1:
 | 
			
		||||
    resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==}
 | 
			
		||||
 | 
			
		||||
  mdn-data@2.0.28:
 | 
			
		||||
    resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
 | 
			
		||||
@@ -2871,6 +2893,10 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
 | 
			
		||||
    engines: {node: '>=12'}
 | 
			
		||||
 | 
			
		||||
  minimatch@10.1.1:
 | 
			
		||||
    resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
 | 
			
		||||
    engines: {node: 20 || >=22}
 | 
			
		||||
 | 
			
		||||
  minimatch@3.1.2:
 | 
			
		||||
    resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
 | 
			
		||||
 | 
			
		||||
@@ -2966,8 +2992,8 @@ packages:
 | 
			
		||||
  node-mock-http@1.0.3:
 | 
			
		||||
    resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==}
 | 
			
		||||
 | 
			
		||||
  node-releases@2.0.26:
 | 
			
		||||
    resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==}
 | 
			
		||||
  node-releases@2.0.27:
 | 
			
		||||
    resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
 | 
			
		||||
 | 
			
		||||
  nopt@8.1.0:
 | 
			
		||||
    resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==}
 | 
			
		||||
@@ -3180,20 +3206,20 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.38
 | 
			
		||||
 | 
			
		||||
  postcss-colormin@7.0.4:
 | 
			
		||||
    resolution: {integrity: sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw==}
 | 
			
		||||
  postcss-colormin@7.0.5:
 | 
			
		||||
    resolution: {integrity: sha512-ekIBP/nwzRWhEMmIxHHbXHcMdzd1HIUzBECaj5KEdLz9DVP2HzT065sEhvOx1dkLjYW7jyD0CngThx6bpFi2fA==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-convert-values@7.0.7:
 | 
			
		||||
    resolution: {integrity: sha512-HR9DZLN04Xbe6xugRH6lS4ZQH2zm/bFh/ZyRkpedZozhvh+awAfbA0P36InO4fZfDhvYfNJeNvlTf1sjwGbw/A==}
 | 
			
		||||
  postcss-convert-values@7.0.8:
 | 
			
		||||
    resolution: {integrity: sha512-+XNKuPfkHTCEo499VzLMYn94TiL3r9YqRE3Ty+jP7UX4qjewUONey1t7CG21lrlTLN07GtGM8MqFVp86D4uKJg==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-discard-comments@7.0.4:
 | 
			
		||||
    resolution: {integrity: sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==}
 | 
			
		||||
  postcss-discard-comments@7.0.5:
 | 
			
		||||
    resolution: {integrity: sha512-IR2Eja8WfYgN5n32vEGSctVQ1+JARfu4UH8M7bgGh1bC+xI/obsPJXaBpQF7MAByvgwZinhpHpdrmXtvVVlKcQ==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3222,8 +3248,8 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-merge-rules@7.0.6:
 | 
			
		||||
    resolution: {integrity: sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ==}
 | 
			
		||||
  postcss-merge-rules@7.0.7:
 | 
			
		||||
    resolution: {integrity: sha512-njWJrd/Ms6XViwowaaCc+/vqhPG3SmXn725AGrnl+BgTuRPEacjiLEaGq16J6XirMJbtKkTwnt67SS+e2WGoew==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3240,8 +3266,8 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-minify-params@7.0.4:
 | 
			
		||||
    resolution: {integrity: sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw==}
 | 
			
		||||
  postcss-minify-params@7.0.5:
 | 
			
		||||
    resolution: {integrity: sha512-FGK9ky02h6Ighn3UihsyeAH5XmLEE2MSGH5Tc4tXMFtEDx7B+zTG6hD/+/cT+fbF7PbYojsmmWjyTwFwW1JKQQ==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3288,8 +3314,8 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-normalize-unicode@7.0.4:
 | 
			
		||||
    resolution: {integrity: sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g==}
 | 
			
		||||
  postcss-normalize-unicode@7.0.5:
 | 
			
		||||
    resolution: {integrity: sha512-X6BBwiRxVaFHrb2WyBMddIeB5HBjJcAaUHyhLrM2FsxSq5TFqcHSsK7Zu1otag+o0ZphQGJewGH1tAyrD0zX1Q==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3312,8 +3338,8 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
 | 
			
		||||
  postcss-reduce-initial@7.0.4:
 | 
			
		||||
    resolution: {integrity: sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q==}
 | 
			
		||||
  postcss-reduce-initial@7.0.5:
 | 
			
		||||
    resolution: {integrity: sha512-RHagHLidG8hTZcnr4FpyMB2jtgd/OcyAazjMhoy5qmWJOx1uxKh4ntk0Pb46ajKM0rkf32lRH4C8c9qQiPR6IA==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3556,8 +3582,8 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
 | 
			
		||||
    engines: {node: '>=14'}
 | 
			
		||||
 | 
			
		||||
  simple-git@3.28.0:
 | 
			
		||||
    resolution: {integrity: sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==}
 | 
			
		||||
  simple-git@3.29.0:
 | 
			
		||||
    resolution: {integrity: sha512-PEBgFYc8plTys6/XuxinxAJ+6CbXVh+xxsBTOEXw/uYBd3sYlGGoyB12nX5rRPGsFrdnnZWb81qluSl7a83HtA==}
 | 
			
		||||
 | 
			
		||||
  sirv@3.0.2:
 | 
			
		||||
    resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
 | 
			
		||||
@@ -3674,8 +3700,8 @@ packages:
 | 
			
		||||
  style-value-types@5.1.2:
 | 
			
		||||
    resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==}
 | 
			
		||||
 | 
			
		||||
  stylehacks@7.0.6:
 | 
			
		||||
    resolution: {integrity: sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg==}
 | 
			
		||||
  stylehacks@7.0.7:
 | 
			
		||||
    resolution: {integrity: sha512-bJkD0JkEtbRrMFtwgpJyBbFIwfDDONQ1Ov3sDLZQP8HuJ73kBOyx66H4bOcAbVWmnfLdvQ0AJwXxOMkpujcO6g==}
 | 
			
		||||
    engines: {node: ^18.12.0 || ^20.9.0 || >=22.0}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      postcss: ^8.4.32
 | 
			
		||||
@@ -3719,8 +3745,8 @@ packages:
 | 
			
		||||
  tar-stream@3.1.7:
 | 
			
		||||
    resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
 | 
			
		||||
 | 
			
		||||
  tar@7.5.1:
 | 
			
		||||
    resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==}
 | 
			
		||||
  tar@7.5.2:
 | 
			
		||||
    resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==}
 | 
			
		||||
    engines: {node: '>=18'}
 | 
			
		||||
 | 
			
		||||
  terser@5.44.0:
 | 
			
		||||
@@ -3804,8 +3830,8 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==}
 | 
			
		||||
    engines: {node: '>=20.18.1'}
 | 
			
		||||
 | 
			
		||||
  unenv@2.0.0-rc.23:
 | 
			
		||||
    resolution: {integrity: sha512-NeOb/HbW2OwOzYaV21MewVQYfzlSwG0kVUB74RyV0gEIP44M5DsYTK9e7jDcekB/3YU+pfNWniZj+r4M/aejyQ==}
 | 
			
		||||
  unenv@2.0.0-rc.24:
 | 
			
		||||
    resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
 | 
			
		||||
 | 
			
		||||
  unhead@2.0.19:
 | 
			
		||||
    resolution: {integrity: sha512-gEEjkV11Aj+rBnY6wnRfsFtF2RxKOLaPN4i+Gx3UhBxnszvV6ApSNZbGk7WKyy/lErQ6ekPN63qdFL7sa1leow==}
 | 
			
		||||
@@ -3830,8 +3856,8 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==}
 | 
			
		||||
    engines: {node: '>=20.19.0'}
 | 
			
		||||
 | 
			
		||||
  unplugin-vue-router@0.16.0:
 | 
			
		||||
    resolution: {integrity: sha512-yFmUQoN07KABkbxMSaNvfjnflwSi3nkSVKi7v6FTwXlzXyRDSx63vQ8Se4ho0T9Ao9I8U5FJB12fzmrGxFB0CA==}
 | 
			
		||||
  unplugin-vue-router@0.16.1:
 | 
			
		||||
    resolution: {integrity: sha512-7A7gUVzLIYMBrBPKk8l4lZoZXDOrO8+etw6/RTrqG3OzpLUUZEXJFUW7+OyMIpQK93sEbdkR2z9ZNNl/r32FMw==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      '@vue/compiler-sfc': ^3.5.17
 | 
			
		||||
      vue-router: ^4.6.0
 | 
			
		||||
@@ -4361,10 +4387,10 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      mime: 3.0.0
 | 
			
		||||
 | 
			
		||||
  '@dxup/nuxt@0.2.0(magicast@0.5.0)':
 | 
			
		||||
  '@dxup/nuxt@0.2.0(magicast@0.3.5)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@dxup/unimport': 0.1.0
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      chokidar: 4.0.3
 | 
			
		||||
      pathe: 2.0.3
 | 
			
		||||
      tinyglobby: 0.2.15
 | 
			
		||||
@@ -4484,9 +4510,9 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@eslint-community/regexpp@4.12.2': {}
 | 
			
		||||
 | 
			
		||||
  '@eslint/compat@1.4.0(eslint@9.38.0(jiti@2.6.1))':
 | 
			
		||||
  '@eslint/compat@1.4.1(eslint@9.38.0(jiti@2.6.1))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@eslint/core': 0.16.0
 | 
			
		||||
      '@eslint/core': 0.17.0
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      eslint: 9.38.0(jiti@2.6.1)
 | 
			
		||||
 | 
			
		||||
@@ -4498,9 +4524,9 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
 | 
			
		||||
  '@eslint/config-helpers@0.4.1':
 | 
			
		||||
  '@eslint/config-helpers@0.4.2':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@eslint/core': 0.16.0
 | 
			
		||||
      '@eslint/core': 0.17.0
 | 
			
		||||
 | 
			
		||||
  '@eslint/config-inspector@1.3.0(eslint@9.38.0(jiti@2.6.1))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
@@ -4529,6 +4555,10 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@types/json-schema': 7.0.15
 | 
			
		||||
 | 
			
		||||
  '@eslint/core@0.17.0':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@types/json-schema': 7.0.15
 | 
			
		||||
 | 
			
		||||
  '@eslint/eslintrc@3.3.1':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      ajv: 6.12.6
 | 
			
		||||
@@ -4547,11 +4577,13 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@eslint/object-schema@2.1.7': {}
 | 
			
		||||
 | 
			
		||||
  '@eslint/plugin-kit@0.4.0':
 | 
			
		||||
  '@eslint/plugin-kit@0.4.1':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@eslint/core': 0.16.0
 | 
			
		||||
      '@eslint/core': 0.17.0
 | 
			
		||||
      levn: 0.4.1
 | 
			
		||||
 | 
			
		||||
  '@formkit/auto-animate@0.9.0': {}
 | 
			
		||||
 | 
			
		||||
  '@humanfs/core@0.19.1': {}
 | 
			
		||||
 | 
			
		||||
  '@humanfs/node@0.16.7':
 | 
			
		||||
@@ -4565,6 +4597,12 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@ioredis/commands@1.4.0': {}
 | 
			
		||||
 | 
			
		||||
  '@isaacs/balanced-match@4.0.1': {}
 | 
			
		||||
 | 
			
		||||
  '@isaacs/brace-expansion@5.0.0':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@isaacs/balanced-match': 4.0.1
 | 
			
		||||
 | 
			
		||||
  '@isaacs/cliui@8.0.2':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      string-width: 5.1.2
 | 
			
		||||
@@ -4618,7 +4656,7 @@ snapshots:
 | 
			
		||||
      node-fetch: 2.7.0
 | 
			
		||||
      nopt: 8.1.0
 | 
			
		||||
      semver: 7.7.3
 | 
			
		||||
      tar: 7.5.1
 | 
			
		||||
      tar: 7.5.2
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - encoding
 | 
			
		||||
      - supports-color
 | 
			
		||||
@@ -4661,9 +4699,9 @@ snapshots:
 | 
			
		||||
      '@nodelib/fs.scandir': 4.0.1
 | 
			
		||||
      fastq: 1.19.1
 | 
			
		||||
 | 
			
		||||
  '@nuxt/cli@3.29.3(magicast@0.5.0)':
 | 
			
		||||
  '@nuxt/cli@3.29.3(magicast@0.3.5)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.0)
 | 
			
		||||
      c12: 3.3.1(magicast@0.3.5)
 | 
			
		||||
      citty: 0.1.6
 | 
			
		||||
      clipboardy: 5.0.0
 | 
			
		||||
      confbox: 0.2.2
 | 
			
		||||
@@ -4703,9 +4741,9 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
  '@nuxt/devtools-kit@3.0.0(magicast@0.5.0)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
 | 
			
		||||
  '@nuxt/devtools-kit@3.0.0(magicast@0.3.5)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      execa: 8.0.1
 | 
			
		||||
      vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
@@ -4748,7 +4786,7 @@ snapshots:
 | 
			
		||||
      perfect-debounce: 1.0.0
 | 
			
		||||
      pkg-types: 2.3.0
 | 
			
		||||
      semver: 7.7.3
 | 
			
		||||
      simple-git: 3.28.0
 | 
			
		||||
      simple-git: 3.29.0
 | 
			
		||||
      sirv: 3.0.2
 | 
			
		||||
      structured-clone-es: 1.0.0
 | 
			
		||||
      tinyglobby: 0.2.15
 | 
			
		||||
@@ -4778,7 +4816,7 @@ snapshots:
 | 
			
		||||
      eslint-merge-processors: 2.0.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-import-lite: 0.3.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
 | 
			
		||||
      eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-jsdoc: 61.1.10(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-jsdoc: 61.1.11(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-regexp: 2.10.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-unicorn: 62.0.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint-plugin-vue: 10.5.1(@stylistic/eslint-plugin@5.5.0(eslint@9.38.0(jiti@2.6.1)))(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.38.0(jiti@2.6.1)))
 | 
			
		||||
@@ -4803,13 +4841,13 @@ snapshots:
 | 
			
		||||
      - supports-color
 | 
			
		||||
      - typescript
 | 
			
		||||
 | 
			
		||||
  '@nuxt/eslint@1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.5.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
 | 
			
		||||
  '@nuxt/eslint@1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(magicast@0.3.5)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@eslint/config-inspector': 1.3.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      '@nuxt/devtools-kit': 3.0.0(magicast@0.5.0)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
      '@nuxt/devtools-kit': 3.0.0(magicast@0.3.5)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
      '@nuxt/eslint-config': 1.10.0(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.22)(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
 | 
			
		||||
      '@nuxt/eslint-plugin': 1.10.0(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      chokidar: 4.0.3
 | 
			
		||||
      eslint: 9.38.0(jiti@2.6.1)
 | 
			
		||||
      eslint-flat-config-utils: 2.1.4
 | 
			
		||||
@@ -4857,35 +4895,9 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
  '@nuxt/kit@3.20.0(magicast@0.5.0)':
 | 
			
		||||
  '@nuxt/kit@4.2.0(magicast@0.3.5)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.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.6.1
 | 
			
		||||
      klona: 2.0.6
 | 
			
		||||
      knitwork: 1.2.0
 | 
			
		||||
      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.3
 | 
			
		||||
      tinyglobby: 0.2.15
 | 
			
		||||
      ufo: 1.6.1
 | 
			
		||||
      unctx: 2.4.1
 | 
			
		||||
      untyped: 2.0.0
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
  '@nuxt/kit@4.2.0(magicast@0.5.0)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.0)
 | 
			
		||||
      c12: 3.3.1(magicast@0.3.5)
 | 
			
		||||
      consola: 3.4.2
 | 
			
		||||
      defu: 6.1.4
 | 
			
		||||
      destr: 2.0.5
 | 
			
		||||
@@ -4908,10 +4920,10 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
  '@nuxt/nitro-server@4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.0)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)':
 | 
			
		||||
  '@nuxt/nitro-server@4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@nuxt/devalue': 2.0.2
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      '@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      '@vue/shared': 3.5.22
 | 
			
		||||
      consola: 3.4.2
 | 
			
		||||
@@ -4926,7 +4938,7 @@ snapshots:
 | 
			
		||||
      klona: 2.0.6
 | 
			
		||||
      mocked-exports: 0.1.1
 | 
			
		||||
      nitropack: 2.12.9
 | 
			
		||||
      nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
      nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
      pathe: 2.0.3
 | 
			
		||||
      pkg-types: 2.3.0
 | 
			
		||||
      radix3: 1.1.2
 | 
			
		||||
@@ -4980,9 +4992,9 @@ snapshots:
 | 
			
		||||
      pkg-types: 2.3.0
 | 
			
		||||
      std-env: 3.10.0
 | 
			
		||||
 | 
			
		||||
  '@nuxt/telemetry@2.6.6(magicast@0.5.0)':
 | 
			
		||||
  '@nuxt/telemetry@2.6.6(magicast@0.3.5)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@nuxt/kit': 3.20.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 3.20.0(magicast@0.3.5)
 | 
			
		||||
      citty: 0.1.6
 | 
			
		||||
      consola: 3.4.2
 | 
			
		||||
      destr: 2.0.5
 | 
			
		||||
@@ -4997,15 +5009,15 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
  '@nuxt/vite-builder@4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.0)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)':
 | 
			
		||||
  '@nuxt/vite-builder@4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.3.5)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@rollup/plugin-replace': 6.0.2(rollup@4.52.5)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      '@rollup/plugin-replace': 6.0.3(rollup@4.52.5)
 | 
			
		||||
      '@vitejs/plugin-vue': 6.0.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      '@vitejs/plugin-vue-jsx': 5.1.1(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      autoprefixer: 10.4.21(postcss@8.5.6)
 | 
			
		||||
      consola: 3.4.2
 | 
			
		||||
      cssnano: 7.1.1(postcss@8.5.6)
 | 
			
		||||
      cssnano: 7.1.2(postcss@8.5.6)
 | 
			
		||||
      defu: 6.1.4
 | 
			
		||||
      esbuild: 0.25.11
 | 
			
		||||
      escape-string-regexp: 5.0.0
 | 
			
		||||
@@ -5017,7 +5029,7 @@ snapshots:
 | 
			
		||||
      magic-string: 0.30.21
 | 
			
		||||
      mlly: 1.8.0
 | 
			
		||||
      mocked-exports: 0.1.1
 | 
			
		||||
      nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
      nuxt: 4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1)
 | 
			
		||||
      pathe: 2.0.3
 | 
			
		||||
      pkg-types: 2.3.0
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
@@ -5025,7 +5037,7 @@ snapshots:
 | 
			
		||||
      seroval: 1.3.2
 | 
			
		||||
      std-env: 3.10.0
 | 
			
		||||
      ufo: 1.6.1
 | 
			
		||||
      unenv: 2.0.0-rc.23
 | 
			
		||||
      unenv: 2.0.0-rc.24
 | 
			
		||||
      vite: 7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
 | 
			
		||||
      vite-node: 3.2.4(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)
 | 
			
		||||
      vite-plugin-checker: 0.11.0(eslint@9.38.0(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))
 | 
			
		||||
@@ -5325,7 +5337,7 @@ snapshots:
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      rollup: 4.52.5
 | 
			
		||||
 | 
			
		||||
  '@rollup/plugin-replace@6.0.2(rollup@4.52.5)':
 | 
			
		||||
  '@rollup/plugin-replace@6.0.3(rollup@4.52.5)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@rollup/pluginutils': 5.3.0(rollup@4.52.5)
 | 
			
		||||
      magic-string: 0.30.21
 | 
			
		||||
@@ -5862,7 +5874,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@vueuse/metadata@13.9.0': {}
 | 
			
		||||
 | 
			
		||||
  '@vueuse/motion@3.0.3(magicast@0.5.0)(vue@3.5.22(typescript@5.9.3))':
 | 
			
		||||
  '@vueuse/motion@3.0.3(magicast@0.3.5)(vue@3.5.22(typescript@5.9.3))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@vueuse/core': 13.9.0(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      '@vueuse/shared': 13.9.0(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
@@ -5872,7 +5884,7 @@ snapshots:
 | 
			
		||||
      style-value-types: 5.1.2
 | 
			
		||||
      vue: 3.5.22(typescript@5.9.3)
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      '@nuxt/kit': 3.20.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/kit': 3.20.0(magicast@0.3.5)
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - magicast
 | 
			
		||||
 | 
			
		||||
@@ -5983,7 +5995,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  base64-js@1.5.1: {}
 | 
			
		||||
 | 
			
		||||
  baseline-browser-mapping@2.8.20: {}
 | 
			
		||||
  baseline-browser-mapping@2.8.21: {}
 | 
			
		||||
 | 
			
		||||
  bindings@1.5.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
@@ -6008,10 +6020,10 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  browserslist@4.27.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      baseline-browser-mapping: 2.8.20
 | 
			
		||||
      baseline-browser-mapping: 2.8.21
 | 
			
		||||
      caniuse-lite: 1.0.30001751
 | 
			
		||||
      electron-to-chromium: 1.5.243
 | 
			
		||||
      node-releases: 2.0.26
 | 
			
		||||
      node-releases: 2.0.27
 | 
			
		||||
      update-browserslist-db: 1.1.4(browserslist@4.27.0)
 | 
			
		||||
 | 
			
		||||
  buffer-crc32@1.0.0: {}
 | 
			
		||||
@@ -6051,7 +6063,7 @@ snapshots:
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      magicast: 0.3.5
 | 
			
		||||
 | 
			
		||||
  c12@3.3.1(magicast@0.5.0):
 | 
			
		||||
  c12@3.3.1(magicast@0.5.1):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      chokidar: 4.0.3
 | 
			
		||||
      confbox: 0.2.2
 | 
			
		||||
@@ -6066,7 +6078,7 @@ snapshots:
 | 
			
		||||
      pkg-types: 2.3.0
 | 
			
		||||
      rc9: 2.1.2
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      magicast: 0.5.0
 | 
			
		||||
      magicast: 0.5.1
 | 
			
		||||
 | 
			
		||||
  cac@6.7.14: {}
 | 
			
		||||
 | 
			
		||||
@@ -6222,24 +6234,24 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  cssesc@3.0.0: {}
 | 
			
		||||
 | 
			
		||||
  cssnano-preset-default@7.0.9(postcss@8.5.6):
 | 
			
		||||
  cssnano-preset-default@7.0.10(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      css-declaration-sorter: 7.3.0(postcss@8.5.6)
 | 
			
		||||
      cssnano-utils: 5.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-calc: 10.1.1(postcss@8.5.6)
 | 
			
		||||
      postcss-colormin: 7.0.4(postcss@8.5.6)
 | 
			
		||||
      postcss-convert-values: 7.0.7(postcss@8.5.6)
 | 
			
		||||
      postcss-discard-comments: 7.0.4(postcss@8.5.6)
 | 
			
		||||
      postcss-colormin: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-convert-values: 7.0.8(postcss@8.5.6)
 | 
			
		||||
      postcss-discard-comments: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-discard-duplicates: 7.0.2(postcss@8.5.6)
 | 
			
		||||
      postcss-discard-empty: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-discard-overridden: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-merge-longhand: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-merge-rules: 7.0.6(postcss@8.5.6)
 | 
			
		||||
      postcss-merge-rules: 7.0.7(postcss@8.5.6)
 | 
			
		||||
      postcss-minify-font-values: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-minify-gradients: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-minify-params: 7.0.4(postcss@8.5.6)
 | 
			
		||||
      postcss-minify-params: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-minify-selectors: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-charset: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-display-values: 7.0.1(postcss@8.5.6)
 | 
			
		||||
@@ -6247,11 +6259,11 @@ snapshots:
 | 
			
		||||
      postcss-normalize-repeat-style: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-string: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-timing-functions: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-unicode: 7.0.4(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-unicode: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-url: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-normalize-whitespace: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-ordered-values: 7.0.2(postcss@8.5.6)
 | 
			
		||||
      postcss-reduce-initial: 7.0.4(postcss@8.5.6)
 | 
			
		||||
      postcss-reduce-initial: 7.0.5(postcss@8.5.6)
 | 
			
		||||
      postcss-reduce-transforms: 7.0.1(postcss@8.5.6)
 | 
			
		||||
      postcss-svgo: 7.1.0(postcss@8.5.6)
 | 
			
		||||
      postcss-unique-selectors: 7.0.4(postcss@8.5.6)
 | 
			
		||||
@@ -6260,9 +6272,9 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
 | 
			
		||||
  cssnano@7.1.1(postcss@8.5.6):
 | 
			
		||||
  cssnano@7.1.2(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      cssnano-preset-default: 7.0.9(postcss@8.5.6)
 | 
			
		||||
      cssnano-preset-default: 7.0.10(postcss@8.5.6)
 | 
			
		||||
      lilconfig: 3.1.3
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
 | 
			
		||||
@@ -6405,7 +6417,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  eslint-config-flat-gitignore@2.1.0(eslint@9.38.0(jiti@2.6.1)):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@eslint/compat': 1.4.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      '@eslint/compat': 1.4.1(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      eslint: 9.38.0(jiti@2.6.1)
 | 
			
		||||
 | 
			
		||||
  eslint-flat-config-utils@2.1.4:
 | 
			
		||||
@@ -6439,7 +6451,7 @@ snapshots:
 | 
			
		||||
      eslint: 9.38.0(jiti@2.6.1)
 | 
			
		||||
      eslint-import-context: 0.1.9(unrs-resolver@1.11.1)
 | 
			
		||||
      is-glob: 4.0.3
 | 
			
		||||
      minimatch: 9.0.5
 | 
			
		||||
      minimatch: 10.1.1
 | 
			
		||||
      semver: 7.7.3
 | 
			
		||||
      stable-hash-x: 0.2.0
 | 
			
		||||
      unrs-resolver: 1.11.1
 | 
			
		||||
@@ -6448,7 +6460,7 @@ snapshots:
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
 | 
			
		||||
  eslint-plugin-jsdoc@61.1.10(eslint@9.38.0(jiti@2.6.1)):
 | 
			
		||||
  eslint-plugin-jsdoc@61.1.11(eslint@9.38.0(jiti@2.6.1)):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@es-joy/jsdoccomment': 0.76.0
 | 
			
		||||
      '@es-joy/resolve.exports': 1.2.0
 | 
			
		||||
@@ -6483,7 +6495,7 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@babel/helper-validator-identifier': 7.28.5
 | 
			
		||||
      '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      '@eslint/plugin-kit': 0.4.0
 | 
			
		||||
      '@eslint/plugin-kit': 0.4.1
 | 
			
		||||
      change-case: 5.4.4
 | 
			
		||||
      ci-info: 4.3.1
 | 
			
		||||
      clean-regexp: 1.0.0
 | 
			
		||||
@@ -6540,11 +6552,11 @@ snapshots:
 | 
			
		||||
      '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1))
 | 
			
		||||
      '@eslint-community/regexpp': 4.12.2
 | 
			
		||||
      '@eslint/config-array': 0.21.1
 | 
			
		||||
      '@eslint/config-helpers': 0.4.1
 | 
			
		||||
      '@eslint/config-helpers': 0.4.2
 | 
			
		||||
      '@eslint/core': 0.16.0
 | 
			
		||||
      '@eslint/eslintrc': 3.3.1
 | 
			
		||||
      '@eslint/js': 9.38.0
 | 
			
		||||
      '@eslint/plugin-kit': 0.4.0
 | 
			
		||||
      '@eslint/plugin-kit': 0.4.1
 | 
			
		||||
      '@humanfs/node': 0.16.7
 | 
			
		||||
      '@humanwhocodes/module-importer': 1.0.1
 | 
			
		||||
      '@humanwhocodes/retry': 0.4.3
 | 
			
		||||
@@ -7165,7 +7177,7 @@ snapshots:
 | 
			
		||||
      '@babel/types': 7.28.5
 | 
			
		||||
      source-map-js: 1.2.1
 | 
			
		||||
 | 
			
		||||
  magicast@0.5.0:
 | 
			
		||||
  magicast@0.5.1:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@babel/parser': 7.28.5
 | 
			
		||||
      '@babel/types': 7.28.5
 | 
			
		||||
@@ -7196,6 +7208,10 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  mimic-fn@4.0.0: {}
 | 
			
		||||
 | 
			
		||||
  minimatch@10.1.1:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@isaacs/brace-expansion': 5.0.0
 | 
			
		||||
 | 
			
		||||
  minimatch@3.1.2:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      brace-expansion: 1.1.12
 | 
			
		||||
@@ -7249,11 +7265,11 @@ snapshots:
 | 
			
		||||
      '@rollup/plugin-inject': 5.0.5(rollup@4.52.5)
 | 
			
		||||
      '@rollup/plugin-json': 6.1.0(rollup@4.52.5)
 | 
			
		||||
      '@rollup/plugin-node-resolve': 16.0.3(rollup@4.52.5)
 | 
			
		||||
      '@rollup/plugin-replace': 6.0.2(rollup@4.52.5)
 | 
			
		||||
      '@rollup/plugin-replace': 6.0.3(rollup@4.52.5)
 | 
			
		||||
      '@rollup/plugin-terser': 0.4.4(rollup@4.52.5)
 | 
			
		||||
      '@vercel/nft': 0.30.3(rollup@4.52.5)
 | 
			
		||||
      archiver: 7.0.1
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.0)
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.1)
 | 
			
		||||
      chokidar: 4.0.3
 | 
			
		||||
      citty: 0.1.6
 | 
			
		||||
      compatx: 0.2.0
 | 
			
		||||
@@ -7281,7 +7297,7 @@ snapshots:
 | 
			
		||||
      knitwork: 1.2.0
 | 
			
		||||
      listhen: 1.9.0
 | 
			
		||||
      magic-string: 0.30.21
 | 
			
		||||
      magicast: 0.5.0
 | 
			
		||||
      magicast: 0.5.1
 | 
			
		||||
      mime: 4.1.0
 | 
			
		||||
      mlly: 1.8.0
 | 
			
		||||
      node-fetch-native: 1.6.7
 | 
			
		||||
@@ -7305,7 +7321,7 @@ snapshots:
 | 
			
		||||
      ultrahtml: 1.6.0
 | 
			
		||||
      uncrypto: 0.1.3
 | 
			
		||||
      unctx: 2.4.1
 | 
			
		||||
      unenv: 2.0.0-rc.23
 | 
			
		||||
      unenv: 2.0.0-rc.24
 | 
			
		||||
      unimport: 5.5.0
 | 
			
		||||
      unplugin-utils: 0.3.1
 | 
			
		||||
      unstorage: 1.17.1(db0@0.3.4)(ioredis@5.8.2)
 | 
			
		||||
@@ -7357,7 +7373,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  node-mock-http@1.0.3: {}
 | 
			
		||||
 | 
			
		||||
  node-releases@2.0.26: {}
 | 
			
		||||
  node-releases@2.0.27: {}
 | 
			
		||||
 | 
			
		||||
  nopt@8.1.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
@@ -7380,19 +7396,19 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      boolbase: 1.0.0
 | 
			
		||||
 | 
			
		||||
  nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1):
 | 
			
		||||
  nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@dxup/nuxt': 0.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/cli': 3.29.3(magicast@0.5.0)
 | 
			
		||||
      '@dxup/nuxt': 0.2.0(magicast@0.3.5)
 | 
			
		||||
      '@nuxt/cli': 3.29.3(magicast@0.3.5)
 | 
			
		||||
      '@nuxt/devtools': 2.7.0(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/nitro-server': 4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.5.0)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)
 | 
			
		||||
      '@nuxt/kit': 4.2.0(magicast@0.3.5)
 | 
			
		||||
      '@nuxt/nitro-server': 4.2.0(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3)
 | 
			
		||||
      '@nuxt/schema': 4.2.0
 | 
			
		||||
      '@nuxt/telemetry': 2.6.6(magicast@0.5.0)
 | 
			
		||||
      '@nuxt/vite-builder': 4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.0)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)
 | 
			
		||||
      '@nuxt/telemetry': 2.6.6(magicast@0.3.5)
 | 
			
		||||
      '@nuxt/vite-builder': 4.2.0(eslint@9.38.0(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.3.5)(nuxt@4.2.0(@parcel/watcher@2.5.1)(@vue/compiler-sfc@3.5.22)(db0@0.3.4)(eslint@9.38.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))(yaml@2.8.1)
 | 
			
		||||
      '@unhead/vue': 2.0.19(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      '@vue/shared': 3.5.22
 | 
			
		||||
      c12: 3.3.1(magicast@0.5.0)
 | 
			
		||||
      c12: 3.3.1(magicast@0.3.5)
 | 
			
		||||
      chokidar: 4.0.3
 | 
			
		||||
      compatx: 0.2.0
 | 
			
		||||
      consola: 3.4.2
 | 
			
		||||
@@ -7435,7 +7451,7 @@ snapshots:
 | 
			
		||||
      unctx: 2.4.1
 | 
			
		||||
      unimport: 5.5.0
 | 
			
		||||
      unplugin: 2.3.10
 | 
			
		||||
      unplugin-vue-router: 0.16.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      unplugin-vue-router: 0.16.1(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
      untyped: 2.0.0
 | 
			
		||||
      vue: 3.5.22(typescript@5.9.3)
 | 
			
		||||
      vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
@@ -7713,7 +7729,7 @@ snapshots:
 | 
			
		||||
      postcss-selector-parser: 7.1.0
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-colormin@7.0.4(postcss@8.5.6):
 | 
			
		||||
  postcss-colormin@7.0.5(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      caniuse-api: 3.0.0
 | 
			
		||||
@@ -7721,13 +7737,13 @@ snapshots:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-convert-values@7.0.7(postcss@8.5.6):
 | 
			
		||||
  postcss-convert-values@7.0.8(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-discard-comments@7.0.4(postcss@8.5.6):
 | 
			
		||||
  postcss-discard-comments@7.0.5(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-selector-parser: 7.1.0
 | 
			
		||||
@@ -7748,9 +7764,9 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
      stylehacks: 7.0.6(postcss@8.5.6)
 | 
			
		||||
      stylehacks: 7.0.7(postcss@8.5.6)
 | 
			
		||||
 | 
			
		||||
  postcss-merge-rules@7.0.6(postcss@8.5.6):
 | 
			
		||||
  postcss-merge-rules@7.0.7(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      caniuse-api: 3.0.0
 | 
			
		||||
@@ -7770,7 +7786,7 @@ snapshots:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-minify-params@7.0.4(postcss@8.5.6):
 | 
			
		||||
  postcss-minify-params@7.0.5(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      cssnano-utils: 5.0.1(postcss@8.5.6)
 | 
			
		||||
@@ -7812,7 +7828,7 @@ snapshots:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-normalize-unicode@7.0.4(postcss@8.5.6):
 | 
			
		||||
  postcss-normalize-unicode@7.0.5(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
@@ -7834,7 +7850,7 @@ snapshots:
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
 | 
			
		||||
  postcss-reduce-initial@7.0.4(postcss@8.5.6):
 | 
			
		||||
  postcss-reduce-initial@7.0.5(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      caniuse-api: 3.0.0
 | 
			
		||||
@@ -8085,7 +8101,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  signal-exit@4.1.0: {}
 | 
			
		||||
 | 
			
		||||
  simple-git@3.28.0:
 | 
			
		||||
  simple-git@3.29.0:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@kwsites/file-exists': 1.1.1
 | 
			
		||||
      '@kwsites/promise-deferred': 1.1.1
 | 
			
		||||
@@ -8195,7 +8211,7 @@ snapshots:
 | 
			
		||||
      hey-listen: 1.0.8
 | 
			
		||||
      tslib: 2.4.0
 | 
			
		||||
 | 
			
		||||
  stylehacks@7.0.6(postcss@8.5.6):
 | 
			
		||||
  stylehacks@7.0.7(postcss@8.5.6):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.27.0
 | 
			
		||||
      postcss: 8.5.6
 | 
			
		||||
@@ -8240,7 +8256,7 @@ snapshots:
 | 
			
		||||
      - bare-abort-controller
 | 
			
		||||
      - react-native-b4a
 | 
			
		||||
 | 
			
		||||
  tar@7.5.1:
 | 
			
		||||
  tar@7.5.2:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@isaacs/fs-minipass': 4.0.1
 | 
			
		||||
      chownr: 3.0.0
 | 
			
		||||
@@ -8321,7 +8337,7 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  undici@7.16.0: {}
 | 
			
		||||
 | 
			
		||||
  unenv@2.0.0-rc.23:
 | 
			
		||||
  unenv@2.0.0-rc.24:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      pathe: 2.0.3
 | 
			
		||||
 | 
			
		||||
@@ -8360,7 +8376,7 @@ snapshots:
 | 
			
		||||
      pathe: 2.0.3
 | 
			
		||||
      picomatch: 4.0.3
 | 
			
		||||
 | 
			
		||||
  unplugin-vue-router@0.16.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)):
 | 
			
		||||
  unplugin-vue-router@0.16.1(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)):
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@babel/generator': 7.28.5
 | 
			
		||||
      '@vue-macros/common': 3.1.1(vue@3.5.22(typescript@5.9.3))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								server/api/magnet.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								server/api/magnet.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
import { getMagnetUrl, parseMagnet } from "~~/server/utils/magnetParser";
 | 
			
		||||
import { addTrackers, getTrackers } from "~~/server/utils/trackerHelper";
 | 
			
		||||
 | 
			
		||||
export default defineEventHandler(async (event) => {
 | 
			
		||||
  const body = await readBody<{ magnet?: string }>(event);
 | 
			
		||||
  const magnetUrl = body?.magnet;
 | 
			
		||||
 | 
			
		||||
  if (!magnetUrl) {
 | 
			
		||||
    throw createError({
 | 
			
		||||
      statusCode: 400,
 | 
			
		||||
      statusMessage: "Missing magnet URL",
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    const maxedMagnet = addTrackers(
 | 
			
		||||
      parseMagnet(magnetUrl),
 | 
			
		||||
      await getTrackers()
 | 
			
		||||
    );
 | 
			
		||||
    return {
 | 
			
		||||
      totalTrackers: maxedMagnet.tr?.length,
 | 
			
		||||
      name: maxedMagnet.dn,
 | 
			
		||||
      id: maxedMagnet.xt.slice(9),
 | 
			
		||||
      maxedMagnet: getMagnetUrl(maxedMagnet),
 | 
			
		||||
    };
 | 
			
		||||
  } catch (error: any) {
 | 
			
		||||
    throw createError({
 | 
			
		||||
      statusCode: 400,
 | 
			
		||||
      statusMessage: error.message || "Invalid magnet URL",
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										68
									
								
								server/utils/magnetParser.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								server/utils/magnetParser.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
import type { MagnetUrl } from "../../shared/types/magnet";
 | 
			
		||||
 | 
			
		||||
export function parseMagnet(magnetUrl: string): MagnetUrl {
 | 
			
		||||
  if (!magnetUrl.startsWith("magnet:?")) {
 | 
			
		||||
    throw new Error('Invalid magnet URL: Must start with "magnet:?"');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const params = new URLSearchParams(magnetUrl.substring(8)); // Remove 'magnet:?' prefix
 | 
			
		||||
  const xt = params.get("xt");
 | 
			
		||||
 | 
			
		||||
  if (!xt) {
 | 
			
		||||
    throw new Error("Invalid magnet URL: Missing required xt parameter");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Validate xt format (btih hash)
 | 
			
		||||
  const btihRegex = /^urn:btih:([a-fA-F0-9]{40}|[A-Z2-7]{32})$/;
 | 
			
		||||
  if (!btihRegex.test(xt)) {
 | 
			
		||||
    throw new Error("Invalid magnet URL: Invalid xt parameter format");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const magnet: MagnetUrl = {
 | 
			
		||||
    xt,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const dn = params.get("dn");
 | 
			
		||||
  if (dn) {
 | 
			
		||||
    magnet.dn = decodeURIComponent(dn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const tr = params.getAll("tr");
 | 
			
		||||
  if (tr.length > 0) {
 | 
			
		||||
    magnet.tr = tr.map(decodeURIComponent);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const as = params.getAll("as");
 | 
			
		||||
  if (as.length > 0) {
 | 
			
		||||
    magnet.as = as.map(decodeURIComponent);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const xs = params.getAll("xs");
 | 
			
		||||
  if (xs.length > 0) {
 | 
			
		||||
    magnet.xs = xs.map(decodeURIComponent);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const kt = params.get("kt");
 | 
			
		||||
  if (kt) {
 | 
			
		||||
    magnet.kt = decodeURIComponent(kt);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const mt = params.get("mt");
 | 
			
		||||
  if (mt) {
 | 
			
		||||
    magnet.mt = decodeURIComponent(mt);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return magnet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMagnetUrl(magnet: MagnetUrl): string {
 | 
			
		||||
  const params = new URLSearchParams();
 | 
			
		||||
  Object.entries(magnet).forEach(([key, value]) => {
 | 
			
		||||
    if (Array.isArray(value)) {
 | 
			
		||||
      value.forEach((v) => params.append(`${key}`, v));
 | 
			
		||||
    } else {
 | 
			
		||||
      params.append(`${key}`, value);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  return `magnet:?${params.toString()}`;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								server/utils/trackerHelper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								server/utils/trackerHelper.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
import type { MagnetUrl } from "../../shared/types/magnet";
 | 
			
		||||
 | 
			
		||||
let cachedTrackers: string[] | null = null;
 | 
			
		||||
let lastFetched = 0;
 | 
			
		||||
const CACHE_TTL = 1000 * 60 * 10; // 10 minutes
 | 
			
		||||
 | 
			
		||||
export async function getTrackers(): Promise<string[]> {
 | 
			
		||||
  const now = Date.now();
 | 
			
		||||
 | 
			
		||||
  if (cachedTrackers && now - lastFetched < CACHE_TTL) {
 | 
			
		||||
    return cachedTrackers;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const TRACKER_URLS = [
 | 
			
		||||
    "https://raw.githubusercontent.com/XIU2/TrackersListCollection/refs/heads/master/all.txt",
 | 
			
		||||
    "https://raw.githubusercontent.com/ngosang/trackerslist/refs/heads/master/trackers_all.txt",
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  for (const url of TRACKER_URLS) {
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await fetch(url);
 | 
			
		||||
      if (response.ok) {
 | 
			
		||||
        const text = await response.text();
 | 
			
		||||
        const trackers = text
 | 
			
		||||
          .split("\n")
 | 
			
		||||
          .map((line) => line.trim())
 | 
			
		||||
          .filter((line) => line !== "");
 | 
			
		||||
 | 
			
		||||
        // update cache
 | 
			
		||||
        cachedTrackers = trackers;
 | 
			
		||||
        lastFetched = now;
 | 
			
		||||
        return trackers;
 | 
			
		||||
      }
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.error(err);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // fallback: return cached even if stale, or empty
 | 
			
		||||
  return cachedTrackers ?? [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function addTrackers(magnet: MagnetUrl, trackers: string[]): MagnetUrl {
 | 
			
		||||
  if (trackers.length > 0) {
 | 
			
		||||
    // avoid duplicates
 | 
			
		||||
    const existing = new Set(magnet.tr ?? []);
 | 
			
		||||
    for (const tracker of trackers) {
 | 
			
		||||
      if (!existing.has(tracker)) {
 | 
			
		||||
        magnet.tr?.push(tracker);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return magnet;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								shared/types/magnet.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								shared/types/magnet.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
export type MagnetUrl = {
 | 
			
		||||
  /**
 | 
			
		||||
   * A magnet link is a string that contains all the information needed to download a torrent file.
 | 
			
		||||
   * It consists of several parameters that are separated by ampersands (&).
 | 
			
		||||
   * The parameters are:
 | 
			
		||||
   * - xt (exact topic): The hash of the torrent file.
 | 
			
		||||
   * - dn (display name): The name of the torrent file.
 | 
			
		||||
   * - tr (tracker URL): The URL of the tracker.
 | 
			
		||||
   * - as (acceptable source): The URL of the acceptable source.
 | 
			
		||||
   * - xs (exact source): The URL of the exact source.
 | 
			
		||||
   * - kt (keyword topic): The keyword topic.
 | 
			
		||||
   * - mt (magnet topic): The magnet topic.
 | 
			
		||||
   */
 | 
			
		||||
  xt: string;
 | 
			
		||||
  dn?: string;
 | 
			
		||||
  tr?: string[];
 | 
			
		||||
  as?: string[];
 | 
			
		||||
  xs?: string[];
 | 
			
		||||
  kt?: string;
 | 
			
		||||
  mt?: string;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user