{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "synthetic-data-generator",
  "title": "Synthetic Data Generator",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/synthetic-data-generator/SyntheticDataGenerator.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Check,\n  Code2,\n  Cpu,\n  Database,\n  Download,\n  FileSpreadsheet,\n  Info,\n  Layers,\n  Lock,\n  Plus,\n  RefreshCw,\n  ShieldCheck,\n  Sliders,\n  Sparkles,\n  Trash2,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Separator } from '@/components/ui/separator'\nimport { Slider } from '@/components/ui/slider'\nimport { Switch } from '@/components/ui/switch'\nimport type {\n  FieldDataType,\n  FidelityMetrics,\n  GeneratedRecord,\n  SchemaField,\n  SyntheticDataGeneratorProps,\n  TemplatePreset,\n} from './synthetic-data-types'\nimport {\n  boxMullerRandom as boxMullerRandomHelper,\n  CARD_BRANDS,\n  FIRST_NAMES,\n  LAST_NAMES,\n  TEMPLATES,\n} from './synthetic-data-templates'\nimport { SyntheticDataPreview } from './SyntheticDataPreview'\n\nexport type {\n  FieldDataType,\n  FidelityMetrics,\n  GeneratedRecord,\n  SchemaField,\n  SyntheticDataGeneratorProps,\n  TemplatePreset,\n}\n\nexport function SyntheticDataGenerator({\n  className,\n  initialTemplate = 'customer-transactions',\n  initialRowCount = 1000,\n  initialEpsilon = 1.2,\n}: SyntheticDataGeneratorProps) {\n  // --- STATE ---\n  const [selectedTemplateKey, setSelectedTemplateKey] = React.useState<string>(initialTemplate)\n  const [outputFormat, setOutputFormat] = React.useState<'csv' | 'jsonl'>('csv')\n  const [rowCount, setRowCount] = React.useState<number>(initialRowCount)\n  const [epsilon, setEpsilon] = React.useState<number>(initialEpsilon)\n  const [kAnonymity, setKAnonymity] = React.useState<boolean>(true)\n  const [saltedHash, setSaltedHash] = React.useState<boolean>(true)\n  const [noiseMechanism, setNoiseMechanism] = React.useState<boolean>(true)\n\n  const [activeFields, setActiveFields] = React.useState<SchemaField[]>(() => {\n    return TEMPLATES[initialTemplate]?.fields ? JSON.parse(JSON.stringify(TEMPLATES[initialTemplate].fields)) : []\n  })\n\n  const [isGenerating, setIsGenerating] = React.useState<boolean>(false)\n  const [copied, setCopied] = React.useState<boolean>(false)\n  const [downloadToast, setDownloadToast] = React.useState<string | null>(null)\n  const [previewTab, setPreviewTab] = React.useState<'table' | 'json' | 'metrics'>('table')\n  const [generationSeed, setGenerationSeed] = React.useState<number>(48291)\n\n  // Field addition state\n  const [showAddField, setShowAddField] = React.useState<boolean>(false)\n  const [newFieldName, setNewFieldName] = React.useState<string>('')\n  const [newFieldType, setNewFieldType] = React.useState<FieldDataType>('gaussian_float')\n\n  // Handle template selection switch\n  const handleTemplateChange = (key: string) => {\n    setSelectedTemplateKey(key)\n    const tpl = TEMPLATES[key]\n    if (tpl) {\n      setActiveFields(JSON.parse(JSON.stringify(tpl.fields)))\n      triggerRegeneration()\n    }\n  }\n\n  // Generation trigger\n  const triggerRegeneration = () => {\n    setIsGenerating(true)\n    setGenerationSeed(Math.floor(Math.random() * 90000) + 10000)\n    setTimeout(() => {\n      setIsGenerating(false)\n    }, 450)\n  }\n\n  // Box-Muller Gaussian random generator with differential privacy noise\n  const boxMullerRandom = (mean: number, stdDev: number, seedOffset: number): number => {\n    return boxMullerRandomHelper(mean, stdDev, seedOffset, generationSeed, noiseMechanism, epsilon)\n  }\n\n  // Dynamic preview records computation\n  const previewRecords = React.useMemo<GeneratedRecord[]>(() => {\n    const rows: GeneratedRecord[] = []\n    const count = 6\n\n    for (let i = 0; i < count; i++) {\n      const fn = FIRST_NAMES[(i * 3 + generationSeed) % FIRST_NAMES.length]\n      const ln = LAST_NAMES[(i * 5 + generationSeed + 2) % LAST_NAMES.length]\n      const fullName = `${fn} ${ln}`\n      const baseSlug = `${fn.charAt(0).toLowerCase()}.${ln.toLowerCase().replace(/[^a-z]/g, '')}`\n\n      const record: GeneratedRecord = {\n        id: saltedHash\n          ? `syn_${((generationSeed * 9301 + i * 49297) % 233280).toString(16).padStart(6, '0')}`\n          : `usr_${1000 + i}`,\n      }\n\n      for (const field of activeFields) {\n        if (field.name.includes('id') || field.name.includes('uuid') || field.name.includes('token')) {\n          record[field.name] = record.id\n          continue\n        }\n\n        switch (field.type) {\n          case 'name':\n            record[field.name] = fullName\n            break\n\n          case 'email': {\n            const dom = field.params.domain || 'synthetic-vault.io'\n            record[field.name] = `${baseSlug}@${dom}`\n            break\n          }\n\n          case 'credit_card': {\n            const last4 = (((generationSeed * 7 + i * 1337 + 1000) % 9000) + 1000).toString()\n            const brand = CARD_BRANDS[i % CARD_BRANDS.length]\n            record[field.name] = `${brand} •••• ${last4}`\n            break\n          }\n\n          case 'gaussian_float': {\n            const m = field.params.mean ?? 100\n            const s = field.params.stdDev ?? 20\n            const rawVal = boxMullerRandom(m, s, i)\n            const val = Math.max(m * 0.1, rawVal)\n\n            if (field.params.currency) {\n              record[field.name] = `${field.params.currency}${val.toFixed(2)}`\n            } else if (field.params.unit) {\n              record[field.name] = `${val.toFixed(1)} ${field.params.unit}`\n            } else {\n              record[field.name] = parseFloat(val.toFixed(2))\n            }\n            break\n          }\n\n          case 'category_weights': {\n            const cats = field.params.categories || ['Standard', 'Premium']\n            const catIndex = (i + Math.floor(generationSeed / 100)) % cats.length\n            record[field.name] = cats[catIndex]\n            break\n          }\n\n          case 'date_range': {\n            const day = ((10 + i * 4) % 28) + 1\n            const month = (i % 8) + 1\n            const dayStr = day.toString().padStart(2, '0')\n            const monthStr = month.toString().padStart(2, '0')\n            const hour = (8 + i * 3) % 24\n            const hourStr = hour.toString().padStart(2, '0')\n            record[field.name] = `2025-${monthStr}-${dayStr} ${hourStr}:24:18 UTC`\n            break\n          }\n\n          default:\n            record[field.name] = `value_${i}`\n        }\n      }\n\n      rows.push(record)\n    }\n\n    return rows\n  }, [activeFields, generationSeed, saltedHash, noiseMechanism, epsilon])\n\n  // Statistical fidelity metrics\n  const fidelityMetrics = React.useMemo(() => {\n    const rawSimilarity = Math.min(99.4, Math.max(82.0, 99.2 - ((5.0 - epsilon) / 4.9) * 9.6))\n    const similarity = parseFloat(rawSimilarity.toFixed(1))\n    const leakageRisk = kAnonymity && saltedHash && epsilon <= 3.5 ? 0.0 : Math.max(0, (epsilon - 3.5) * 0.04)\n    const correlationRetention = parseFloat(Math.min(99.1, 98.6 - ((5.0 - epsilon) / 4.9) * 6.2).toFixed(1))\n    const wassersteinDistance = parseFloat((0.032 + ((5.0 - epsilon) / 4.9) * 0.024).toFixed(3))\n    const laplaceNoiseStd = (0.12 / Math.max(0.1, epsilon)).toFixed(3)\n\n    let privacyTier = 'Balanced Privacy & Utility'\n    let privacyBadgeColor = 'bg-info/10 text-info border-info/30'\n\n    if (epsilon <= 0.5) {\n      privacyTier = 'Maximum Privacy / High DP Noise'\n      privacyBadgeColor = 'bg-success/10 text-success border-success/30'\n    } else if (epsilon > 2.5) {\n      privacyTier = 'High Statistical Utility / Minimal Noise'\n      privacyBadgeColor = 'bg-warning/10 text-warning border-warning/30'\n    }\n\n    return {\n      similarity,\n      leakageRisk: leakageRisk.toFixed(2),\n      correlationRetention,\n      wassersteinDistance,\n      laplaceNoiseStd,\n      privacyTier,\n      privacyBadgeColor,\n    }\n  }, [epsilon, kAnonymity, saltedHash])\n\n  // Estimated file size calculation\n  const estimatedFileSize = React.useMemo(() => {\n    const bytesPerRow = outputFormat === 'csv' ? 180 : 380\n    const totalKb = (rowCount * bytesPerRow) / 1024\n    if (totalKb < 1024) {\n      return `~${totalKb.toFixed(1)} KB`\n    }\n    return `~${(totalKb / 1024).toFixed(2)} MB`\n  }, [outputFormat, rowCount])\n\n  // Add field handler\n  const handleAddCustomField = () => {\n    if (!newFieldName.trim()) return\n\n    const cleanName = newFieldName.trim().toLowerCase().replace(/\\s+/g, '_')\n    const newField: SchemaField = {\n      id: `f-custom-${Date.now()}`,\n      name: cleanName,\n      label: newFieldName.trim(),\n      type: newFieldType,\n      description: `Custom ${newFieldType} schema column`,\n      params:\n        newFieldType === 'gaussian_float'\n          ? { mean: 500, stdDev: 120, currency: '$' }\n          : newFieldType === 'category_weights'\n            ? { categories: ['Alpha', 'Beta', 'Gamma'], weights: [0.5, 0.3, 0.2] }\n            : {},\n    }\n\n    setActiveFields((prev) => [...prev, newField])\n    setNewFieldName('')\n    setShowAddField(false)\n    triggerRegeneration()\n  }\n\n  // Remove field handler\n  const removeField = (fieldId: string) => {\n    if (activeFields.length <= 2) return\n    setActiveFields((prev) => prev.filter((f) => f.id !== fieldId))\n    triggerRegeneration()\n  }\n\n  // Copy JSON lines\n  const copyJsonLines = async () => {\n    try {\n      const jsonLinesText = previewRecords.map((r) => JSON.stringify(r)).join('\\n')\n      if (navigator?.clipboard?.writeText) {\n        await navigator.clipboard.writeText(jsonLinesText)\n      }\n      setCopied(true)\n      setTimeout(() => {\n        setCopied(false)\n      }, 2000)\n    } catch (err) {\n      console.error('Failed to copy to clipboard', err)\n    }\n  }\n\n  // Download simulation\n  const handleDownloadDataset = () => {\n    const filename = `synthetic_${selectedTemplateKey}_${rowCount}_rows.${outputFormat === 'csv' ? 'csv' : 'jsonl'}`\n    setDownloadToast(`Downloaded ${rowCount.toLocaleString()} synthetic records (${filename})`)\n    setTimeout(() => {\n      setDownloadToast(null)\n    }, 3500)\n  }\n\n  return (\n    <div data-slot=\"synthetic-data-generator\" className={cn('mx-auto w-full max-w-7xl space-y-6', className)}>\n      {/* TOP HEADER HERO */}\n      <Card className=\"border-border overflow-hidden shadow-xs\">\n        <CardHeader className=\"border-border/60 bg-muted/20 border-b pb-4\">\n          <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n            <div className=\"space-y-1\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <div className=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n                  <Cpu className=\"size-4.5\" />\n                </div>\n                <CardTitle className=\"text-lg font-bold tracking-tight md:text-xl\">\n                  Synthetic Dataset Generator &amp; Privacy Engine\n                </CardTitle>\n                <Badge variant=\"outline\" className=\"gap-1 text-xs font-normal\">\n                  <span className=\"bg-success size-1.5 animate-pulse rounded-full\" />\n                  Differential Privacy Enabled\n                </Badge>\n              </div>\n              <CardDescription className=\"text-xs md:text-sm\">\n                Mathematical &amp; LLM-guided synthetic tabular dataset synthesizer with configurable (ε, δ)-DP noise\n                injection.\n              </CardDescription>\n            </div>\n\n            {/* Header Right Quick Actions */}\n            <div className=\"flex flex-wrap items-center gap-2.5\">\n              {/* Format Selector Segmented Control */}\n              <div className=\"bg-muted/60 border-border inline-flex items-center rounded-lg border p-0.5 text-xs\">\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'flex cursor-pointer items-center gap-1.5 rounded-md px-2.5 py-1.5 font-medium transition-colors',\n                    outputFormat === 'csv'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setOutputFormat('csv')}\n                >\n                  <FileSpreadsheet className=\"size-3.5\" />\n                  <span>Tabular CSV</span>\n                </button>\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'flex cursor-pointer items-center gap-1.5 rounded-md px-2.5 py-1.5 font-medium transition-colors',\n                    outputFormat === 'jsonl'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setOutputFormat('jsonl')}\n                >\n                  <Code2 className=\"size-3.5\" />\n                  <span>JSON Lines</span>\n                </button>\n              </div>\n\n              {/* Download Button */}\n              <Button\n                aria-label=\"Download attachment\"\n                variant=\"outline\"\n                size=\"sm\"\n                className=\"h-9 gap-1.5 text-xs font-medium\"\n                onClick={handleDownloadDataset}\n              >\n                <Download className=\"size-3.5\" />\n                <span>Download Dataset</span>\n              </Button>\n\n              {/* Primary Generate Batch Button */}\n              <Button\n                variant=\"default\"\n                size=\"sm\"\n                className=\"h-9 gap-1.5 px-4 text-xs font-semibold shadow-xs transition-[color,background-color,border-color,box-shadow,opacity,transform,scale,translate,rotate] active:scale-95\"\n                disabled={isGenerating}\n                onClick={triggerRegeneration}\n              >\n                {isGenerating ? <RefreshCw className=\"size-3.5 animate-spin\" /> : <Sparkles className=\"size-3.5\" />}\n                <span>{isGenerating ? 'Synthesizing...' : 'Generate Synthetic Batch'}</span>\n              </Button>\n            </div>\n          </div>\n\n          {/* Template Selector Bar */}\n          <div className=\"border-border/50 bg-background/50 mt-3 flex flex-wrap items-center justify-between gap-3 rounded-lg border px-3.5 py-2\">\n            <div className=\"flex items-center gap-2\">\n              <Layers className=\"text-muted-foreground size-4\" />\n              <span className=\"text-foreground text-xs font-semibold\">Schema Template:</span>\n            </div>\n\n            <div className=\"w-full min-w-0 sm:max-w-md sm:flex-1\">\n              <Select value={selectedTemplateKey} onValueChange={handleTemplateChange}>\n                <SelectTrigger className=\"bg-background h-8.5 w-full text-xs font-medium [&>span]:truncate [&>svg]:shrink-0\">\n                  <SelectValue placeholder=\"Select Schema Template\" />\n                </SelectTrigger>\n                <SelectContent>\n                  {Object.entries(TEMPLATES).map(([key, tpl]) => (\n                    <SelectItem key={key} value={key} className=\"text-xs\">\n                      {tpl.name}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            </div>\n\n            <div className=\"text-muted-foreground hidden items-center gap-2 text-xs sm:flex\">\n              <Badge variant=\"secondary\" className=\"px-2 py-0.5 text-xs font-normal\">\n                {TEMPLATES[selectedTemplateKey]?.category}\n              </Badge>\n              <span>•</span>\n              <span className=\"font-mono tabular-nums\">{activeFields.length} fields configured</span>\n            </div>\n          </div>\n        </CardHeader>\n      </Card>\n\n      {/* DOWNLOAD SUCCESS NOTIFICATION */}\n      {downloadToast && (\n        <div className=\"border-success/30 bg-success/10 text-success text-success flex items-center justify-between rounded-lg border px-4 py-2.5 text-xs font-medium shadow-xs\">\n          <div className=\"flex items-center gap-2\">\n            <Check className=\"size-4 stroke-[2.5]\" />\n            <span>{downloadToast}</span>\n          </div>\n          <Badge variant=\"outline\" className=\"border-success/40 font-mono text-xs\">\n            {estimatedFileSize}\n          </Badge>\n        </div>\n      )}\n\n      {/* 2-COLUMN STUDIO GENERATOR */}\n      <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-12\">\n        {/* LEFT COLUMN: SCHEMA & PRIVACY CONFIGURATION (40% / 5 Cols) */}\n        <div className=\"space-y-6 lg:col-span-5\">\n          {/* CARD 1: ROW COUNT & BATCH SCALE */}\n          <Card className=\"border-border shadow-xs\">\n            <CardHeader className=\"border-border/50 border-b pb-3\">\n              <div className=\"flex items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n                    <Database className=\"size-3.5\" />\n                  </div>\n                  <CardTitle className=\"text-sm font-semibold\">Dataset Generation Volume</CardTitle>\n                </div>\n                <Badge variant=\"secondary\" className=\"font-mono text-xs font-semibold tabular-nums\">\n                  {rowCount.toLocaleString()} rows\n                </Badge>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4 pt-4\">\n              {/* Row Slider */}\n              <div className=\"space-y-2\">\n                <div className=\"text-muted-foreground flex items-center justify-between text-xs\">\n                  <span>100 rows</span>\n                  <span className=\"text-foreground font-mono font-medium\">Estimated: {estimatedFileSize}</span>\n                  <span>50,000 rows</span>\n                </div>\n\n                <Slider\n                  value={[rowCount]}\n                  min={100}\n                  max={50000}\n                  step={100}\n                  className=\"w-full py-1\"\n                  onValueChange={(val) => setRowCount(val[0])}\n                />\n              </div>\n\n              {/* Quick Preset Chips */}\n              <div className=\"flex flex-wrap items-center gap-1.5 pt-1\">\n                <span className=\"text-muted-foreground mr-1 text-xs\">Presets:</span>\n                {[100, 1000, 5000, 10000, 50000].map((preset) => (\n                  <button\n                    key={preset}\n                    type=\"button\"\n                    className={cn(\n                      'cursor-pointer rounded-md border px-2.5 py-1 text-xs font-medium transition-colors',\n                      rowCount === preset\n                        ? 'bg-primary text-primary-foreground border-primary shadow-xs'\n                        : 'bg-muted/40 text-muted-foreground border-border hover:bg-muted hover:text-foreground',\n                    )}\n                    onClick={() => setRowCount(preset)}\n                  >\n                    {preset >= 1000 ? `${preset / 1000}k` : preset}\n                  </button>\n                ))}\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* CARD 2: DIFFERENTIAL PRIVACY EPSILON (ε) CONTROLS */}\n          <Card className=\"border-border shadow-xs\">\n            <CardHeader className=\"border-border/50 border-b pb-3\">\n              <div className=\"flex items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                    <ShieldCheck className=\"size-3.5\" />\n                  </div>\n                  <div>\n                    <CardTitle className=\"text-sm font-semibold\">Differential Privacy Budget</CardTitle>\n                    <CardDescription className=\"text-xs\">Laplace (ε, δ)-DP noise calibration</CardDescription>\n                  </div>\n                </div>\n                <Badge variant=\"outline\" className=\"font-mono text-xs font-bold tabular-nums\">\n                  ε = {epsilon.toFixed(1)}\n                </Badge>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4 pt-4\">\n              {/* Epsilon Slider */}\n              <div className=\"space-y-2\">\n                <div className=\"flex items-center justify-between text-xs\">\n                  <span className=\"text-success font-medium\">ε=0.1 (High Privacy)</span>\n                  <span className=\"text-warning font-medium\">ε=5.0 (High Fidelity)</span>\n                </div>\n\n                <Slider\n                  value={[epsilon]}\n                  min={0.1}\n                  max={5.0}\n                  step={0.1}\n                  className=\"w-full py-1\"\n                  onValueChange={(val) => setEpsilon(val[0])}\n                />\n              </div>\n\n              {/* Epsilon Interpretation Banner */}\n              <div\n                className={cn(\n                  'flex items-start gap-2.5 rounded-lg border p-3 text-xs',\n                  fidelityMetrics.privacyBadgeColor,\n                )}\n              >\n                <Info className=\"mt-0.5 size-4 shrink-0\" />\n                <div className=\"space-y-1\">\n                  <div className=\"font-semibold\">{fidelityMetrics.privacyTier}</div>\n                  <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                    Laplace noise scale:{' '}\n                    <span className=\"text-foreground font-mono font-medium\">σ=±{fidelityMetrics.laplaceNoiseStd}</span>{' '}\n                    • Delta: <span className=\"text-foreground font-mono font-medium\">δ=10⁻⁵</span> • Zero memorization\n                    guarantee.\n                  </p>\n                </div>\n              </div>\n\n              {/* Quick Epsilon Presets */}\n              <div className=\"grid grid-cols-3 gap-2 pt-1\">\n                {[\n                  { eps: 0.5, label: 'Healthcare' },\n                  { eps: 1.2, label: 'Standard' },\n                  { eps: 3.0, label: 'Analytics' },\n                ].map(({ eps, label }) => (\n                  <button\n                    key={eps}\n                    type=\"button\"\n                    className={cn(\n                      'cursor-pointer rounded-lg border p-2 text-center text-xs transition-colors',\n                      epsilon === eps\n                        ? 'border-primary bg-primary/10 text-primary font-semibold'\n                        : 'border-border bg-background text-muted-foreground hover:bg-muted/40',\n                    )}\n                    onClick={() => setEpsilon(eps)}\n                  >\n                    <div className=\"font-bold\">ε = {eps.toFixed(1)}</div>\n                    <div className=\"text-muted-foreground text-xs\">{label}</div>\n                  </button>\n                ))}\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* CARD 3: FIELD SCHEMAS GENERATOR */}\n          <Card className=\"border-border shadow-xs\">\n            <CardHeader className=\"border-border/50 border-b pb-3\">\n              <div className=\"flex items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n                    <Sliders className=\"size-3.5\" />\n                  </div>\n                  <div>\n                    <CardTitle className=\"text-sm font-semibold\">Schema Fields Generator</CardTitle>\n                    <CardDescription className=\"text-xs\">\n                      {activeFields.length} active synthesizer distributions\n                    </CardDescription>\n                  </div>\n                </div>\n                <Button\n                  variant=\"outline\"\n                  size=\"sm\"\n                  className=\"h-7.5 gap-1 px-2.5 text-xs\"\n                  onClick={() => setShowAddField(!showAddField)}\n                >\n                  <Plus className=\"size-3.5\" />\n                  <span>{showAddField ? 'Cancel' : 'Add Field'}</span>\n                </Button>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-3 pt-4\">\n              {/* Add Field Form */}\n              {showAddField && (\n                <div className=\"border-border/80 bg-muted/30 space-y-3 rounded-lg border p-3.5 text-xs\">\n                  <div className=\"text-foreground font-semibold\">Configure New Synthetic Field</div>\n                  <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n                    <div className=\"space-y-1\">\n                      <label className=\"text-muted-foreground text-xs\">Field Identifier</label>\n                      <Input\n                        value={newFieldName}\n                        onChange={(e) => setNewFieldName(e.target.value)}\n                        placeholder=\"e.g. account_balance\"\n                        className=\"h-8 text-xs\"\n                      />\n                    </div>\n                    <div className=\"space-y-1\">\n                      <label className=\"text-muted-foreground text-xs\">Data Distribution Type</label>\n                      <Select value={newFieldType} onValueChange={(val) => setNewFieldType(val as FieldDataType)}>\n                        <SelectTrigger className=\"bg-background h-8 w-full min-w-0 text-xs\">\n                          <SelectValue placeholder=\"Type\" />\n                        </SelectTrigger>\n                        <SelectContent>\n                          <SelectItem value=\"gaussian_float\" className=\"text-xs\">\n                            Float Gaussian Distribution\n                          </SelectItem>\n                          <SelectItem value=\"name\" className=\"text-xs\">\n                            Full Name Faker\n                          </SelectItem>\n                          <SelectItem value=\"email\" className=\"text-xs\">\n                            Email Faker\n                          </SelectItem>\n                          <SelectItem value=\"credit_card\" className=\"text-xs\">\n                            Credit Card Faker\n                          </SelectItem>\n                          <SelectItem value=\"category_weights\" className=\"text-xs\">\n                            Category Weights\n                          </SelectItem>\n                          <SelectItem value=\"date_range\" className=\"text-xs\">\n                            Date Range\n                          </SelectItem>\n                        </SelectContent>\n                      </Select>\n                    </div>\n                  </div>\n\n                  <div className=\"flex justify-end gap-2 pt-1\">\n                    <Button variant=\"ghost\" size=\"sm\" className=\"h-7.5 text-xs\" onClick={() => setShowAddField(false)}>\n                      Cancel\n                    </Button>\n                    <Button\n                      variant=\"default\"\n                      size=\"sm\"\n                      className=\"h-7.5 text-xs\"\n                      disabled={!newFieldName.trim()}\n                      onClick={handleAddCustomField}\n                    >\n                      Add to Schema\n                    </Button>\n                  </div>\n                </div>\n              )}\n\n              {/* Fields List */}\n              <div className=\"divide-border/60 max-h-[320px] space-y-2 overflow-y-auto pr-1\">\n                {activeFields.map((field) => (\n                  <div\n                    key={field.id}\n                    className=\"group border-border/70 bg-card hover:bg-muted/20 flex items-center justify-between rounded-lg border p-2.5 transition-colors\"\n                  >\n                    <div className=\"min-w-0 space-y-0.5\">\n                      <div className=\"flex items-center gap-2\">\n                        <span className=\"text-foreground font-mono text-xs font-semibold\">{field.name}</span>\n                        <Badge\n                          variant=\"outline\"\n                          className={cn(\n                            'px-1.5 py-0 text-xs font-semibold tracking-wider uppercase',\n                            field.type === 'gaussian_float' && 'border-info/20 bg-info/10 text-info',\n                            field.type === 'name' && 'border-chart-1/20 bg-chart-1/10 text-chart-1',\n                            field.type === 'email' && 'border-chart-2/20 bg-chart-2/10 text-chart-2',\n                            field.type === 'credit_card' && 'border-warning/20 bg-warning/10 text-warning',\n                            field.type === 'category_weights' && 'border-success/20 bg-success/10 text-success',\n                            field.type === 'date_range' && 'border-destructive/20 bg-destructive/10 text-destructive',\n                          )}\n                        >\n                          {field.type.replace('_', ' ')}\n                        </Badge>\n                      </div>\n                      <p className=\"text-muted-foreground truncate text-xs\">\n                        {field.description || 'Configured synthesizer parameter'}\n                      </p>\n                    </div>\n\n                    <Button\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      className=\"text-muted-foreground hover:text-destructive h-7 w-7 p-0 opacity-80 group-hover:opacity-100\"\n                      aria-label=\"Delete field\"\n                      disabled={activeFields.length <= 2}\n                      onClick={() => removeField(field.id)}\n                    >\n                      <Trash2 className=\"size-3.5\" />\n                    </Button>\n                  </div>\n                ))}\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* CARD 4: PII ANONYMIZATION POLICY SWITCHES */}\n          <Card className=\"border-border shadow-xs\">\n            <CardHeader className=\"border-border/50 border-b pb-3\">\n              <div className=\"flex items-center gap-2\">\n                <div className=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n                  <Lock className=\"size-3.5\" />\n                </div>\n                <div>\n                  <CardTitle className=\"text-sm font-semibold\">PII Anonymization Policy</CardTitle>\n                  <CardDescription className=\"text-xs\">Zero linkage &amp; re-identification guarantees</CardDescription>\n                </div>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4 pt-4\">\n              {/* K-Anonymity Switch */}\n              <div className=\"flex items-start justify-between gap-3\">\n                <div className=\"space-y-0.5\">\n                  <div className=\"text-foreground text-xs font-semibold\">K-Anonymity (k = 5 Cohort Enforcement)</div>\n                  <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                    Generalizes quasi-identifiers so each demographic bucket contains ≥ 5 records.\n                  </p>\n                </div>\n                <Switch checked={kAnonymity} onCheckedChange={setKAnonymity} />\n              </div>\n\n              <Separator />\n\n              {/* Salted Hash Switch */}\n              <div className=\"flex items-start justify-between gap-3\">\n                <div className=\"space-y-0.5\">\n                  <div className=\"text-foreground text-xs font-semibold\">Salted HMAC-SHA256 for Primary Keys</div>\n                  <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                    Deterministically pseudonymizes primary keys with ephemeral cryptographic salt.\n                  </p>\n                </div>\n                <Switch checked={saltedHash} onCheckedChange={setSaltedHash} />\n              </div>\n\n              <Separator />\n\n              {/* Noise Injection Switch */}\n              <div className=\"flex items-start justify-between gap-3\">\n                <div className=\"space-y-0.5\">\n                  <div className=\"text-foreground text-xs font-semibold\">Differential Privacy Gaussian Noise</div>\n                  <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                    Injects calibrated noise calibrated to global sensitivity (Δf / ε).\n                  </p>\n                </div>\n                <Switch checked={noiseMechanism} onCheckedChange={setNoiseMechanism} />\n              </div>\n            </CardContent>\n          </Card>\n        </div>\n\n        {/* RIGHT COLUMN: LIVE GENERATED SYNTHETIC DATA PREVIEW (60% / 7 Cols) */}\n        <div className=\"space-y-6 lg:col-span-7\">\n          <SyntheticDataPreview\n            previewTab={previewTab}\n            onPreviewTabChange={setPreviewTab}\n            previewRecords={previewRecords}\n            activeFields={activeFields}\n            fidelityMetrics={fidelityMetrics}\n            epsilon={epsilon}\n            rowCount={rowCount}\n            outputFormat={outputFormat}\n            generationSeed={generationSeed}\n            copied={copied}\n            onCopyJsonLines={copyJsonLines}\n          />\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport default SyntheticDataGenerator\n",
      "type": "registry:block",
      "target": "~/components/blocks/SyntheticDataGenerator.tsx"
    },
    {
      "path": "packages/registry-react/blocks/synthetic-data-generator/SyntheticDataPreview.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { BarChart3, Binary, Check, Code2, Copy, Shield, ShieldCheck, Table as TableIcon, Zap } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport type { FidelityMetrics, GeneratedRecord, SchemaField } from './synthetic-data-types'\n\ninterface SyntheticDataPreviewProps {\n  previewTab: 'table' | 'json' | 'metrics'\n  onPreviewTabChange: (tab: 'table' | 'json' | 'metrics') => void\n  previewRecords: GeneratedRecord[]\n  activeFields: SchemaField[]\n  fidelityMetrics: FidelityMetrics\n  epsilon: number\n  rowCount: number\n  outputFormat: 'csv' | 'jsonl'\n  generationSeed: number\n  copied: boolean\n  onCopyJsonLines: () => void\n}\n\nexport function SyntheticDataPreview({\n  previewTab,\n  onPreviewTabChange,\n  previewRecords,\n  activeFields,\n  fidelityMetrics,\n  epsilon,\n  rowCount,\n  outputFormat,\n  generationSeed,\n  copied,\n  onCopyJsonLines,\n}: SyntheticDataPreviewProps) {\n  return (\n    <div className=\"space-y-6\">\n      {/* TOP GAUGE BANNER: STATISTICAL FIDELITY VS PRIVACY */}\n      <Card className=\"border-border overflow-hidden shadow-xs\">\n        <div className=\"border-border/60 bg-success/10 dark:bg-success/10 border-b px-4 py-3\">\n          <div className=\"flex flex-wrap items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <ShieldCheck className=\"text-success size-4.5\" />\n              <span className=\"text-foreground font-mono text-sm font-bold tracking-tight\">\n                {fidelityMetrics.similarity}% Distribution Similarity &bull; {fidelityMetrics.leakageRisk}% PII Leakage\n                Risk\n              </span>\n            </div>\n            <Badge variant=\"outline\" className=\"bg-background border-success/40 text-success text-xs font-semibold\">\n              &epsilon;-DP Bound: &le; {epsilon.toFixed(1)}\n            </Badge>\n          </div>\n        </div>\n\n        <CardContent className=\"grid grid-cols-1 gap-4 pt-4 sm:grid-cols-3\">\n          {/* Metric 1: Fidelity Score */}\n          <div className=\"border-border/60 bg-muted/10 space-y-1.5 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Fidelity Score</span>\n              <Zap className=\"text-warning size-3.5\" />\n            </div>\n            <div className=\"text-foreground font-mono text-lg font-bold tabular-nums\">\n              {fidelityMetrics.similarity}%\n            </div>\n            <Progress value={fidelityMetrics.similarity} className=\"h-1.5\" />\n          </div>\n\n          {/* Metric 2: Correlation Preservation */}\n          <div className=\"border-border/60 bg-muted/10 space-y-1.5 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Covariance Retention</span>\n              <BarChart3 className=\"text-info size-3.5\" />\n            </div>\n            <div className=\"text-foreground font-mono text-lg font-bold tabular-nums\">\n              {fidelityMetrics.correlationRetention}%\n            </div>\n            <Progress value={fidelityMetrics.correlationRetention} className=\"h-1.5\" />\n          </div>\n\n          {/* Metric 3: Wasserstein Distance */}\n          <div className=\"border-border/60 bg-muted/10 space-y-1.5 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground flex items-center justify-between text-xs\">\n              <span>Wasserstein Distance</span>\n              <Binary className=\"text-chart-1 size-3.5\" />\n            </div>\n            <div className=\"text-foreground font-mono text-lg font-bold tabular-nums\">\n              {fidelityMetrics.wassersteinDistance}\n            </div>\n            <div className=\"text-muted-foreground text-xs\">Low error bound (&lt; 0.05)</div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* PREVIEW TABS CARD */}\n      <Card className=\"border-border shadow-xs\">\n        <CardHeader className=\"border-border/50 border-b pb-3\">\n          <div className=\"flex flex-wrap items-center justify-between gap-2\">\n            <div className=\"flex items-center gap-2\">\n              <div className=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n                <TableIcon className=\"size-3.5\" />\n              </div>\n              <div>\n                <CardTitle className=\"text-sm font-semibold\">Live Generated Synthetic Data Preview</CardTitle>\n                <CardDescription className=\"text-xs\">\n                  Real-time sampler showing first {previewRecords.length} synthesized records\n                </CardDescription>\n              </div>\n            </div>\n\n            {/* View Switcher */}\n            <Tabs\n              value={previewTab}\n              onValueChange={(val) => onPreviewTabChange(val as 'table' | 'json' | 'metrics')}\n              className=\"w-auto\"\n            >\n              <TabsList className=\"h-8\">\n                <TabsTrigger value=\"table\" className=\"h-7 px-2.5 text-xs\">\n                  <TableIcon className=\"mr-1 size-3\" />\n                  <span>Table</span>\n                </TabsTrigger>\n                <TabsTrigger value=\"json\" className=\"h-7 px-2.5 text-xs\">\n                  <Code2 className=\"mr-1 size-3\" />\n                  <span>JSONL</span>\n                </TabsTrigger>\n                <TabsTrigger value=\"metrics\" className=\"h-7 px-2.5 text-xs\">\n                  <BarChart3 className=\"mr-1 size-3\" />\n                  <span>Marginals</span>\n                </TabsTrigger>\n              </TabsList>\n            </Tabs>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"pt-4\">\n          {/* TAB 1: TABULAR PREVIEW */}\n          {previewTab === 'table' && (\n            <div className=\"space-y-3\">\n              <div className=\"border-border overflow-hidden rounded-lg border\">\n                <div className=\"overflow-x-auto\">\n                  <Table className=\"min-w-full text-xs\">\n                    <TableHeader className=\"bg-muted/40\">\n                      <TableRow>\n                        {activeFields.map((f) => (\n                          <TableHead\n                            key={f.id}\n                            className=\"text-foreground font-mono text-xs font-semibold whitespace-nowrap\"\n                          >\n                            {f.name}\n                          </TableHead>\n                        ))}\n                      </TableRow>\n                    </TableHeader>\n                    <TableBody>\n                      {previewRecords.map((row, idx) => (\n                        <TableRow key={idx} className=\"hover:bg-muted/30 transition-colors\">\n                          {activeFields.map((f) => (\n                            <TableCell key={f.id} className=\"py-2.5 whitespace-nowrap\">\n                              {f.name === 'id' ||\n                              f.name.includes('id') ||\n                              f.name.includes('uuid') ||\n                              f.name.includes('token') ? (\n                                <span className=\"text-muted-foreground font-mono font-medium\">{row[f.name]}</span>\n                              ) : f.type === 'category_weights' ? (\n                                <Badge variant=\"secondary\" className=\"font-mono text-xs font-medium\">\n                                  {row[f.name]}\n                                </Badge>\n                              ) : f.type === 'gaussian_float' ? (\n                                <span className=\"text-foreground font-mono font-semibold tabular-nums\">\n                                  {row[f.name]}\n                                </span>\n                              ) : f.type === 'credit_card' ? (\n                                <span className=\"text-foreground font-mono text-xs font-medium\">{row[f.name]}</span>\n                              ) : f.type === 'email' ? (\n                                <span className=\"text-primary font-mono text-xs font-normal\">{row[f.name]}</span>\n                              ) : (\n                                <span className=\"text-foreground font-medium\">{row[f.name]}</span>\n                              )}\n                            </TableCell>\n                          ))}\n                        </TableRow>\n                      ))}\n                    </TableBody>\n                  </Table>\n                </div>\n              </div>\n\n              <div className=\"text-muted-foreground flex flex-wrap items-center justify-between gap-2 px-1 text-xs\">\n                <span className=\"flex items-center gap-1.5 font-mono tabular-nums\">\n                  <span className=\"bg-success size-1.5 rounded-full\" />\n                  Showing {previewRecords.length} sample records of {rowCount.toLocaleString()} generated rows\n                </span>\n                <span className=\"text-muted-foreground font-mono text-xs\">Seed: #{generationSeed}</span>\n              </div>\n            </div>\n          )}\n\n          {/* TAB 2: JSON LINES PREVIEW */}\n          {previewTab === 'json' && (\n            <div className=\"space-y-3\">\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-muted-foreground text-xs\">Streaming JSON Lines formatted output:</span>\n                <Button\n                  variant=\"outline\"\n                  size=\"sm\"\n                  className=\"h-7.5 gap-1.5 px-2.5 text-xs font-medium\"\n                  onClick={onCopyJsonLines}\n                >\n                  {copied ? <Check className=\"text-success size-3 stroke-[2.5]\" /> : <Copy className=\"size-3\" />}\n                  <span>{copied ? 'Copied JSONL' : 'Copy JSON Lines'}</span>\n                </Button>\n              </div>\n\n              <div className=\"border-border/80 bg-muted/40 max-h-[380px] overflow-x-auto overflow-y-auto rounded-lg border p-4 font-mono text-xs leading-relaxed\">\n                {previewRecords.map((rec, idx) => (\n                  <div key={idx} className=\"hover:bg-muted/60 rounded px-1.5 py-1 whitespace-pre transition-colors\">\n                    <span className=\"text-muted-foreground select-none\">{idx + 1}&nbsp;</span>\n                    <span className=\"text-foreground\">{'{ '}</span>\n                    {Object.entries(rec).map(([key, val], kIdx, arr) => (\n                      <React.Fragment key={key}>\n                        <span className=\"text-info font-semibold\">\"{key}\"</span>\n                        <span className=\"text-muted-foreground\">: </span>\n                        <span className={typeof val === 'number' ? 'text-warning font-medium' : 'text-success'}>\n                          {typeof val === 'number' ? val : `\"${val}\"`}\n                        </span>\n                        {kIdx < arr.length - 1 && <span className=\"text-muted-foreground\">, </span>}\n                      </React.Fragment>\n                    ))}\n                    <span className=\"text-foreground\">{' }'}</span>\n                  </div>\n                ))}\n              </div>\n            </div>\n          )}\n\n          {/* TAB 3: MARGINALS & FIDELITY DENSITY */}\n          {previewTab === 'metrics' && (\n            <div className=\"space-y-4\">\n              <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n                {/* Density Gauge 1 */}\n                <div className=\"border-border/60 bg-muted/20 space-y-2 rounded-lg border p-3.5\">\n                  <div className=\"flex items-center justify-between text-xs\">\n                    <span className=\"text-foreground font-semibold\">Gaussian Distribution Overlap</span>\n                    <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                      96.2%\n                    </Badge>\n                  </div>\n                  <p className=\"text-muted-foreground text-xs\">\n                    Kolmogorov-Smirnov distance between synthetic batch and continuous Gaussian ground truth.\n                  </p>\n                  <Progress value={96.2} className=\"h-2\" />\n                </div>\n\n                {/* Density Gauge 2 */}\n                <div className=\"border-border/60 bg-muted/20 space-y-2 rounded-lg border p-3.5\">\n                  <div className=\"flex items-center justify-between text-xs\">\n                    <span className=\"text-foreground font-semibold\">Categorical Frequency Prior</span>\n                    <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                      98.4%\n                    </Badge>\n                  </div>\n                  <p className=\"text-muted-foreground text-xs\">\n                    Total variation distance across categorical weight assignments.\n                  </p>\n                  <Progress value={98.4} className=\"h-2\" />\n                </div>\n              </div>\n\n              {/* Mathematical Guarantees Breakdown */}\n              <div className=\"border-border/60 bg-muted/10 space-y-2.5 rounded-lg border p-4 text-xs\">\n                <div className=\"text-foreground flex items-center gap-1.5 font-semibold\">\n                  <Shield className=\"text-primary size-4\" />\n                  <span>Mathematical Privacy Guarantees &bull; Formal Specs</span>\n                </div>\n                <div className=\"text-muted-foreground grid grid-cols-1 gap-2 sm:grid-cols-2\">\n                  <div className=\"flex items-center gap-1.5\">\n                    <Check className=\"text-success size-3.5\" />\n                    <span>Differential Privacy (ε = {epsilon.toFixed(1)}, δ = 10⁻⁵)</span>\n                  </div>\n                  <div className=\"flex items-center gap-1.5\">\n                    <Check className=\"text-success size-3.5\" />\n                    <span>K-Anonymity (k = 5) Cohort Clamping</span>\n                  </div>\n                  <div className=\"flex items-center gap-1.5\">\n                    <Check className=\"text-success size-3.5\" />\n                    <span>Zero Direct Row Memorization</span>\n                  </div>\n                  <div className=\"flex items-center gap-1.5\">\n                    <Check className=\"text-success size-3.5\" />\n                    <span>Ephemeral In-Memory Compute</span>\n                  </div>\n                </div>\n              </div>\n            </div>\n          )}\n        </CardContent>\n\n        <CardFooter className=\"border-border/40 text-muted-foreground flex flex-wrap items-center justify-between border-t py-3 text-xs\">\n          <span className=\"flex items-center gap-1.5\">\n            <Zap className=\"text-warning size-3.5\" />\n            Powered by LLM Semantic Synthesis &amp; Laplace Noise Engine\n          </span>\n          <span className=\"font-mono tabular-nums\">\n            Output: {outputFormat.toUpperCase()} &bull; {activeFields.length} fields &bull; {rowCount.toLocaleString()}{' '}\n            records\n          </span>\n        </CardFooter>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/SyntheticDataPreview.tsx"
    },
    {
      "path": "packages/registry-react/blocks/synthetic-data-generator/synthetic-data-types.ts",
      "content": "export type FieldDataType = 'name' | 'email' | 'credit_card' | 'gaussian_float' | 'date_range' | 'category_weights'\n\nexport interface SchemaField {\n  id: string\n  name: string\n  label: string\n  type: FieldDataType\n  description?: string\n  params: {\n    mean?: number\n    stdDev?: number\n    currency?: string\n    unit?: string\n    categories?: string[]\n    weights?: number[]\n    domain?: string\n    dateStart?: string\n    dateEnd?: string\n  }\n}\n\nexport interface TemplatePreset {\n  id: string\n  name: string\n  description: string\n  category: string\n  fields: SchemaField[]\n}\n\nexport interface GeneratedRecord {\n  id: string\n  [key: string]: string | number\n}\n\nexport interface FidelityMetrics {\n  similarity: number\n  leakageRisk: string\n  correlationRetention: number\n  wassersteinDistance: number\n  laplaceNoiseStd: string\n  privacyTier: string\n  privacyBadgeColor: string\n}\n\nexport interface SyntheticDataGeneratorProps {\n  className?: string\n  initialTemplate?: string\n  initialRowCount?: number\n  initialEpsilon?: number\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/synthetic-data-types.ts"
    },
    {
      "path": "packages/registry-react/blocks/synthetic-data-generator/synthetic-data-templates.ts",
      "content": "import type { TemplatePreset } from './synthetic-data-types'\n\nexport const TEMPLATES: Record<string, TemplatePreset> = {\n  'customer-transactions': {\n    id: 'customer-transactions',\n    name: 'Customer Transactions & Demographics Dataset',\n    description:\n      'High-dimensional e-commerce customer cohort, synthetic PII, spending distribution, and country codes.',\n    category: 'E-Commerce & Retail',\n    fields: [\n      {\n        id: 'f-id',\n        name: 'cust_id',\n        label: 'Customer ID',\n        type: 'name',\n        description: 'Salted pseudonymized primary key',\n        params: {},\n      },\n      {\n        id: 'f-name',\n        name: 'full_name',\n        label: 'Full Name',\n        type: 'name',\n        description: 'Synthetic person name generator',\n        params: {},\n      },\n      {\n        id: 'f-email',\n        name: 'email_address',\n        label: 'Synthetic Email',\n        type: 'email',\n        description: 'Faker email with domain isolation',\n        params: { domain: 'syn-corp.io' },\n      },\n      {\n        id: 'f-card',\n        name: 'masked_card',\n        label: 'Card PAN',\n        type: 'credit_card',\n        description: 'Luhn-compliant masked payment token',\n        params: {},\n      },\n      {\n        id: 'f-spend',\n        name: 'spending_amount',\n        label: 'Spending Amount',\n        type: 'gaussian_float',\n        description: 'Gaussian spending curve (μ=$342.50, σ=$85.20)',\n        params: { mean: 342.5, stdDev: 85.2, currency: '$' },\n      },\n      {\n        id: 'f-country',\n        name: 'country_code',\n        label: 'Country Region',\n        type: 'category_weights',\n        description: 'Categorical distribution [US, DE, GB, FR, JP]',\n        params: {\n          categories: ['US', 'DE', 'GB', 'FR', 'JP'],\n          weights: [0.45, 0.2, 0.15, 0.1, 0.1],\n        },\n      },\n      {\n        id: 'f-created',\n        name: 'created_at',\n        label: 'Registration Date',\n        type: 'date_range',\n        description: 'ISO-8601 timestamp range (2024-2025)',\n        params: { dateStart: '2024-01-01', dateEnd: '2025-08-20' },\n      },\n    ],\n  },\n  'healthcare-ehr': {\n    id: 'healthcare-ehr',\n    name: 'Healthcare Patient Clinical Records (EHR)',\n    description: 'HIPAA-compliant patient cohort with biomarker telemetry, blood pressure, and triage severity tiers.',\n    category: 'Healthcare & Life Sciences',\n    fields: [\n      {\n        id: 'f-h-id',\n        name: 'patient_id',\n        label: 'Patient ID',\n        type: 'name',\n        description: 'Deterministic HIPAA salted identifier',\n        params: {},\n      },\n      {\n        id: 'f-h-name',\n        name: 'patient_name',\n        label: 'Patient Name',\n        type: 'name',\n        description: 'Synthetic medical record moniker',\n        params: {},\n      },\n      {\n        id: 'f-h-email',\n        name: 'contact_email',\n        label: 'Contact Email',\n        type: 'email',\n        description: 'Synthetic provider contact',\n        params: { domain: 'med-synthetic.org' },\n      },\n      {\n        id: 'f-h-glucose',\n        name: 'blood_glucose',\n        label: 'Glucose (mg/dL)',\n        type: 'gaussian_float',\n        description: 'Fast fasting blood glucose (μ=108.4, σ=22.1)',\n        params: { mean: 108.4, stdDev: 22.1, unit: 'mg/dL' },\n      },\n      {\n        id: 'f-h-bp',\n        name: 'systolic_bp',\n        label: 'Systolic BP',\n        type: 'gaussian_float',\n        description: 'Arterial blood pressure (μ=124.0, σ=15.5)',\n        params: { mean: 124.0, stdDev: 15.5, unit: 'mmHg' },\n      },\n      {\n        id: 'f-h-tier',\n        name: 'triage_tier',\n        label: 'Triage Severity',\n        type: 'category_weights',\n        description: 'Clinical priority classification',\n        params: {\n          categories: ['Routine', 'Elevated', 'Urgent', 'Critical'],\n          weights: [0.52, 0.28, 0.14, 0.06],\n        },\n      },\n      {\n        id: 'f-h-date',\n        name: 'admission_date',\n        label: 'Admission Date',\n        type: 'date_range',\n        description: 'Encounter timestamps',\n        params: { dateStart: '2024-06-01', dateEnd: '2025-08-20' },\n      },\n    ],\n  },\n  'fintech-fraud': {\n    id: 'fintech-fraud',\n    name: 'Fintech Fraud Detection & Risk Scoring',\n    description: 'Transaction monitoring telemetry for anti-fraud classifiers with skewed anomalous patterns.',\n    category: 'Fintech & Risk',\n    fields: [\n      {\n        id: 'f-ff-id',\n        name: 'tx_token',\n        label: 'Transaction ID',\n        type: 'name',\n        description: 'Cryptographic ledger token',\n        params: {},\n      },\n      {\n        id: 'f-ff-name',\n        name: 'merchant_name',\n        label: 'Merchant Name',\n        type: 'name',\n        description: 'Synthetic counterparty vendor',\n        params: {},\n      },\n      {\n        id: 'f-ff-email',\n        name: 'auth_email',\n        label: 'Auth Email',\n        type: 'email',\n        description: 'Tokenized transaction origin email',\n        params: { domain: 'syn-pay.net' },\n      },\n      {\n        id: 'f-ff-card',\n        name: 'card_pan',\n        label: 'Card PAN',\n        type: 'credit_card',\n        description: 'Tokenized 16-digit card surrogate',\n        params: {},\n      },\n      {\n        id: 'f-ff-amt',\n        name: 'settlement_usd',\n        label: 'Settlement ($)',\n        type: 'gaussian_float',\n        description: 'Transaction gross volume (μ=$1420.00, σ=$480.00)',\n        params: { mean: 1420.0, stdDev: 480.0, currency: '$' },\n      },\n      {\n        id: 'f-ff-verdict',\n        name: 'risk_verdict',\n        label: 'Risk Verdict',\n        type: 'category_weights',\n        description: 'Ground truth classifier target',\n        params: {\n          categories: ['Legitimate', 'Suspicious', 'Flagged_Fraud'],\n          weights: [0.89, 0.08, 0.03],\n        },\n      },\n      {\n        id: 'f-ff-ts',\n        name: 'settled_at',\n        label: 'Settlement Time',\n        type: 'date_range',\n        description: 'High-precision event timestamp',\n        params: { dateStart: '2025-01-01', dateEnd: '2025-08-20' },\n      },\n    ],\n  },\n  'saas-telemetry': {\n    id: 'saas-telemetry',\n    name: 'SaaS Product Telemetry & Usage Metrics',\n    description: 'B2B subscription telemetry with active seat distribution, recurring revenue, and subscription tiers.',\n    category: 'Cloud Software & B2B',\n    fields: [\n      {\n        id: 'f-st-id',\n        name: 'org_uuid',\n        label: 'Organization UUID',\n        type: 'name',\n        description: 'Tenant identifier',\n        params: {},\n      },\n      {\n        id: 'f-st-name',\n        name: 'tenant_name',\n        label: 'Tenant Name',\n        type: 'name',\n        description: 'Synthetic enterprise tenant moniker',\n        params: {},\n      },\n      {\n        id: 'f-st-email',\n        name: 'admin_email',\n        label: 'Admin Email',\n        type: 'email',\n        description: 'Primary owner email',\n        params: { domain: 'syn-saas.io' },\n      },\n      {\n        id: 'f-st-seats',\n        name: 'active_seats',\n        label: 'Active Seats',\n        type: 'gaussian_float',\n        description: 'Provisioned enterprise seats (μ=48.0, σ=18.0)',\n        params: { mean: 48.0, stdDev: 18.0, unit: 'seats' },\n      },\n      {\n        id: 'f-st-mrr',\n        name: 'mrr_usd',\n        label: 'Monthly Revenue',\n        type: 'gaussian_float',\n        description: 'MRR ledger (μ=$2850.00, σ=$950.00)',\n        params: { mean: 2850.0, stdDev: 950.0, currency: '$' },\n      },\n      {\n        id: 'f-st-plan',\n        name: 'plan_tier',\n        label: 'Plan Tier',\n        type: 'category_weights',\n        description: 'Subscription entitlement level',\n        params: {\n          categories: ['Starter', 'Growth', 'Enterprise'],\n          weights: [0.48, 0.36, 0.16],\n        },\n      },\n      {\n        id: 'f-st-date',\n        name: 'provisioned_at',\n        label: 'Provisioned Date',\n        type: 'date_range',\n        description: 'Cohort subscription activation',\n        params: { dateStart: '2024-01-01', dateEnd: '2025-08-20' },\n      },\n    ],\n  },\n}\n\nexport const FIRST_NAMES = [\n  'Elena',\n  'Malik',\n  'Siddharth',\n  'Claire',\n  'Liam',\n  'Amara',\n  'Kenji',\n  'Sofia',\n  'Devon',\n  'Maya',\n  'Tobias',\n  'Fatima',\n  'Mateo',\n  'Astrid',\n  'Zara',\n]\n\nexport const LAST_NAMES = [\n  'Rostova',\n  'Al-Mansoor',\n  'Patel',\n  'Chen',\n  \"O'Connor\",\n  'Okafor',\n  'Sato',\n  'Alvarez',\n  'Vance',\n  'Lin',\n  'Richter',\n  'Zahra',\n  'Silva',\n  'Lindqvist',\n  'Novak',\n]\n\nexport const CARD_BRANDS = ['Visa', 'Mastercard', 'Amex']\n\nexport function boxMullerRandom(\n  mean: number,\n  stdDev: number,\n  seedOffset: number,\n  seed: number,\n  noiseMechanism: boolean,\n  epsilon: number,\n): number {\n  const u1 = Math.max(1e-6, Math.abs(Math.sin(seed + seedOffset * 17.3)))\n  const u2 = Math.max(1e-6, Math.abs(Math.cos(seed + seedOffset * 31.7)))\n  const z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2)\n\n  const dpNoiseScale = noiseMechanism ? stdDev / (Math.max(0.1, epsilon) * 12) : 0\n  const dpNoise = Math.sin(seed * 3.7 + seedOffset * 5.1) * dpNoiseScale\n\n  return mean + z0 * stdDev + dpNoise\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/synthetic-data-templates.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/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/slider.json",
    "https://uipkge.dev/r/react/switch.json",
    "https://uipkge.dev/r/react/table.json",
    "https://uipkge.dev/r/react/tabs.json"
  ],
  "description": "Gretel and Tonic-style LLM and mathematical synthetic dataset generator with differential privacy epsilon controls, custom schema field builders, K-anonymity policy toggles, live tabular CSV preview, and streaming JSON Lines export.",
  "categories": [
    "ai",
    "data",
    "app",
    "security"
  ]
}