{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "parquet-metadata-inspector",
  "title": "Parquet Metadata Inspector",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/ParquetMetadataInspector.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { Binary, Check, Code2, Copy, Download, FileCode2, FolderTree, Layers, Search, Table2 } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { cn } from '@/lib/utils'\nimport { ParquetFileTelemetryCards } from './ParquetFileTelemetryCards'\nimport { ParquetChunksTab } from './ParquetChunksTab'\nimport { ParquetSchemaTree } from './ParquetSchemaTree'\nimport { ParquetDictionaryTab } from './ParquetDictionaryTab'\nimport type { ColumnChunk, RowGroupMeta } from './parquet-metadata-types'\nimport { defaultRowGroupsData, parquetHeaderJson } from './parquet-metadata-data'\nimport { schemaTreeNodes } from './parquet-schema'\n\nexport type { ColumnChunk, RowGroupMeta }\n\nexport interface ParquetMetadataInspectorProps {\n  className?: string\n  filePath?: string\n  formatSpec?: string\n  totalRows?: string\n  fileSize?: string\n  compressionRatio?: string\n  uncompressedSize?: string\n  rowGroups?: RowGroupMeta[]\n}\n\nexport function ParquetMetadataInspector({\n  className,\n  filePath = 's3://lakehouse-gold/orders_2026_q3_part0042.parquet',\n  formatSpec = 'Apache Parquet v2.10 · Snappy Compressed',\n  totalRows = '250,000 Rows',\n  fileSize = '18.4 MB',\n  compressionRatio = '74.2%',\n  uncompressedSize = '71.4 MB',\n  rowGroups = defaultRowGroupsData,\n}: ParquetMetadataInspectorProps) {\n  const [selectedRowGroup, setSelectedRowGroup] = React.useState<number>(0)\n  const [activeTab, setActiveTab] = React.useState<string>('chunks')\n  const [searchQuery, setSearchQuery] = React.useState<string>('')\n  const [encodingFilter, setEncodingFilter] = React.useState<'all' | 'dictionary' | 'plain'>('all')\n  const [copiedJson, setCopiedJson] = React.useState<boolean>(false)\n  const [copiedUri, setCopiedUri] = React.useState<boolean>(false)\n  const [downloadingJson, setDownloadingJson] = React.useState<boolean>(false)\n\n  const activeRowGroup = React.useMemo(() => {\n    return rowGroups[selectedRowGroup] ?? rowGroups[0]\n  }, [rowGroups, selectedRowGroup])\n\n  const filteredColumns = React.useMemo(() => {\n    const query = searchQuery.trim().toLowerCase()\n    return activeRowGroup.columns.filter((col) => {\n      const matchesSearch =\n        !query ||\n        col.name.toLowerCase().includes(query) ||\n        col.physicalType.toLowerCase().includes(query) ||\n        col.logicalType.toLowerCase().includes(query) ||\n        col.encodings.some((enc) => enc.toLowerCase().includes(query))\n\n      const matchesEncoding =\n        encodingFilter === 'all' ||\n        (encodingFilter === 'dictionary' && col.isDictionaryEncoded) ||\n        (encodingFilter === 'plain' && !col.isDictionaryEncoded)\n\n      return matchesSearch && matchesEncoding\n    })\n  }, [activeRowGroup, searchQuery, encodingFilter])\n\n  const dictionaryColumns = React.useMemo(() => {\n    return activeRowGroup.columns.filter((col) => col.isDictionaryEncoded)\n  }, [activeRowGroup])\n\n  const copyJsonToClipboard = React.useCallback(() => {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(parquetHeaderJson)\n      setCopiedJson(true)\n      setTimeout(() => {\n        setCopiedJson(false)\n      }, 2000)\n    }\n  }, [])\n\n  const copyUriToClipboard = React.useCallback(() => {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(filePath)\n      setCopiedUri(true)\n      setTimeout(() => {\n        setCopiedUri(false)\n      }, 2000)\n    }\n  }, [filePath])\n\n  const handleDownloadJson = React.useCallback(() => {\n    setDownloadingJson(true)\n    setTimeout(() => {\n      if (typeof document !== 'undefined') {\n        const blob = new Blob([parquetHeaderJson], { type: 'application/json' })\n        const url = URL.createObjectURL(blob)\n        const a = document.createElement('a')\n        a.href = url\n        a.download = 'parquet-file-metadata.json'\n        document.body.appendChild(a)\n        a.click()\n        document.body.removeChild(a)\n        URL.revokeObjectURL(url)\n      }\n      setDownloadingJson(false)\n    }, 400)\n  }, [])\n\n  return (\n    <div\n      data-slot=\"parquet-metadata-inspector\"\n      className={cn(\n        'bg-background text-foreground border-border w-full overflow-hidden rounded-xl border shadow-xs',\n        className,\n      )}\n    >\n      {/* Top Parquet File Header */}\n      <header className=\"border-border bg-card/70 border-b px-4 py-4 sm:px-6\">\n        <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n          <div className=\"space-y-1.5\">\n            <div className=\"flex flex-wrap items-center gap-2.5\">\n              <div className=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n                <FileCode2 className=\"size-4\" />\n              </div>\n              <h2 className=\"font-mono text-sm font-semibold tracking-tight break-all sm:text-base\">{filePath}</h2>\n              <button\n                type=\"button\"\n                className=\"text-muted-foreground hover:text-foreground cursor-pointer transition-colors\"\n                aria-label=\"Copy S3 URI\"\n                onClick={copyUriToClipboard}\n              >\n                {copiedUri ? <Check className=\"text-success size-3.5\" /> : <Copy className=\"size-3.5\" />}\n              </button>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs\">\n              <Badge variant=\"outline\" className=\"gap-1.5 font-mono text-xs font-normal\">\n                <span className=\"bg-success size-1.5 rounded-full\" />\n                <span>{formatSpec}</span>\n              </Badge>\n              <span className=\"text-muted-foreground\">\n                Total Rows: <strong className=\"text-foreground font-semibold tabular-nums\">{totalRows}</strong>\n              </span>\n              <div className=\"border-success/30 bg-success/10 text-success inline-flex items-center gap-1 rounded-md border px-2 py-0.5 font-mono text-xs font-medium\">\n                <span>{fileSize}</span>\n                <span>·</span>\n                <span className=\"tabular-nums\">{compressionRatio} Compression Ratio</span>\n              </div>\n            </div>\n          </div>\n\n          <div className=\"flex flex-wrap items-center gap-2\">\n            <Button variant=\"outline\" size=\"sm\" className=\"h-8 gap-1.5 text-xs shadow-xs\" onClick={copyJsonToClipboard}>\n              {copiedJson ? <Check className=\"text-success size-3.5\" /> : <Copy className=\"size-3.5\" />}\n              <span>{copiedJson ? 'JSON Copied' : 'Copy Header JSON'}</span>\n            </Button>\n\n            <Button\n              aria-label=\"Download attachment\"\n              size=\"sm\"\n              className=\"h-8 gap-1.5 text-xs shadow-xs\"\n              disabled={downloadingJson}\n              onClick={handleDownloadJson}\n            >\n              {!downloadingJson ? (\n                <Download className=\"size-3.5\" />\n              ) : (\n                <span className=\"size-3.5 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n              )}\n              <span>Download Parquet Header JSON</span>\n            </Button>\n          </div>\n        </div>\n      </header>\n\n      <div className=\"space-y-6 p-4 sm:p-6\">\n        {/* 4 Parquet File Telemetry Cards */}\n        <ParquetFileTelemetryCards fileSize={fileSize} uncompressedSize={uncompressedSize} />\n\n        {/* Row Groups Switcher Banner */}\n        <Card className=\"border-border bg-card shadow-xs\">\n          <CardContent className=\"p-3\">\n            <div className=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                  Inspect Row Group:\n                </span>\n                <div className=\"flex flex-wrap items-center gap-1.5\">\n                  {rowGroups.map((rg) => (\n                    <button\n                      key={rg.id}\n                      type=\"button\"\n                      className={cn(\n                        'cursor-pointer rounded-lg border px-3 py-1.5 text-xs font-medium transition-colors',\n                        selectedRowGroup === rg.id\n                          ? 'bg-primary/10 text-primary border-primary/30 shadow-xs'\n                          : 'bg-muted/40 text-muted-foreground hover:bg-muted hover:text-foreground border-transparent',\n                      )}\n                      onClick={() => setSelectedRowGroup(rg.id)}\n                    >\n                      <div className=\"flex items-center gap-2\">\n                        <Layers className=\"size-3.5 opacity-70\" />\n                        <span className=\"font-mono font-semibold\">Row Group #{rg.id}</span>\n                        <span className=\"bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs tabular-nums\">\n                          {rg.numRowsFormatted}\n                        </span>\n                        <span className=\"text-muted-foreground font-mono text-xs tabular-nums\">\n                          ({rg.totalCompressedSize})\n                        </span>\n                      </div>\n                    </button>\n                  ))}\n                </div>\n              </div>\n\n              <div className=\"flex flex-wrap items-center gap-2 text-xs\">\n                <span className=\"text-muted-foreground whitespace-nowrap\">Row Group Offset:</span>\n                <Badge variant=\"outline\" className=\"min-w-0 truncate font-mono text-xs\">\n                  {activeRowGroup.fileOffset}\n                </Badge>\n                <span className=\"text-muted-foreground\">Raw Footprint:</span>\n                <span className=\"text-foreground font-mono font-medium tabular-nums\">\n                  {activeRowGroup.totalByteSize}\n                </span>\n              </div>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Main Tabs View */}\n        <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n          <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n            <TabsList className=\"grid h-9 w-full grid-cols-2 p-1 sm:w-auto md:grid-cols-4\">\n              <TabsTrigger value=\"chunks\" className=\"gap-1.5 text-xs\">\n                <Table2 className=\"size-3.5\" />\n                <span>Column Chunks</span>\n                <span className=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">\n                  {activeRowGroup.columns.length}\n                </span>\n              </TabsTrigger>\n              <TabsTrigger value=\"schema\" className=\"gap-1.5 text-xs\">\n                <FolderTree className=\"size-3.5\" />\n                <span>Schema Tree</span>\n                <span className=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">{schemaTreeNodes.length}</span>\n              </TabsTrigger>\n              <TabsTrigger value=\"dictionary\" className=\"gap-1.5 text-xs\">\n                <Binary className=\"size-3.5\" />\n                <span>Dictionary Metrics</span>\n                <span className=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">\n                  {dictionaryColumns.length}\n                </span>\n              </TabsTrigger>\n              <TabsTrigger value=\"thrift\" className=\"gap-1.5 text-xs\">\n                <Code2 className=\"size-3.5\" />\n                <span>Thrift Metadata</span>\n              </TabsTrigger>\n            </TabsList>\n\n            {/* Search & Filters when in Chunks view */}\n            {activeTab === 'chunks' && (\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <div className=\"relative w-full sm:w-56\">\n                  <Search className=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n                  <input\n                    value={searchQuery}\n                    onChange={(e) => setSearchQuery(e.target.value)}\n                    type=\"text\"\n                    placeholder=\"Search column chunks...\"\n                    className=\"border-border bg-background text-foreground focus-visible:border-ring focus-visible:ring-ring/50 h-8 w-full rounded-md border pr-2.5 pl-8 text-xs focus-visible:ring-2 focus-visible:outline-none\"\n                  />\n                </div>\n                <div className=\"bg-muted border-border flex items-center rounded-md border p-0.5 text-xs\">\n                  <button\n                    type=\"button\"\n                    className={cn(\n                      'cursor-pointer rounded px-2 py-1 transition-colors',\n                      encodingFilter === 'all'\n                        ? 'bg-background text-foreground shadow-xs'\n                        : 'text-muted-foreground hover:text-foreground',\n                    )}\n                    onClick={() => setEncodingFilter('all')}\n                  >\n                    All\n                  </button>\n                  <button\n                    type=\"button\"\n                    className={cn(\n                      'cursor-pointer rounded px-2 py-1 transition-colors',\n                      encodingFilter === 'dictionary'\n                        ? 'bg-background text-foreground shadow-xs'\n                        : 'text-muted-foreground hover:text-foreground',\n                    )}\n                    onClick={() => setEncodingFilter('dictionary')}\n                  >\n                    Dict Encoded\n                  </button>\n                  <button\n                    type=\"button\"\n                    className={cn(\n                      'cursor-pointer rounded px-2 py-1 transition-colors',\n                      encodingFilter === 'plain'\n                        ? 'bg-background text-foreground shadow-xs'\n                        : 'text-muted-foreground hover:text-foreground',\n                    )}\n                    onClick={() => setEncodingFilter('plain')}\n                  >\n                    Plain\n                  </button>\n                </div>\n              </div>\n            )}\n          </div>\n\n          {/* TAB 1: Column Chunks Breakdown Table */}\n          <ParquetChunksTab columns={filteredColumns} />\n\n          {/* TAB 2: Parquet Schema Tree */}\n          <ParquetSchemaTree nodes={schemaTreeNodes} />\n\n          {/* TAB 3: Dictionary & Compression Deep Dive */}\n          <ParquetDictionaryTab dictionaryColumns={dictionaryColumns} />\n\n          {/* TAB 4: Parquet Header JSON (Thrift) */}\n          <TabsContent value=\"thrift\" className=\"mt-4 space-y-4\">\n            <div className=\"border-border bg-muted/30 overflow-hidden rounded-lg border\">\n              <div className=\"border-border bg-card flex items-center justify-between gap-x-2 border-b px-4 py-2.5\">\n                <div className=\"flex items-center gap-2\">\n                  <Code2 className=\"text-primary size-4\" />\n                  <span className=\"text-foreground font-mono text-xs font-medium\">FileMetaData.thrift.json</span>\n                  <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                    Thrift Compact Protocol\n                  </Badge>\n                </div>\n                <Button variant=\"ghost\" size=\"sm\" className=\"h-7 gap-1 text-xs\" onClick={copyJsonToClipboard}>\n                  {copiedJson ? <Check className=\"text-success size-3\" /> : <Copy className=\"size-3\" />}\n                  <span>{copiedJson ? 'Copied' : 'Copy JSON'}</span>\n                </Button>\n              </div>\n\n              <div className=\"overflow-x-auto bg-neutral-950 p-4 font-mono text-xs leading-relaxed text-neutral-100 dark:bg-neutral-950\">\n                <pre className=\"whitespace-pre\">\n                  <code>{parquetHeaderJson}</code>\n                </pre>\n              </div>\n            </div>\n          </TabsContent>\n        </Tabs>\n      </div>\n    </div>\n  )\n}\n\nexport default ParquetMetadataInspector\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/ParquetMetadataInspector.tsx"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/ParquetFileTelemetryCards.tsx",
      "content": "import * as React from 'react'\nimport { Binary, Columns3, HardDrive, Layers } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\n\nexport interface ParquetFileTelemetryCardsProps {\n  fileSize?: string\n  uncompressedSize?: string\n}\n\nexport function ParquetFileTelemetryCards({\n  fileSize = '18.4 MB',\n  uncompressedSize = '71.4 MB',\n}: ParquetFileTelemetryCardsProps) {\n  return (\n    <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n      {/* 1. Row Groups */}\n      <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs\">\n        <CardHeader className=\"pb-2\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <div className=\"border-info/20 bg-info/10 text-info flex size-7 items-center justify-center rounded-md border\">\n                <Layers className=\"size-3.5\" />\n              </div>\n              <CardTitle className=\"text-xs font-medium\">Row Groups</CardTitle>\n            </div>\n            <Badge variant=\"outline\" className=\"font-mono text-xs tabular-nums\">\n              2 Groups\n            </Badge>\n          </div>\n        </CardHeader>\n        <CardContent className=\"space-y-2 pt-1\">\n          <div className=\"flex items-baseline gap-1.5\">\n            <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">2</span>\n            <span className=\"text-muted-foreground text-xs font-medium\">Row Groups</span>\n          </div>\n          <div className=\"border-border/60 border-t pt-2 text-xs\">\n            <div className=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Chunk Partitioning:</span>\n              <span className=\"text-foreground font-medium tabular-nums\">125,000 rows / group</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* 2. Columns / Schema */}\n      <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs\">\n        <CardHeader className=\"pb-2\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <div className=\"border-chart-1/20 bg-chart-1/10 text-chart-1 flex size-7 items-center justify-center rounded-md border\">\n                <Columns3 className=\"size-3.5\" />\n              </div>\n              <CardTitle className=\"text-xs font-medium\">Columns / Schema</CardTitle>\n            </div>\n            <Badge variant=\"outline\" className=\"font-mono text-xs tabular-nums\">\n              14 Chunks\n            </Badge>\n          </div>\n        </CardHeader>\n        <CardContent className=\"space-y-2 pt-1\">\n          <div className=\"flex items-baseline gap-1.5\">\n            <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">14</span>\n            <span className=\"text-muted-foreground text-xs font-medium\">Column Chunks</span>\n          </div>\n          <div className=\"border-border/60 border-t pt-2 text-xs\">\n            <div className=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Nested Topology:</span>\n              <span className=\"text-foreground font-medium tabular-nums\">2 Structs · 1 List</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* 3. Uncompressed Size */}\n      <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs\">\n        <CardHeader className=\"pb-2\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <div className=\"border-success/20 bg-success/10 text-success flex size-7 items-center justify-center rounded-md border\">\n                <HardDrive className=\"size-3.5\" />\n              </div>\n              <CardTitle className=\"text-xs font-medium\">Uncompressed Size</CardTitle>\n            </div>\n            <Badge\n              variant=\"secondary\"\n              className=\"border-success/30 text-success text-success font-mono text-xs tabular-nums\"\n            >\n              3.88x Savings\n            </Badge>\n          </div>\n        </CardHeader>\n        <CardContent className=\"space-y-2 pt-1\">\n          <div className=\"flex items-baseline gap-1.5\">\n            <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">\n              {uncompressedSize}\n            </span>\n            <span className=\"text-muted-foreground text-xs font-medium\">Raw</span>\n          </div>\n          <div className=\"border-border/60 border-t pt-2 text-xs\">\n            <div className=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Snappy Footprint:</span>\n              <span className=\"text-foreground font-medium tabular-nums\">{fileSize} (Saved 53.0 MB)</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* 4. Dictionary Encoding Ratio */}\n      <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs\">\n        <CardHeader className=\"pb-2\">\n          <div className=\"flex items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <div className=\"border-warning/20 bg-warning/10 text-warning flex size-7 items-center justify-center rounded-md border\">\n                <Binary className=\"size-3.5\" />\n              </div>\n              <CardTitle className=\"text-xs font-medium\">Dictionary Encoding</CardTitle>\n            </div>\n            <Badge variant=\"outline\" className=\"font-mono text-xs tabular-nums\">\n              85.7%\n            </Badge>\n          </div>\n        </CardHeader>\n        <CardContent className=\"space-y-2 pt-1\">\n          <div className=\"flex items-baseline gap-1.5\">\n            <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">12 / 14</span>\n            <span className=\"text-muted-foreground text-xs font-medium\">Columns Encoded</span>\n          </div>\n          <div className=\"border-border/60 border-t pt-2 text-xs\">\n            <div className=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Encoding Algorithms:</span>\n              <span className=\"text-foreground font-medium\">RLE + PLAIN_DICT</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/ParquetFileTelemetryCards.tsx"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/ParquetChunksTab.tsx",
      "content": "import * as React from 'react'\nimport { ArrowRight } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Card } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { TabsContent } from '@/components/ui/tabs'\nimport type { ColumnChunk } from './parquet-metadata-types'\n\nexport interface ParquetChunksTabProps {\n  columns: ColumnChunk[]\n}\n\nexport function ParquetChunksTab({ columns }: ParquetChunksTabProps) {\n  return (\n    <TabsContent value=\"chunks\" className=\"mt-4 space-y-4\">\n      <Card className=\"border-border overflow-hidden border shadow-none\">\n        <div className=\"overflow-x-auto\">\n          <Table>\n            <TableHeader>\n              <TableRow className=\"bg-muted/40 hover:bg-muted/40\">\n                <TableHead className=\"min-w-[200px] text-xs font-semibold\">Column Name & Type</TableHead>\n                <TableHead className=\"min-w-[170px] text-xs font-semibold\">Encoding & Codec</TableHead>\n                <TableHead className=\"min-w-[280px] text-xs font-semibold\">Min / Max Column Statistics</TableHead>\n                <TableHead className=\"min-w-[130px] text-xs font-semibold\">Null Values</TableHead>\n                <TableHead className=\"min-w-[190px] text-xs font-semibold\">Compressed / Raw Footprint</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {columns.map((col) => (\n                <TableRow key={col.name} className=\"text-xs\">\n                  {/* Column Name & Physical Type */}\n                  <TableCell>\n                    <div className=\"space-y-1\">\n                      <div className=\"flex items-center gap-1.5\">\n                        <span className=\"text-foreground font-mono text-xs font-semibold\">{col.name}</span>\n                        <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                          ID: {col.fieldId}\n                        </Badge>\n                      </div>\n                      <div className=\"flex flex-wrap items-center gap-1 text-xs\">\n                        <Badge variant=\"secondary\" className=\"font-mono text-xs font-normal\">\n                          {col.physicalType}\n                        </Badge>\n                        <ArrowRight className=\"text-muted-foreground size-2.5\" />\n                        <span className=\"text-muted-foreground font-mono text-xs\">{col.logicalType}</span>\n                      </div>\n                    </div>\n                  </TableCell>\n\n                  {/* Encoding & Compression */}\n                  <TableCell>\n                    <div className=\"space-y-1.5\">\n                      <div className=\"flex flex-wrap items-center gap-1\">\n                        {col.encodings.map((enc) => (\n                          <Badge\n                            key={enc}\n                            variant={enc.includes('DICTIONARY') ? 'default' : 'outline'}\n                            className=\"font-mono text-xs font-normal\"\n                          >\n                            {enc}\n                          </Badge>\n                        ))}\n                      </div>\n                      <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                        <span className=\"text-foreground font-medium\">Codec:</span>\n                        <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                          {col.compression}\n                        </Badge>\n                      </div>\n                    </div>\n                  </TableCell>\n\n                  {/* Min / Max Column Statistics */}\n                  <TableCell>\n                    <div className=\"border-border/70 bg-muted/20 space-y-1 rounded-md border p-2 font-mono text-xs\">\n                      <div className=\"flex items-baseline gap-1.5\">\n                        <span className=\"text-muted-foreground shrink-0\">Min:</span>\n                        <span className=\"text-foreground truncate font-medium\" title={col.minStat}>\n                          {col.minStat}\n                        </span>\n                      </div>\n                      <div className=\"flex items-baseline gap-1.5\">\n                        <span className=\"text-muted-foreground shrink-0\">Max:</span>\n                        <span className=\"text-foreground truncate font-medium\" title={col.maxStat}>\n                          {col.maxStat}\n                        </span>\n                      </div>\n                    </div>\n                  </TableCell>\n\n                  {/* Null Values Count */}\n                  <TableCell>\n                    <div className=\"space-y-1\">\n                      <div className=\"flex items-center gap-1.5\">\n                        <Badge\n                          variant={col.nullCount === 0 ? 'secondary' : 'outline'}\n                          className={\n                            col.nullCount === 0\n                              ? 'border-success/30 text-success font-mono text-xs'\n                              : 'font-mono text-xs'\n                          }\n                        >\n                          {col.nullCount} nulls\n                        </Badge>\n                      </div>\n                      <p className=\"text-muted-foreground font-mono text-xs tabular-nums\">\n                        {col.nullPct} of {col.numValues} rows\n                      </p>\n                    </div>\n                  </TableCell>\n\n                  {/* Compressed vs Uncompressed Footprint */}\n                  <TableCell>\n                    <div className=\"space-y-1.5\">\n                      <div className=\"flex items-center justify-between gap-x-2 font-mono text-xs\">\n                        <span className=\"text-foreground font-semibold tabular-nums\">{col.compressedBytes}</span>\n                        <span className=\"text-muted-foreground tabular-nums\">/ {col.uncompressedBytes}</span>\n                      </div>\n                      <div className=\"space-y-1\">\n                        <Progress value={col.compressionPct} className=\"h-1.5\" />\n                        <div className=\"text-muted-foreground flex items-center justify-between gap-x-2 text-xs\">\n                          <span className=\"text-success text-success font-mono font-medium tabular-nums\">\n                            {col.compressionRatio} saved\n                          </span>\n                          <span className=\"font-mono text-xs\">Offset: {col.dataPageOffset}</span>\n                        </div>\n                      </div>\n                    </div>\n                  </TableCell>\n                </TableRow>\n              ))}\n\n              {columns.length === 0 && (\n                <TableRow>\n                  <TableCell colSpan={5} className=\"text-muted-foreground py-8 text-center text-xs\">\n                    No matching column chunks found for filter criteria.\n                  </TableCell>\n                </TableRow>\n              )}\n            </TableBody>\n          </Table>\n        </div>\n      </Card>\n    </TabsContent>\n  )\n}\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/ParquetChunksTab.tsx"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/ParquetSchemaTree.tsx",
      "content": "'use client'\n\nimport { ArrowRight, FolderTree } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { TabsContent } from '@/components/ui/tabs'\nimport { cn } from '@/lib/utils'\nimport { type SchemaTreeNode } from './parquet-schema'\n\nexport function ParquetSchemaTree({ nodes }: { nodes: SchemaTreeNode[] }) {\n  return (\n    <>\n      {/* TAB 2: Parquet File Schema Tree Visualizer */}\n      <TabsContent value=\"schema\" className=\"mt-4 space-y-4\">\n        <Card className=\"border-border shadow-none\">\n          <CardHeader className=\"border-border border-b pb-3\">\n            <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n              <div>\n                <CardTitle className=\"text-sm font-semibold\">Parquet Schema Definition & Field Hierarchy</CardTitle>\n                <CardDescription className=\"text-xs\">\n                  Hierarchical view of logical schema nodes, repetition rules (REQUIRED, OPTIONAL, REPEATED), and\n                  maximum definition / repetition levels for column projection.\n                </CardDescription>\n              </div>\n              <div className=\"flex flex-wrap items-center gap-1.5\">\n                <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                  D: Def Level\n                </Badge>\n                <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                  R: Rep Level\n                </Badge>\n              </div>\n            </div>\n          </CardHeader>\n          <CardContent className=\"p-0\">\n            <div className=\"divide-border divide-y\">\n              {/* Root node */}\n              <div className=\"bg-muted/40 flex items-center justify-between gap-x-2 px-4 py-2.5 font-mono text-xs\">\n                <div className=\"flex items-center gap-2\">\n                  <FolderTree className=\"text-primary size-4\" />\n                  <span className=\"text-foreground font-bold\">message schema</span>\n                  <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                    Root Message\n                  </Badge>\n                </div>\n                <span className=\"text-muted-foreground font-mono text-xs\">14 column fields</span>\n              </div>\n\n              {/* Hierarchical Tree Rows */}\n              {nodes.map((node) => (\n                <div\n                  key={node.id}\n                  className=\"hover:bg-muted/30 flex flex-col justify-between gap-2 px-4 py-3 text-xs transition-colors md:flex-row md:items-center\"\n                  style={{ paddingLeft: `${Math.max(1, node.depth * 1.5 + 1)}rem` }}\n                >\n                  <div className=\"flex min-w-0 items-center gap-2\">\n                    <span className=\"text-muted-foreground font-mono select-none\">\n                      {node.depth === 0 ? '├─' : '└─'}\n                    </span>\n                    <span\n                      className={cn(\n                        'truncate font-mono font-medium',\n                        node.isGroup ? 'text-primary font-bold' : 'text-foreground',\n                      )}\n                    >\n                      {node.name}\n                    </span>\n                    <Badge\n                      variant={\n                        node.repetition === 'REQUIRED'\n                          ? 'default'\n                          : node.repetition === 'REPEATED'\n                            ? 'secondary'\n                            : 'outline'\n                      }\n                      className=\"font-mono text-xs font-normal\"\n                    >\n                      {node.repetition}\n                    </Badge>\n                    <Badge variant=\"secondary\" className=\"font-mono text-xs font-normal\">\n                      {node.physicalType}\n                    </Badge>\n                    <ArrowRight className=\"text-muted-foreground size-3 shrink-0\" />\n                    <Badge variant=\"outline\" className=\"text-muted-foreground font-mono text-xs font-normal\">\n                      {node.logicalType}\n                    </Badge>\n                  </div>\n\n                  <div className=\"flex shrink-0 flex-wrap items-center gap-2\">\n                    <span\n                      className=\"text-muted-foreground hidden max-w-[220px] truncate text-xs lg:inline-block\"\n                      title={node.description}\n                    >\n                      {node.description}\n                    </span>\n                    <div className=\"bg-muted/60 border-border flex items-center gap-2 rounded border px-2 py-0.5 font-mono text-xs\">\n                      <span title=\"Max Definition Level\">\n                        max_def: <strong className=\"text-foreground font-bold tabular-nums\">{node.defLevel}</strong>\n                      </span>\n                      <span className=\"text-muted-foreground\">|</span>\n                      <span title=\"Max Repetition Level\">\n                        max_rep: <strong className=\"text-foreground font-bold tabular-nums\">{node.repLevel}</strong>\n                      </span>\n                    </div>\n                    <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                      ID: {node.id}\n                    </Badge>\n                  </div>\n                </div>\n              ))}\n            </div>\n          </CardContent>\n        </Card>\n      </TabsContent>\n    </>\n  )\n}\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/ParquetSchemaTree.tsx"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/ParquetDictionaryTab.tsx",
      "content": "import * as React from 'react'\nimport { Badge } from '@/components/ui/badge'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { TabsContent } from '@/components/ui/tabs'\nimport type { ColumnChunk } from './parquet-metadata-types'\n\nexport interface ParquetDictionaryTabProps {\n  dictionaryColumns: ColumnChunk[]\n}\n\nexport function ParquetDictionaryTab({ dictionaryColumns }: ParquetDictionaryTabProps) {\n  return (\n    <TabsContent value=\"dictionary\" className=\"mt-4 space-y-4\">\n      <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n        {/* Summary card */}\n        <Card className=\"border-border shadow-none lg:col-span-1\">\n          <CardHeader className=\"pb-3\">\n            <CardTitle className=\"text-sm font-semibold\">Dictionary Optimization Impact</CardTitle>\n            <CardDescription className=\"text-xs\">\n              Plain dictionary replaces repeated byte strings and integers with compact 3-bit to 16-bit dictionary index\n              pointers.\n            </CardDescription>\n          </CardHeader>\n          <CardContent className=\"space-y-4 text-xs\">\n            <div className=\"border-border bg-muted/20 space-y-2 rounded-lg border p-3\">\n              <div className=\"flex items-center justify-between gap-x-2\">\n                <span className=\"text-muted-foreground\">Dictionary Enabled Columns:</span>\n                <span className=\"text-foreground font-mono font-semibold\">6 / 8 Monitored</span>\n              </div>\n              <div className=\"flex items-center justify-between gap-x-2\">\n                <span className=\"text-muted-foreground\">Avg Space Reduction:</span>\n                <span className=\"text-success text-success font-mono font-semibold tabular-nums\">78.4%</span>\n              </div>\n              <div className=\"flex items-center justify-between gap-x-2\">\n                <span className=\"text-muted-foreground\">Dictionary Page Overhead:</span>\n                <span className=\"text-foreground font-mono font-semibold tabular-nums\">0.34 MB total</span>\n              </div>\n              <div className=\"flex items-center justify-between gap-x-2\">\n                <span className=\"text-muted-foreground\">RLE Run Length Efficiency:</span>\n                <span className=\"text-foreground font-mono font-semibold\">Optimal</span>\n              </div>\n            </div>\n\n            <div className=\"space-y-2\">\n              <span className=\"text-muted-foreground font-medium\">Compression Distribution by Codec:</span>\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between gap-x-2 font-mono\">\n                  <span>Snappy + RLE Dict</span>\n                  <span className=\"font-semibold tabular-nums\">74.2%</span>\n                </div>\n                <Progress value={74.2} className=\"h-1.5\" />\n              </div>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Dictionary Table */}\n        <Card className=\"border-border overflow-hidden shadow-none lg:col-span-2\">\n          <div className=\"overflow-x-auto\">\n            <Table>\n              <TableHeader>\n                <TableRow className=\"bg-muted/40 hover:bg-muted/40\">\n                  <TableHead className=\"text-xs font-semibold\">Column</TableHead>\n                  <TableHead className=\"text-xs font-semibold\">Distinct Entries</TableHead>\n                  <TableHead className=\"text-xs font-semibold\">Bit Width</TableHead>\n                  <TableHead className=\"text-xs font-semibold\">Dict Page Offset</TableHead>\n                  <TableHead className=\"text-xs font-semibold\">Space Savings</TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody>\n                {dictionaryColumns.map((col) => (\n                  <TableRow key={col.name} className=\"text-xs\">\n                    <TableCell className=\"text-foreground font-mono font-medium\">{col.name}</TableCell>\n                    <TableCell className=\"font-mono tabular-nums\">\n                      <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                        {col.dictEntries?.toLocaleString()} values\n                      </Badge>\n                    </TableCell>\n                    <TableCell className=\"font-mono tabular-nums\"> {col.bitWidth} bits / row </TableCell>\n                    <TableCell className=\"text-muted-foreground font-mono text-xs\">{col.dictPageOffset}</TableCell>\n                    <TableCell>\n                      <div className=\"flex items-center gap-2\">\n                        <span className=\"text-success text-success font-mono font-semibold tabular-nums\">\n                          {col.compressionRatio}\n                        </span>\n                        <span className=\"text-muted-foreground font-mono text-xs\">({col.compressedBytes})</span>\n                      </div>\n                    </TableCell>\n                  </TableRow>\n                ))}\n              </TableBody>\n            </Table>\n          </div>\n        </Card>\n      </div>\n    </TabsContent>\n  )\n}\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/ParquetDictionaryTab.tsx"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/parquet-metadata-data.ts",
      "content": "import type { RowGroupMeta } from './parquet-metadata-types'\n\nexport const parquetHeaderJson = `{\n  \"version\": 2,\n  \"created_by\": \"parquet-mr version 1.13.1 (build e29fa2b)\",\n  \"num_rows\": 250000,\n  \"num_row_groups\": 2,\n  \"file_size_bytes\": 19293798,\n  \"uncompressed_bytes\": 74868326,\n  \"compression_codec\": \"SNAPPY\",\n  \"encryption_algorithm\": null,\n  \"schema\": [\n    { \"name\": \"schema\", \"num_children\": 10 },\n    { \"name\": \"order_id\", \"type\": \"FIXED_LEN_BYTE_ARRAY\", \"type_length\": 16, \"repetition_type\": \"REQUIRED\", \"field_id\": 1, \"converted_type\": \"UUID\" },\n    { \"name\": \"customer_id\", \"type\": \"INT64\", \"repetition_type\": \"REQUIRED\", \"field_id\": 2, \"converted_type\": \"INT_64\" },\n    { \"name\": \"order_status\", \"type\": \"BYTE_ARRAY\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 3, \"converted_type\": \"UTF8\" },\n    { \"name\": \"gross_amount\", \"type\": \"FIXED_LEN_BYTE_ARRAY\", \"type_length\": 9, \"repetition_type\": \"REQUIRED\", \"field_id\": 4, \"converted_type\": \"DECIMAL\", \"scale\": 2, \"precision\": 18 },\n    { \"name\": \"created_at\", \"type\": \"INT64\", \"repetition_type\": \"REQUIRED\", \"field_id\": 5, \"converted_type\": \"TIMESTAMP_MICROS\" },\n    { \"name\": \"customer_metadata\", \"num_children\": 2, \"repetition_type\": \"OPTIONAL\", \"field_id\": 6 },\n    { \"name\": \"loyalty_tier\", \"type\": \"BYTE_ARRAY\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 7, \"converted_type\": \"UTF8\" },\n    { \"name\": \"lifetime_orders\", \"type\": \"INT32\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 8, \"converted_type\": \"INT_32\" },\n    { \"name\": \"line_items\", \"num_children\": 1, \"repetition_type\": \"OPTIONAL\", \"field_id\": 9, \"converted_type\": \"LIST\" },\n    { \"name\": \"list\", \"num_children\": 1, \"repetition_type\": \"REPEATED\" },\n    { \"name\": \"element\", \"num_children\": 2, \"repetition_type\": \"REQUIRED\" },\n    { \"name\": \"sku\", \"type\": \"BYTE_ARRAY\", \"repetition_type\": \"REQUIRED\", \"field_id\": 12, \"converted_type\": \"UTF8\" },\n    { \"name\": \"quantity\", \"type\": \"INT32\", \"repetition_type\": \"REQUIRED\", \"field_id\": 13, \"converted_type\": \"INT_32\" },\n    { \"name\": \"shipping_country\", \"type\": \"BYTE_ARRAY\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 14, \"converted_type\": \"UTF8\" },\n    { \"name\": \"discount_rate\", \"type\": \"FLOAT\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 15 },\n    { \"name\": \"fulfillment_node\", \"type\": \"BYTE_ARRAY\", \"repetition_type\": \"OPTIONAL\", \"field_id\": 16, \"converted_type\": \"UTF8\" }\n  ],\n  \"row_groups\": [\n    {\n      \"ordinal\": 0,\n      \"num_rows\": 125000,\n      \"total_byte_size\": 37434163,\n      \"total_compressed_size\": 9646899,\n      \"file_offset\": 4,\n      \"columns_count\": 14\n    },\n    {\n      \"ordinal\": 1,\n      \"num_rows\": 125000,\n      \"total_byte_size\": 37434163,\n      \"total_compressed_size\": 9646899,\n      \"file_offset\": 9646903,\n      \"columns_count\": 14\n    }\n  ],\n  \"key_value_metadata\": [\n    { \"key\": \"org.apache.spark.sql.parquet.row.metadata\", \"value\": \"{\\\\\"type\\\\\":\\\\\"struct\\\\\",\\\\\"fields\\\\\":[...]}\" },\n    { \"key\": \"writer.model.name\", \"value\": \"lakehouse-batch-pipeline-gold-orders\" },\n    { \"key\": \"parquet.version\", \"value\": \"2.10.0\" }\n  ]\n}`\n\nexport const defaultRowGroupsData: RowGroupMeta[] = [\n  {\n    id: 0,\n    numRows: 125000,\n    numRowsFormatted: '125,000 rows',\n    totalByteSize: '35.7 MB',\n    totalCompressedSize: '9.2 MB',\n    compressionRatio: '74.2%',\n    fileOffset: '0x00000004',\n    columns: [\n      {\n        name: 'order_id',\n        physicalType: 'FIXED_LEN_BYTE_ARRAY(16)',\n        logicalType: 'UUID',\n        fieldId: 1,\n        encodings: ['PLAIN', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '001a4e21-9a7c-4821-bc10-1a29f8c00192',\n        maxStat: 'ffe918b2-3c11-4fa0-8914-df7201bca908',\n        uncompressedBytes: '4.8 MB',\n        compressedBytes: '1.2 MB',\n        compressionRatio: '75.0%',\n        compressionPct: 75,\n        isDictionaryEncoded: false,\n        dictEntries: null,\n        dictPageOffset: null,\n        dataPageOffset: '0x00000020',\n        bitWidth: null,\n      },\n      {\n        name: 'customer_id',\n        physicalType: 'INT64',\n        logicalType: 'INTEGER(64, true)',\n        fieldId: 2,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '10,001',\n        maxStat: '994,210',\n        uncompressedBytes: '3.2 MB',\n        compressedBytes: '0.9 MB',\n        compressionRatio: '71.9%',\n        compressionPct: 71.9,\n        isDictionaryEncoded: true,\n        dictEntries: 54200,\n        dictPageOffset: '0x00125000',\n        dataPageOffset: '0x00140200',\n        bitWidth: 16,\n      },\n      {\n        name: 'order_status',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 3,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: \"'cancelled'\",\n        maxStat: \"'shipped'\",\n        uncompressedBytes: '1.8 MB',\n        compressedBytes: '0.2 MB',\n        compressionRatio: '88.9%',\n        compressionPct: 88.9,\n        isDictionaryEncoded: true,\n        dictEntries: 5,\n        dictPageOffset: '0x0021a400',\n        dataPageOffset: '0x0021a480',\n        bitWidth: 3,\n      },\n      {\n        name: 'gross_amount',\n        physicalType: 'FIXED_LEN_BYTE_ARRAY(9)',\n        logicalType: 'DECIMAL(18, 2)',\n        fieldId: 4,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '$4.50',\n        maxStat: '$14,820.00',\n        uncompressedBytes: '3.4 MB',\n        compressedBytes: '0.8 MB',\n        compressionRatio: '76.5%',\n        compressionPct: 76.5,\n        isDictionaryEncoded: true,\n        dictEntries: 28450,\n        dictPageOffset: '0x0023a100',\n        dataPageOffset: '0x0026e000',\n        bitWidth: 15,\n      },\n      {\n        name: 'created_at',\n        physicalType: 'INT64',\n        logicalType: 'TIMESTAMP(MICROS, UTC)',\n        fieldId: 5,\n        encodings: ['DELTA_BINARY_PACKED', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '2026-07-01 00:00:00.124000',\n        maxStat: '2026-07-26 23:59:58.910000',\n        uncompressedBytes: '3.1 MB',\n        compressedBytes: '0.7 MB',\n        compressionRatio: '77.4%',\n        compressionPct: 77.4,\n        isDictionaryEncoded: false,\n        dictEntries: null,\n        dictPageOffset: null,\n        dataPageOffset: '0x002e1000',\n        bitWidth: null,\n      },\n      {\n        name: 'shipping_country',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 6,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 24,\n        nullPct: '0.02%',\n        minStat: \"'AE'\",\n        maxStat: \"'US'\",\n        uncompressedBytes: '1.6 MB',\n        compressedBytes: '0.3 MB',\n        compressionRatio: '81.2%',\n        compressionPct: 81.2,\n        isDictionaryEncoded: true,\n        dictEntries: 48,\n        dictPageOffset: '0x0034a000',\n        dataPageOffset: '0x0034a240',\n        bitWidth: 6,\n      },\n      {\n        name: 'discount_rate',\n        physicalType: 'FLOAT',\n        logicalType: 'FLOAT(32)',\n        fieldId: 7,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '0.00',\n        maxStat: '0.35',\n        uncompressedBytes: '1.5 MB',\n        compressedBytes: '0.4 MB',\n        compressionRatio: '73.3%',\n        compressionPct: 73.3,\n        isDictionaryEncoded: true,\n        dictEntries: 12,\n        dictPageOffset: '0x00390100',\n        dataPageOffset: '0x00390180',\n        bitWidth: 4,\n      },\n      {\n        name: 'fulfillment_node',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 8,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 82,\n        nullPct: '0.07%',\n        minStat: \"'wh-ap-east-1'\",\n        maxStat: \"'wh-us-west-2'\",\n        uncompressedBytes: '1.7 MB',\n        compressedBytes: '0.3 MB',\n        compressionRatio: '82.4%',\n        compressionPct: 82.4,\n        isDictionaryEncoded: true,\n        dictEntries: 16,\n        dictPageOffset: '0x003e4000',\n        dataPageOffset: '0x003e4120',\n        bitWidth: 4,\n      },\n    ],\n  },\n  {\n    id: 1,\n    numRows: 125000,\n    numRowsFormatted: '125,000 rows',\n    totalByteSize: '35.7 MB',\n    totalCompressedSize: '9.2 MB',\n    compressionRatio: '74.2%',\n    fileOffset: '0x00933250',\n    columns: [\n      {\n        name: 'order_id',\n        physicalType: 'FIXED_LEN_BYTE_ARRAY(16)',\n        logicalType: 'UUID',\n        fieldId: 1,\n        encodings: ['PLAIN', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '00021c90-410a-49bf-a870-19efbc441200',\n        maxStat: 'fff8a910-1840-4221-a109-ccb001928371',\n        uncompressedBytes: '4.8 MB',\n        compressedBytes: '1.2 MB',\n        compressionRatio: '75.0%',\n        compressionPct: 75,\n        isDictionaryEncoded: false,\n        dictEntries: null,\n        dictPageOffset: null,\n        dataPageOffset: '0x00933270',\n        bitWidth: null,\n      },\n      {\n        name: 'customer_id',\n        physicalType: 'INT64',\n        logicalType: 'INTEGER(64, true)',\n        fieldId: 2,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '10,042',\n        maxStat: '995,800',\n        uncompressedBytes: '3.2 MB',\n        compressedBytes: '0.9 MB',\n        compressionRatio: '71.9%',\n        compressionPct: 71.9,\n        isDictionaryEncoded: true,\n        dictEntries: 53900,\n        dictPageOffset: '0x00a58000',\n        dataPageOffset: '0x00a73000',\n        bitWidth: 16,\n      },\n      {\n        name: 'order_status',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 3,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: \"'cancelled'\",\n        maxStat: \"'shipped'\",\n        uncompressedBytes: '1.8 MB',\n        compressedBytes: '0.2 MB',\n        compressionRatio: '88.9%',\n        compressionPct: 88.9,\n        isDictionaryEncoded: true,\n        dictEntries: 5,\n        dictPageOffset: '0x00b41000',\n        dataPageOffset: '0x00b41080',\n        bitWidth: 3,\n      },\n      {\n        name: 'gross_amount',\n        physicalType: 'FIXED_LEN_BYTE_ARRAY(9)',\n        logicalType: 'DECIMAL(18, 2)',\n        fieldId: 4,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '$3.90',\n        maxStat: '$16,240.00',\n        uncompressedBytes: '3.4 MB',\n        compressedBytes: '0.8 MB',\n        compressionRatio: '76.5%',\n        compressionPct: 76.5,\n        isDictionaryEncoded: true,\n        dictEntries: 28120,\n        dictPageOffset: '0x00b65000',\n        dataPageOffset: '0x00b99000',\n        bitWidth: 15,\n      },\n      {\n        name: 'created_at',\n        physicalType: 'INT64',\n        logicalType: 'TIMESTAMP(MICROS, UTC)',\n        fieldId: 5,\n        encodings: ['DELTA_BINARY_PACKED', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '2026-07-27 00:00:01.002000',\n        maxStat: '2026-08-21 14:28:00.000000',\n        uncompressedBytes: '3.1 MB',\n        compressedBytes: '0.7 MB',\n        compressionRatio: '77.4%',\n        compressionPct: 77.4,\n        isDictionaryEncoded: false,\n        dictEntries: null,\n        dictPageOffset: null,\n        dataPageOffset: '0x00c12000',\n        bitWidth: null,\n      },\n      {\n        name: 'shipping_country',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 6,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 18,\n        nullPct: '0.01%',\n        minStat: \"'AE'\",\n        maxStat: \"'US'\",\n        uncompressedBytes: '1.6 MB',\n        compressedBytes: '0.3 MB',\n        compressionRatio: '81.2%',\n        compressionPct: 81.2,\n        isDictionaryEncoded: true,\n        dictEntries: 48,\n        dictPageOffset: '0x00c7b000',\n        dataPageOffset: '0x00c7b240',\n        bitWidth: 6,\n      },\n      {\n        name: 'discount_rate',\n        physicalType: 'FLOAT',\n        logicalType: 'FLOAT(32)',\n        fieldId: 7,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 0,\n        nullPct: '0.0%',\n        minStat: '0.00',\n        maxStat: '0.35',\n        uncompressedBytes: '1.5 MB',\n        compressedBytes: '0.4 MB',\n        compressionRatio: '73.3%',\n        compressionPct: 73.3,\n        isDictionaryEncoded: true,\n        dictEntries: 12,\n        dictPageOffset: '0x00cc1000',\n        dataPageOffset: '0x00cc1080',\n        bitWidth: 4,\n      },\n      {\n        name: 'fulfillment_node',\n        physicalType: 'BYTE_ARRAY',\n        logicalType: 'STRING (UTF8)',\n        fieldId: 8,\n        encodings: ['PLAIN_DICTIONARY', 'RLE'],\n        compression: 'Snappy',\n        numValues: '125,000',\n        nullCount: 64,\n        nullPct: '0.05%',\n        minStat: \"'wh-ap-east-1'\",\n        maxStat: \"'wh-us-west-2'\",\n        uncompressedBytes: '1.7 MB',\n        compressedBytes: '0.3 MB',\n        compressionRatio: '82.4%',\n        compressionPct: 82.4,\n        isDictionaryEncoded: true,\n        dictEntries: 16,\n        dictPageOffset: '0x00d15000',\n        dataPageOffset: '0x00d15120',\n        bitWidth: 4,\n      },\n    ],\n  },\n]\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/parquet-metadata-data.ts"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/parquet-metadata-types.ts",
      "content": "export interface ColumnChunk {\n  name: string\n  physicalType: string\n  logicalType: string\n  fieldId: number\n  encodings: string[]\n  compression: string\n  numValues: string\n  nullCount: number\n  nullPct: string\n  minStat: string\n  maxStat: string\n  uncompressedBytes: string\n  compressedBytes: string\n  compressionRatio: string\n  compressionPct: number\n  isDictionaryEncoded: boolean\n  dictEntries: number | null\n  dictPageOffset: string | null\n  dataPageOffset: string\n  bitWidth: number | null\n}\n\nexport interface RowGroupMeta {\n  id: number\n  numRows: number\n  numRowsFormatted: string\n  totalByteSize: string\n  totalCompressedSize: string\n  compressionRatio: string\n  fileOffset: string\n  columns: ColumnChunk[]\n}\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/parquet-metadata-types.ts"
    },
    {
      "path": "packages/registry-react/blocks/parquet-metadata-inspector/parquet-schema.ts",
      "content": "export interface SchemaTreeNode {\n  id: number\n  path: string\n  name: string\n  repetition: 'REQUIRED' | 'OPTIONAL' | 'REPEATED'\n  physicalType: string\n  logicalType: string\n  defLevel: number\n  repLevel: number\n  depth: number\n  isGroup?: boolean\n  description: string\n}\n\nexport const schemaTreeNodes: SchemaTreeNode[] = [\n  {\n    id: 1,\n    path: 'schema.order_id',\n    name: 'order_id',\n    repetition: 'REQUIRED',\n    physicalType: 'FIXED_LEN_BYTE_ARRAY(16)',\n    logicalType: 'UUID',\n    defLevel: 0,\n    repLevel: 0,\n    depth: 0,\n    description: 'Unique RFC 4122 order identifier binary token.',\n  },\n  {\n    id: 2,\n    path: 'schema.customer_id',\n    name: 'customer_id',\n    repetition: 'REQUIRED',\n    physicalType: 'INT64',\n    logicalType: 'INTEGER(64, true)',\n    defLevel: 0,\n    repLevel: 0,\n    depth: 0,\n    description: 'Foreign purchaser identity key.',\n  },\n  {\n    id: 3,\n    path: 'schema.order_status',\n    name: 'order_status',\n    repetition: 'OPTIONAL',\n    physicalType: 'BYTE_ARRAY',\n    logicalType: 'STRING (UTF8)',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    description: 'Lifecycle transition stage enumerated string.',\n  },\n  {\n    id: 4,\n    path: 'schema.gross_amount',\n    name: 'gross_amount',\n    repetition: 'REQUIRED',\n    physicalType: 'FIXED_LEN_BYTE_ARRAY(9)',\n    logicalType: 'DECIMAL(18, 2)',\n    defLevel: 0,\n    repLevel: 0,\n    depth: 0,\n    description: 'High-precision billing total charge with 2 scale points.',\n  },\n  {\n    id: 5,\n    path: 'schema.created_at',\n    name: 'created_at',\n    repetition: 'REQUIRED',\n    physicalType: 'INT64',\n    logicalType: 'TIMESTAMP(MICROS, UTC)',\n    defLevel: 0,\n    repLevel: 0,\n    depth: 0,\n    description: 'UTC microsecond epoch transaction timestamp.',\n  },\n  {\n    id: 6,\n    path: 'schema.customer_metadata',\n    name: 'customer_metadata',\n    repetition: 'OPTIONAL',\n    physicalType: 'GROUP',\n    logicalType: 'STRUCT',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    isGroup: true,\n    description: 'Nested profile attributes struct.',\n  },\n  {\n    id: 7,\n    path: 'schema.customer_metadata.loyalty_tier',\n    name: 'loyalty_tier',\n    repetition: 'OPTIONAL',\n    physicalType: 'BYTE_ARRAY',\n    logicalType: 'STRING (UTF8)',\n    defLevel: 2,\n    repLevel: 0,\n    depth: 1,\n    description: 'Customer loyalty tier status membership level.',\n  },\n  {\n    id: 8,\n    path: 'schema.customer_metadata.lifetime_orders',\n    name: 'lifetime_orders',\n    repetition: 'OPTIONAL',\n    physicalType: 'INT32',\n    logicalType: 'INTEGER(32, true)',\n    defLevel: 2,\n    repLevel: 0,\n    depth: 1,\n    description: 'Cumulative prior purchases count.',\n  },\n  {\n    id: 9,\n    path: 'schema.line_items',\n    name: 'line_items',\n    repetition: 'OPTIONAL',\n    physicalType: 'GROUP',\n    logicalType: 'LIST',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    isGroup: true,\n    description: '3-level Parquet Standard list layout.',\n  },\n  {\n    id: 10,\n    path: 'schema.line_items.list',\n    name: 'list',\n    repetition: 'REPEATED',\n    physicalType: 'GROUP',\n    logicalType: 'BAG',\n    defLevel: 2,\n    repLevel: 1,\n    depth: 1,\n    isGroup: true,\n    description: 'Repeated list item wrapper group.',\n  },\n  {\n    id: 11,\n    path: 'schema.line_items.list.element',\n    name: 'element',\n    repetition: 'REQUIRED',\n    physicalType: 'GROUP',\n    logicalType: 'STRUCT',\n    defLevel: 2,\n    repLevel: 1,\n    depth: 2,\n    isGroup: true,\n    description: 'Item tuple struct.',\n  },\n  {\n    id: 12,\n    path: 'schema.line_items.list.element.sku',\n    name: 'sku',\n    repetition: 'REQUIRED',\n    physicalType: 'BYTE_ARRAY',\n    logicalType: 'STRING (UTF8)',\n    defLevel: 2,\n    repLevel: 1,\n    depth: 3,\n    description: 'Stock keeping unit barcode tag.',\n  },\n  {\n    id: 13,\n    path: 'schema.line_items.list.element.quantity',\n    name: 'quantity',\n    repetition: 'REQUIRED',\n    physicalType: 'INT32',\n    logicalType: 'INTEGER(32, true)',\n    defLevel: 2,\n    repLevel: 1,\n    depth: 3,\n    description: 'Purchased quantity count.',\n  },\n  {\n    id: 14,\n    path: 'schema.shipping_country',\n    name: 'shipping_country',\n    repetition: 'OPTIONAL',\n    physicalType: 'BYTE_ARRAY',\n    logicalType: 'STRING (UTF8)',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    description: 'ISO-3166-1 alpha-2 destination country.',\n  },\n  {\n    id: 15,\n    path: 'schema.discount_rate',\n    name: 'discount_rate',\n    repetition: 'OPTIONAL',\n    physicalType: 'FLOAT',\n    logicalType: 'FLOAT(32)',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    description: 'Promotional discount multiplier applied.',\n  },\n  {\n    id: 16,\n    path: 'schema.fulfillment_node',\n    name: 'fulfillment_node',\n    repetition: 'OPTIONAL',\n    physicalType: 'BYTE_ARRAY',\n    logicalType: 'STRING (UTF8)',\n    defLevel: 1,\n    repLevel: 0,\n    depth: 0,\n    description: 'Assigned logistics warehouse cluster.',\n  },\n]\n",
      "type": "registry:page",
      "target": "~/components/blocks/parquet-metadata-inspector/parquet-schema.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/table.json",
    "https://uipkge.dev/r/react/tabs.json"
  ],
  "description": "Apache Parquet file format deep-dive inspector with telemetry overview, row groups switcher, column chunk statistics, dictionary encoding metrics, and hierarchical schema tree with repetition and definition levels.",
  "categories": [
    "devops",
    "app"
  ]
}