osuVisualizer/public/build/bundle.css.map
2024-06-25 12:01:57 +02:00

18 lines
No EOL
26 KiB
Text

{
"version": 3,
"file": "bundle.css",
"sources": [
"App.svelte",
"Menu.svelte",
"Visualizer.svelte",
"options.svelte"
],
"sourcesContent": [
"<script>\n import Menu from \"./Menu.svelte\";\n import Visualizer from \"./Visualizer.svelte\";\n const Store = require('electron-store');\n\n const store = new Store();\n\n var songData = {};\n var config = store.get(\"config\");\n var osuData = {};\n const osuFolder = process.env.OSU_FOLDER || process.env.USERPROFILE + \"/AppData/Local/osu!\";\n \n (() => {\n const configTemplate = {\n parallax: {\n enabled: true,\n treshold: 10\n },\n rpc: true,\n backgrounds: 0,\n mediaSession: true,\n videoBackground: true,\n autohide: {\n info: 2000,\n volume: 2000\n }\n };\n\n function checkSettings(value, template) {\n if(value === undefined) return template;\n if(typeof value !== \"object\") return value;\n\n var out = {};\n\n for(var key in template) {\n if(value[key] === undefined || typeof value[key] === \"undefined\") {\n out[key] = template[key];\n continue;\n }\n if(typeof value[key] === \"object\") out[key] = checkSettings(value[key], template[key]);\n if(typeof value[key] !== \"object\") out[key] = value[key];\n }\n\n return out;\n }\n config = checkSettings(config, configTemplate);\n })();\n\n $: store.set(\"config\", config);\n</script>\n\n<main>\n <div class=\"background\">\n <Visualizer bind:songData bind:osuData {config} {osuFolder} />\n </div>\n <div class=\"menu\">\n <Menu bind:song={songData} bind:osuData bind:config {osuFolder} />\n </div>\n</main>\n\n<style>\n main {\n position: relative;\n width: 100vw;\n height: 100vh;\n }\n .background {\n position: fixed;\n z-index: 0;\n left: 0;\n right: 0;\n width: 100vw;\n height: 100vh;\n }\n .menu {\n position: absolute;\n z-index: 1;\n left: 0;\n right: 0;\n width: 100vw;\n height: 100vh;\n }\n</style>",
"<script>\n import Options from \"./components/options.svelte\";\n\n export var osuData;\n export var song;\n export var config;\n export var osuFolder;\n\n var last = Date.now();\n var lastVolumeUpdate = Date.now() - 5000;\n var settingsOpen = false;\n var now = Date.now();\n\n setInterval(() => {\n now = Date.now();\n }, 800);\n\n function resetPool() {\n if(!osuData.songs) return false;\n osuData.songPool = osuData.songs.filter(v => true);\n let a = osuData.songPool;\n for (let i = a.length - 1; i > 0; i--) { // shuffle\n const j = Math.floor(Math.random() * (i + 1));\n [a[i], a[j]] = [a[j], a[i]];\n }\n osuData.songPool.forEach(v => {\n delete v.audio;\n delete v.video;\n v.playing = true;\n })\n song = osuData.songPool.shift();\n }\n\n function playNext() {\n if(song.audio) {\n song.audio.pause();\n }\n if(osuData.songPool.length) {\n song = osuData.songPool.shift();\n } else {\n resetPool();\n }\n }\n\n $: resetPool(osuData.songs);\n\n $: console.log(song);\n\n $: {\n (() => {\n if(song && song.folder && !song.audio) {\n // var audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n // song.context = audioCtx;\n // song.analyser = audioCtx.createAnalyser();\n song.audio = new Audio(`${osuFolder}/Songs/${song.folder}/${song.audioFile}`);\n // song.source = audioCtx.createMediaElementSource(song.audio);\n // song.source.connect(song.analyser);\n // song.analyser.connect(audioCtx.destination);\n song.audio.play();\n\n song.audio.onended = () => {\n playNext();\n }\n song.audio.onpause = () => {\n song.playing = false;\n if(song.video) song.video.pause();\n }\n song.audio.onplay = () => {\n song.playing = true;\n if(song.video) song.video.play();\n }\n if ('mediaSession' in navigator && config.mediaSession) {\n navigator.mediaSession.metadata = new MediaMetadata({\n title: song.song,\n artist: song.artist,\n album: \"Osu! visualizer\",\n artwork: [\n { src: `${osuFolder}/Data/bt/${song.id}.jpg`, type: 'image/jpeg' },\n ]\n });\n\n navigator.mediaSession.setActionHandler('play', function() { song.playing = true; song.audio.play(); });\n navigator.mediaSession.setActionHandler('pause', function() { song.playing = false; song.audio.pause(); });\n navigator.mediaSession.setActionHandler('nexttrack', function() { playNext()});\n }\n }\n })();\n }\n\n $: if(song && song.audio && config.rpc) {\n if(song.playing) {\n window.songActivity = {\n state: \"Listening to osu! beatmaps\",\n details: `${song.artist} - ${song.song}`,\n startTimestamp: Date.now(),\n endTimestamp: Date.now() + song.audio.duration * 1000,\n instance: false,\n largeImageKey: \"logo\",\n largeImageText: \"Osu!visualizer\"\n }\n } else {\n window.songActivity = {\n state: \"Paused\",\n details: `${song.artist} - ${song.song}`,\n instance: false,\n largeImageKey: \"logo\",\n largeImageText: \"Osu!visualizer\"\n }\n }\n }\n\n function togglePlay() {\n song.playing = !song.playing;\n if(!song.audio) return;\n if(song.playing) {\n song.audio.play();\n } else {\n song.audio.pause();\n }\n }\n\n var volume = 1;\n\n function updateVolume(e) {\n if(!song || !song.audio || !e.altKey) return;\n lastVolumeUpdate = Date.now();\n volume += e.deltaY * -0.0005;\n volume = Math.min(1, Math.max(volume, 0));\n }\n\n $: if(song.audio) song.audio.volume = volume;\n\n setTimeout(() => {\n playNext();\n }, 200);\n\n const volumeWidth = 100;\n const volumeStroke = 4;\n const volumeRadius = 50;\n</script>\n\n<svelte:window on:mousemove={() => last = Date.now()} on:wheel={e => updateVolume(e)} />\n\n<div class=\"menu\">\n {#if now - last < config.autohide.info + 1000}\n <div class=\"info\" class:hidden={now - last > config.autohide.info}>\n {#if song}\n <div class=\"song\">\n <h2>{song.artist} - {song.song}</h2>\n <div class=\"controls\">\n <div class=\"play\" on:click={togglePlay}>\n <img src=\"images/music_{song.playing ? \"pause\" : \"play\"}.svg\" alt=\"{song.playing ? \"Pause\" : \"Play\"} music\" title=\"{song.playing ? \"Pause\" : \"Play\"} music\">\n </div>\n <div class=\"forward\" on:click={playNext}>\n <img src=\"images/music_forward.svg\" alt=\"Skip the song\" title=\"Skip the song\">\n </div>\n <div class=\"settings\" on:click={() => settingsOpen = !settingsOpen}>\n <img src=\"images/settings.svg\" alt=\"Settings\" title=\"Open settings\">\n </div>\n </div>\n </div>\n {/if}\n </div>\n {/if}\n {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio}\n <div class=\"volume\" class:hidden={now - lastVolumeUpdate > config.autohide.volume}>\n <div class=\"slider\">\n <div class=\"percent\">\n {Math.round(song.audio.volume * 100)}%\n </div>\n <svg class=\"progress-ring\" width={volumeWidth} height={volumeWidth}>\n <circle\n stroke-width={volumeStroke}\n fill=\"transparent\"\n stroke=\"blue\"\n stroke-dasharray={volumeRadius * 2 * Math.PI + \" \" + volumeRadius * 2 * Math.PI}\n stroke-dashoffset={volumeRadius * 2 * Math.PI - song.audio.volume * volumeRadius * 2 * Math.PI}\n r={volumeRadius - 1}\n cx={volumeRadius - 1}\n cy={volumeRadius + 1}\n />\n </svg>\n </div>\n </div>\n {/if}\n <Options bind:config={config} bind:visible={settingsOpen} {osuFolder} />\n</div>\n\n<style>\n .info {\n opacity: 1;\n position: relative;\n top: 0;\n left: 0;\n width: 100vw;\n height: 80px;\n transition: opacity 0.6s;\n z-index: 2;\n }\n\n .volume {\n opacity: 1;\n position: fixed;\n z-index: 5;\n right: 0;\n bottom: 0;\n border-radius: 50%;\n font-size: 30px;\n color: white;\n background-color: black;\n width: 100px;\n height: 100px;\n }\n .volume .slider {\n position: relative;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n .percent {\n position: absolute;\n top: 25px;\n left: 0;\n width: 100%;\n height: 100%;\n text-align: center;\n }\n .progress-ring {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n .progress-ring circle {\n transition: stroke-dashoffset 0.32s;\n transform: rotate(-90deg);\n transform-origin: 50% 50%;\n position: absolute;\n top: 1px;\n left: 1px;\n width: 100%;\n height: 100%;\n }\n\n .hidden {\n opacity: 0;\n transition: opacity 1s;\n }\n\n .info .song {\n color: white;\n position: absolute;\n padding: 5px 5px 5px 25px;\n top: 0;\n right: 0;\n text-align: right;\n background: black;\n\n background: linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 15%, rgba(0,0,0,0.5) 100%);\n }\n\n .info .song h2 {\n margin: 0;\n }\n\n .info .controls {\n height: 50px;\n display: flex;\n }\n .info .controls div {\n height: 100%;\n }\n .info .controls img {\n height: 100%;\n filter: invert(100%);\n }\n .info .controls .settings img {\n height: 65%;\n padding-top: 25%;\n }\n</style>",
"<script>\n const fs = require(\"fs\");\n const OsuDBParser = require(\"osu-db-parser\");\n const osuParser = require(\"./lib/osu-parser.js\");\n export var osuData;\n export var songData;\n export var config;\n export var osuFolder;\n\n var wallpapers = [];\n try {\n wallpapers = fs.readdirSync(`${osuFolder}/Data/bg`);\n } catch(e) {\n console.error(\"Osu backgrounds weren't found. You must have osu installed and started at least once.\", e);\n alert(\"Osu backgrounds not found!\");\n }\n\n try {\n osuData = (new OsuDBParser(Buffer.from(fs.readFileSync(`${osuFolder}/osu!.db`)))).getOsuDBData();\n console.log(osuData);\n osuData.songs = osuData.beatmaps.map(v => ({\n artist: v.artist_name,\n artist_u: v.artist_name_unicode,\n audioFile: v.audio_file_name,\n folder: v.folder_name,\n song: v.song_title,\n song_u: v.song_title_unicode,\n id: v.beatmapset_id,\n dataFile: `${v.artist_name} - ${v.song_title} (${v.creator_name}) [${v.difficulty}].osu`.replace(/\\/|\\*|\"|:|\\?/g, \"\"),\n playing: true\n })).filter((v, i, a) => a.findIndex(x => x.id === v.id) === i);\n } catch(e) {\n console.error(\"Osu DB weren't found. You must have osu installed and started at least once.\", e);\n alert(\"Osu DB not found!\");\n }\n\n var wallpaper;\n function shuffleWallpapers() {\n switch(config.backgrounds) {\n case 1:\n if(songData.beatmap) {\n wallpaper = `${osuFolder}/Songs/${songData.folder}/${songData.beatmap.bgFilename}`;\n } else {\n wallpaper = `${osuFolder}/Data/bg/${wallpapers[Math.floor(Math.random() * wallpapers.length)]}`;\n }\n break;\n case 0:\n default:\n wallpaper = `${osuFolder}/Data/bg/${wallpapers[Math.floor(Math.random() * wallpapers.length)]}`;\n }\n }\n shuffleWallpapers();\n\n var lastSong = null;\n var lastBackgroundOption = null;\n\n $: {\n if(songData !== lastSong) {\n lastSong = songData;\n shuffleWallpapers();\n }\n if(config.backgrounds !== lastBackgroundOption) {\n lastBackgroundOption = config.backgrounds;\n shuffleWallpapers();\n }\n }\n function fetchBeatmap() {\n let file = fs.readFileSync(`${osuFolder}/Songs/${songData.folder}/${songData.dataFile}`);\n songData.beatmap = osuParser.parseContent(file);\n\n if(config.backgrounds === 1) {\n wallpaper = `${osuFolder}/Songs/${songData.folder}/${songData.beatmap.bgFilename}`;\n }\n }\n $: if(songData && songData.dataFile && !songData.beatmap) fetchBeatmap();\n\n var mouse = {\n x: 0.5,\n y: 0.5\n };\n\n var parallaxTreshold;\n $: parallaxTreshold = config.parallax.treshold;\n\n function updateMouse(e) {\n if(!config.parallax.enabled) return;\n mouse = {\n x: -(e.clientX / window.innerWidth) * parallaxTreshold - parallaxTreshold/2,\n y: -(e.clientY / window.innerHeight) * parallaxTreshold - parallaxTreshold/2\n }\n }\n\n var isWidthSmaller = false;\n\n function resize() {\n isWidthSmaller = window.innerWidth * 9 < window.innerHeight * 16;\n }\n resize();\n\n var animDuration = 0;\n var kiaiTime = false;\n\n setInterval(() => {\n if(!songData) return;\n if(!songData.beatmap && songData.dataFile) fetchBeatmap();\n if(!songData.beatmap || !songData.audio) return;\n\n var tp = null;\n for(var t of songData.beatmap.timingPoints) {\n if(t.offset > songData.audio.currentTime * 1000) break;\n tp = t;\n }\n if(!tp) {\n animDuration = 0;\n kiaiTime = false;\n return;\n }\n if(tp.beatLength/2 !== animDuration)\n animDuration = tp.beatLength/2;\n kiaiTime = tp.kiaiTimeActive;\n }, 50);\n\n $: {\n if(!songData || !songData.beatmap || !songData.beatmap.video || !config.videoBackground) window.backgroundVideo = null;\n }\n\n $: console.log(\"Wallpaper\", wallpaper);\n\n $: console.log(\"Beatmap\", songData.beatmap);\n\n var backgroundVideo;\n\n $: {\n if(backgroundVideo) {\n songData.video = backgroundVideo;\n if(songData && songData.audio && songData.video) {\n songData.video.currentTime = songData.audio.currentTime;\n }\n }\n }\n</script>\n\n<svelte:window on:mousemove={updateMouse} on:resize={resize} />\n\n<div\n class=\"main\"\n style=\"\n background-image: url('{wallpaper}');\n background-size: {!isWidthSmaller ? `calc(100% + ${parallaxTreshold * 1.5}px) auto` : `auto calc(100% + ${parallaxTreshold * 1.5}px)`};\n background-position: {mouse.x}px {mouse.y}px;\n \"\n>\n {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground}\n <!-- svelte-ignore a11y-media-has-caption -->\n <video bind:this={backgroundVideo} style=\"\n width: {isWidthSmaller ? \"auto\" : `calc(100% + ${parallaxTreshold * 1.5}px)`};\n height: {!isWidthSmaller ? \"auto\" : `calc(100% + ${parallaxTreshold * 1.5}px)`};\n top: {mouse.y}px;\n left: {mouse.x}px;\n \">\n <source src=\"file://{osuFolder}/Songs/{songData.folder}/{songData.beatmap.video}\">\n </video>\n {/if}\n <img src=\"images/logo.svg\" alt=\"logo\" class=\"logo\" style=\"animation-duration: {animDuration}ms;\" class:repeat={songData.playing}>\n <img src=\"images/logo.svg\" alt=\"\" class=\"shadow\" style=\"animation-duration: {animDuration * 2}ms;\" class:repeat={songData.playing}>\n</div>\n\n<style>\n .main {\n width: 100%;\n height: 100%;\n background-size: cover;\n background-repeat: no-repeat;\n }\n\n @keyframes bpm {\n from {\n width: 500px;\n height: 500px;\n top: calc(50vh - 250px);\n left: calc(50vw - 250px);\n }\n to {\n width: 525px;\n height: 525px;\n top: calc(50vh - 262.5px);\n left: calc(50vw - 262.5px);\n }\n }\n\n @keyframes bpmShadow {\n 0% {\n width: 500px;\n height: 500px;\n top: calc(50vh - 250px);\n left: calc(50vw - 250px);\n }\n 70% {\n width: 510px;\n height: 510px;\n top: calc(50vh - 255px);\n left: calc(50vw - 255px);\n }\n 100% {\n width: 500px;\n height: 500px;\n top: calc(50vh - 250px);\n left: calc(50vw - 250px);\n }\n }\n\n video {\n position: fixed;\n z-index: 0;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n }\n\n .main img {\n position: fixed;\n width: 500px;\n height: 500px;\n top: calc(50vh - 250px);\n left: calc(50vw - 250px);\n z-index: 1;\n }\n\n .main .logo {\n animation-name: bpm;\n animation-direction: alternate;\n }\n\n .main .shadow {\n opacity: 0.2;\n animation-name: bpmShadow;\n animation-delay: 50ms;\n }\n\n .main .repeat {\n animation-iteration-count: infinite;\n }\n</style>",
"<script>\n export var config;\n export var visible;\n export var osuFolder;\n\n $: console.log(\"Config\", config);\n</script>\n\n<div class=\"options\">\n <div class=\"bg\" class:visible={visible} on:click={() => visible = false}></div>\n <nav class:visible={visible}>\n <h2>Options</h2>\n\n <div class=\"group\">\n <h3>Parallax</h3>\n <div class=\"row\">\n <span>Enable parallax</span>\n <input type=\"checkbox\" bind:checked={config.parallax.enabled}>\n </div>\n <div class=\"row\" class:enabled={config.parallax.enabled}>\n <span>Parallax treshold</span>\n <input type=\"range\" min=\"1\" max=\"30\" bind:value={config.parallax.treshold}>\n </div>\n </div>\n <div class=\"group\">\n <h3>Integrations</h3>\n <div class=\"row\">\n <span>Discord Rich Presence</span>\n <input type=\"checkbox\" bind:checked={config.rpc}>\n </div>\n <div class=\"row\">\n <span>MediaSession (system-wide controls)</span>\n <input type=\"checkbox\" bind:checked={config.mediaSession}>\n </div>\n </div>\n <div class=\"group\">\n <h3>Backgrounds</h3>\n <select bind:value={config.backgrounds}>\n <option value={0}>Osu!wallpapers</option>\n <option value={1}>Beatmap wallpapers</option>\n </select>\n <div class=\"row\">\n <span>Video backgrounds</span>\n <input type=\"checkbox\" bind:checked={config.videoBackground}>\n </div>\n </div>\n <div class=\"group\">\n <h3>UI</h3>\n <div class=\"row\">\n <span>Song info hide timeout</span>\n <input type=\"range\" min=\"1000\" max=\"15000\" step=\"500\" bind:value={config.autohide.info}>\n </div>\n <div class=\"row\">\n <span>Volume hide timeout</span>\n <input type=\"range\" min=\"1000\" max=\"15000\" step=\"500\" bind:value={config.autohide.volume}>\n </div>\n </div>\n <span>Osu folder used: <code>{osuFolder}</code></span>\n </nav>\n</div>\n \n<style>\n .bg {\n position: fixed;\n display: none;\n width: 100vw;\n height: 100vh;\n top: 0;\n left: 0;\n z-index: 3;\n }\n .bg.visible {\n display: block;\n }\n nav {\n position: fixed;\n height: 100vh;\n width: 400px;\n top: 0;\n left: -400px;\n opacity: 0;\n background: rgba(0,0,0,0.4);\n color: white;\n z-index: 4;\n padding-left: 1rem;\n transition: opacity 0.3s, left 0.3s;\n }\n nav.visible {\n left: 0;\n opacity: 1;\n }\n</style>"
],
"names": [],
"mappings": "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"
}