{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "graphql-query-explorer",
  "title": "Graphql Query Explorer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/graphql-query-explorer/GraphqlQueryExplorer.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport {\n  AlignLeft,\n  Check,\n  ChevronDown,\n  ChevronUp,\n  Copy,\n  FileCode,\n  Globe,\n  History,\n  Loader2,\n  Play,\n  Zap,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card } from '@/components/ui/card'\nimport GraphqlSchemaSidebar from './GraphqlSchemaSidebar.vue'\nimport GraphqlTracingPanel from './GraphqlTracingPanel.vue'\nimport type { QueryPreset, SchemaField } from './graphql-query-explorer-types'\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n\n// --- State ---\nconst endpointUrl = ref('https://api.uipkge.dev/graphql')\nconst editorMode = ref<'edit' | 'preview'>('edit')\nconst activeCenterTab = ref<'variables' | 'headers'>('variables')\nconst isVariablesCollapsed = ref(false)\nconst activeResponseTab = ref<'response' | 'tracing' | 'headers'>('response')\n\nconst isLoading = ref(false)\nconst copiedResponse = ref(false)\nconst showHistoryDropdown = ref(false)\n\n// Sample Query Presets & History\nconst presets: QueryPreset[] = [\n  {\n    id: 'preset-customer',\n    name: 'GetCustomerProfile',\n    operationType: 'query',\n    query: `query GetCustomerProfile($id: ID!) {\n  customer(id: $id) {\n    id\n    name\n    email\n    avatarUrl\n    status\n    createdAt\n    subscriptions {\n      id\n      status\n      plan\n      renewalDate\n      seats\n    }\n    billingAddress {\n      city\n      country\n      postalCode\n    }\n  }\n}`,\n    variables: `{\\n  \"id\": \"cust_8492\"\\n}`,\n    response: {\n      data: {\n        customer: {\n          id: 'cust_8492',\n          name: 'Sarah Jenkins',\n          email: 'sarah.jenkins@acme-corp.io',\n          avatarUrl: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330',\n          status: 'ACTIVE',\n          createdAt: '2024-03-15T08:22:19Z',\n          subscriptions: [\n            {\n              id: 'sub_9812',\n              status: 'ACTIVE',\n              plan: 'ENTERPRISE_ANNUAL',\n              renewalDate: '2027-03-15',\n              seats: 48,\n            },\n            {\n              id: 'sub_4410',\n              status: 'CANCELED',\n              plan: 'STARTER_TRIAL',\n              renewalDate: '2024-04-01',\n              seats: 5,\n            },\n          ],\n          billingAddress: {\n            city: 'San Francisco',\n            country: 'US',\n            postalCode: '94107',\n          },\n        },\n      },\n      extensions: {\n        tracing: {\n          version: 1,\n          duration: 64120000,\n        },\n      },\n    },\n    latency: '64ms',\n    size: '1.8 kB',\n    timestamp: 'Just now',\n  },\n  {\n    id: 'preset-users',\n    name: 'ListUsers',\n    operationType: 'query',\n    query: `query ListUsers($limit: Int, $offset: Int) {\n  users(limit: $limit, offset: $offset) {\n    id\n    fullName\n    email\n    role\n    isVerified\n    lastActiveAt\n  }\n}`,\n    variables: `{\\n  \"limit\": 3,\\n  \"offset\": 0\\n}`,\n    response: {\n      data: {\n        users: [\n          {\n            id: 'usr_9011',\n            fullName: 'Alex Rivera',\n            email: 'alex.rivera@uipkge.dev',\n            role: 'ADMIN',\n            isVerified: true,\n            lastActiveAt: '2026-08-21T10:45:00Z',\n          },\n          {\n            id: 'usr_9012',\n            fullName: 'Elena Rostova',\n            email: 'elena.r@uipkge.dev',\n            role: 'DEVELOPER',\n            isVerified: true,\n            lastActiveAt: '2026-08-21T09:12:30Z',\n          },\n          {\n            id: 'usr_9013',\n            fullName: 'Marcus Chen',\n            email: 'marcus.chen@uipkge.dev',\n            role: 'MEMBER',\n            isVerified: false,\n            lastActiveAt: '2026-08-20T18:04:12Z',\n          },\n        ],\n      },\n    },\n    latency: '38ms',\n    size: '0.9 kB',\n    timestamp: '2 mins ago',\n  },\n  {\n    id: 'preset-create-order',\n    name: 'CreateOrder',\n    operationType: 'mutation',\n    query: `mutation CreateOrder($input: CreateOrderInput!) {\n  createOrder(input: $input) {\n    order {\n      id\n      status\n      totalAmount\n      currency\n      itemsCount\n      createdAt\n    }\n    clientSecret\n    error {\n      code\n      message\n    }\n  }\n}`,\n    variables: `{\\n  \"input\": {\\n    \"customerId\": \"cust_8492\",\\n    \"items\": [\\n      { \"sku\": \"SKU_PRO_REGISTRY\", \"quantity\": 1, \"price\": 149.00 }\\n    ],\\n    \"currency\": \"USD\"\\n  }\\n}`,\n    response: {\n      data: {\n        createOrder: {\n          order: {\n            id: 'ord_88201',\n            status: 'PENDING_PAYMENT',\n            totalAmount: 149.0,\n            currency: 'USD',\n            itemsCount: 1,\n            createdAt: '2026-08-21T12:00:00Z',\n          },\n          clientSecret: 'pi_3Mtwx2_secret_9941a8',\n          error: null,\n        },\n      },\n    },\n    latency: '112ms',\n    size: '1.1 kB',\n    timestamp: '5 mins ago',\n  },\n  {\n    id: 'preset-subscription-stream',\n    name: 'OnOrderStatusChanged',\n    operationType: 'subscription',\n    query: `subscription OnOrderStatusChanged($orderId: ID!) {\n  orderStatusUpdated(orderId: $orderId) {\n    orderId\n    previousStatus\n    newStatus\n    updatedAt\n    carrierTracking {\n      carrier\n      trackingNumber\n      estimatedDelivery\n    }\n  }\n}`,\n    variables: `{\\n  \"orderId\": \"ord_88201\"\\n}`,\n    response: {\n      data: {\n        orderStatusUpdated: {\n          orderId: 'ord_88201',\n          previousStatus: 'PROCESSING',\n          newStatus: 'SHIPPED',\n          updatedAt: '2026-08-21T12:05:44Z',\n          carrierTracking: {\n            carrier: 'FedEx Priority',\n            trackingNumber: 'FDX-9982-1049-US',\n            estimatedDelivery: '2026-08-23T16:00:00Z',\n          },\n        },\n      },\n    },\n    latency: '18ms',\n    size: '0.7 kB',\n    timestamp: '12 mins ago',\n  },\n]\n\n// Current active values\nconst activeQuery = ref(presets[0].query)\nconst activeVariables = ref(presets[0].variables)\nconst activeHeaders = ref(`{\\n  \"Authorization\": \"Bearer uipkge_live_9f81a7\",\\n  \"X-Tenant-ID\": \"tenant_prod_eu\"\\n}`)\nconst responseJson = ref<Record<string, unknown>>(presets[0].response)\nconst responseStatus = ref('200 OK')\nconst responseLatency = ref('64ms')\nconst responseSize = ref('1.8 kB')\n\n// Computed\nconst queryLines = computed(() => activeQuery.value.split('\\n'))\nconst variableLines = computed(() => activeVariables.value.split('\\n'))\nconst headersLines = computed(() => activeHeaders.value.split('\\n'))\nconst formattedResponseString = computed(() => JSON.stringify(responseJson.value, null, 2))\nconst responseLines = computed(() => formattedResponseString.value.split('\\n'))\n\nconst detectedOperation = computed(() => {\n  const q = activeQuery.value.trim()\n  if (q.startsWith('mutation')) return { type: 'mutation', color: 'bg-warning/10 text-warning border-warning/30' }\n  if (q.startsWith('subscription'))\n    return { type: 'subscription', color: 'bg-chart-1/10 text-chart-1 border-chart-1/30' }\n  return { type: 'query', color: 'bg-info/10 text-info border-info/30' }\n})\n\nconst isVariablesValidJson = computed(() => {\n  try {\n    JSON.parse(activeVariables.value)\n    return true\n  } catch {\n    return false\n  }\n})\n\n// --- Helper Functions ---\nfunction escapeHtml(str: string): string {\n  return str\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#039;')\n}\n\nfunction highlightJsonLine(line: string): string {\n  if (!line) return ''\n  const escaped = escapeHtml(line)\n  return escaped.replace(\n    /(&quot;(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*&quot;(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n    (match) => {\n      let cls = 'text-warning'\n      if (/^&quot;/.test(match)) {\n        if (/:$/.test(match)) {\n          cls = 'text-info font-medium'\n        } else {\n          cls = 'text-success'\n        }\n      } else if (/true|false/.test(match)) {\n        cls = 'text-chart-2 font-semibold'\n      } else if (/null/.test(match)) {\n        cls = 'text-destructive italic'\n      }\n      return `<span class=\"${cls}\">${match}</span>`\n    },\n  )\n}\n\nfunction highlightGraphqlLine(line: string): string {\n  if (!line) return ''\n  const escaped = escapeHtml(line)\n  if (escaped.trim().startsWith('#')) {\n    return `<span class=\"text-muted-foreground/60 italic\">${escaped}</span>`\n  }\n\n  // Park each emitted <span> behind a letter-only placeholder: the type pass\n  // (`:\\s*Type`) otherwise matched the `dark:text-...` inside markup an earlier\n  // pass had already inserted, splitting the class attribute.\n  const parked: string[] = []\n  const park = (html: string) => {\n    const key = String(parked.length)\n      .split('')\n      .map((d) => String.fromCharCode(97 + Number(d)))\n      .join('')\n    parked.push(html)\n    return `\\u0000${key}\\u0000`\n  }\n\n  return escaped\n    .replace(/\\b(query|mutation|subscription|fragment|on)\\b/g, (m) =>\n      park(`<span class=\"text-info font-semibold\">${m}</span>`),\n    )\n    .replace(/(\\$[a-zA-Z0-9_]+)/g, (m) => park(`<span class=\"text-success font-medium\">${m}</span>`))\n    .replace(/:\\s*([A-Za-z0-9_\\[\\]!]+)/g, (_, t) => ': ' + park(`<span class=\"text-chart-1 font-mono\">${t}</span>`))\n    .replace(/(@[a-zA-Z0-9_]+)/g, (m) => park(`<span class=\"text-warning\">${m}</span>`))\n    .replace(/\\u0000([a-j]+)\\u0000/g, (_, key: string) => {\n      const idx = Number(\n        key\n          .split('')\n          .map((c: string) => String(c.charCodeAt(0) - 97))\n          .join(''),\n      )\n      return parked[idx] ?? ''\n    })\n}\n\nfunction prettifyGraphql(queryStr: string): string {\n  const lines = queryStr.split('\\n')\n  let indentLevel = 0\n  const formatted: string[] = []\n\n  for (const rawLine of lines) {\n    const line = rawLine.trim()\n    if (!line) continue\n\n    if (line.startsWith('}') || line.startsWith(')')) {\n      indentLevel = Math.max(0, indentLevel - 1)\n    }\n\n    formatted.push('  '.repeat(indentLevel) + line)\n\n    if (line.endsWith('{') || line.endsWith('(')) {\n      indentLevel++\n    }\n  }\n\n  return formatted.join('\\n')\n}\n\nfunction handlePrettify() {\n  activeQuery.value = prettifyGraphql(activeQuery.value)\n  if (isVariablesValidJson.value) {\n    try {\n      activeVariables.value = JSON.stringify(JSON.parse(activeVariables.value), null, 2)\n    } catch {\n      // Keep as-is\n    }\n  }\n}\n\nfunction runQuery() {\n  if (isLoading.value) return\n  isLoading.value = true\n\n  setTimeout(() => {\n    // Generate realistic dynamic latency and check for matching preset\n    const randMs = Math.floor(Math.random() * 40) + 35\n    responseLatency.value = `${randMs}ms`\n\n    const trimmed = activeQuery.value.trim()\n    if (trimmed.includes('createOrder') || trimmed.includes('mutation')) {\n      responseJson.value = presets[2].response\n      responseSize.value = presets[2].size\n      responseStatus.value = '200 OK'\n    } else if (trimmed.includes('orderStatusUpdated') || trimmed.includes('subscription')) {\n      responseJson.value = presets[3].response\n      responseSize.value = presets[3].size\n      responseStatus.value = '200 OK · SSE Stream'\n    } else if (trimmed.includes('users') || trimmed.includes('ListUsers')) {\n      responseJson.value = presets[1].response\n      responseSize.value = presets[1].size\n      responseStatus.value = '200 OK'\n    } else {\n      responseJson.value = presets[0].response\n      responseSize.value = presets[0].size\n      responseStatus.value = '200 OK'\n    }\n\n    isLoading.value = false\n  }, 260)\n}\n\nfunction loadPreset(preset: QueryPreset) {\n  activeQuery.value = preset.query\n  activeVariables.value = preset.variables\n  responseJson.value = preset.response\n  responseLatency.value = preset.latency\n  responseSize.value = preset.size\n  showHistoryDropdown.value = false\n}\n\nfunction loadFieldQuery(field: SchemaField) {\n  activeQuery.value = field.sampleQuery\n  activeVariables.value = field.sampleVariables\n}\n\nfunction copyResponse() {\n  navigator.clipboard.writeText(formattedResponseString.value)\n  copiedResponse.value = true\n  setTimeout(() => {\n    copiedResponse.value = false\n  }, 2000)\n}\n</script>\n\n<template>\n  <Card\n    data-slot=\"graphql-query-explorer\"\n    :class=\"\n      cn(\n        'border-border bg-card text-card-foreground flex min-h-[720px] flex-col overflow-hidden rounded-xl border shadow-xs',\n        props.class,\n      )\n    \"\n  >\n    <!-- TOP TOOLBAR -->\n    <header class=\"border-border bg-muted/40 flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n      <!-- Left: Endpoint & Method & Schema Badge -->\n      <div class=\"flex flex-wrap items-center gap-2.5\">\n        <Badge variant=\"outline\" class=\"border-border bg-background font-mono text-xs font-semibold tracking-wider\">\n          POST\n        </Badge>\n\n        <div class=\"border-border bg-background flex h-8 items-center gap-2 rounded-md border px-3 text-xs shadow-xs\">\n          <Globe class=\"text-muted-foreground size-3.5\" />\n          <input\n            v-model=\"endpointUrl\"\n            type=\"text\"\n            class=\"text-foreground w-64 bg-transparent font-mono text-xs focus:outline-none\"\n            placeholder=\"https://api.example.com/graphql\"\n          />\n        </div>\n\n        <Badge variant=\"secondary\" class=\"gap-1.5 py-1 font-mono text-xs font-normal\">\n          <span class=\"bg-success size-1.5 animate-pulse rounded-full\" />\n          Schema v2.4 · 48 Types\n        </Badge>\n      </div>\n\n      <!-- Right: Action Buttons -->\n      <div class=\"flex flex-wrap items-center gap-2\">\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          class=\"h-8 gap-1.5 text-xs\"\n          title=\"Format query (Shift + Option + F)\"\n          @click=\"handlePrettify\"\n        >\n          <AlignLeft class=\"size-3.5\" />\n          Prettify\n        </Button>\n\n        <!-- History Menu Toggle -->\n        <div class=\"relative\">\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-8 gap-1.5 text-xs\"\n            @click=\"showHistoryDropdown = !showHistoryDropdown\"\n          >\n            <History class=\"size-3.5\" />\n            History\n            <Badge variant=\"secondary\" class=\"ml-0.5 h-4 px-1 font-mono text-xs\">\n              {{ presets.length }}\n            </Badge>\n          </Button>\n\n          <!-- History Dropdown Card -->\n          <div\n            v-if=\"showHistoryDropdown\"\n            class=\"border-border bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-80 rounded-lg border p-2 text-xs shadow-md\"\n          >\n            <div\n              class=\"border-border text-muted-foreground flex items-center justify-between gap-x-2 border-b px-2 py-1.5 font-medium\"\n            >\n              <span>Recent Executions</span>\n              <span class=\"font-mono text-xs\">Saved Stubs</span>\n            </div>\n            <div class=\"mt-1 max-h-60 space-y-1 overflow-y-auto\">\n              <button\n                v-for=\"preset in presets\"\n                :key=\"preset.id\"\n                class=\"hover:bg-muted focus:bg-muted flex w-full flex-col gap-0.5 rounded-md p-2 text-left transition-colors\"\n                @click=\"loadPreset(preset)\"\n              >\n                <div class=\"flex items-center justify-between gap-x-2\">\n                  <span class=\"text-foreground font-mono font-medium\">{{ preset.name }}</span>\n                  <Badge variant=\"outline\" class=\"font-mono text-xs font-normal\">\n                    {{ preset.latency }}\n                  </Badge>\n                </div>\n                <div class=\"text-muted-foreground flex flex-wrap items-center gap-2 font-mono text-xs\">\n                  <span class=\"text-primary font-semibold uppercase\">{{ preset.operationType }}</span>\n                  <span>·</span>\n                  <span>{{ preset.timestamp }}</span>\n                </div>\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <!-- Run Query Primary Action -->\n        <Button\n          variant=\"default\"\n          size=\"sm\"\n          class=\"bg-primary text-primary-foreground hover:bg-primary/90 h-8 gap-2 text-xs font-semibold shadow-xs\"\n          :disabled=\"isLoading\"\n          @click=\"runQuery\"\n        >\n          <Loader2 v-if=\"isLoading\" class=\"size-3.5 animate-spin\" />\n          <Play v-else class=\"size-3.5 fill-current\" />\n          Run Query\n          <kbd\n            class=\"border-primary-foreground/30 bg-primary-foreground/15 hidden rounded border px-1 py-0.5 font-mono text-xs font-normal sm:inline-block\"\n          >\n            ⌘↵\n          </kbd>\n        </Button>\n      </div>\n    </header>\n\n    <!-- 3-COLUMN STUDIO LAYOUT -->\n    <div\n      class=\"divide-border grid flex-1 grid-cols-1 divide-y overflow-hidden lg:grid-cols-12 lg:divide-x lg:divide-y-0\"\n    >\n      <!-- COLUMN 1: SCHEMA DOCUMENTATION SIDEBAR (w-56 / lg:col-span-3) -->\n      <GraphqlSchemaSidebar @load-field=\"loadFieldQuery\" />\n\n      <!-- COLUMN 2: CENTER QUERY & VARIABLES EDITOR (lg:col-span-5) -->\n      <main class=\"bg-card flex flex-col overflow-hidden lg:col-span-5\">\n        <!-- Query Toolbar -->\n        <div class=\"border-border bg-muted/20 flex items-center justify-between gap-x-2 border-b px-3 py-2\">\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <FileCode class=\"text-primary size-4\" />\n            <span class=\"text-foreground font-mono text-xs font-semibold\">Query.graphql</span>\n            <Badge variant=\"outline\" :class=\"cn('font-mono text-xs uppercase', detectedOperation.color)\">\n              {{ detectedOperation.type }}\n            </Badge>\n          </div>\n\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <span class=\"text-muted-foreground font-mono text-xs\">\n              {{ queryLines.length }} lines · {{ activeQuery.length }} chars\n            </span>\n            <div class=\"border-border bg-muted/60 flex items-center rounded-md border p-0.5\">\n              <button\n                class=\"min-h-6 rounded px-2 py-0.5 text-xs font-medium transition-colors\"\n                :class=\"\n                  editorMode === 'edit'\n                    ? 'bg-background text-foreground shadow-xs'\n                    : 'text-muted-foreground hover:text-foreground'\n                \"\n                @click=\"editorMode = 'edit'\"\n              >\n                Edit\n              </button>\n              <button\n                class=\"min-h-6 rounded px-2 py-0.5 text-xs font-medium transition-colors\"\n                :class=\"\n                  editorMode === 'preview'\n                    ? 'bg-background text-foreground shadow-xs'\n                    : 'text-muted-foreground hover:text-foreground'\n                \"\n                @click=\"editorMode = 'preview'\"\n              >\n                Preview\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <!-- Query Editor Body with Line Numbers -->\n        <div class=\"relative flex min-h-[260px] flex-1 overflow-hidden\">\n          <!-- Line Numbers Gutter -->\n          <div\n            class=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-10 shrink-0 overflow-hidden border-r py-3 pr-2 text-right font-mono text-xs leading-relaxed select-none\"\n          >\n            <div v-for=\"n in queryLines.length\" :key=\"n\">{{ n }}</div>\n          </div>\n\n          <!-- Code Area: Editable or Syntax Preview -->\n          <div class=\"bg-background/50 flex-1 overflow-auto\">\n            <!-- Edit Mode: Monospace Textarea -->\n            <textarea\n              v-if=\"editorMode === 'edit'\"\n              v-model=\"activeQuery\"\n              spellcheck=\"false\"\n              class=\"text-foreground h-full w-full resize-none bg-transparent p-3 font-mono text-xs leading-relaxed focus:outline-none\"\n              placeholder=\"# Write GraphQL query or mutation here...\"\n            />\n\n            <!-- Preview Mode: Syntax Highlighted Lines -->\n            <div v-else class=\"space-y-0.5 p-3 font-mono text-xs leading-relaxed\">\n              <div\n                v-for=\"(line, idx) in queryLines\"\n                :key=\"idx\"\n                class=\"whitespace-pre\"\n                v-html=\"highlightGraphqlLine(line)\"\n              />\n            </div>\n          </div>\n        </div>\n\n        <!-- COLLAPSIBLE BOTTOM PANE: VARIABLES / HEADERS -->\n        <div class=\"border-border bg-muted/10 flex flex-col border-t\">\n          <!-- Pane Header -->\n          <div class=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-1.5 text-xs\">\n            <div class=\"flex items-center gap-3\">\n              <button\n                class=\"font-mono font-medium transition-colors\"\n                :class=\"\n                  activeCenterTab === 'variables' ? 'text-foreground' : 'text-muted-foreground hover:text-foreground'\n                \"\n                @click=\"activeCenterTab = 'variables'\"\n              >\n                { } Query Variables\n              </button>\n              <span class=\"text-border\">|</span>\n              <button\n                class=\"font-mono font-medium transition-colors\"\n                :class=\"\n                  activeCenterTab === 'headers' ? 'text-foreground' : 'text-muted-foreground hover:text-foreground'\n                \"\n                @click=\"activeCenterTab = 'headers'\"\n              >\n                HTTP Headers (2)\n              </button>\n            </div>\n\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <Badge\n                v-if=\"activeCenterTab === 'variables'\"\n                variant=\"outline\"\n                :class=\"\n                  isVariablesValidJson ? 'border-success/30 text-success' : 'border-destructive/30 text-destructive'\n                \"\n                class=\"font-mono text-xs\"\n              >\n                {{ isVariablesValidJson ? 'Valid JSON' : 'Invalid JSON' }}\n              </Badge>\n\n              <button\n                class=\"text-muted-foreground hover:text-foreground min-h-6 p-0.5 transition-colors\"\n                :title=\"isVariablesCollapsed ? 'Expand pane' : 'Collapse pane'\"\n                @click=\"isVariablesCollapsed = !isVariablesCollapsed\"\n              >\n                <ChevronUp v-if=\"isVariablesCollapsed\" class=\"size-3.5\" />\n                <ChevronDown v-else class=\"size-3.5\" />\n              </button>\n            </div>\n          </div>\n\n          <!-- Pane Content -->\n          <div v-if=\"!isVariablesCollapsed\" class=\"bg-background/50 relative flex h-36 min-h-[140px] overflow-hidden\">\n            <!-- Variables Mode -->\n            <template v-if=\"activeCenterTab === 'variables'\">\n              <div\n                class=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-8 shrink-0 overflow-hidden border-r py-2 pr-2 text-right font-mono text-xs leading-relaxed select-none\"\n              >\n                <div v-for=\"n in variableLines.length\" :key=\"n\">{{ n }}</div>\n              </div>\n              <textarea\n                v-model=\"activeVariables\"\n                spellcheck=\"false\"\n                class=\"text-foreground h-full w-full resize-none bg-transparent p-2 font-mono text-xs leading-relaxed focus:outline-none\"\n                placeholder=\"{}\"\n              />\n            </template>\n\n            <!-- Headers Mode -->\n            <template v-else>\n              <div\n                class=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-8 shrink-0 overflow-hidden border-r py-2 pr-2 text-right font-mono text-xs leading-relaxed select-none\"\n              >\n                <div v-for=\"n in headersLines.length\" :key=\"n\">{{ n }}</div>\n              </div>\n              <textarea\n                v-model=\"activeHeaders\"\n                spellcheck=\"false\"\n                class=\"text-foreground h-full w-full resize-none bg-transparent p-2 font-mono text-xs leading-relaxed focus:outline-none\"\n              />\n            </template>\n          </div>\n        </div>\n      </main>\n\n      <!-- COLUMN 3: RIGHT RESPONSE PANEL (lg:col-span-4) -->\n      <section class=\"bg-muted/10 flex flex-col overflow-hidden lg:col-span-4\">\n        <!-- Response Header -->\n        <div class=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-2\">\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <Badge\n              variant=\"outline\"\n              class=\"border-success/30 bg-success/10 text-success gap-1.5 font-mono text-xs font-semibold\"\n            >\n              <span class=\"bg-success size-1.5 rounded-full\" />\n              {{ responseStatus }}\n            </Badge>\n\n            <span class=\"text-muted-foreground flex items-center gap-1 font-mono text-xs\">\n              <Zap class=\"text-warning size-3\" />\n              {{ responseLatency }}\n            </span>\n\n            <span class=\"text-muted-foreground font-mono text-xs\">\n              {{ responseSize }}\n            </span>\n          </div>\n\n          <Button variant=\"ghost\" size=\"sm\" class=\"h-7 gap-1 px-2 text-xs\" @click=\"copyResponse\">\n            <Check v-if=\"copiedResponse\" class=\"text-success size-3\" />\n            <Copy v-else class=\"size-3\" />\n            <span>{{ copiedResponse ? 'Copied' : 'Copy' }}</span>\n          </Button>\n        </div>\n\n        <!-- Response View Tabs -->\n        <div class=\"border-border bg-muted/20 flex items-center gap-1 border-b px-3 py-1\">\n          <button\n            class=\"min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors\"\n            :class=\"\n              activeResponseTab === 'response'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground'\n            \"\n            @click=\"activeResponseTab = 'response'\"\n          >\n            Response JSON\n          </button>\n          <button\n            class=\"min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors\"\n            :class=\"\n              activeResponseTab === 'tracing'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground'\n            \"\n            @click=\"activeResponseTab = 'tracing'\"\n          >\n            Tracing\n          </button>\n          <button\n            class=\"min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors\"\n            :class=\"\n              activeResponseTab === 'headers'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground'\n            \"\n            @click=\"activeResponseTab = 'headers'\"\n          >\n            Headers\n          </button>\n        </div>\n\n        <!-- Loading Indicator -->\n        <div v-if=\"isLoading\" class=\"flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center\">\n          <Loader2 class=\"text-primary size-6 animate-spin\" />\n          <div class=\"space-y-1\">\n            <p class=\"text-foreground font-mono text-xs font-medium\">Executing GraphQL Operation...</p>\n            <p class=\"text-muted-foreground font-mono text-xs\">{{ endpointUrl }}</p>\n          </div>\n        </div>\n\n        <!-- Response Body: Tab 1 (JSON Response) -->\n        <div\n          v-else-if=\"activeResponseTab === 'response'\"\n          class=\"relative flex flex-1 overflow-auto bg-neutral-950 text-neutral-100 dark:bg-neutral-950\"\n        >\n          <!-- Gutter -->\n          <div\n            class=\"w-10 shrink-0 overflow-hidden border-r border-neutral-800 bg-neutral-900/50 py-3 pr-2 text-right font-mono text-xs leading-relaxed text-neutral-500 select-none\"\n          >\n            <div v-for=\"n in responseLines.length\" :key=\"n\">{{ n }}</div>\n          </div>\n\n          <!-- Colorized JSON Code -->\n          <div class=\"flex-1 overflow-auto p-3 font-mono text-xs leading-relaxed\">\n            <div\n              v-for=\"(line, idx) in responseLines\"\n              :key=\"idx\"\n              class=\"font-mono whitespace-pre\"\n              v-html=\"highlightJsonLine(line)\"\n            />\n          </div>\n        </div>\n\n        <!-- Response Body: Tab 2 (Tracing Waterfall) -->\n        <GraphqlTracingPanel v-else-if=\"activeResponseTab === 'tracing'\" :latency=\"responseLatency\" />\n\n        <!-- Response Body: Tab 3 (HTTP Response Headers) -->\n        <div v-else-if=\"activeResponseTab === 'headers'\" class=\"flex-1 space-y-2 overflow-y-auto p-3 font-mono text-xs\">\n          <div class=\"border-border bg-card space-y-2 rounded-lg border p-3\">\n            <div class=\"border-border/50 flex justify-between border-b pb-1.5\">\n              <span class=\"text-muted-foreground\">content-type:</span>\n              <span class=\"text-foreground font-medium\">application/graphql-response+json; charset=utf-8</span>\n            </div>\n            <div class=\"border-border/50 flex justify-between border-b pb-1.5\">\n              <span class=\"text-muted-foreground\">cache-control:</span>\n              <span class=\"text-foreground font-medium\">max-age=0, private, must-revalidate</span>\n            </div>\n            <div class=\"border-border/50 flex justify-between border-b pb-1.5\">\n              <span class=\"text-muted-foreground\">x-request-id:</span>\n              <span class=\"text-foreground font-medium\">req_01hx8921a9vnm8</span>\n            </div>\n            <div class=\"flex justify-between\">\n              <span class=\"text-muted-foreground\">server-timing:</span>\n              <span class=\"text-foreground font-medium\">graphql;dur=64.1</span>\n            </div>\n          </div>\n        </div>\n      </section>\n    </div>\n  </Card>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/graphql-query-explorer/GraphqlQueryExplorer.vue"
    },
    {
      "path": "packages/registry-vue/blocks/graphql-query-explorer/GraphqlSchemaSidebar.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronDown, ChevronRight, Database, Search } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Input } from '@/components/ui/input'\nimport { cn } from '@/lib/utils'\nimport type { RootType, SchemaField } from './graphql-query-explorer-types'\n\nconst emit = defineEmits<{\n  'load-field': [field: SchemaField]\n}>()\n\nconst selectedRootType = ref<'Query' | 'Mutation' | 'Subscription' | 'all'>('all')\nconst schemaSearch = ref('')\nconst selectedField = ref<SchemaField | null>(null)\nconst expandedRoots = ref<Record<string, boolean>>({\n  Query: true,\n  Mutation: true,\n  Subscription: true,\n})\n\n// Schema Root Types\nconst schemaRoots: RootType[] = [\n  {\n    name: 'Query',\n    color: 'text-info',\n    badgeVariant: 'default',\n    fields: [\n      {\n        name: 'customer',\n        args: 'id: ID!',\n        returnType: 'Customer',\n        description: 'Fetches verified customer account, active SaaS subscriptions, and verified billing profile.',\n        sampleQuery: `query GetCustomerProfile($id: ID!) {\\n  customer(id: $id) {\\n    id\\n    name\\n    email\\n    subscriptions { id status plan }\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"cust_8492\"\\n}`,\n      },\n      {\n        name: 'users',\n        args: 'limit: Int, offset: Int',\n        returnType: '[User!]!',\n        description: 'Returns paginated workspace members with security roles and activity status flags.',\n        sampleQuery: `query ListUsers($limit: Int, $offset: Int) {\\n  users(limit: $limit, offset: $offset) {\\n    id\\n    fullName\\n    email\\n    role\\n  }\\n}`,\n        sampleVariables: `{\\n  \"limit\": 10,\\n  \"offset\": 0\\n}`,\n      },\n      {\n        name: 'userById',\n        args: 'id: ID!',\n        returnType: 'User',\n        description: 'Look up specific team member by their unique UUID identifier.',\n        sampleQuery: `query GetUser($id: ID!) {\\n  userById(id: $id) {\\n    id\\n    fullName\\n    email\\n    role\\n    isVerified\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"usr_9011\"\\n}`,\n      },\n      {\n        name: 'products',\n        args: 'category: String, inStock: Boolean',\n        returnType: '[Product!]!',\n        description: 'Catalog items inventory with real-time stock levels and tiered price book.',\n        sampleQuery: `query GetProducts($category: String) {\\n  products(category: $category) {\\n    id\\n    title\\n    price\\n    inventoryCount\\n  }\\n}`,\n        sampleVariables: `{\\n  \"category\": \"developer-tools\"\\n}`,\n      },\n      {\n        name: 'orders',\n        args: 'status: OrderStatus, limit: Int',\n        returnType: '[Order!]!',\n        description: 'Historical and in-flight purchase orders with settlement metadata.',\n        sampleQuery: `query GetOrders($status: OrderStatus) {\\n  orders(status: $status) {\\n    id\\n    status\\n    totalAmount\\n    createdAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"status\": \"COMPLETED\"\\n}`,\n      },\n      {\n        name: 'organization',\n        args: 'slug: String!',\n        returnType: 'Organization',\n        description: 'Retrieve tenant workspace configurations, member limits, and billing tier.',\n        sampleQuery: `query GetOrg($slug: String!) {\\n  organization(slug: $slug) {\\n    id\\n    name\\n    slug\\n    memberCount\\n  }\\n}`,\n        sampleVariables: `{\\n  \"slug\": \"acme-corp\"\\n}`,\n      },\n    ],\n  },\n  {\n    name: 'Mutation',\n    color: 'text-warning',\n    badgeVariant: 'secondary',\n    fields: [\n      {\n        name: 'createOrder',\n        args: 'input: CreateOrderInput!',\n        returnType: 'OrderPayload!',\n        description: 'Creates new purchase order, holds inventory reservations, and emits payment intent.',\n        sampleQuery: `mutation CreateOrder($input: CreateOrderInput!) {\\n  createOrder(input: $input) {\\n    order { id status totalAmount }\\n    clientSecret\\n  }\\n}`,\n        sampleVariables: `{\\n  \"input\": {\\n    \"customerId\": \"cust_8492\",\\n    \"items\": [{ \"sku\": \"SKU_01\", \"quantity\": 1, \"price\": 149.00 }]\\n  }\\n}`,\n      },\n      {\n        name: 'updateCustomer',\n        args: 'id: ID!, input: CustomerInput!',\n        returnType: 'Customer!',\n        description: 'Updates customer profile attributes and notification preferences.',\n        sampleQuery: `mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {\\n  updateCustomer(id: $id, input: $input) {\\n    id\\n    name\\n    email\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"cust_8492\",\\n  \"input\": { \"name\": \"Sarah Jenkins\" }\\n}`,\n      },\n      {\n        name: 'cancelSubscription',\n        args: 'id: ID!, reason: String',\n        returnType: 'SubscriptionResult!',\n        description: 'Immediately pauses or schedules cancellation for recurring billing plan.',\n        sampleQuery: `mutation CancelSub($id: ID!, $reason: String) {\\n  cancelSubscription(id: $id, reason: $reason) {\\n    id\\n    status\\n    effectiveDate\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"sub_4410\",\\n  \"reason\": \"Upgraded to Enterprise annual\"\\n}`,\n      },\n      {\n        name: 'rotateApiKey',\n        args: 'keyId: ID!',\n        returnType: 'ApiKeyRotationPayload!',\n        description: 'Invalidates existing API secret and provisions new machine token.',\n        sampleQuery: `mutation RotateKey($keyId: ID!) {\\n  rotateApiKey(keyId: $keyId) {\\n    keyId\\n    secretToken\\n    expiresAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"keyId\": \"key_live_9941\"\\n}`,\n      },\n    ],\n  },\n  {\n    name: 'Subscription',\n    color: 'text-chart-1',\n    badgeVariant: 'outline',\n    fields: [\n      {\n        name: 'orderStatusUpdated',\n        args: 'orderId: ID!',\n        returnType: 'OrderStatusEvent!',\n        description: 'Live push stream delivering order state transitions and logistics milestones.',\n        sampleQuery: `subscription WatchOrder($orderId: ID!) {\\n  orderStatusUpdated(orderId: $orderId) {\\n    orderId\\n    newStatus\\n    updatedAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"orderId\": \"ord_88201\"\\n}`,\n      },\n      {\n        name: 'userActivityStream',\n        args: 'channelId: ID!',\n        returnType: 'ActivityEvent!',\n        description: 'Workspace real-time collaboration telemetry and presence updates.',\n        sampleQuery: `subscription ActivityStream($channelId: ID!) {\\n  userActivityStream(channelId: $channelId) {\\n    userId\\n    action\\n    timestamp\\n  }\\n}`,\n        sampleVariables: `{\\n  \"channelId\": \"chan_engineering\"\\n}`,\n      },\n    ],\n  },\n]\n\nconst filteredSchemaRoots = computed(() => {\n  const query = schemaSearch.value.trim().toLowerCase()\n  if (!query) {\n    if (selectedRootType.value === 'all') return schemaRoots\n    return schemaRoots.filter((r) => r.name === selectedRootType.value)\n  }\n\n  return schemaRoots\n    .map((root) => {\n      const matchingFields = root.fields.filter(\n        (f) =>\n          f.name.toLowerCase().includes(query) ||\n          f.returnType.toLowerCase().includes(query) ||\n          (f.args && f.args.toLowerCase().includes(query)) ||\n          f.description.toLowerCase().includes(query),\n      )\n      return {\n        ...root,\n        fields: matchingFields,\n      }\n    })\n    .filter((root) => root.fields.length > 0)\n})\n\nfunction toggleRoot(name: string) {\n  expandedRoots.value[name] = !expandedRoots.value[name]\n}\n\nfunction selectField(field: SchemaField) {\n  selectedField.value = field\n  emit('load-field', field)\n}\n</script>\n\n<template>\n  <!-- COLUMN 1: SCHEMA DOCUMENTATION SIDEBAR (w-56 / lg:col-span-3) -->\n  <aside class=\"bg-muted/15 flex flex-col overflow-hidden lg:col-span-3\">\n    <!-- Sidebar Header -->\n    <div class=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-2.5\">\n      <div class=\"flex items-center gap-1.5 text-xs font-semibold\">\n        <Database class=\"text-primary size-3.5\" />\n        <span>Schema Explorer</span>\n      </div>\n      <Badge variant=\"outline\" class=\"font-mono text-xs\"> v2.4 </Badge>\n    </div>\n\n    <!-- Search Types Input -->\n    <div class=\"border-border border-b p-2.5\">\n      <div class=\"relative\">\n        <Search class=\"text-muted-foreground absolute top-2.5 left-2.5 size-3.5\" />\n        <Input\n          v-model=\"schemaSearch\"\n          type=\"text\"\n          placeholder=\"Search types & fields...\"\n          class=\"h-8 pl-8 font-mono text-xs\"\n        />\n      </div>\n    </div>\n\n    <!-- Root Types & Field Tree -->\n    <div class=\"flex-1 space-y-3 overflow-y-auto p-2.5\">\n      <div v-for=\"root in filteredSchemaRoots\" :key=\"root.name\" class=\"space-y-1\">\n        <!-- Root Type Toggle -->\n        <button\n          class=\"hover:bg-muted/60 flex w-full items-center justify-between rounded-md px-2 py-1.5 text-left text-xs font-semibold transition-colors\"\n          @click=\"toggleRoot(root.name)\"\n        >\n          <div class=\"flex items-center gap-1.5\">\n            <ChevronDown v-if=\"expandedRoots[root.name]\" class=\"text-muted-foreground size-3.5\" />\n            <ChevronRight v-else class=\"text-muted-foreground size-3.5\" />\n            <span :class=\"root.color\">{{ root.name }}</span>\n          </div>\n          <Badge variant=\"secondary\" class=\"font-mono text-xs font-normal\">\n            {{ root.fields.length }}\n          </Badge>\n        </button>\n\n        <!-- Fields List -->\n        <div v-if=\"expandedRoots[root.name]\" class=\"border-border/70 ml-2 space-y-0.5 border-l pl-2\">\n          <button\n            v-for=\"field in root.fields\"\n            :key=\"field.name\"\n            class=\"hover:bg-muted focus:bg-muted group flex w-full flex-col gap-0.5 rounded px-2 py-1.5 text-left transition-colors\"\n            :class=\"selectedField?.name === field.name ? 'bg-muted/90 ring-border ring-1' : ''\"\n            @click=\"selectField(field)\"\n          >\n            <div class=\"flex items-center justify-between gap-x-2\">\n              <span class=\"text-foreground group-hover:text-primary font-mono text-xs font-medium transition-colors\">\n                {{ field.name }}\n              </span>\n              <span class=\"text-muted-foreground font-mono text-xs\">\n                {{ field.returnType }}\n              </span>\n            </div>\n            <div v-if=\"field.args\" class=\"text-muted-foreground truncate font-mono text-xs\">({{ field.args }})</div>\n          </button>\n        </div>\n      </div>\n    </div>\n\n    <!-- Selected Field Documentation Preview -->\n    <div v-if=\"selectedField\" class=\"border-border bg-card/60 border-t p-3 text-xs\">\n      <div class=\"flex items-center justify-between gap-x-2\">\n        <span class=\"text-foreground font-mono font-semibold\">{{ selectedField.name }}</span>\n        <Badge variant=\"secondary\" class=\"font-mono text-xs\">{{ selectedField.returnType }}</Badge>\n      </div>\n      <p class=\"text-muted-foreground mt-1.5 text-xs leading-normal\">\n        {{ selectedField.description }}\n      </p>\n      <div v-if=\"selectedField.args\" class=\"border-border bg-muted/40 mt-2 rounded border p-1.5 font-mono text-xs\">\n        <span class=\"text-muted-foreground\">Args: </span>\n        <span class=\"text-foreground font-medium\">{{ selectedField.args }}</span>\n      </div>\n    </div>\n  </aside>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/graphql-query-explorer/GraphqlSchemaSidebar.vue"
    },
    {
      "path": "packages/registry-vue/blocks/graphql-query-explorer/GraphqlTracingPanel.vue",
      "content": "<script setup lang=\"ts\">\nimport { Badge } from '@/components/ui/badge'\nimport type { ResolverTrace } from './graphql-query-explorer-types'\n\ndefineProps<{\n  latency: string\n}>()\n\n// Resolver Waterfall Tracing Data\nconst traces: ResolverTrace[] = [\n  {\n    path: 'Query.customer',\n    parentType: 'Query',\n    fieldName: 'customer',\n    returnType: 'Customer',\n    durationMs: 48.2,\n    percentage: 75,\n  },\n  {\n    path: 'Customer.subscriptions',\n    parentType: 'Customer',\n    fieldName: 'subscriptions',\n    returnType: '[Subscription!]!',\n    durationMs: 14.9,\n    percentage: 23,\n  },\n  {\n    path: 'Customer.billingAddress',\n    parentType: 'Customer',\n    fieldName: 'billingAddress',\n    returnType: 'BillingAddress',\n    durationMs: 1.0,\n    percentage: 2,\n  },\n]\n</script>\n\n<template>\n  <!-- Response Body: Tab 2 (Tracing Waterfall) -->\n  <div class=\"flex-1 space-y-3 overflow-y-auto p-4\">\n    <div class=\"border-border bg-card flex items-center justify-between gap-x-2 rounded-lg border p-3\">\n      <div>\n        <span class=\"text-muted-foreground text-xs\">Total Duration</span>\n        <p class=\"text-foreground font-mono text-base font-bold\">{{ latency }}</p>\n      </div>\n      <Badge variant=\"secondary\" class=\"font-mono text-xs\">Apollo Tracing v1</Badge>\n    </div>\n\n    <div class=\"space-y-2\">\n      <span class=\"text-muted-foreground font-mono text-xs font-medium\">Resolver Execution Times</span>\n      <div class=\"space-y-2\">\n        <div\n          v-for=\"trace in traces\"\n          :key=\"trace.path\"\n          class=\"border-border bg-card space-y-1.5 rounded-lg border p-2.5 text-xs\"\n        >\n          <div class=\"flex items-center justify-between gap-x-2\">\n            <span class=\"text-foreground font-mono font-semibold\">{{ trace.path }}</span>\n            <span class=\"text-muted-foreground font-mono\">{{ trace.durationMs }}ms</span>\n          </div>\n          <div class=\"bg-muted h-1.5 w-full overflow-hidden rounded-full\">\n            <div class=\"bg-primary h-full rounded-full\" :style=\"{ width: `${trace.percentage}%` }\" />\n          </div>\n          <div class=\"text-muted-foreground flex justify-between font-mono text-xs\">\n            <span>Type: {{ trace.returnType }}</span>\n            <span>{{ trace.percentage }}% of query</span>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/graphql-query-explorer/GraphqlTracingPanel.vue"
    },
    {
      "path": "packages/registry-vue/blocks/graphql-query-explorer/graphql-query-explorer-types.ts",
      "content": "export interface SchemaField {\n  name: string\n  args?: string\n  returnType: string\n  description: string\n  sampleQuery: string\n  sampleVariables: string\n}\n\nexport interface RootType {\n  name: 'Query' | 'Mutation' | 'Subscription'\n  color: string\n  badgeVariant: 'default' | 'secondary' | 'outline'\n  fields: SchemaField[]\n}\n\nexport interface QueryPreset {\n  id: string\n  name: string\n  operationType: 'query' | 'mutation' | 'subscription'\n  query: string\n  variables: string\n  response: Record<string, unknown>\n  latency: string\n  size: string\n  timestamp: string\n}\n\nexport interface ResolverTrace {\n  path: string\n  parentType: string\n  fieldName: string\n  returnType: string\n  durationMs: number\n  percentage: number\n}\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/graphql-query-explorer/graphql-query-explorer-types.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",
    "https://uipkge.dev/r/vue/input.json"
  ],
  "description": "Apollo and GraphiQL style GraphQL query builder and response inspector with schema documentation sidebar, syntax-highlighted query & variables editor, query history presets, execution tracing, and formatted JSON response viewer.",
  "categories": [
    "devops",
    "app"
  ]
}