{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drop-upload",
  "title": "Drop Upload",
  "description": "A file card drops in and fills an upload bar until a check confirms it.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "registryDependencies": ["@remocn/gsh"],
  "files": [
    {
      "path": "registry/remocn/drop-upload/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont as loadInstrument } from \"@remotion/google-fonts/InstrumentSans\";\nimport { loadFont as loadJetBrains } from \"@remotion/google-fonts/JetBrainsMono\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  spring,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\nimport type { GradientParams } from \"@/lib/remocn/gsh/gradient-engine\";\nimport { GshGround } from \"@/lib/remocn/gsh/gsh-ground\";\nimport type { GshPresetId } from \"@/lib/remocn/gsh/presets\";\n\nconst instrument = loadInstrument(\"normal\", {\n  weights: [\"400\"],\n  subsets: [\"latin\"],\n});\nconst jetbrains = loadJetBrains(\"normal\", {\n  weights: [\"300\", \"400\"],\n  subsets: [\"latin\"],\n});\n\nconst ENTER = Easing.bezier(0.32, 0.72, 0, 1);\nconst EXIT = Easing.bezier(0.55, 0, 1, 0.45);\nconst FILL = Easing.bezier(0.83, 0, 0.17, 1);\nconst HEAVY = { mass: 1, damping: 26, stiffness: 120 };\nconst CARD = { mass: 0.8, damping: 18, stiffness: 160 };\nconst CHIP = { mass: 0.5, damping: 12, stiffness: 200 };\nconst MORPH = { damping: 200 };\n\nconst B = {\n  zone: -8,\n  title: -2,\n  fly: 6,\n  hover: 30,\n  drop: 54,\n  collapse: 60,\n  info: 72,\n  progress: 78,\n  done: 114,\n  end: 162,\n};\n\nconst ramp = (f: number, start: number, dur: number, easing = ENTER) =>\n  interpolate(f, [start, start + dur], [0, 1], {\n    extrapolateLeft: \"clamp\",\n    extrapolateRight: \"clamp\",\n    easing,\n  });\n\nconst mix = (a: number, b: number, t: number) => a + (b - a) * t;\n\nfunction FileTile({\n  kind,\n  accent,\n  w,\n}: {\n  kind: string;\n  accent: string;\n  w: number;\n}) {\n  const h = w * 1.26;\n  const fold = w * 0.27;\n  return (\n    <div style={{ position: \"relative\", width: w, height: h }}>\n      <svg\n        width={w}\n        height={h}\n        viewBox={`0 0 ${w} ${h}`}\n        style={{ position: \"absolute\", inset: 0, overflow: \"visible\" }}\n        aria-hidden\n      >\n        <defs>\n          <linearGradient id=\"du-paper\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n            <stop offset=\"0\" stopColor=\"#ffffff\" />\n            <stop offset=\"1\" stopColor=\"#eceef6\" />\n          </linearGradient>\n        </defs>\n        <path\n          d={`M ${w * 0.1} 0 H ${w - fold} L ${w} ${fold} V ${h - w * 0.1} Q ${w} ${h} ${w * 0.9} ${h} H ${w * 0.1} Q 0 ${h} 0 ${h - w * 0.1} V ${w * 0.1} Q 0 0 ${w * 0.1} 0 Z`}\n          fill=\"url(#du-paper)\"\n          stroke=\"rgba(20,24,48,0.1)\"\n        />\n        <path\n          d={`M ${w - fold} 0 V ${fold * 0.72} Q ${w - fold} ${fold} ${w - fold * 0.72} ${fold} H ${w} Z`}\n          fill=\"#d7dbea\"\n        />\n        {[0.3, 0.4, 0.5, 0.6].map((y, i) => (\n          <rect\n            key={y}\n            x={w * 0.16}\n            y={h * y}\n            width={w * (i === 3 ? 0.36 : i === 0 ? 0.4 : 0.62)}\n            height={w * 0.045}\n            rx={w * 0.022}\n            fill={i === 0 ? \"#b9bfd6\" : \"#d9dce8\"}\n          />\n        ))}\n      </svg>\n      <div\n        style={{\n          position: \"absolute\",\n          left: w * 0.12,\n          bottom: w * 0.12,\n          height: w * 0.24,\n          padding: `0 ${w * 0.08}px`,\n          borderRadius: w * 0.06,\n          background: accent,\n          color: \"#fff\",\n          fontFamily: jetbrains.fontFamily,\n          fontSize: w * 0.15,\n          display: \"flex\",\n          alignItems: \"center\",\n          letterSpacing: \"0.04em\",\n          boxShadow: \"inset 0 1px 0 rgba(255,255,255,0.3)\",\n        }}\n      >\n        {kind}\n      </div>\n    </div>\n  );\n}\n\nexport interface DropUploadProps {\n  theme?: \"dark\" | \"light\";\n  accent?: string;\n  title?: string;\n  fileName?: string;\n  fileKind?: string;\n  fileSize?: string;\n  hint?: string;\n  history?: { name: string; kind: string; size: string; ago: string }[];\n  ground?: GshPresetId;\n  groundParams?: Partial<GradientParams>;\n}\n\nexport function DropUpload({\n  theme = \"dark\",\n  accent = \"#3B5BFD\",\n  title = \"Drop in your launch notes\",\n  fileName = \"launch-notes.md\",\n  fileKind = \"MD\",\n  fileSize = \"2.4 MB\",\n  hint = \"MD, PDF or ZIP · up to 50 MB\",\n  history = [\n    {\n      name: \"changelog-2.0.pdf\",\n      kind: \"PDF\",\n      size: \"1.1 MB\",\n      ago: \"4 min ago\",\n    },\n    { name: \"press-kit.zip\", kind: \"ZIP\", size: \"18.6 MB\", ago: \"12 min ago\" },\n  ],\n  ground,\n  groundParams,\n}: DropUploadProps) {\n  const frame = useCurrentFrame();\n  const { width, height, fps } = useVideoConfig();\n  const dark = theme === \"dark\";\n  const portrait = height > width * 1.2;\n  const stageW = portrait ? 760 : 1280;\n  const stageH = portrait ? 1351 : 720;\n  const sc = width / stageW;\n\n  const ink = dark ? \"#f1f2fb\" : \"#151824\";\n  const soft = dark ? \"rgba(225,228,250,0.7)\" : \"rgba(21,24,36,0.66)\";\n  const muted = dark ? \"rgba(225,228,250,0.46)\" : \"rgba(21,24,36,0.44)\";\n  const dash = dark ? \"rgba(225,228,250,0.34)\" : \"rgba(21,24,36,0.26)\";\n  const base = dark ? \"#11141f\" : \"#ffffff\";\n  const rowShadow = (k: number) =>\n    dark\n      ? `0 0 0 1px rgba(255,255,255,${0.08 * k}), 0 40px 90px -24px rgba(0,2,14,${0.7 * k})`\n      : `0 0 0 1px rgba(20,24,48,${0.07 * k}), 0 1px 3px rgba(20,24,48,${0.06 * k}), 0 36px 80px -24px rgba(20,30,70,${0.22 * k})`;\n  const accentMix = (pct: number, base: string) =>\n    `color-mix(in oklab, ${accent} ${pct}%, ${base})`;\n\n  const zoneW = portrait ? 564 : 760;\n  const zoneH = portrait ? 440 : 320;\n  const rowW = portrait ? 564 : 760;\n  const rowH = 104;\n  const cx = stageW / 2;\n  const cy = portrait ? 640 : 412;\n  const titleSize = portrait ? 50 : 60;\n  const titleGap = portrait ? 56 : 44;\n\n  const zoneIn = spring({ frame: frame - B.zone, fps, config: HEAVY });\n  const titleIn = ramp(frame, B.title, 15);\n  const collapse = spring({ frame: frame - B.collapse, fps, config: MORPH });\n  const highlight =\n    ramp(frame, B.hover - 8, 12) * (1 - ramp(frame, B.collapse, 8, EXIT));\n  const breathe =\n    Math.sin(((frame - B.hover) / 22) * Math.PI * 2) * 0.012 * highlight;\n  const dropHit = spring({ frame: frame - B.drop - 6, fps, config: CHIP });\n  const dropPunch =\n    0.03 *\n    Math.sin(Math.PI * Math.min(1, dropHit)) *\n    (1 - ramp(frame, B.drop + 14, 6));\n\n  const solid = ramp(frame, B.collapse - 2, 14);\n  const tint = accentMix(Math.round(12 * highlight), \"transparent\");\n  const radius = mix(24, 20, collapse);\n  const zW = mix(zoneW, rowW, collapse);\n  const zH = mix(zoneH, rowH, collapse);\n  const zL = cx - zW / 2;\n  const zT = cy - zH / 2;\n\n  const startX = portrait ? cx + 260 : cx + 560;\n  const startY = portrait ? cy + 600 : cy + 360;\n  const ctrlX = portrait ? cx + 300 : cx + 300;\n  const ctrlY = portrait ? cy - 200 : cy - 300;\n  const hoverX = cx + 30;\n  const hoverY = cy - (portrait ? 84 : 66);\n  const flyT = (f: number) =>\n    spring({ frame: f - B.fly, fps, config: CARD, durationInFrames: 26 });\n  const bez = (t: number, a: number, c: number, b: number) =>\n    (1 - t) * (1 - t) * a + 2 * (1 - t) * t * c + t * t * b;\n  const p = flyT(frame);\n  const pPrev = flyT(frame - 1);\n  let tx = bez(p, startX, ctrlX, hoverX);\n  let ty = bez(p, startY, ctrlY, hoverY);\n  const speed = Math.hypot(\n    tx - bez(pPrev, startX, ctrlX, hoverX),\n    ty - bez(pPrev, startY, ctrlY, hoverY),\n  );\n  const hoverAmt = ramp(frame, B.hover - 4, 10) * (1 - ramp(frame, B.drop, 8));\n  tx += Math.sin((frame - B.hover) / 7) * 5 * hoverAmt;\n  ty += Math.cos((frame - B.hover) / 9) * 5 * hoverAmt;\n  let rot = mix(28, -7, p) + Math.sin((frame - B.hover) / 10) * 2.5 * hoverAmt;\n  let lift = mix(1.2, 0.74, p);\n  const drop = ramp(frame, B.drop, 8, EXIT);\n  lift *= mix(1, 0.84, drop);\n  ty += 16 * drop;\n  rot = mix(rot, -3, drop);\n  const tileW = 112;\n  const iconW = 48;\n  const iconX = cx - rowW / 2 + 26 + iconW / 2;\n  const iconY = cy;\n  const toRow = spring({ frame: frame - B.collapse - 2, fps, config: MORPH });\n  tx = mix(tx, iconX, toRow);\n  ty = mix(ty, iconY, toRow);\n  rot = mix(rot, 0, toRow);\n  const tileScale = mix(lift, iconW / tileW, toRow);\n  const tileBlur = Math.min(6, speed * 0.1);\n  const shadowAmt = (1 - drop * 0.7) * (1 - toRow);\n\n  const zoneContent = 1 - ramp(frame, B.collapse - 2, 8, EXIT);\n  const info = ramp(frame, B.info, 12);\n  const prog = interpolate(frame, [B.progress, B.done - 4], [0, 1], {\n    extrapolateLeft: \"clamp\",\n    extrapolateRight: \"clamp\",\n    easing: FILL,\n  });\n  const done = spring({ frame: frame - B.done, fps, config: CHIP });\n  const doneIn = ramp(frame, B.done, 6);\n  const pct = Math.round(prog * 100);\n\n  const camIn = spring({ frame: frame + 8, fps, config: HEAVY });\n  const rowFocus = spring({ frame: frame - B.collapse, fps, config: HEAVY });\n  const rotX = mix(18, 4, camIn) - 2.5 * rowFocus;\n  const rotY = mix(14, 4, camIn) - 4 * rowFocus;\n  const push =\n    mix(0.9, 1, camIn) +\n    0.025 * ramp(frame, 0, B.end, Easing.linear) +\n    (portrait ? 0.06 : 0.26) * rowFocus;\n  const titleTop0 = cy - zoneH / 2 - titleGap - titleSize * 1.05;\n  const titleTop1 = cy - rowH / 2 - (portrait ? 44 : 34) - titleSize * 1.05;\n  const titleTop = mix(titleTop0, titleTop1, rowFocus);\n  const histH = 84;\n  const histGap = 14;\n  const shown = portrait ? history : [];\n  const listBottom = cy + rowH / 2 + shown.length * (histH + histGap);\n  const groupMid = (titleTop1 + listBottom) / 2;\n  const camY = rowFocus * (groupMid - cy) * 0.9;\n\n  const resolvedGround: GshPresetId =\n    ground ?? (dark ? \"earthshine\" : \"paper-crease\");\n  const resolvedParams =\n    groundParams ??\n    (dark\n      ? undefined\n      : {\n          colors: [\"#9db8e6\", \"#d4e1f4\", \"#eef2f8\", \"#2c4f9e\"],\n          background: \"#f1f3f6\",\n        });\n\n  return (\n    <AbsoluteFill\n      style={{ fontFamily: instrument.fontFamily, overflow: \"hidden\" }}\n    >\n      <GshGround\n        preset={resolvedGround}\n        params={resolvedParams}\n        timeOffset={2}\n        timeScale={0.5}\n      />\n      <div\n        style={{\n          position: \"absolute\",\n          left: 0,\n          top: 0,\n          width: stageW,\n          height: stageH,\n          transform: `scale(${sc})`,\n          transformOrigin: \"0 0\",\n          perspective: 2000,\n        }}\n      >\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            transformStyle: \"preserve-3d\",\n            transformOrigin: `${cx}px ${cy}px`,\n            transform: `translateY(${-camY * push}px) scale(${push}) rotateX(${rotX}deg) rotateY(${rotY}deg)`,\n          }}\n        >\n          <div\n            style={{\n              position: \"absolute\",\n              left: 40,\n              right: 40,\n              top: titleTop,\n              height: titleSize * 1.25,\n              overflow: \"hidden\",\n              textAlign: \"center\",\n            }}\n          >\n            <div\n              style={{\n                fontSize: titleSize,\n                lineHeight: 1.15,\n                letterSpacing: \"-0.035em\",\n                fontWeight: 400,\n                color: ink,\n                transform: `translateY(${mix(105, 0, titleIn)}%)`,\n              }}\n            >\n              {title}\n            </div>\n          </div>\n\n          <div\n            style={{\n              position: \"absolute\",\n              left: zL,\n              top: zT,\n              width: zW,\n              height: zH,\n              borderRadius: radius,\n              background: `linear-gradient(${tint}, ${tint}), color-mix(in oklab, ${base} ${Math.round(mix(dark ? 58 : 52, 100, solid))}%, transparent)`,\n              boxShadow: rowShadow(solid),\n              opacity: ramp(frame, -6, 8),\n              transform: `translateY(${mix(60, 0, zoneIn)}px) scale(${mix(0.94, 1, zoneIn) * (1 + breathe + dropPunch)})`,\n              overflow: \"hidden\",\n            }}\n          >\n            <svg\n              width={zW}\n              height={zH}\n              style={{ position: \"absolute\", inset: 0, opacity: zoneContent }}\n              aria-hidden\n            >\n              <rect\n                x={0.75}\n                y={0.75}\n                width={Math.max(0, zW - 1.5)}\n                height={Math.max(0, zH - 1.5)}\n                rx={radius - 0.75}\n                fill=\"none\"\n                stroke={\n                  highlight > 0.02\n                    ? accentMix(Math.round(85 * highlight), dash)\n                    : dash\n                }\n                strokeWidth={1.5}\n                strokeDasharray=\"9 7\"\n                strokeDashoffset={-frame * 0.7 * (0.25 + highlight)}\n              />\n            </svg>\n            <div\n              style={{\n                position: \"absolute\",\n                inset: 0,\n                display: \"flex\",\n                flexDirection: \"column\",\n                alignItems: \"center\",\n                justifyContent: \"center\",\n                gap: 14,\n                opacity: zoneContent,\n                transform: `translateY(${36 * highlight}px) scale(${mix(0.94, 1, zoneContent)})`,\n              }}\n            >\n              <div\n                style={{\n                  width: 44,\n                  height: 44,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  transform: `scale(${mix(1, 0.6, highlight)})`,\n                  opacity: 1 - highlight,\n                }}\n              >\n                <svg viewBox=\"0 0 24 24\" width={34} height={34} aria-hidden>\n                  <path\n                    d=\"M12 15V4M7.5 8.5 12 4l4.5 4.5M5 14v4.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V14\"\n                    fill=\"none\"\n                    stroke={soft}\n                    strokeWidth={1.5}\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                  />\n                </svg>\n              </div>\n              <div\n                style={{\n                  position: \"relative\",\n                  height: 28,\n                  width: zW - 60,\n                  textAlign: \"center\",\n                }}\n              >\n                <div\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    fontSize: 21,\n                    color: ink,\n                    letterSpacing: \"-0.01em\",\n                    opacity: 1 - highlight,\n                    transform: `translateY(${-8 * highlight}px)`,\n                  }}\n                >\n                  Drag and drop a file, or{\" \"}\n                  <span\n                    style={{\n                      color: dark ? accentMix(50, \"#ffffff\") : accent,\n                      textDecoration: \"underline\",\n                      textUnderlineOffset: 4,\n                      textDecorationThickness: 1,\n                    }}\n                  >\n                    browse\n                  </span>\n                </div>\n                <div\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    fontSize: 21,\n                    color: dark ? \"#ffffff\" : accent,\n                    opacity: highlight,\n                    transform: `translateY(${8 * (1 - highlight)}px)`,\n                  }}\n                >\n                  Release to upload\n                </div>\n              </div>\n              <div\n                style={{\n                  fontFamily: jetbrains.fontFamily,\n                  fontSize: 17,\n                  color: muted,\n                }}\n              >\n                {hint}\n              </div>\n            </div>\n\n            <div\n              style={{\n                position: \"absolute\",\n                left: 26 + iconW + 20,\n                right: 26,\n                top: 0,\n                height: rowH,\n                opacity: info,\n                display: frame >= B.info ? \"block\" : \"none\",\n              }}\n            >\n              <div\n                style={{\n                  position: \"absolute\",\n                  left: 0,\n                  right: 64,\n                  top: 24,\n                  display: \"flex\",\n                  alignItems: \"baseline\",\n                  gap: 12,\n                  transform: `translateY(${mix(12, 0, info)}px)`,\n                }}\n              >\n                <span\n                  style={{ fontSize: 21, color: ink, letterSpacing: \"-0.01em\" }}\n                >\n                  {fileName}\n                </span>\n                <span\n                  style={{\n                    fontFamily: jetbrains.fontFamily,\n                    fontSize: 17,\n                    color: muted,\n                  }}\n                >\n                  {fileSize}\n                </span>\n                <div style={{ flex: 1 }} />\n                <span\n                  style={{\n                    position: \"relative\",\n                    fontSize: 17,\n                    color: soft,\n                    width: 110,\n                    textAlign: \"right\",\n                  }}\n                >\n                  <span\n                    style={{\n                      position: \"absolute\",\n                      right: 0,\n                      opacity: 1 - doneIn,\n                    }}\n                  >\n                    Uploading\n                  </span>\n                  <span\n                    style={{\n                      position: \"absolute\",\n                      right: 0,\n                      color: dark ? accentMix(45, \"#ffffff\") : accent,\n                      opacity: doneIn,\n                      transform: `translateY(${mix(8, 0, doneIn)}px)`,\n                    }}\n                  >\n                    Uploaded\n                  </span>\n                </span>\n              </div>\n              <div\n                style={{\n                  position: \"absolute\",\n                  left: 0,\n                  right: 64,\n                  top: 64,\n                  height: 6,\n                  borderRadius: 3,\n                  background: dark\n                    ? \"rgba(255,255,255,0.08)\"\n                    : \"rgba(20,24,48,0.07)\",\n                  overflow: \"hidden\",\n                }}\n              >\n                <div\n                  style={{\n                    width: `${prog * 100}%`,\n                    height: \"100%\",\n                    borderRadius: 3,\n                    background: accent,\n                  }}\n                />\n              </div>\n              <div\n                style={{\n                  position: \"absolute\",\n                  right: 0,\n                  top: (rowH - 40) / 2,\n                  width: 40,\n                  height: 40,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                }}\n              >\n                <span\n                  style={{\n                    position: \"absolute\",\n                    fontFamily: jetbrains.fontFamily,\n                    fontSize: 17,\n                    color: muted,\n                    opacity: 1 - doneIn,\n                    fontVariantNumeric: \"tabular-nums\",\n                  }}\n                >\n                  {pct}%\n                </span>\n                <div\n                  style={{\n                    width: 40,\n                    height: 40,\n                    borderRadius: 20,\n                    background: accent,\n                    boxShadow: \"inset 0 1px 0 rgba(255,255,255,0.25)\",\n                    transform: `scale(${done})`,\n                    opacity: doneIn,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"center\",\n                  }}\n                >\n                  <svg viewBox=\"0 0 24 24\" width={22} height={22} aria-hidden>\n                    <path\n                      d=\"m6 12.5 4 4 8-9\"\n                      fill=\"none\"\n                      stroke=\"#fff\"\n                      strokeWidth={2.2}\n                      strokeLinecap=\"round\"\n                      strokeLinejoin=\"round\"\n                      strokeDasharray={20}\n                      strokeDashoffset={20 * (1 - ramp(frame, B.done + 2, 8))}\n                    />\n                  </svg>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          {shown.map((h, i) => {\n            const at = B.info + 2 + i * 5;\n            const k = spring({ frame: frame - at, fps, config: CARD });\n            return (\n              <div\n                key={h.name}\n                style={{\n                  position: \"absolute\",\n                  left: cx - rowW / 2,\n                  top: cy + rowH / 2 + histGap + i * (histH + histGap),\n                  width: rowW,\n                  height: histH,\n                  borderRadius: 20,\n                  background: base,\n                  boxShadow: rowShadow(0.55),\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 20,\n                  padding: \"0 26px 0 32px\",\n                  opacity: ramp(frame, at, 8),\n                  transform: `translateY(${mix(28, 0, k)}px)`,\n                }}\n              >\n                <FileTile kind={h.kind} accent={accent} w={38} />\n                <span\n                  style={{ fontSize: 21, color: ink, letterSpacing: \"-0.01em\" }}\n                >\n                  {h.name}\n                </span>\n                <span\n                  style={{\n                    fontFamily: jetbrains.fontFamily,\n                    fontSize: 17,\n                    color: muted,\n                  }}\n                >\n                  {h.size}\n                </span>\n                <div style={{ flex: 1 }} />\n                <span style={{ fontSize: 17, color: muted }}>{h.ago}</span>\n              </div>\n            );\n          })}\n\n          <div\n            style={{\n              position: \"absolute\",\n              left: tx - tileW / 2,\n              top: ty - (tileW * 1.26) / 2,\n              transform: `rotate(${rot}deg) scale(${tileScale})`,\n              filter: [\n                tileBlur > 0.3 ? `blur(${tileBlur}px)` : \"\",\n                `drop-shadow(0 ${mix(4, 34, shadowAmt)}px ${mix(6, 36, shadowAmt)}px rgba(4,6,30,${dark ? 0.55 : 0.22}))`,\n              ].join(\" \"),\n              opacity: ramp(frame, B.fly, 4),\n            }}\n          >\n            <FileTile kind={fileKind} accent={accent} w={tileW} />\n          </div>\n        </div>\n      </div>\n    </AbsoluteFill>\n  );\n}\n\nexport default DropUpload;\n",
      "type": "registry:component",
      "target": "components/remocn/drop-upload.tsx"
    }
  ],
  "type": "registry:component"
}
