{
  "name": "infusion",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "name": "Infusion.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, type CSSProperties } from 'vue';\n\ninterface Props {\n  src: string;\n  opacity?: number;\n  opacityDark?: number;\n  zIndex?: number;\n  blur?: number;\n  noiseIntensity?: number;\n  noiseScale?: number;\n  noiseOpacity?: number;\n  blendMode?: CSSProperties['mixBlendMode'];\n  relative?: boolean;\n  type?: 'image' | 'video';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  src: '',\n  opacity: 0.2,\n  opacityDark: 0.3,\n  zIndex: 100,\n  blur: 64,\n  noiseIntensity: 0.5,\n  noiseScale: 1,\n  noiseOpacity: 0.05,\n  blendMode: 'normal',\n  relative: false,\n  type: 'image',\n});\n\nconst imageStyle = computed(() => ({\n  '--infusion-opacity': props.opacity,\n  '--infusion-opacity-dark': props.opacityDark,\n  '--infusion-z-index': props.zIndex,\n  '--infusion-blur': `${props.blur}px`,\n  '--infusion-noise-intensity': props.noiseIntensity,\n  '--infusion-noise-scale': props.noiseScale,\n  '--infusion-noise-opacity': props.noiseOpacity,\n  'mixBlendMode': props.blendMode,\n}));\n\nconst noiseDataUrl = computed(() => {\n  if (props.noiseIntensity === 0) {\n    return '';\n  }\n\n  if (typeof document === 'undefined') {\n    return '';\n  }\n\n  const canvas = document.createElement('canvas');\n  canvas.width = 256;\n  canvas.height = 256;\n  const context = canvas.getContext('2d');\n\n  if (!context) {\n    return '';\n  }\n\n  const imageData = context.createImageData(canvas.width, canvas.height);\n  const data = imageData.data;\n\n  for (let index = 0; index < data.length; index += 4) {\n    const value = Math.random() * 255;\n    data[index] = value;\n    data[index + 1] = value;\n    data[index + 2] = value;\n    data[index + 3] = props.noiseIntensity * 255;\n  }\n\n  context.putImageData(imageData, 0, 0);\n  return canvas.toDataURL();\n});\n\nconst containerClass = computed(() => [\n  'infusion-container',\n  {\n    'infusion-container--relative': props.relative,\n  },\n]);\n</script>\n\n<template>\n  <div\n    :class=\"containerClass\"\n    :style=\"imageStyle\"\n  >\n    <img\n      v-if=\"props.type === 'image'\"\n      class=\"infusion-image\"\n      :src=\"props.src\"\n      alt=\"\"\n    >\n    <video\n      v-if=\"props.type === 'video'\"\n      class=\"infusion-video\"\n      :src=\"props.src\"\n      autoplay\n      loop\n      muted\n      playsinline\n      alt=\"\"\n    />\n    <div\n      v-if=\"noiseIntensity > 0\"\n      class=\"infusion-noise\"\n      :style=\"{ backgroundImage: `url(${noiseDataUrl})` }\"\n    />\n  </div>\n</template>\n\n<style scoped>\n.infusion-container {\n  position: fixed;\n  z-index: var(--infusion-z-index);\n  top: 0;\n  left: 0;\n  overflow: hidden;\n  width: 100vw;\n  height: 100vh;\n  pointer-events: none;\n}\n\n.infusion-container--relative {\n  position: absolute;\n  z-index: var(--infusion-z-index);\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.infusion-image {\n  width: 100%;\n  height: 100%;\n  filter: blur(var(--infusion-blur));\n  object-fit: cover;\n  opacity: var(--infusion-opacity);\n  transform: scale(1.1)\n}\n\n.dark .infusion-image {\n  opacity: var(--infusion-opacity-dark);\n}\n\n.infusion-video {\n  width: 100%;\n  height: 100%;\n  filter: blur(var(--infusion-blur));\n  object-fit: cover;\n  opacity: var(--infusion-opacity);\n  transform: scale(1.1)\n}\n\n.dark .infusion-video {\n  opacity: var(--infusion-opacity-dark);\n}\n\n.infusion-noise {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-repeat: repeat;\n  background-size: calc(256px * var(--infusion-noise-scale));\n  mix-blend-mode: overlay;\n  opacity: var(--infusion-noise-opacity);\n}\n</style>\n"
    },
    {
      "name": "index.ts",
      "content": "export { default as Infusion } from './Infusion.vue';\n"
    }
  ],
  "type": "components:ui"
}