{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "impact-punch-medium-002",
  "type": "registry:block",
  "title": "Impact Punch Medium 002",
  "author": "Kenney <https://kenney.nl>",
  "description": "A distinct, medium punch sound, useful for confirming a successful game attack, a satisfying form submission, or a robust button press.",
  "files": [
    {
      "path": "registry/soundcn/sounds/impact-punch-medium-002/impact-punch-medium-002.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const impactPunchMedium002Sound: SoundAsset = {\n  name: \"impact-punch-medium-002\",\n  dataUri: \"data:audio/mpeg;base64,SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYyLjMuMTAwAAAAAAAAAAAAAAD/+1DAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAABYAABLFABYWFhYhISEhISwsLCw3Nzc3N0JCQkJNTU1NTVhYWFhkZGRkZG9vb296enp6eoWFhYWQkJCQkJubm5ubpqamprKysrKyvb29vcjIyMjI09PT097e3t7e6enp6fT09PT0/////wAAAABMYXZjNjIuMTEAAAAAAAAAAAAAAAAkA3wAAAAAAAASxW80hqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//tQxAAACDirLM0Ea8G/qSZquIAAAEKAMHNJmSUGYBFkENF2OJDli3n0xjGMa48xgAAAAAAm///f/Xd0RERERHd3d3d0RBAIAgCYPg+D4f///W/KHP5QAXkGyCUqD6JtM1jsxOIS275K8aC7MAzUahqggyXyKkf4QxUJxDNGqo62ayjmtlmlVVVbaIZmZllVVVVYaOw7KiOZ//+daqla2hoZilVTVVVVma2jiKXquZnaP4uJ1D+Z67u74uEeLhJqQ8Hyz///QgBQa5YrWIw3Yf/7UsQEgAtku2u5g4ARfhLqp7aAAAkI40AlGfYtdLvBlLGVu26Srt8mpwqiRBZQACIsCE94TiOJYjCce9yaMchcf+Y3LsNI5q2xhqqfRUb/9suIwmM/fIOexjafwsYaAAAOHhP//sYAAhPAAAacbA6ZNZ1zSL8yUDNRKwEbkgQGAz1LDOtEZZSX5TnIaHDLuynOFrzel9er5biL6r9VrZm7s4Tl8vmmiKQEQEFT0OIK1//uZY8kTCR2BAaKFj0S3f//9bTeeMUhKS2W6xJotiIB//tSxAUAC30jd6eYr3F8lW388YosgEDIINdCUEoGBHsivaFe9UjfgEQLc9JS1TXaiJIiDGFoBaGqTRnfTxcO3fWaj/DqlbVJTbuYh/r2/96edSf/lYa/xaYFa/cOEYvWsyr7+1vuOgAqbsqnHkkzexYzeASRUHQciCO1hgIcroDCaaLoq48A5KgbpuZF0/oU8vRD34VTw86iEXBEhxeX20xQgEgOMFBcf9eo4clDCOtlaEMwfLjgQePNyYvqcseIE19bz5KNACnyT2iaaSZFIQD/+1LEBYAL2I1prDDFIW+nbLGBlizaenu9Sl5GuSzMOcPBoI5XLJ7A0FPYoss8p7MNKAzDGpmQrKRy72st4Y/I3qyrn/TuthiaGDiIcGljSUsdekNmHQlGho/Fmhm6tP1Rxhvr7vEvolgAfYwLjM1pzL8TlDPN1kbU/lj3wZG5qNPFSyGzGcO5iaTODqOcle9KHJOVtuqnzWERsDivuyN7fS+tUee2irSd+Y5VKrBJVKlFKy+mnf/+gtIsCj0syais6dKrUgAmqoZnn+/a7ceEwv/7UsQGAAuA/XHnsGHhgphrcYYMtD7QCAuslEQekhoVRFOEx36VqMGBo5gSHJpm+DTcEPVLjGldjYtmNUQiKot2HLy//9tb07cu/fv+ZLOxc82omV3jlSt9FgqoNCD6Qu59bWfqACyxSZLQuNpQEAgqsTtq1gYXkA8cNAaAfBEzWPLDzGUlK4A8gnpqW9A7aa+3qjEx3187CuDKGff//roZ34z4zkTRcOwIUDgNEYfH363NpSSdU5h4QJIFY/PKZVflPKBorQAkaIVWZtXRyUa6//tSxAWAC9SJY+eYcGFvjy0w9gzuFjnRROU2S2Kcygdo83UUmnyRcVCxRn7pLhKFjcupVoG0tW57Zd4HYzh0zRxjPDj4OuuTGEnzIs9xEFWoFBQokRgJHzJSpSYlxEdDrbnM3W+bd+9IC1sksq+WyTK85SwtZCRvj8PAzEIyjVGYyJo5PnUej+YQclMhJdzqN1qdNKwr2UhQyjGAxARUo3a4m5SzLQAEkLKmGkkPCIwp/R/GHgARBJwFCOY/tMXXEm0jkLUALN1pkqMAJgpC3UH/+1LEBgALIIdTrDDDoYInKfGBiezx+ArAOMlgExDLJySzYqpF46mDCvS8eH3yjf2c+M+TT4WhfMitpoExMbMeWR5QypWEBEfYw9OxKZ//GXb1TCQcDaho4ev/WdeqxKLK7ADHECjBQtgdLSVOCJkMIbKSgqje6KZw3QSKOW7wcSViKPxNQSCVWXbYlIibKmz4Yd2v+iV9ro1HuU1lZ7Eumqu5S0byl72Sm+/++0xqGPQhjiDAqbIxn0yxINNICMAhiVUARFHvCDoibJC5LUONbP/7UsQHAApws0CspGWBQZYn1ZeMcDApFgwaD4HzBAhQExAcgtqPSYE4phKkZ4RngVUdibCiiFFiTclkaf/95/b06SkQMcDoQAkJkTRcwkjWF9P8t01rW9f/+dHANgaMGUgpk1BxegISKW1l8xqB4h8Y0maRfvWZUccO1gGiPQZigw4kIHGZo6M2ylVChqUnLz/8yyQp+GMww4FRQLkS6Bl+5tNrHeZ3///r2ABHeWRkRpUpNgEcJRLCpLHREDEMhFJVCjfYniSeIq0rO7ITEcWH//tSxBMAClRzT+eM0SFKlmjw8w3cw6xRG0qbQ1qtKpaVEMPeFDH9ZqOCgsAVBxgXsG+5QolyFQ26KLDdztBJTO5wBknabQ5aG8DkM1OHqqTiL0jlymVUdR5JpmjKEcckyETunHZcxqNlsvlm6lOFnTYOaVSz/5/tnym3DKCjBHgOMXAJ0sv8QmHVLHTqnBRn1tJ9BOoDvQAFKQ7wAtVfjUKRPp35e98TSGCYKEKTig4LahgnhlldAorBVBJbFSqzqhg1pCCp5xiJi/n+Z/f/+/L/+1LEHgAKWM87LCRpgU+NJ/WEjSAQkwzBv7qywLTrQOAQYIxQVjItu/2ttAMkrbBKkSkAOQPNSeEi0rZWkRdwnRBlchBsSoSzYVx7kK+/06lWOzq7lmaAnVRyKFAC4PCisF2HmgU6SgIiBBgxAs//LCZ6ViiyyVjVjEfYRQ+TRQBXI0gAZC2xCjfsIRCYtYKBtGDEyJqQdzWE4HBY6vVwMGosfeg5rNHSUanEW4MEcbUWGVjRcUlliwqBR94QBhzjhJYdUU9ZShKdhSx6Vf1oL//7UsQogEo4czmssGOBP6JntYYMdaABN/aS0o1hgLFMxC6QmDbCmSFLg2Slg0IsBitPKezMpkQGOOCMze0ci9rVsxoa1IY2fD/+8/NJ/1zY/saZOEFlaWd7P84jGRmZV8utPgakUgE0aJdkNt6NsAWgOUm41TtEXFpiE4lNIy8IzighB0nPlqy6E7dfMWeOzt3aFATQVRRupFsKQVC7//+UyqUs2Z64sT4QOBbi1rtQu40R6OdWBQFeQRkgDNlj5miQMFBaxktYPliCMSdADi4K//tSxDWACiC9PeewZ2E5GSTlpIz4nsIwcvYwe9zlSFKLcClc90KhUYSuaM59WkRl+X/drIUL6Wx5gF7sV9BBEq332fb6FGfqxSoAVpBPEAgWBwIKyO1JWNnQRUOYXCrZmEef9QDJQjKytYQaadXVbgaitjHaf59VWbjGsJnnRodhUMmjYUlCoLGzwKrOMaBH/ux3jf/3+r06wGA8gAiBiHoXIkiuURx9eEdpZGkTorWIhLcPQ6sDKwIhdqDn4YMM+iqY6QEIFmGyDgG8WHgIqlz/+1LEQ4AJ6HcjLLDFARqPY9mkjKi4NFQ+E4LN+n/2VU///9EAAmWOQBYc4bFIkFG5Gw2RZ6t7/vcc41Sii1PZe2+Ucf7zHdVl0RW/Z79Rk61octcMUUJBAsGRa5tFYhcfPyTqXWZbRto1vjO6vJt/0gABkolExN3BgAAASFJIzQWRAvIzCIvb3oBkJDYy6pYbM8aKmRG0l73uOQLsC0TRaBMMnUYgqAn4b6LOYsXlnDsT8bgvAnQjCavb3JULwP5LkuMTZCpfayi4SBqPclR7qf/7UsRWgAmcgSE1owACZ8FlMzLQAda2QZk61L1cc5gShw0N2cuftvq+t7GxcWXDM3MzcuFpc7Kb/t//shdNRocPJnjNNNL/////////NFkAASQAAAAA4AiTJgJAwRdV512oKW1ac3lwlUPZ/31Lf8Q0qvdXQIQVDMUdK2fMFoApChiNmk5U1rdWCEkbJtWrbL+p54G5w7kUkwQbv3vmeN3jyPo9Zs56NNZE7vrr6a+ZVgdxUXEDKJNaZM+a5q+Ov+/7S5NWtKoc5KykSsWY/I/W//tSxEEAEQVZHNnFgAEcj2LLsjAAHf/y7f/0IQABAKD52SL3gtkM9zVn/3hr8cc6h/r/nwdEWU/K33Z+GSAhYQY1nwgu5nYWrFdppV4RPpGI44jbbSMprc5y2bEews2R//qVAEgAMXNvZGdYwGQuHRZJsoS16Z5KUf2eWH5LwNQQ8DVShEF2JYQWdxFq6Sf7v993P3eSYmwcouFUGOhg51lEy9zfxvNfT3/jdUk0K77T3nWvNvrEvfKuPl67/yDNnVWiKLAvypkRARySIYSh9Sf/+1LENwJLcHkOrKRiiV0OIUWTDIkfOeakptGIp3r33p3MmriYLJJsU6ho2LJ7v1NtZkGPOBYqLVsJgUk/hJSovLudM/c7ERsTIoTdz57/59jt9d/Pu7XRUvUAIABcAdUEMgWnNVRtHjRCwgoVvTEA6RGZxajXyLyUvFcmUKceYp0CkHJWiIeCR2hb/dUyil01S4og3kWZSnW0tyHiHZ3KTc8iXfytSnVNVLPJryF0+YptUFtZnvcRQfz+q6ALLGmYCC90KkTvT10JkJtt+Kab6P/7UsQ7ggwlVQitGGTJN4ghpYCM6ICjgwPFz5sWFHnZUxmXpAw8UPUBFMe1URA6iEkQ7PUzYlLAq5KRyahQS68OpHyzmBGVZLHga33LACABiw5wi0PNNhuOOnSVqa5LLFzGK+uzYzZGbs758ruL+M/du66QD/6QA9eJtIhGOou5mxAuNkVNZU9HIy4t65QieGzGzGyvUIlMOpi7CLAbT6L2edas2L2hrj1haqusgZXJxEDJg+8FANXi8EP890UkKmMzSsy0qs+lqWs4d6TVXmKl//tSxEICzIkDBq0YbcmELiCBkZU4pVFYDC4SCYKNEwwIgQGEAZhpyKW5ULsre1Soj1Nt+Wios3M6kVGVlGHSr6to91LIezURULTpUimujmWnQc9Ao6OVIAVDoghYGHkJaNTcsBYso06VoWECbmIGip40LirBVdLgTFA2ZDIRFkzO1Jk0LCxn/bq0KVR/tYiLMo2So//tpSSAwHUQAUAIWMHcV3D2eEOapbbPRl1tu1UNpI9prraY1WUnvQua/VOj0TlbKZ9Wzd2Ny7OzzI9Kt9T/+1LEPQMIDCMGTTDAgSiw3onGCBGpm6p/R9DfzGTUv6G+VtRMJQAA+cAbtkDRKRKJSKQbRQsgQHoparYMIjAKROu/WkQf+0f7P7PsMt/6TozUn//+0efauDvGFJgO5nUoUZBxAy4CHzMvDgvjNA5QYAeAyTKguyf////9IPZAAIn4lAsaBs8NJ3/+n///////Sj/CwngwC8AIB5R8ClUygkWkp4U8EhtXf/////3////1f//vQ9tJNKQp7xgJVlYYEwiKzdIqjM/T5jpfzD+////7UsRVgoYMGu1OpMBA7Q7Xgf1EIP0O5vod0u//9HSa5ioVrrM2Is+IYP8xDWOE6k6pV5vBAsYHGkiRpxZhNBakUjTizLi9RSNOLKPiFqSmpZ7jcqalmuLUtGpNKuLzZqpZ4uNyalna4TWjUnFtcRqgkrDDFkpWgMWShNURZYKqqHLA1VQ5dESqiKogaqOJRA1UMSqDE6RKqIqAgThwj2BMPCOahQSDFJqSmjTiy4XmzRpxQOGgKDIkDxoChQW4s3/1C/FmahfqZ//1ivWKcVbx//tSxH2CBGAYug/nAAChAmBpoIwEQWx4t/8WF0xBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+1LEtYMPBN8ETLzBCPeHG4j2GAiqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg==\",\n  duration: 0.541,\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.541,
    "format": "mp3",
    "sizeKb": 5,
    "license": "CC0",
    "tags": [
      "impact",
      "punch",
      "medium",
      "002"
    ],
    "keywords": [
      "impact",
      "punch",
      "medium",
      "distinct",
      "game attack",
      "form submission",
      "robust button",
      "ui feedback",
      "solid",
      "satisfying",
      "thud",
      "clear",
      "combat",
      "positive",
      "action",
      "confirm",
      "select",
      "game sfx",
      "interface",
      "submit"
    ]
  },
  "categories": [
    "impact"
  ]
}