{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select-004",
  "type": "registry:block",
  "title": "Select 004",
  "author": "Kenney <https://kenney.nl>",
  "description": "A distinct, short sound indicating a successful selection, ideal for button presses, menu choices, or confirming an option in an interactive interface.",
  "files": [
    {
      "path": "registry/soundcn/sounds/select-004/select-004.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const select004Sound: SoundAsset = {\n  name: \"select-004\",\n  dataUri: \"data:audio/mpeg;base64,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AVNYohOStTSVvL4F2y3CbqQbSE611sHXWtd4Kkw2K8LTwg460iNJGmERyAOaTIYA2BEJQj06/vfgXf//ofhnucsIIApayAAEGeIpvNIWVrTlzGiVw+JIk6Ylmg5AyII2F4uBoC43JAHBIMITxA/7tbs3z+NKXsdusNZS//tSxBwACjDFPYYEdgFNCym0V+E2MhAsQHBEBwZBFD3QIv/0TOok1lFDXDmMTtUtu+jBlrIBAZLQxcSZo1iRGM8dn8ujqjYYnKj7/G6q2Kyn6dJ2gSQVugmNCgwkZnwwLAkJVCVAlgq4S9y57qVBV0sDRUBAIWBwLBoTlBB//574igNfq4wBcIAwEb11K32V9FS6bIoHF4z0n7LW7NMiaJqmoUahpb+pH/X////72SYynYg4n/Rl3ZaI5REpSgUUBH///3//9Z2NCobCmRZrb///+1LEJ4AJKP8ppuC0QR0gIgFMFlD/R1zT7M6a1B7+xxW5E1irtNabZGUDJfSLiYgDF/////+b+oiHSzP/KjcRFVY2pSsYSAIUFv//7P8NLd3tgriINPoAC0AZgAD6ABEeE8eOKP7Lrttv6/a2ZtxTtWEJem6LaSWbSW//3T//WyUNqn//f9HBf9UAYDg4Bf///1v/ukv////Uoon+Ih5QFAwADBadAkKAQNKQEYsjlFWTUma3ET8hPelUOQIRaIxIeLiKJLM///U47//p/N//5v/7UsQ9AAldqPUqvLRBJTVc9eCceP6sc//HQWkh1v/////81v///+g8b/Nc1lGrVT/jA2MOBtxjRiWChJIgyUsOH3Vv/////+7///+v//939Z8YAb4YTCAyHWkgwYPClBQEBoKpsoiQVM//////u///////3D+7gv8wfkC9PqlbcewVhyLD948iFw/f/////93///9f//7j5HAN0wOcCYOqsNKSS6kQIk0xBkFToif/////9H//////+ipMQU1Fqqo/vIBcMFgA9D8QDUFBIBOg//tSxFCDxCQUvg/hgECPAxgB/SQImDcnuavXnxAZ/////+j////b//9B8dQYiYOABFnkSvRBiYUaiyhmPCV3/////6P//////9E/14RIHhRg49/MjGjKAQuet9nBgbAgWGIT9IIA6R//////R////t//+gAlpmsJnTAgoHEXQeiGAOBMRyxU7EsSyevxYZmZ+/ixYsMH8OCQJBg5q8mGB45q8zM18TZ2ZmZ++wsMzM/9g4MDxz2FhgeLOuvMDxZ1169e/Vs7MzNf7CwzM3/YODD/+1LEjAPEUBi+D+ngAIsCWAH9MAhY5jBwYLHNbXmCxzW169ffV5mZn7+LDAzP38WGBgs5hYYGCymr15gspdeZn6/215mfr/osWH6/6LDhY5LCxYsc669eeOc2vXr38bXr178sLFi9+WFixZTViyhMQU1FMy4xMAABow4GvAQJZEsykS02YZUw0AEDpZYJQNgbCUtw6EoSjJ7TkyMj57VpiYrbORBQkjLEiJEjjHEiSWMcSJJa5pIlWuaRRnzJFGexxsz6qqr1VVXmaqvMzOeZmf/7UsTEA8SUGr4P6YBAgQLYAf0MEM9VM56qq1qqq3ybVa8zM95IkZxqJGzjUSSr1RJKteTarzJGZ8yRmfVHSaFBRUKCjgUGOigtTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//tSxP+CBSgmvg/tgILetJ/lvDAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/+1LE6QPR1Xz8TDDJiAAANIAAAARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==\",\n  duration: 0.380,\n  format: \"mp3\",\n  license: \"CC0\",\n  author: \"Kenney\",\n};\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-types.ts",
      "content": "export interface SoundAsset {\r\n  /** Unique identifier for the sound */\r\n  name: string;\r\n  /** Base64-encoded data URI (data:audio/mpeg;base64,...) */\r\n  dataUri: string;\r\n  /** Duration in seconds */\r\n  duration: number;\r\n  /** Audio format */\r\n  format: \"mp3\" | \"wav\" | \"ogg\";\r\n  /** License identifier */\r\n  license: \"CC0\" | \"OGA-BY\" | \"MIT\";\r\n  /** Original author/creator */\r\n  author: string;\r\n}\r\n\r\nexport interface UseSoundOptions {\r\n  /** Volume level from 0 to 1. Default: 1 */\r\n  volume?: number;\r\n  /** Playback speed multiplier. Default: 1 */\r\n  playbackRate?: number;\r\n  /** If true, calling play() stops current playback first. Default: false */\r\n  interrupt?: boolean;\r\n  /** If false, play() does nothing. Useful for user preferences. Default: true */\r\n  soundEnabled?: boolean;\r\n  /** Called when playback starts */\r\n  onPlay?: () => void;\r\n  /** Called when playback ends naturally */\r\n  onEnd?: () => void;\r\n  /** Called when pause() is called */\r\n  onPause?: () => void;\r\n  /** Called when stop() is called */\r\n  onStop?: () => void;\r\n}\r\n\r\nexport type PlayFunction = (overrides?: {\r\n  volume?: number;\r\n  playbackRate?: number;\r\n}) => void;\r\n\r\nexport interface SoundControls {\r\n  stop: () => void;\r\n  pause: () => void;\r\n  isPlaying: boolean;\r\n  duration: number | null;\r\n  sound: SoundAsset;\r\n}\r\n\r\nexport type UseSoundReturn = readonly [PlayFunction, SoundControls];\r\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-engine.ts",
      "content": "let audioContext: AudioContext | null = null;\nconst bufferCache = new Map<string, AudioBuffer>();\n\nexport function getAudioContext(): AudioContext {\n  if (!audioContext) {\n    audioContext = new AudioContext();\n  }\n  return audioContext;\n}\n\nexport async function decodeAudioData(dataUri: string): Promise<AudioBuffer> {\n  const cached = bufferCache.get(dataUri);\n  if (cached) return cached;\n\n  const ctx = getAudioContext();\n  const base64 = dataUri.split(\",\")[1];\n  const binaryString = atob(base64);\n  const bytes = new Uint8Array(binaryString.length);\n  for (let i = 0; i < binaryString.length; i++) {\n    bytes[i] = binaryString.charCodeAt(i);\n  }\n\n  const audioBuffer = await ctx.decodeAudioData(bytes.buffer.slice(0));\n  bufferCache.set(dataUri, audioBuffer);\n  return audioBuffer;\n}\n\nexport interface PlaySoundOptions {\n  volume?: number;\n  playbackRate?: number;\n  onEnd?: () => void;\n}\n\nexport interface SoundPlayback {\n  stop: () => void;\n}\n\nexport async function playSound(\n  dataUri: string,\n  options: PlaySoundOptions = {}\n): Promise<SoundPlayback> {\n  const { volume = 1, playbackRate = 1, onEnd } = options;\n  const ctx = getAudioContext();\n  if (ctx.state === \"suspended\") {\n    await ctx.resume();\n  }\n\n  const buffer = await decodeAudioData(dataUri);\n  const source = ctx.createBufferSource();\n  const gain = ctx.createGain();\n\n  source.buffer = buffer;\n  source.playbackRate.value = playbackRate;\n  gain.gain.value = volume;\n\n  source.connect(gain);\n  gain.connect(ctx.destination);\n\n  source.onended = () => {\n    onEnd?.();\n  };\n\n  source.start(0);\n\n  return {\n    stop: () => {\n      try {\n        source.stop();\n      } catch {\n        // No-op if already stopped.\n      }\n    },\n  };\n}\n",
      "type": "registry:lib"
    }
  ],
  "meta": {
    "duration": 0.38,
    "format": "mp3",
    "sizeKb": 4,
    "license": "CC0",
    "tags": [
      "select",
      "004"
    ],
    "keywords": [
      "click",
      "tap",
      "press",
      "choice",
      "confirmation",
      "menu",
      "button",
      "ui element",
      "interactive",
      "feedback",
      "short",
      "crisp",
      "subtle",
      "positive",
      "game ui",
      "highlight",
      "activation",
      "option",
      "select",
      "affirm"
    ]
  },
  "categories": [
    "select"
  ]
}