{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "rate-limiting-config",
  "title": "Rate Limiting Config",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/rate-limiting-config/RateLimitingConfig.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Activity,\n  AlertTriangle,\n  CheckCircle2,\n  Copy,\n  Database,\n  Edit3,\n  MoreHorizontal,\n  Plus,\n  RefreshCw,\n  Search,\n  Shield,\n  ShieldAlert,\n  ShieldCheck,\n  Sliders,\n  Timer,\n  Trash2,\n  TrendingUp,\n  Zap,\n  ZapOff,\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 {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Progress } from '@/components/ui/progress'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Slider } from '@/components/ui/slider'\nimport { Switch } from '@/components/ui/switch'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\n\nexport interface RateLimitRule {\n  id: string\n  name: string\n  scope: string\n  path: string\n  method: string\n  limitThreshold: string\n  mitigationAction: 'HTTP 429 Too Many Requests' | 'CAPTCHA Challenge' | 'Block IP'\n  actionVariant: 'warning' | 'secondary' | 'destructive'\n  enabled: boolean\n  lastTriggered: string\n  blocked24h: string\n}\n\nexport interface RateLimitingConfigProps {\n  className?: string\n}\n\nconst INITIAL_RULES: RateLimitRule[] = [\n  {\n    id: 'rule-auth-bruteforce',\n    name: 'auth-endpoint-bruteforce',\n    scope: 'Login & SSO token issuance',\n    path: '/api/v1/auth/*',\n    method: 'POST',\n    limitThreshold: '100 req / 60s per IP',\n    mitigationAction: 'HTTP 429 Too Many Requests',\n    actionVariant: 'warning',\n    enabled: true,\n    lastTriggered: '2 mins ago',\n    blocked24h: '842 blocks',\n  },\n  {\n    id: 'rule-public-unauth',\n    name: 'public-api-v1-unauthenticated',\n    scope: 'Anonymous REST endpoints',\n    path: '/api/v1/public/*',\n    method: 'GET, POST',\n    limitThreshold: '300 req / 60s per IP',\n    mitigationAction: 'CAPTCHA Challenge',\n    actionVariant: 'secondary',\n    enabled: true,\n    lastTriggered: '14 mins ago',\n    blocked24h: '412 challenges',\n  },\n  {\n    id: 'rule-ai-inference',\n    name: 'ai-inference-tier-standard',\n    scope: 'LLM completions & embeddings',\n    path: '/api/v1/models/generate',\n    method: 'POST',\n    limitThreshold: '20 req / 60s per API Key',\n    mitigationAction: 'HTTP 429 Too Many Requests',\n    actionVariant: 'warning',\n    enabled: true,\n    lastTriggered: '1 hour ago',\n    blocked24h: '148 throttled',\n  },\n  {\n    id: 'rule-search-cluster',\n    name: 'search-endpoints',\n    scope: 'Vector & fuzzy full-text query',\n    path: '/api/v1/search/*',\n    method: 'GET',\n    limitThreshold: '60 req / 60s per IP',\n    mitigationAction: 'Block IP',\n    actionVariant: 'destructive',\n    enabled: false,\n    lastTriggered: '3 days ago',\n    blocked24h: '18 blocks',\n  },\n]\n\nexport function RateLimitingConfig({ className }: RateLimitingConfigProps) {\n  const [globalProtection, setGlobalProtection] = React.useState(true)\n  const [algorithm, setAlgorithm] = React.useState<'token-bucket' | 'sliding-window'>('token-bucket')\n  const [simVolume, setSimVolume] = React.useState(120)\n  const [searchQuery, setSearchQuery] = React.useState('')\n  const [rules, setRules] = React.useState<RateLimitRule[]>(INITIAL_RULES)\n\n  const toggleRule = React.useCallback((id: string) => {\n    setRules((prev) => prev.map((r) => (r.id === id ? { ...r, enabled: !r.enabled } : r)))\n  }, [])\n\n  const activeRulesCount = React.useMemo(() => rules.filter((r) => r.enabled).length, [rules])\n\n  const filteredRules = React.useMemo(() => {\n    if (!searchQuery.trim()) return rules\n    const q = searchQuery.toLowerCase()\n    return rules.filter(\n      (r) =>\n        r.name.toLowerCase().includes(q) ||\n        r.path.toLowerCase().includes(q) ||\n        r.scope.toLowerCase().includes(q) ||\n        r.mitigationAction.toLowerCase().includes(q),\n    )\n  }, [rules, searchQuery])\n\n  const simStats = React.useMemo(() => {\n    const vol = simVolume\n    if (algorithm === 'token-bucket') {\n      const refillRate = 50\n      const burstCapacity = 100\n      if (vol <= refillRate) {\n        return {\n          allowed: vol,\n          dropped: 0,\n          allowedPct: 100,\n          droppedPct: 0,\n          bucketFill: Math.round(100 - (vol / refillRate) * 20),\n          status: 'optimal' as const,\n          statusLabel: 'Optimal Throughput · No Throttling',\n          latency: '0.35ms',\n          description: `Traffic volume (${vol} req/s) is well within the 50 req/s continuous refill capacity. 100% of requests pass with zero drop rate.`,\n        }\n      } else if (vol <= burstCapacity) {\n        const drop = 0\n        return {\n          allowed: vol,\n          dropped: drop,\n          allowedPct: 100,\n          droppedPct: 0,\n          bucketFill: Math.max(10, Math.round(100 - ((vol - refillRate) / (burstCapacity - refillRate)) * 80)),\n          status: 'burst' as const,\n          statusLabel: 'Consuming Burst Pool · 0% Dropped',\n          latency: '0.42ms',\n          description: `Traffic exceeds the 50 req/s replenishment rate. Tokens are being drawn from the 100-token burst reservoir. Zero requests dropped so far.`,\n        }\n      } else {\n        const allowed = burstCapacity\n        const dropped = vol - allowed\n        const allowedPct = Math.round((allowed / vol) * 100)\n        const droppedPct = 100 - allowedPct\n        return {\n          allowed,\n          dropped,\n          allowedPct,\n          droppedPct,\n          bucketFill: 0,\n          status: 'throttling' as const,\n          statusLabel: `Rate Limiting Active · ${droppedPct}% Dropped`,\n          latency: '0.51ms',\n          description: `Burst reservoir exhausted. Token bucket limiter is actively enforcing HTTP 429 throttling on ${dropped} req/s excess traffic.`,\n        }\n      }\n    } else {\n      // Sliding window mode\n      const windowLimit = 120\n      if (vol <= windowLimit) {\n        const allowedPct = 100\n        return {\n          allowed: vol,\n          dropped: 0,\n          allowedPct,\n          droppedPct: 0,\n          bucketFill: Math.round((vol / windowLimit) * 100),\n          status: 'optimal' as const,\n          statusLabel: 'Within Sliding Window Quota',\n          latency: '0.38ms',\n          description: `Current 60-second rolling window is ${Math.round((vol / windowLimit) * 100)}% utilized. No mitigation actions triggered.`,\n        }\n      } else {\n        const allowed = windowLimit\n        const dropped = vol - allowed\n        const allowedPct = Math.round((allowed / vol) * 100)\n        const droppedPct = 100 - allowedPct\n        return {\n          allowed,\n          dropped,\n          allowedPct,\n          droppedPct,\n          bucketFill: 100,\n          status: 'throttling' as const,\n          statusLabel: `Window Saturated · ${droppedPct}% Shed`,\n          latency: '0.48ms',\n          description: `Rolling time-window threshold exceeded (${vol} req/s > ${windowLimit} limit). Excess requests are rejected at edge proxy.`,\n        }\n      }\n    }\n  }, [simVolume, algorithm])\n\n  return (\n    <div data-slot=\"rate-limiting-config\" className={cn('mx-auto w-full max-w-6xl space-y-6', className)}>\n      {/* Header Section */}\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\">\n            <Badge variant=\"outline\" className=\"text-xs font-medium tracking-wide uppercase\">\n              <ShieldCheck className=\"text-primary size-3.5\" />\n              Edge Protection\n            </Badge>\n            <span className=\"text-muted-foreground text-xs\">Cloudflare & Upstash compatible</span>\n          </div>\n          <h1 className=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">\n            Rate Limiting & Traffic Protection\n          </h1>\n          <p className=\"text-muted-foreground text-sm\">\n            Configure DDoS mitigation, IP throttling, and per-tier request quotas.\n          </p>\n        </div>\n\n        {/* Header Controls */}\n        <div className=\"flex flex-wrap items-center gap-3\">\n          <div className=\"bg-card border-border flex items-center gap-3 rounded-lg border px-3 py-2 shadow-xs\">\n            <div className=\"flex flex-col\">\n              <span className=\"text-foreground text-xs font-semibold\">Global Protection</span>\n              <span className=\"text-muted-foreground text-xs tabular-nums\">\n                {globalProtection ? `${activeRulesCount} Active Rules` : 'Disabled (Bypassed)'}\n              </span>\n            </div>\n            <Switch checked={globalProtection} onCheckedChange={setGlobalProtection} />\n          </div>\n\n          <Button className=\"gap-1.5 shadow-xs\">\n            <Plus className=\"size-4\" />\n            <span>Add Rate Limit Rule</span>\n          </Button>\n        </div>\n      </div>\n\n      {/* 4 Health Cards */}\n      <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        {/* Card 1: Total Requests */}\n        <Card className=\"shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Total Requests / min</CardTitle>\n            <div className=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-md\">\n              <Activity className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-1\">\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">4,250 req/s</div>\n            <div className=\"flex items-center gap-1.5 text-xs\">\n              <Badge variant=\"success\" className=\"h-4.5 px-1 py-0 text-xs\">\n                <TrendingUp className=\"size-3\" />\n                +12.4%\n              </Badge>\n              <span className=\"text-muted-foreground tabular-nums\">255.0k / min · 99.98% ok</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Card 2: Blocked Attacks */}\n        <Card className=\"shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Blocked Attacks</CardTitle>\n            <div className=\"bg-destructive/10 text-destructive flex size-8 items-center justify-center rounded-md\">\n              <ShieldAlert className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-1\">\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">1,420 in 24h</div>\n            <div className=\"flex items-center gap-1.5 text-xs\">\n              <Badge variant=\"outline\" className=\"h-4.5 px-1.5 py-0 text-xs font-normal\">\n                Tier-1 Edge\n              </Badge>\n              <span className=\"text-muted-foreground truncate tabular-nums\">18 brute-force bursts</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Card 3: Active Throttles */}\n        <Card className=\"shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Active Throttles</CardTitle>\n            <div className=\"bg-warning/10 text-warning flex size-8 items-center justify-center rounded-md\">\n              <ZapOff className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-1\">\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">18 IPs</div>\n            <div className=\"flex items-center gap-1.5 text-xs\">\n              <span className=\"bg-warning inline-block size-1.5 rounded-full\"></span>\n              <span className=\"text-muted-foreground truncate tabular-nums\">4 edge clusters · Exp 15m</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Card 4: Median Latency Overhead */}\n        <Card className=\"shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Median Latency Overhead</CardTitle>\n            <div className=\"bg-info/10 text-info flex size-8 items-center justify-center rounded-md\">\n              <Timer className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-1\">\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">0.4ms</div>\n            <div className=\"flex items-center gap-1.5 text-xs\">\n              <span className=\"text-muted-foreground tabular-nums\">p99 &lt; 1.2ms · Multi-Region Redis</span>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n\n      {/* Interactive Token Bucket Visualizer */}\n      <Card className=\"shadow-xs\">\n        <CardHeader className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"space-y-1\">\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <CardTitle className=\"text-lg font-semibold\">Algorithm Simulation & Token Dynamics</CardTitle>\n              <Badge variant=\"outline\" className=\"text-xs font-normal\">\n                Interactive Sandbox\n              </Badge>\n            </div>\n            <CardDescription className=\"text-xs\">\n              Test traffic volume against token reservoir dynamics and rolling time windows.\n            </CardDescription>\n          </div>\n\n          {/* Algorithm Selector */}\n          <div className=\"flex flex-wrap items-center gap-2\">\n            <span className=\"text-muted-foreground text-xs font-medium\">Algorithm:</span>\n            <Select value={algorithm} onValueChange={(val) => setAlgorithm(val as 'token-bucket' | 'sliding-window')}>\n              <SelectTrigger className=\"w-52 text-xs\">\n                <SelectValue placeholder=\"Select algorithm\" />\n              </SelectTrigger>\n              <SelectContent>\n                <SelectItem value=\"token-bucket\">Token Bucket (Burst Tolerant)</SelectItem>\n                <SelectItem value=\"sliding-window\">Sliding Window Counter</SelectItem>\n              </SelectContent>\n            </Select>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"space-y-6\">\n          {/* Visual Algorithm Diagram / Pipeline */}\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            {/* Step 1 */}\n            <div className=\"bg-muted/30 border-border relative flex flex-col justify-between rounded-lg border p-3.5\">\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">\n                    {algorithm === 'token-bucket' ? '1. Refill Velocity' : '1. Time Window'}\n                  </span>\n                  <RefreshCw className=\"text-muted-foreground size-3.5\" />\n                </div>\n                <div className=\"text-foreground text-lg font-semibold tabular-nums\">\n                  {algorithm === 'token-bucket' ? '50 tokens / s' : '60s Window'}\n                </div>\n                <p className=\"text-muted-foreground text-xs\">\n                  {algorithm === 'token-bucket'\n                    ? 'Deterministic continuous refill into pool'\n                    : 'Rolling granular sub-window slices'}\n                </p>\n              </div>\n              <div className=\"mt-3\">\n                <Progress value={100} className=\"h-1.5\" />\n              </div>\n            </div>\n\n            {/* Step 2 */}\n            <div className=\"bg-muted/30 border-border relative flex flex-col justify-between rounded-lg border p-3.5\">\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">\n                    {algorithm === 'token-bucket' ? '2. Reservoir Capacity' : '2. Window Ceiling'}\n                  </span>\n                  <Database className=\"text-muted-foreground size-3.5\" />\n                </div>\n                <div className=\"text-foreground text-lg font-semibold tabular-nums\">\n                  {algorithm === 'token-bucket' ? '100 tokens max' : '120 req / window'}\n                </div>\n                <p className=\"text-muted-foreground text-xs\">\n                  {algorithm === 'token-bucket'\n                    ? `Pool status: ${simStats.bucketFill}% available`\n                    : `Window utilized: ${simStats.bucketFill}%`}\n                </p>\n              </div>\n              <div className=\"mt-3\">\n                <Progress value={simStats.bucketFill} className=\"h-1.5\" />\n              </div>\n            </div>\n\n            {/* Step 3 */}\n            <div className=\"bg-muted/30 border-border relative flex flex-col justify-between rounded-lg border p-3.5\">\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">\n                    3. Test Traffic Load\n                  </span>\n                  <Zap className=\"text-primary size-3.5\" />\n                </div>\n                <div className=\"text-foreground text-lg font-semibold tabular-nums\">{simVolume} req/s</div>\n                <p className=\"text-muted-foreground text-xs\">Simulated rate generated from slider</p>\n              </div>\n              <div className=\"mt-3\">\n                <Progress value={Math.min(100, Math.round((simVolume / 500) * 100))} className=\"h-1.5\" />\n              </div>\n            </div>\n\n            {/* Step 4 */}\n            <div className=\"bg-muted/30 border-border relative flex flex-col justify-between rounded-lg border p-3.5\">\n              <div className=\"space-y-1.5\">\n                <div className=\"flex items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">\n                    4. Edge Gate Verdict\n                  </span>\n                  {simStats.status === 'optimal' ? (\n                    <CheckCircle2 className=\"text-success size-3.5\" />\n                  ) : simStats.status === 'burst' ? (\n                    <AlertTriangle className=\"text-warning size-3.5\" />\n                  ) : (\n                    <ShieldAlert className=\"text-destructive size-3.5\" />\n                  )}\n                </div>\n                <div className=\"text-foreground text-lg font-semibold tabular-nums\">\n                  {simStats.allowed} Pass · {simStats.dropped} Drop\n                </div>\n                <p className=\"text-muted-foreground text-xs\">Overhead: {simStats.latency}</p>\n              </div>\n              <div className=\"mt-3\">\n                <div className=\"bg-secondary relative h-1.5 w-full overflow-hidden rounded-full\">\n                  <div\n                    className=\"bg-success absolute top-0 bottom-0 left-0 transition-colors duration-150\"\n                    style={{ width: `${simStats.allowedPct}%` }}\n                  />\n                  <div\n                    className=\"bg-destructive absolute top-0 right-0 bottom-0 transition-colors duration-150\"\n                    style={{ width: `${simStats.droppedPct}%` }}\n                  />\n                </div>\n              </div>\n            </div>\n          </div>\n\n          {/* Interactive Simulator Slider Box */}\n          <div className=\"bg-muted/20 border-border space-y-4 rounded-lg border p-4\">\n            <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n              <div className=\"space-y-0.5\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                  <Sliders className=\"text-primary size-4\" />\n                  <span className=\"text-foreground text-sm font-semibold\">Simulate Incoming Request Volume</span>\n                </div>\n                <p className=\"text-muted-foreground text-xs\">\n                  Drag the slider to stress-test the algorithm against burst spikes and DDoS loads.\n                </p>\n              </div>\n\n              {/* Current Rate Pill */}\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <Badge\n                  variant={\n                    simStats.status === 'optimal' ? 'success' : simStats.status === 'burst' ? 'warning' : 'destructive'\n                  }\n                  className=\"text-xs font-medium\"\n                >\n                  {simStats.statusLabel}\n                </Badge>\n                <div className=\"bg-card border-border rounded border px-2.5 py-1 font-mono text-sm font-bold tabular-nums\">\n                  {simVolume} req/s\n                </div>\n              </div>\n            </div>\n\n            {/* Slider */}\n            <div className=\"space-y-2 pt-2\">\n              <Slider\n                value={[simVolume]}\n                onValueChange={(val) => setSimVolume(val[0] ?? 120)}\n                min={10}\n                max={500}\n                step={10}\n                className=\"w-full\"\n              />\n              <div className=\"text-muted-foreground flex justify-between text-xs tabular-nums\">\n                <span>10 req/s (Low)</span>\n                <span>50 req/s (Refill Rate)</span>\n                <span>100 req/s (Burst Limit)</span>\n                <span>250 req/s (Heavy Spike)</span>\n                <span>500 req/s (DDoS Attack)</span>\n              </div>\n            </div>\n\n            {/* Simulation Visual Metrics & Split Bar */}\n            <div className=\"space-y-3 pt-2\">\n              {/* Split Bar */}\n              <div className=\"space-y-1.5\">\n                <div className=\"flex justify-between text-xs font-medium\">\n                  <span className=\"text-success flex items-center gap-1\">\n                    <span className=\"bg-success size-2 rounded-full\"></span>\n                    Allowed: {simStats.allowed} req/s ({simStats.allowedPct}%)\n                  </span>\n                  <span className=\"text-destructive flex items-center gap-1\">\n                    <span className=\"bg-destructive size-2 rounded-full\"></span>\n                    Rate Limited / 429: {simStats.dropped} req/s ({simStats.droppedPct}%)\n                  </span>\n                </div>\n\n                <div className=\"bg-muted border-border/50 relative h-2.5 w-full overflow-hidden rounded-full border\">\n                  <div\n                    className=\"bg-success absolute top-0 bottom-0 left-0 transition-colors duration-150\"\n                    style={{ width: `${simStats.allowedPct}%` }}\n                  />\n                  <div\n                    className=\"bg-destructive absolute top-0 right-0 bottom-0 transition-colors duration-150\"\n                    style={{ width: `${simStats.droppedPct}%` }}\n                  />\n                </div>\n              </div>\n\n              {/* Simulation Summary Description */}\n              <div className=\"bg-card border-border/80 flex items-start gap-2.5 rounded-md border p-3 text-xs\">\n                <Shield className=\"text-primary mt-0.5 size-4 shrink-0\" />\n                <p className=\"text-muted-foreground leading-relaxed\">{simStats.description}</p>\n              </div>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* Configured Rules Table Card */}\n      <Card className=\"shadow-xs\">\n        <CardHeader className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"space-y-1\">\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <CardTitle className=\"text-lg font-semibold\">Configured Rate Limiting Rules</CardTitle>\n              <Badge variant=\"secondary\" className=\"text-xs font-normal tabular-nums\">\n                {filteredRules.length} Policies\n              </Badge>\n            </div>\n            <CardDescription className=\"text-xs\">\n              Priority-ordered edge firewall rules evaluated sequentially for incoming traffic.\n            </CardDescription>\n          </div>\n\n          {/* Filter Search Bar */}\n          <div className=\"relative w-full sm:w-64\">\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 rules, paths, actions…\"\n              className=\"border-input bg-background placeholder:text-muted-foreground focus-visible:ring-ring/50 focus-visible:border-ring h-8.5 w-full rounded-md border pr-3 pl-8 text-xs shadow-xs outline-none focus-visible:ring-[3px]\"\n            />\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"p-0\">\n          <div className=\"overflow-x-auto\">\n            <Table>\n              <TableHeader>\n                <TableRow>\n                  <TableHead className=\"w-[280px]\">Rule Name & Scope</TableHead>\n                  <TableHead className=\"w-[220px]\">Path Matcher</TableHead>\n                  <TableHead className=\"w-[180px]\">Limit Threshold</TableHead>\n                  <TableHead className=\"w-[200px]\">Mitigation Action</TableHead>\n                  <TableHead className=\"w-[90px] text-center\">Status</TableHead>\n                  <TableHead className=\"w-[60px] text-right\">Actions</TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody>\n                {filteredRules.map((rule) => (\n                  <TableRow key={rule.id} className={cn(!rule.enabled && 'bg-muted/20 opacity-60')}>\n                    {/* Rule Name & Scope */}\n                    <TableCell>\n                      <div className=\"space-y-0.5\">\n                        <div className=\"flex flex-wrap items-center gap-2\">\n                          <span className=\"text-foreground font-mono text-xs font-semibold\">{rule.name}</span>\n                        </div>\n                        <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                          <span>{rule.scope}</span>\n                          <span>·</span>\n                          <span className=\"tabular-nums\">{rule.blocked24h} in 24h</span>\n                        </div>\n                      </div>\n                    </TableCell>\n\n                    {/* Path Matcher */}\n                    <TableCell>\n                      <div className=\"flex items-center gap-1.5\">\n                        <Badge variant=\"outline\" className=\"font-mono text-xs uppercase\">\n                          {rule.method}\n                        </Badge>\n                        <code className=\"bg-muted/60 border-border text-foreground rounded border px-1.5 py-0.5 font-mono text-xs\">\n                          {rule.path}\n                        </code>\n                      </div>\n                    </TableCell>\n\n                    {/* Limit Threshold */}\n                    <TableCell>\n                      <div className=\"space-y-0.5\">\n                        <div className=\"text-foreground font-mono text-xs font-medium tabular-nums\">\n                          {rule.limitThreshold}\n                        </div>\n                        <div className=\"text-muted-foreground text-xs\">Triggered {rule.lastTriggered}</div>\n                      </div>\n                    </TableCell>\n\n                    {/* Mitigation Action Badge */}\n                    <TableCell>\n                      <Badge variant={rule.actionVariant} className=\"text-xs font-medium\">\n                        <span\n                          className={cn(\n                            'mr-1 size-1.5 rounded-full',\n                            rule.actionVariant === 'warning'\n                              ? 'bg-warning'\n                              : rule.actionVariant === 'destructive'\n                                ? 'bg-destructive'\n                                : 'bg-secondary-foreground',\n                          )}\n                        />\n                        {rule.mitigationAction}\n                      </Badge>\n                    </TableCell>\n\n                    {/* Status Switch */}\n                    <TableCell className=\"text-center\">\n                      <Switch checked={rule.enabled} onCheckedChange={() => toggleRule(rule.id)} />\n                    </TableCell>\n\n                    {/* Actions Dropdown */}\n                    <TableCell className=\"text-right\">\n                      <DropdownMenu>\n                        <DropdownMenuTrigger asChild>\n                          <Button variant=\"ghost\" size=\"icon\" className=\"size-8\">\n                            <MoreHorizontal className=\"size-4\" />\n                            <span className=\"sr-only\">Open menu</span>\n                          </Button>\n                        </DropdownMenuTrigger>\n                        <DropdownMenuContent align=\"end\" className=\"w-48\">\n                          <DropdownMenuLabel className=\"text-xs\">Rule Configuration</DropdownMenuLabel>\n                          <DropdownMenuItem className=\"gap-2 text-xs\">\n                            <Edit3 className=\"size-3.5\" />\n                            <span>Edit Rule</span>\n                          </DropdownMenuItem>\n                          <DropdownMenuItem className=\"gap-2 text-xs\">\n                            <Activity className=\"size-3.5\" />\n                            <span>View Metrics</span>\n                          </DropdownMenuItem>\n                          <DropdownMenuItem className=\"gap-2 text-xs\">\n                            <Copy className=\"size-3.5\" />\n                            <span>Duplicate Rule</span>\n                          </DropdownMenuItem>\n                          <DropdownMenuSeparator />\n                          <DropdownMenuItem className=\"text-destructive focus:text-destructive gap-2 text-xs\">\n                            <Trash2 className=\"size-3.5\" />\n                            <span>Delete Rule</span>\n                          </DropdownMenuItem>\n                        </DropdownMenuContent>\n                      </DropdownMenu>\n                    </TableCell>\n                  </TableRow>\n                ))}\n              </TableBody>\n            </Table>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/RateLimitingConfig.tsx"
    }
  ],
  "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/dropdown-menu.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/slider.json",
    "https://uipkge.dev/r/react/switch.json",
    "https://uipkge.dev/r/react/table.json"
  ],
  "description": "Cloudflare/Upstash style API rate limiting rules builder and token bucket traffic monitor with 4 health metrics cards, interactive token bucket vs sliding window simulation slider, and configured mitigation rules table with status controls and contextual action menus.",
  "categories": [
    "devops",
    "app",
    "dashboard"
  ]
}