{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "hero-globe-interactive-nodes",
  "title": "Hero Globe Interactive Nodes",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/hero-globe-interactive-nodes/HeroGlobeInteractiveNodes.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Activity, ArrowRight, Check, Copy, Globe, Radio, Server, ShieldCheck, Terminal, Zap } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { cn } from '@/lib/utils'\n\nexport interface EdgeNode {\n  id: string\n  name: string\n  region: string\n  country: string\n  city: string\n  latencyMs: number\n  p99LatencyMs: number\n  cacheHitRatio: number\n  qps: number\n  status: 'optimal' | 'operational' | 'degraded'\n  coordinates: { x: number; y: number }\n}\n\nexport interface HeroGlobeInteractiveNodesProps {\n  title?: string\n  description?: string\n  cliCommand?: string\n  nodes?: EdgeNode[]\n  class?: string\n}\n\nconst DEFAULT_NODES: EdgeNode[] = [\n  {\n    id: 'node-iad',\n    name: 'iad-1',\n    region: 'us-east-1',\n    country: 'United States',\n    city: 'Washington, D.C.',\n    latencyMs: 8,\n    p99LatencyMs: 14,\n    cacheHitRatio: 99.4,\n    qps: 18450,\n    status: 'optimal',\n    coordinates: { x: 28, y: 38 },\n  },\n  {\n    id: 'node-sfo',\n    name: 'sfo-1',\n    region: 'us-west-1',\n    country: 'United States',\n    city: 'San Francisco',\n    latencyMs: 12,\n    p99LatencyMs: 22,\n    cacheHitRatio: 99.1,\n    qps: 14200,\n    status: 'optimal',\n    coordinates: { x: 18, y: 40 },\n  },\n  {\n    id: 'node-fra',\n    name: 'fra-1',\n    region: 'eu-central-1',\n    country: 'Germany',\n    city: 'Frankfurt',\n    latencyMs: 15,\n    p99LatencyMs: 27,\n    cacheHitRatio: 98.9,\n    qps: 21300,\n    status: 'optimal',\n    coordinates: { x: 52, y: 32 },\n  },\n  {\n    id: 'node-sin',\n    name: 'sin-1',\n    region: 'ap-southeast-1',\n    country: 'Singapore',\n    city: 'Singapore',\n    latencyMs: 24,\n    p99LatencyMs: 41,\n    cacheHitRatio: 98.6,\n    qps: 16800,\n    status: 'optimal',\n    coordinates: { x: 76, y: 58 },\n  },\n  {\n    id: 'node-nrt',\n    name: 'nrt-1',\n    region: 'ap-northeast-1',\n    country: 'Japan',\n    city: 'Tokyo',\n    latencyMs: 19,\n    p99LatencyMs: 34,\n    cacheHitRatio: 99.2,\n    qps: 19400,\n    status: 'optimal',\n    coordinates: { x: 84, y: 42 },\n  },\n  {\n    id: 'node-syd',\n    name: 'syd-1',\n    region: 'ap-southeast-2',\n    country: 'Australia',\n    city: 'Sydney',\n    latencyMs: 32,\n    p99LatencyMs: 52,\n    cacheHitRatio: 98.2,\n    qps: 9800,\n    status: 'optimal',\n    coordinates: { x: 88, y: 78 },\n  },\n  {\n    id: 'node-gru',\n    name: 'gru-1',\n    region: 'sa-east-1',\n    country: 'Brazil',\n    city: 'São Paulo',\n    latencyMs: 44,\n    p99LatencyMs: 68,\n    cacheHitRatio: 97.9,\n    qps: 7600,\n    status: 'optimal',\n    coordinates: { x: 36, y: 74 },\n  },\n  {\n    id: 'node-lhr',\n    name: 'lhr-1',\n    region: 'eu-west-2',\n    country: 'United Kingdom',\n    city: 'London',\n    latencyMs: 11,\n    p99LatencyMs: 20,\n    cacheHitRatio: 99.5,\n    qps: 24600,\n    status: 'optimal',\n    coordinates: { x: 48, y: 30 },\n  },\n]\n\nconst props = withDefaults(defineProps<HeroGlobeInteractiveNodesProps>(), {\n  title: 'Sub-millisecond UI edge delivery across 310+ PoPs globally.',\n  description:\n    'Compile unbundled Vue 3.5 and React 19 components with instant edge caching. Zero cold starts, deterministic tree-shaking, and hardware-accelerated telemetry.',\n  cliCommand: 'npx shadcn-vue add @uipkge/init',\n})\n\nconst activeNodes = computed(() => props.nodes ?? DEFAULT_NODES)\nconst selectedNodeId = ref<string>('node-iad')\nconst copied = ref(false)\n\nconst selectedNode = computed<EdgeNode>(() => {\n  return activeNodes.value.find((n) => n.id === selectedNodeId.value) || activeNodes.value[0]\n})\n\nconst avgGlobalLatency = computed(() => {\n  if (!activeNodes.value.length) return 0\n  const sum = activeNodes.value.reduce((acc, curr) => acc + curr.latencyMs, 0)\n  return Math.round(sum / activeNodes.value.length)\n})\n\nconst totalGlobalQps = computed(() => {\n  return activeNodes.value.reduce((acc, curr) => acc + curr.qps, 0).toLocaleString()\n})\n\nasync function copyCommand() {\n  try {\n    await navigator.clipboard.writeText(props.cliCommand)\n    copied.value = true\n    setTimeout(() => {\n      copied.value = false\n    }, 2000)\n  } catch {\n    // clipboard fallback\n  }\n}\n</script>\n\n<template>\n  <section\n    data-slot=\"hero-globe-interactive-nodes\"\n    :class=\"cn('bg-background relative overflow-hidden py-16 sm:py-24 lg:py-28', props.class)\"\n  >\n    <div class=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n      <div class=\"grid grid-cols-1 gap-12 lg:grid-cols-12 lg:items-center\">\n        <!-- Left: Copy & Actions (6 Cols) -->\n        <div class=\"space-y-6 lg:col-span-6\">\n          <div\n            class=\"border-primary/20 bg-primary/10 text-primary inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium shadow-2xs\"\n          >\n            <Radio class=\"text-primary size-3.5 animate-pulse\" />\n            <span>Global Edge CDN Mesh Active &bull; 310+ PoPs</span>\n          </div>\n\n          <h1 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl\">\n            {{ title }}\n          </h1>\n\n          <p class=\"text-muted-foreground text-base sm:text-lg\">\n            {{ description }}\n          </p>\n\n          <!-- CLI Command Sandbox -->\n          <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center\">\n            <div\n              class=\"border-border bg-muted/60 text-foreground flex items-center justify-between rounded-lg border px-3 py-2 font-mono text-xs shadow-2xs sm:w-80\"\n            >\n              <div class=\"flex items-center gap-2 truncate\">\n                <Terminal class=\"text-muted-foreground size-3.5 shrink-0\" />\n                <span class=\"truncate\">{{ cliCommand }}</span>\n              </div>\n              <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                class=\"text-muted-foreground hover:text-foreground size-7 shrink-0\"\n                @click=\"copyCommand\"\n              >\n                <Check v-if=\"copied\" class=\"text-primary size-3.5\" />\n                <Copy v-else class=\"size-3.5\" />\n              </Button>\n            </div>\n\n            <Button size=\"default\" class=\"gap-1.5 shadow-xs\">\n              <span>Explore Registry</span>\n              <ArrowRight class=\"size-4\" />\n            </Button>\n          </div>\n\n          <!-- Quick Telemetry Strip -->\n          <div class=\"border-border grid grid-cols-3 gap-4 border-t pt-6\">\n            <div class=\"space-y-1\">\n              <div class=\"text-muted-foreground text-xs font-medium\">Global Avg Ping</div>\n              <div class=\"text-foreground text-xl font-bold tracking-tight\">{{ avgGlobalLatency }}ms</div>\n              <div class=\"text-success text-xs font-medium\">&minus;42% vs origin</div>\n            </div>\n            <div class=\"space-y-1\">\n              <div class=\"text-muted-foreground text-xs font-medium\">Network Throughput</div>\n              <div class=\"text-foreground text-xl font-bold tracking-tight\">{{ totalGlobalQps }}</div>\n              <div class=\"text-muted-foreground text-xs\">req/sec live</div>\n            </div>\n            <div class=\"space-y-1\">\n              <div class=\"text-muted-foreground text-xs font-medium\">Edge Availability</div>\n              <div class=\"text-foreground text-xl font-bold tracking-tight\">99.95%</div>\n              <div class=\"text-success text-xs font-medium\">Enterprise SLA</div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Right: Interactive SVG Node Map & Telemetry Workbench (6 Cols) -->\n        <div class=\"space-y-4 lg:col-span-6\">\n          <Card class=\"border-border bg-card shadow-sm\">\n            <CardContent class=\"space-y-4 p-4 sm:p-6\">\n              <!-- Top bar: active node switch -->\n              <div class=\"border-border flex items-center justify-between border-b pb-3\">\n                <div class=\"flex items-center gap-2\">\n                  <Globe class=\"text-primary size-4\" />\n                  <span class=\"text-foreground text-xs font-semibold\">Active Edge Inspection</span>\n                </div>\n                <Badge variant=\"outline\" class=\"border-border text-muted-foreground font-mono text-xs\">\n                  {{ selectedNode.city }} ({{ selectedNode.name }})\n                </Badge>\n              </div>\n\n              <!-- Interactive Node Grid / Map Canvas -->\n              <div class=\"border-border/80 bg-muted/30 relative h-60 w-full overflow-hidden rounded-lg border p-3\">\n                <!-- SVG Connections Network Layer -->\n                <svg class=\"stroke-border/70 absolute inset-0 size-full\" xmlns=\"http://www.w3.org/2000/svg\">\n                  <line\n                    v-for=\"(n, idx) in activeNodes.slice(1)\"\n                    :key=\"idx\"\n                    :x1=\"`${activeNodes[0].coordinates.x}%`\"\n                    :y1=\"`${activeNodes[0].coordinates.y}%`\"\n                    :x2=\"`${n.coordinates.x}%`\"\n                    :y2=\"`${n.coordinates.y}%`\"\n                    stroke-dasharray=\"3 3\"\n                    stroke-width=\"1\"\n                  />\n                </svg>\n\n                <!-- Interactive Region Nodes -->\n                <button\n                  v-for=\"node in activeNodes\"\n                  :key=\"node.id\"\n                  type=\"button\"\n                  :style=\"{ left: `${node.coordinates.x}%`, top: `${node.coordinates.y}%` }\"\n                  :class=\"\n                    cn(\n                      'focus-visible:ring-ring absolute flex -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full transition-colors duration-150 focus-visible:ring-2 focus-visible:outline-none',\n                      selectedNodeId === node.id\n                        ? 'bg-primary text-primary-foreground ring-primary/20 z-10 size-7 scale-110 shadow-sm ring-4'\n                        : 'bg-card hover:bg-accent border-border text-foreground size-5 border hover:scale-105',\n                    )\n                  \"\n                  @click=\"selectedNodeId = node.id\"\n                >\n                  <span class=\"font-mono text-xs leading-none font-bold\">\n                    {{ selectedNodeId === node.id ? node.name.slice(0, 3).toUpperCase() : '' }}\n                  </span>\n                  <span v-if=\"selectedNodeId !== node.id\" class=\"bg-success size-2 rounded-full\" />\n                </button>\n              </div>\n\n              <!-- Edge Node Telemetry Card -->\n              <div class=\"border-border bg-background grid grid-cols-2 gap-2.5 rounded-lg border p-3 sm:grid-cols-4\">\n                <div class=\"space-y-0.5\">\n                  <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                    <Zap class=\"text-primary size-3\" />\n                    <span>Ping (p50)</span>\n                  </div>\n                  <div class=\"text-foreground font-mono text-sm font-bold\">{{ selectedNode.latencyMs }}ms</div>\n                </div>\n\n                <div class=\"space-y-0.5\">\n                  <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                    <Activity class=\"text-success size-3\" />\n                    <span>Ping (p99)</span>\n                  </div>\n                  <div class=\"text-foreground font-mono text-sm font-bold\">{{ selectedNode.p99LatencyMs }}ms</div>\n                </div>\n\n                <div class=\"space-y-0.5\">\n                  <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                    <Server class=\"text-info size-3\" />\n                    <span>Cache Hit</span>\n                  </div>\n                  <div class=\"text-foreground font-mono text-sm font-bold\">{{ selectedNode.cacheHitRatio }}%</div>\n                </div>\n\n                <div class=\"space-y-0.5\">\n                  <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                    <ShieldCheck class=\"text-primary size-3\" />\n                    <span>Throughput</span>\n                  </div>\n                  <div class=\"text-foreground font-mono text-sm font-bold\">\n                    {{ selectedNode.qps.toLocaleString() }} qps\n                  </div>\n                </div>\n              </div>\n\n              <!-- Quick Node Pill Selector -->\n              <div class=\"flex flex-wrap gap-1.5 pt-1\">\n                <button\n                  v-for=\"node in activeNodes\"\n                  :key=\"node.id\"\n                  type=\"button\"\n                  :class=\"\n                    cn(\n                      'rounded-md border px-2 py-1 font-mono text-xs font-medium transition-colors',\n                      selectedNodeId === node.id\n                        ? 'border-primary bg-primary/10 text-primary'\n                        : 'border-border bg-card text-muted-foreground hover:text-foreground hover:bg-accent/50',\n                    )\n                  \"\n                  @click=\"selectedNodeId = node.id\"\n                >\n                  {{ node.name }} &bull; {{ node.city }}\n                </button>\n              </div>\n            </CardContent>\n          </Card>\n        </div>\n      </div>\n    </div>\n  </section>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/hero-globe-interactive-nodes/HeroGlobeInteractiveNodes.vue"
    },
    {
      "path": "packages/registry-vue/blocks/hero-globe-interactive-nodes/index.ts",
      "content": "export { default as HeroGlobeInteractiveNodes } from './HeroGlobeInteractiveNodes.vue'\nexport type { HeroGlobeInteractiveNodesProps, EdgeNode } from './HeroGlobeInteractiveNodes.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/hero-globe-interactive-nodes/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json"
  ],
  "description": "Global edge latency simulation hero with interactive PoP node inspection and real-time telemetry.",
  "categories": [
    "hero",
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "hero"
}