{"version":3,"file":"AudioPlayer.cjs","sources":["../../node_modules/ramda/es/internal/_isObject.js","../../node_modules/ramda/es/mergeDeepWithKey.js","../../node_modules/ramda/es/mergeDeepLeft.js","../../node_modules/parse-ms/index.js","../src/utils/deep-merge.ts","../src/AudioPlayer/AudioPlayer.tsx"],"sourcesContent":["export default function _isObject(x) {\n  return Object.prototype.toString.call(x) === '[object Object]';\n}","import _curry3 from \"./internal/_curry3.js\";\nimport _isObject from \"./internal/_isObject.js\";\nimport mergeWithKey from \"./mergeWithKey.js\";\n/**\n * Creates a new object with the own properties of the two provided objects.\n * If a key exists in both objects:\n * - and both associated values are also objects then the values will be\n *   recursively merged.\n * - otherwise the provided function is applied to the key and associated values\n *   using the resulting value as the new value associated with the key.\n * If a key only exists in one object, the value will be associated with the key\n * of the resulting object.\n *\n * @func\n * @memberOf R\n * @since v0.24.0\n * @category Object\n * @sig ((String, a, a) -> a) -> {a} -> {a} -> {a}\n * @param {Function} fn\n * @param {Object} lObj\n * @param {Object} rObj\n * @return {Object}\n * @see R.mergeWithKey, R.mergeDeepWith\n * @example\n *\n *      let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r\n *      R.mergeDeepWithKey(concatValues,\n *                         { a: true, c: { thing: 'foo', values: [10, 20] }},\n *                         { b: true, c: { thing: 'bar', values: [15, 35] }});\n *      //=> { a: true, b: true, c: { thing: 'bar', values: [10, 20, 15, 35] }}\n */\n\nvar mergeDeepWithKey =\n/*#__PURE__*/\n_curry3(function mergeDeepWithKey(fn, lObj, rObj) {\n  return mergeWithKey(function (k, lVal, rVal) {\n    if (_isObject(lVal) && _isObject(rVal)) {\n      return mergeDeepWithKey(fn, lVal, rVal);\n    } else {\n      return fn(k, lVal, rVal);\n    }\n  }, lObj, rObj);\n});\n\nexport default mergeDeepWithKey;","import _curry2 from \"./internal/_curry2.js\";\nimport mergeDeepWithKey from \"./mergeDeepWithKey.js\";\n/**\n * Creates a new object with the own properties of the first object merged with\n * the own properties of the second object. If a key exists in both objects:\n * - and both values are objects, the two values will be recursively merged\n * - otherwise the value from the first object will be used.\n *\n * @func\n * @memberOf R\n * @since v0.24.0\n * @category Object\n * @sig {a} -> {a} -> {a}\n * @param {Object} lObj\n * @param {Object} rObj\n * @return {Object}\n * @see R.merge, R.mergeDeepRight, R.mergeDeepWith, R.mergeDeepWithKey\n * @example\n *\n *      R.mergeDeepLeft({ name: 'fred', age: 10, contact: { email: 'moo@example.com' }},\n *                      { age: 40, contact: { email: 'baa@example.com' }});\n *      //=> { name: 'fred', age: 10, contact: { email: 'moo@example.com' }}\n */\n\nvar mergeDeepLeft =\n/*#__PURE__*/\n_curry2(function mergeDeepLeft(lObj, rObj) {\n  return mergeDeepWithKey(function (k, lVal, rVal) {\n    return lVal;\n  }, lObj, rObj);\n});\n\nexport default mergeDeepLeft;","const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0;\n\nfunction parseNumber(milliseconds) {\n\treturn {\n\t\tdays: Math.trunc(milliseconds / 86_400_000),\n\t\thours: Math.trunc(milliseconds / 3_600_000 % 24),\n\t\tminutes: Math.trunc(milliseconds / 60_000 % 60),\n\t\tseconds: Math.trunc(milliseconds / 1000 % 60),\n\t\tmilliseconds: Math.trunc(milliseconds % 1000),\n\t\tmicroseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1000) % 1000),\n\t\tnanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1000),\n\t};\n}\n\nfunction parseBigint(milliseconds) {\n\treturn {\n\t\tdays: milliseconds / 86_400_000n,\n\t\thours: milliseconds / 3_600_000n % 24n,\n\t\tminutes: milliseconds / 60_000n % 60n,\n\t\tseconds: milliseconds / 1000n % 60n,\n\t\tmilliseconds: milliseconds % 1000n,\n\t\tmicroseconds: 0n,\n\t\tnanoseconds: 0n,\n\t};\n}\n\nexport default function parseMilliseconds(milliseconds) {\n\tswitch (typeof milliseconds) {\n\t\tcase 'number': {\n\t\t\tif (Number.isFinite(milliseconds)) {\n\t\t\t\treturn parseNumber(milliseconds);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'bigint': {\n\t\t\treturn parseBigint(milliseconds);\n\t\t}\n\n\t\t// No default\n\t}\n\n\tthrow new TypeError('Expected a finite number or bigint');\n}\n","import { mergeDeepLeft } from 'ramda';\n\nexport const deepMerge = mergeDeepLeft;\n","import { type NativeFormControlElement } from '@mui/base/FormControl/FormControl.types.js';\nimport clsx from 'clsx';\nimport parseMilliseconds from 'parse-ms';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport * as React from 'react';\n\nimport { IconButton } from '../Button/IconButton.tsx';\nimport type {\n  ComponentProps,\n  SlotComponentPropsWithoutOverride,\n} from '../components.ts';\nimport { PauseIcon, PlayIcon, VolumeUpIcon } from '../icons/solid.tsx';\nimport { Slider, type SliderProps } from '../Slider/Slider.tsx';\nimport { assocDefaultStyle } from '../utils/assign-default-style.ts';\nimport { deepMerge } from '../utils/deep-merge.ts';\nimport { mergeRootSlotPropsToComponentProps } from '../utils/merge-root-slot-props-to-component-prop.ts';\n\ninterface SlotProps {\n  currentDuration?: SlotComponentPropsWithoutOverride<'span'>;\n  duration?: SlotComponentPropsWithoutOverride<'div'>;\n  root?: SlotComponentPropsWithoutOverride<'div'>;\n  toggle?: SlotComponentPropsWithoutOverride<'button'>;\n  totalDuration?: SlotComponentPropsWithoutOverride<'span'>;\n  volumeControl?: SlotComponentPropsWithoutOverride<'div'>;\n  volumeSlider?: SliderProps;\n}\n\nexport type AudioProps = ComponentProps<\n  SlotProps,\n  {\n    src: string;\n    type: string;\n  }\n>;\n\nfunction formatSecond(second: number) {\n  if (isNaN(second)) return '00:00';\n  if (!Number.isFinite(second)) return '00:00';\n  const { minutes, seconds } = parseMilliseconds(second * 1000);\n  return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(\n    2,\n    '0',\n  )}`;\n}\n\nexport function AudioPlayer({\n  'data-testid': testId,\n  disableDefaultClasses,\n  slotProps: givenSlotProps,\n  src,\n  type,\n  ...rest\n}: AudioProps) {\n  const [audioError, setAudioError] = useState<Error | null>(null);\n  const [audioPlaying, setAudioPlaying] = useState(false);\n  const [audioDuration, setAudioDuration] = useState('00:00');\n  const [audioVolume, setAudioVolume] = useState(0);\n  const audioRef = useRef<HTMLAudioElement>(null);\n  const toggleAudioPlay = useCallback(async () => {\n    if (!audioRef.current) return;\n    try {\n      if (audioPlaying) {\n        await audioRef.current.pause();\n      } else {\n        await audioRef.current.play();\n      }\n      setAudioVolume((audioRef.current.volume ?? 0) * 100);\n      setAudioPlaying(prevState => !prevState);\n    } catch (e) {\n      setAudioError(e as Error);\n    }\n  }, [audioPlaying]);\n  const adjustAudioVolume = useCallback(\n    (event: React.ChangeEvent<NativeFormControlElement>) => {\n      if (!audioRef.current) return;\n      const volume = Number.parseInt(event.target.value, 10);\n      setAudioVolume(volume);\n      audioRef.current.volume = volume / 100.0;\n    },\n    [],\n  ) as any;\n  useEffect(function subscribeAudioTimeChange() {\n    const audioEle = audioRef.current;\n    const updateAudioCurrentTime: (event: Event) => void = () =>\n      setAudioDuration(formatSecond(audioRef.current?.currentTime ?? 0));\n    audioEle?.addEventListener('timeupdate', updateAudioCurrentTime);\n    return () =>\n      audioEle?.removeEventListener('timeupdate', updateAudioCurrentTime);\n  }, []);\n  if (audioError)\n    return (\n      <>\n        <div>Error: {audioError.message}</div>\n      </>\n    );\n  let slotProps = givenSlotProps;\n\n  if (!disableDefaultClasses) {\n    slotProps = assocDefaultStyle<SlotProps>({\n      slotWithDefaultClasses: {\n        currentDuration: clsx('tw-font-bold'),\n        root: clsx('tw-flex', 'tw-items-center', 'tw-gap-1'),\n        volumeControl: clsx('tw-flex', 'tw-gap-1.5'),\n      },\n    })(givenSlotProps);\n    slotProps.volumeSlider = deepMerge<SliderProps, SliderProps>(\n      slotProps.volumeSlider ?? {},\n      {},\n    ) as any;\n  }\n  const rootProps = mergeRootSlotPropsToComponentProps()(slotProps, rest);\n  return (\n    <>\n      <audio ref={audioRef}>\n        <source src={src} type={type} />\n      </audio>\n      <div data-testid={testId && `${testId}-audio-controls`} {...rootProps}>\n        <IconButton onClick={toggleAudioPlay}>\n          {audioPlaying ? <PauseIcon /> : <PlayIcon />}\n        </IconButton>\n        <div>\n          <div className={slotProps?.duration?.className}>\n            <span className={slotProps?.currentDuration?.className}>\n              {audioDuration}\n            </span>\n            /\n            <span className={slotProps?.totalDuration?.className}>\n              {formatSecond(audioRef.current?.duration ?? 0)}\n            </span>\n          </div>\n          <div className={slotProps?.volumeControl?.className}>\n            <VolumeUpIcon />\n            <div className={'tw-w-full'}>\n              <Slider\n                max={100}\n                min={0}\n                onChange={adjustAudioVolume}\n                slotProps={slotProps?.volumeSlider?.slotProps}\n                value={audioVolume}\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n    </>\n  );\n}\n"],"names":["_isObject","x","mergeDeepWithKey","_curry3","fn","lObj","rObj","mergeWithKey","k","lVal","rVal","mergeDeepWithKey$1","mergeDeepLeft","_curry2","mergeDeepLeft$1","toZeroIfInfinity","value","parseNumber","milliseconds","parseBigint","parseMilliseconds","deepMerge","formatSecond","second","minutes","seconds","AudioPlayer","testId","disableDefaultClasses","givenSlotProps","src","type","rest","audioError","setAudioError","useState","audioPlaying","setAudioPlaying","audioDuration","setAudioDuration","audioVolume","setAudioVolume","audioRef","useRef","toggleAudioPlay","useCallback","prevState","e","adjustAudioVolume","event","volume","useEffect","audioEle","updateAudioCurrentTime","_a","jsx","Fragment","slotProps","assocDefaultStyle","clsx","rootProps","mergeRootSlotPropsToComponentProps","jsxs","IconButton","PauseIcon","PlayIcon","_b","_c","_d","_e","VolumeUpIcon","Slider","_f"],"mappings":"+lCAAe,SAASA,EAAUC,EAAG,CACnC,OAAO,OAAO,UAAU,SAAS,KAAKA,CAAC,IAAM,iBAC/C,CC8BA,IAAIC,EAEJC,EAAO,QAAC,SAASD,EAAiBE,EAAIC,EAAMC,EAAM,CAChD,OAAOC,eAAa,SAAUC,EAAGC,EAAMC,EAAM,CAC3C,OAAIV,EAAUS,CAAI,GAAKT,EAAUU,CAAI,EAC5BR,EAAiBE,EAAIK,EAAMC,CAAI,EAE/BN,EAAGI,EAAGC,EAAMC,CAAI,CAE7B,EAAKL,EAAMC,CAAI,CACf,CAAC,EAED,MAAAK,EAAeT,ECpBf,IAAIU,EAEJC,EAAAA,QAAQ,SAAuBR,EAAMC,EAAM,CACzC,OAAOJ,EAAiB,SAAUM,EAAGC,EAAMC,EAAM,CAC/C,OAAOD,CACX,EAAKJ,EAAMC,CAAI,CACf,CAAC,EAED,MAAAQ,EAAeF,EChCTG,EAAmBC,GAAS,OAAO,SAASA,CAAK,EAAIA,EAAQ,EAEnE,SAASC,EAAYC,EAAc,CAClC,MAAO,CACN,KAAM,KAAK,MAAMA,EAAe,KAAU,EAC1C,MAAO,KAAK,MAAMA,EAAe,KAAY,EAAE,EAC/C,QAAS,KAAK,MAAMA,EAAe,IAAS,EAAE,EAC9C,QAAS,KAAK,MAAMA,EAAe,IAAO,EAAE,EAC5C,aAAc,KAAK,MAAMA,EAAe,GAAI,EAC5C,aAAc,KAAK,MAAMH,EAAiBG,EAAe,GAAI,EAAI,GAAI,EACrE,YAAa,KAAK,MAAMH,EAAiBG,EAAe,GAAG,EAAI,GAAI,CACrE,CACA,CAEA,SAASC,EAAYD,EAAc,CAClC,MAAO,CACN,KAAMA,EAAe,UACrB,MAAOA,EAAe,SAAa,IACnC,QAASA,EAAe,OAAU,IAClC,QAASA,EAAe,MAAQ,IAChC,aAAcA,EAAe,MAC7B,aAAc,GACd,YAAa,EACf,CACA,CAEe,SAASE,EAAkBF,EAAc,CACvD,OAAQ,OAAOA,EAAY,CAC1B,IAAK,SAAU,CACd,GAAI,OAAO,SAASA,CAAY,EAC/B,OAAOD,EAAYC,CAAY,EAGhC,KACA,CAED,IAAK,SACJ,OAAOC,EAAYD,CAAY,CAIhC,CAED,MAAM,IAAI,UAAU,oCAAoC,CACzD,CC1CO,MAAMG,EAAYT,ECiCzB,SAASU,EAAaC,EAAgB,CAEhC,GADA,MAAMA,CAAM,GACZ,CAAC,OAAO,SAASA,CAAM,EAAU,MAAA,QACrC,KAAM,CAAE,QAAAC,EAAS,QAAAC,CAAA,EAAYL,EAAkBG,EAAS,GAAI,EACrD,MAAA,GAAG,OAAOC,CAAO,EAAE,SAAS,EAAG,GAAG,CAAC,IAAI,OAAOC,CAAO,EAAE,SAC5D,EACA,GACD,CAAA,EACH,CAEO,SAASC,EAAY,CAC1B,cAAeC,EACf,sBAAAC,EACA,UAAWC,EACX,IAAAC,EACA,KAAAC,EACA,GAAGC,CACL,EAAe,iBACb,KAAM,CAACC,EAAYC,CAAa,EAAIC,WAAuB,IAAI,EACzD,CAACC,EAAcC,CAAe,EAAIF,WAAS,EAAK,EAChD,CAACG,EAAeC,CAAgB,EAAIJ,WAAS,OAAO,EACpD,CAACK,EAAaC,CAAc,EAAIN,WAAS,CAAC,EAC1CO,EAAWC,SAAyB,IAAI,EACxCC,EAAkBC,EAAAA,YAAY,SAAY,CAC9C,GAAKH,EAAS,QACV,GAAA,CACEN,EACI,MAAAM,EAAS,QAAQ,QAEjB,MAAAA,EAAS,QAAQ,OAEzBD,GAAgBC,EAAS,QAAQ,QAAU,GAAK,GAAG,EACnCL,EAAAS,GAAa,CAACA,CAAS,QAChCC,EAAG,CACVb,EAAca,CAAU,CAC1B,CAAA,EACC,CAACX,CAAY,CAAC,EACXY,EAAoBH,EAAA,YACvBI,GAAuD,CACtD,GAAI,CAACP,EAAS,QAAS,OACvB,MAAMQ,EAAS,OAAO,SAASD,EAAM,OAAO,MAAO,EAAE,EACrDR,EAAeS,CAAM,EACZR,EAAA,QAAQ,OAASQ,EAAS,GACrC,EACA,CAAC,CAAA,EAUC,GARJC,EAAA,UAAU,UAAoC,CAC5C,MAAMC,EAAWV,EAAS,QACpBW,EAAiD,IACrD,OAAA,OAAAd,EAAiBjB,IAAagC,EAAAZ,EAAS,UAAT,YAAAY,EAAkB,cAAe,CAAC,CAAC,GACzD,OAAAF,GAAA,MAAAA,EAAA,iBAAiB,aAAcC,GAClC,IACLD,GAAA,YAAAA,EAAU,oBAAoB,aAAcC,EAChD,EAAG,CAAE,CAAA,EACDpB,EAEA,OAAAsB,EAAAA,kBAAAA,IAAAC,EAAAA,kBAAAA,SAAA,CACE,kCAAC,MAAI,CAAA,SAAA,CAAA,UAAQvB,EAAW,OAAA,CAAQ,CAAA,CAClC,CAAA,EAEJ,IAAIwB,EAAY5B,EAEXD,IACH6B,EAAYC,EAAAA,kBAA6B,CACvC,uBAAwB,CACtB,gBAAiBC,OAAK,cAAc,EACpC,KAAMA,EAAA,KAAK,UAAW,kBAAmB,UAAU,EACnD,cAAeA,EAAAA,KAAK,UAAW,YAAY,CAC7C,CAAA,CACD,EAAE9B,CAAc,EACjB4B,EAAU,aAAepC,EACvBoC,EAAU,cAAgB,CAAC,EAC3B,CAAC,CAAA,GAGL,MAAMG,EAAYC,EAAA,mCAAA,EAAqCJ,EAAWzB,CAAI,EACtE,OAEI8B,EAAA,kBAAA,KAAAN,6BAAA,CAAA,SAAA,CAAAD,EAAAA,kBAAAA,IAAC,SAAM,IAAKb,EACV,iCAAC,SAAO,CAAA,IAAAZ,EAAU,KAAAC,EAAY,CAChC,CAAA,EACA+B,EAAAA,kBAAAA,KAAC,OAAI,cAAanC,GAAU,GAAGA,CAAM,kBAAoB,GAAGiC,EAC1D,SAAA,CAACL,EAAAA,kBAAAA,IAAAQ,EAAAA,WAAA,CAAW,QAASnB,EAClB,SAAAR,0BAAgB4B,EAAU,UAAA,CAAA,CAAA,EAAMT,EAAAA,kBAAAA,IAAAU,EAAAA,SAAA,CAAA,CAAS,CAC5C,CAAA,2BACC,MACC,CAAA,SAAA,CAAAH,EAAA,kBAAA,KAAC,MAAI,CAAA,WAAWR,EAAAG,GAAA,YAAAA,EAAW,WAAX,YAAAH,EAAqB,UACnC,SAAA,CAAAC,wBAAC,OAAK,CAAA,WAAWW,EAAAT,GAAA,YAAAA,EAAW,kBAAX,YAAAS,EAA4B,UAC1C,SACH5B,EAAA,EAAO,IAEPiB,EAAAA,kBAAAA,IAAC,OAAK,CAAA,WAAWY,EAAAV,GAAA,YAAAA,EAAW,gBAAX,YAAAU,EAA0B,UACxC,SAAA7C,IAAa8C,EAAA1B,EAAS,UAAT,YAAA0B,EAAkB,WAAY,CAAC,CAC/C,CAAA,CAAA,EACF,EACCN,EAAA,kBAAA,KAAA,MAAA,CAAI,WAAWO,EAAAZ,GAAA,YAAAA,EAAW,gBAAX,YAAAY,EAA0B,UACxC,SAAA,CAAAd,EAAA,kBAAA,IAACe,EAAa,aAAA,EAAA,EACdf,EAAAA,kBAAAA,IAAC,MAAI,CAAA,UAAW,YACd,SAAAA,EAAA,kBAAA,IAACgB,EAAA,OAAA,CACC,IAAK,IACL,IAAK,EACL,SAAUvB,EACV,WAAWwB,EAAAf,GAAA,YAAAA,EAAW,eAAX,YAAAe,EAAyB,UACpC,MAAOhC,CAAA,CAAA,EAEX,CAAA,EACF,CAAA,EACF,CAAA,EACF,CACF,CAAA,CAAA,CAEJ","x_google_ignoreList":[0,1,2,3]}