diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a06a8c6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "Vue.volar", + "vitest.explorer", + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..df9b23b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,103 @@ +{ + // https://github.com/tailwindlabs/tailwindcss/discussions/5258#discussioncomment-1979394 + "css.customData": [ + ".vscode/tailwind.json" + ], + // Disable the default formatter, use eslint instead + "prettier.enable": false, + "editor.formatOnSave": false, + // Auto fix + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + // Silent the stylistic rules in your IDE, but still auto fix them + "eslint.rules.customizations": [ + { + "rule": "style/*", + "severity": "off", + "fixable": true + }, + { + "rule": "format/*", + "severity": "off", + "fixable": true + }, + { + "rule": "*-indent", + "severity": "off", + "fixable": true + }, + { + "rule": "*-spacing", + "severity": "off", + "fixable": true + }, + { + "rule": "*-spaces", + "severity": "off", + "fixable": true + }, + { + "rule": "*-order", + "severity": "off", + "fixable": true + }, + { + "rule": "*-dangle", + "severity": "off", + "fixable": true + }, + { + "rule": "*-newline", + "severity": "off", + "fixable": true + }, + { + "rule": "*quotes", + "severity": "off", + "fixable": true + }, + { + "rule": "*semi", + "severity": "off", + "fixable": true + } + ], + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "xml", + "gql", + "graphql", + "astro", + "svelte", + "css", + "less", + "scss", + "pcss", + "postcss" + ], + "workspaceKeybindings.manimPreviewTask.enabled": true, + "typescript.format.enable": false, + "typescript.tsdk": "./Frontend/node_modules/typescript/lib", + "[vue]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "[typescript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "[javascript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + } +} \ No newline at end of file diff --git a/.vscode/tailwind.json b/.vscode/tailwind.json new file mode 100644 index 0000000..53078b1 --- /dev/null +++ b/.vscode/tailwind.json @@ -0,0 +1,95 @@ +{ + "version": 4.0, + "atDirectives": [ + { + "name": "@theme", + "description": "Use the `@theme` directive to define your project's custom design tokens, like fonts, colors, and breakpoints.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#theme-directive" + } + ] + }, + { + "name": "@source", + "description": "Use the `@source` directive to explicitly specify source files that aren't picked up by Tailwind's automatic content detection.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#source-directive" + } + ] + }, + { + "name": "@utility", + "description": "Use the `@utility` directive to add custom utilities to your project that work with variants like `hover`, `focus` and `lg`.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#utility-directive" + } + ] + }, + { + "name": "@variant", + "description": "Use the `@variant` directive to apply a Tailwind variant to styles in your CSS.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#variant-directive" + } + ] + }, + { + "name": "@custom-variant", + "description": "Use the `@custom-variant` directive to add a custom variant in your project.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#custom-variant-directive" + } + ] + }, + { + "name": "@apply", + "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS.", + "references": [ + { + "name": "Tailwind Documentation", + "url": "https://tailwindcss.com/docs/functions-and-directives#apply-directive" + } + ] + }, + { + "name": "@reference", + "description": "If you want to use `@apply` or `@variant` in the ` diff --git a/Frontend/src/assets/MuzikaGromcheTracks.json b/Frontend/src/assets/MuzikaGromcheTracks.json new file mode 100644 index 0000000..7a24031 --- /dev/null +++ b/Frontend/src/assets/MuzikaGromcheTracks.json @@ -0,0 +1,3342 @@ +{ + "version": "1337.9001.68", + "tracks": [ + { + "Enabled": true, + "Name": "Arcane", + "Artist": "Imagine Dragons & J.I.D", + "Song": "Enemy", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 38.28, + "Bpm": 77.0002, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 41.366, + "FileDurationLoop": 24.935, + "FileNameIntro": "ArcaneIntro.ogg", + "FileNameLoop": "ArcaneLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -1.5, + "FadeOutDuration": 1.5, + "ColorTransitionIn": 0.2, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InOutExpo", + "FlickerLightsTimeSeries": [ + -48.1, + -44.1, + -16.0, + 15.9, + 31.9 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -48.0, + 0.0 + ], + [ + -47.75, + 0.5 + ], + [ + -44.0, + 0.2 + ], + [ + -43.75, + 0.5 + ], + [ + -36.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.25, + 0.4 + ], + [ + 6.0, + 0.0 + ], + [ + 8.0, + 0.0 + ], + [ + 8.25, + 0.4 + ], + [ + 14.0, + 0.0 + ], + [ + 16.0, + 0.0 + ], + [ + 16.25, + 0.4 + ], + [ + 22.0, + 0.0 + ], + [ + 24.0, + 0.0 + ], + [ + 24.25, + 0.4 + ], + [ + 30.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + 24.0, + 0.0 + ], + [ + 24.25, + 0.5 + ], + [ + 30.0, + 0.0 + ] + ], + "Palette": [ + "#F0FBFF", + "#0B95FF", + "#A8F5E2", + "#B79BF2", + "#FED2E1" + ], + "GameOverText": "[LIFE SUPPORT: HEXTECH]" + }, + { + "Enabled": true, + "Name": "AttentionPls1", + "Artist": "Отпетые Мошенники", + "Song": "Обратите внимание", + "IsExplicit": true, + "Season": null, + "Language": "Russian", + "WindUpTimer": 39.19, + "Bpm": 97.8244247, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 49.061, + "FileDurationLoop": 19.627, + "FileNameIntro": "AttentionPls1Intro.ogg", + "FileNameLoop": "AttentionPlsLoop.ogg", + "BeatsOffset": 0.3, + "FadeOutBeat": -6.0, + "FadeOutDuration": 5.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -8.0, + 31.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 7.0, + 0.0 + ], + [ + 12.0, + 0.9 + ], + [ + 15.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + 23.0, + 0.0 + ], + [ + 28.0, + 0.4 + ], + [ + 31.0, + 0.0 + ] + ], + "Palette": [ + "#FCEB3C", + "#FC3C9D", + "#65C7FA", + "#89FC8F", + "#FEE9E9", + "#FCEB3C", + "#89FC8F", + "#FC3C9D" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "AttentionPls2", + "Artist": "Отпетые Мошенники", + "Song": "Обратите внимание", + "IsExplicit": true, + "Season": null, + "Language": "Russian", + "WindUpTimer": 39.19, + "Bpm": 97.8244247, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 49.061, + "FileDurationLoop": 19.627, + "FileNameIntro": "AttentionPls2Intro.ogg", + "FileNameLoop": "AttentionPlsLoop.ogg", + "BeatsOffset": 0.3, + "FadeOutBeat": -6.0, + "FadeOutDuration": 5.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -8.0, + 31.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 7.0, + 0.0 + ], + [ + 12.0, + 0.9 + ], + [ + 15.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + 23.0, + 0.0 + ], + [ + 28.0, + 0.4 + ], + [ + 31.0, + 0.0 + ] + ], + "Palette": [ + "#FCEB3C", + "#FC3C9D", + "#65C7FA", + "#89FC8F", + "#FEE9E9", + "#FCEB3C", + "#89FC8F", + "#FC3C9D" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "BbIXODaHET", + "Artist": "Сплин", + "Song": "Выхода нет", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 40.85, + "Bpm": 84.82064, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 53.368, + "FileDurationLoop": 22.636, + "FileNameIntro": "BbIXODaHETIntro.ogg", + "FileNameLoop": "BbIXODaHETLoop.ogg", + "BeatsOffset": 0.3, + "FadeOutBeat": -6.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.7, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InOutCubic", + "FlickerLightsTimeSeries": [ + -32.5, + -16.5, + 30.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -1.0, + 0.0 + ], + [ + 2.0, + 0.4 + ], + [ + 7.0, + 0.0 + ], + [ + 31.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#E6D58F", + "#612F7E", + "#D9783F", + "#C3411C", + "#D3B742", + "#549BDE" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "BeefLiver1", + "Artist": "Imagine Dragons", + "Song": "Believer", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 39.35, + "Bpm": 124.999992, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 43.166, + "FileDurationLoop": 23.04, + "FileNameIntro": "BeefLiver1Intro.ogg", + "FileNameLoop": "BeefLiverLoop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -3.0, + "FadeOutDuration": 3.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -48.0, + -40.0, + -4.5, + 44.0 + ], + "Lyrics": [ + [ + -66.0, + "First things first" + ], + [ + -62.0, + "First things first,\nI'ma say all the words\ninside my head" + ], + [ + -57.0, + "I'm fired up and tired of" + ], + [ + -52.0, + "the way that things have been,\noh-ooh" + ], + [ + -44.0, + "(x2)\nThe way that things have been,\noh-ooooh" + ], + [ + -34.0, + "I was broken from a young age, taking my sulkin' to the masses" + ], + [ + -27.0, + "Writing my poems for the few" + ], + [ + -23.0, + "that look at me, took to me,\nshook at me, feelin' me" + ], + [ + -19.0, + "Singing from heartache from the pain" + ], + [ + -15.0, + "Singing from heartache from the pain,\ntaking my message from the veins" + ], + [ + -11.0, + "Speaking my lesson from the brain" + ], + [ + -8.0, + "Speaking my lesson from the brain,\nseeing the beauty through the" + ], + [ + -0.1, + "PAIN!" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + 0.5, + 0.6 + ], + [ + 8.0, + 0.0 + ], + [ + 15.0, + 0.0 + ], + [ + 16.0, + 0.4 + ], + [ + 24.0, + 0.0 + ], + [ + 29.0, + 0.0 + ], + [ + 30.0, + 0.3 + ], + [ + 36.0, + 0.0 + ], + [ + 37.0, + 0.0 + ], + [ + 38.0, + 0.3 + ], + [ + 44.0, + 0.0 + ], + [ + 47.5, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FFEBEB", + "#FFEBEB", + "#445782", + "#EBA602", + "#5EEBB9", + "#8EE3DC", + "#A23045", + "#262222" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "BeefLiver3", + "Artist": "Imagine Dragons", + "Song": "Believer", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 39.35, + "Bpm": 124.999992, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 43.166, + "FileDurationLoop": 23.04, + "FileNameIntro": "BeefLiver3Intro.ogg", + "FileNameLoop": "BeefLiverLoop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -3.0, + "FadeOutDuration": 3.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -48.0, + -40.0, + -4.5, + 44.0 + ], + "Lyrics": [ + [ + -66.0, + "Third things third" + ], + [ + -62.0, + "Third things third,\nsend a prayer to the ones up above" + ], + [ + -57.0, + "All the hate that you've heard has turned" + ], + [ + -52.0, + "your spirit to a dove,\noh-ooh" + ], + [ + -44.0, + "(x2)\nYour spirit up above,\noh-ooooh" + ], + [ + -34.0, + "I was chokin' in the crowd, building my rain up in the cloud" + ], + [ + -27.0, + "Falling like ashes to the ground" + ], + [ + -23.0, + "hoping my feelings, they would drown" + ], + [ + -19.0, + "But they never did, ever lived, ebbin' and flowin'" + ], + [ + -15.0, + "Inhibited, limited 'til it broke open" + ], + [ + -11.0, + "Inhibited, limited 'til it broke open and rained down" + ], + [ + -8.0, + "It rained down like" + ], + [ + -0.1, + "PAIN!" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + 0.5, + 0.6 + ], + [ + 8.0, + 0.0 + ], + [ + 15.0, + 0.0 + ], + [ + 16.0, + 0.4 + ], + [ + 24.0, + 0.0 + ], + [ + 29.0, + 0.0 + ], + [ + 30.0, + 0.3 + ], + [ + 36.0, + 0.0 + ], + [ + 37.0, + 0.0 + ], + [ + 38.0, + 0.3 + ], + [ + 44.0, + 0.0 + ], + [ + 47.5, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FFEBEB", + "#FFEBEB", + "#445782", + "#EBA602", + "#5EEBB9", + "#8EE3DC", + "#A23045", + "#262222" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "BeefLiver4", + "Artist": "Imagine Dragons", + "Song": "Believer", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 31.68, + "Bpm": 124.999992, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 35.487, + "FileDurationLoop": 23.04, + "FileNameIntro": "BeefLiver4Intro.ogg", + "FileNameLoop": "BeefLiver4Loop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -3.0, + "FadeOutDuration": 3.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -32.0, + -24.0, + -4.5, + 44.0 + ], + "Lyrics": [ + [ + -50.0, + "Last things last" + ], + [ + -46.0, + "Last things last,\nby the grace\nof the fire and the flames" + ], + [ + -41.0, + "You're the face of the future" + ], + [ + -36.0, + "the blood in my veins, oh-ooh" + ], + [ + -28.0, + "(x2)\nThe blood in my veins, oh-ooooh" + ], + [ + -19.0, + "But they never did, ever lived, ebbin' and flowin'" + ], + [ + -15.0, + "Inhibited, limited 'til it broke open" + ], + [ + -11.0, + "Inhibited, limited 'til it broke open and rained down" + ], + [ + -8.0, + "It rained down like" + ], + [ + -0.1, + "PAIN!" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + 0.5, + 0.6 + ], + [ + 8.0, + 0.0 + ], + [ + 15.0, + 0.0 + ], + [ + 16.0, + 0.4 + ], + [ + 24.0, + 0.0 + ], + [ + 29.0, + 0.0 + ], + [ + 30.0, + 0.3 + ], + [ + 36.0, + 0.0 + ], + [ + 37.0, + 0.0 + ], + [ + 38.0, + 0.3 + ], + [ + 44.0, + 0.0 + ], + [ + 47.5, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FFEBEB", + "#FFEBEB", + "#445782", + "#EBA602", + "#5EEBB9", + "#8EE3DC", + "#A23045", + "#262222" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Beha1", + "Artist": "Ленинград ft. Глюк'oZа ft. ST", + "Song": "Жу-Жу", + "IsExplicit": true, + "Season": null, + "Language": "Russian", + "WindUpTimer": 35.23, + "Bpm": 81.99027, + "Beats": 34, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 47.15, + "FileDurationLoop": 24.881, + "FileNameIntro": "Beha1Intro.ogg", + "FileNameLoop": "BehaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 3.9, + "ColorTransitionIn": 0.1, + "ColorTransitionOut": 0.6, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -6.0, + 16.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#9554F9", + "#3769FD", + "#E43B65", + "#59CFEA", + "#7F3FEE", + "#C831FE" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Beha2", + "Artist": "Ленинград ft. Глюк'oZа ft. ST", + "Song": "Жу-Жу", + "IsExplicit": true, + "Season": null, + "Language": "Russian", + "WindUpTimer": 38.16, + "Bpm": 81.99027, + "Beats": 34, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 50.064, + "FileDurationLoop": 24.881, + "FileNameIntro": "Beha2Intro.ogg", + "FileNameLoop": "BehaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 3.9, + "ColorTransitionIn": 0.1, + "ColorTransitionOut": 0.6, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -6.0, + 16.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#9554F9", + "#3769FD", + "#E43B65", + "#59CFEA", + "#7F3FEE", + "#C831FE" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Beha3", + "Artist": "Ленинград ft. Глюк'oZа ft. ST", + "Song": "Жу-Жу", + "IsExplicit": true, + "Season": null, + "Language": "Russian", + "WindUpTimer": 35.21, + "Bpm": 81.99027, + "Beats": 34, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 47.111, + "FileDurationLoop": 24.881, + "FileNameIntro": "Beha3Intro.ogg", + "FileNameLoop": "BehaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 3.9, + "ColorTransitionIn": 0.1, + "ColorTransitionOut": 0.6, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -6.0, + 16.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#9554F9", + "#3769FD", + "#E43B65", + "#59CFEA", + "#7F3FEE", + "#C831FE" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Chereshnya", + "Artist": "Дискотека Авария", + "Song": "Малинки", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 45.48, + "Bpm": 131.958755, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 46.15, + "FileDurationLoop": 29.1, + "FileNameIntro": "ChereshnyaIntro.ogg", + "FileNameLoop": "ChereshnyaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.3, + "ColorTransitionOut": 0.35, + "ColorTransitionEasing": "InOutCubic", + "FlickerLightsTimeSeries": [ + -5.0, + 27.0, + 29.0, + 59.0, + 61.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#A01471", + "#CB2243", + "#4CAF50", + "#F01D7A", + "#AF005A", + "#EF355F", + "#FFD85D", + "#FF66B2", + "#A01471", + "#4CAF50", + "#CB2243", + "#F01D7A", + "#AF005A", + "#FFD85D", + "#EF355F", + "#FF66B2" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "DeployDestroy", + "Artist": "Noize MC", + "Song": "Устрой дестрой", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 40.68, + "Bpm": 129.878922, + "Beats": 32, + "LoopOffset": 32, + "Ext": "ogg", + "FileDurationIntro": 57.283, + "FileDurationLoop": 14.783, + "FileNameIntro": "DeployDestroyIntro.ogg", + "FileNameLoop": "DeployDestroyLoop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -38.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.25, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -101.0, + -93.0, + -77.0, + -61.0, + -37.0, + -5.0, + 27.0 + ], + "Lyrics": [ + [ + -111.0, + "Deploy Destroy, porjadok eto otstoj" + ], + [ + -103.0, + "Krushi, lomaj, trjasi bashkoju pustoj" + ], + [ + -95.0, + "Dopej, razbej i novuju otkryvaj" + ], + [ + -87.0, + "Davaj-davaj!" + ], + [ + -79.0, + "Chestnoe slovo ja nevinoven" + ], + [ + -75.0, + "Ja ne pomnju, otkuda stol'ko krovi" + ], + [ + -71.0, + "Na moih ladonjah\nyi moej odezhde" + ], + [ + -67.0, + "Ja nikogda nikogo\nne bil prezhde" + ], + [ + -63.0, + "Ja nikogda nichego\nne pil prezhde" + ], + [ + -59.0, + "Byl tih, spokoen,\nso vsemi vezhliv" + ], + [ + -55.0, + "Vsegda tol'ko v urnu\nbrosal musor" + ], + [ + -51.0, + "Obhodil storonoj shumnye tusy" + ], + [ + -47.0, + "Zapreshhjonnyh veshhestv nikakih ne juzal" + ], + [ + -43.0, + "Byl polozhitel'nej samogo pljusa" + ], + [ + -39.0, + "A potom kak-to raz\njetu pesnju uslyshal" + ], + [ + -35.0, + "I vsjo proshhaj, moja krysha" + ], + [ + -31.0, + "Deploy Destroy, porjadok eto otstoj" + ], + [ + -23.0, + "Krushi, lomaj, trjasi bashkoju pustoj" + ], + [ + -15.0, + "Dopej, razbej i novuju otkryvaj" + ], + [ + -7.0, + "Davaj-davaj!" + ], + [ + 1.0, + "Deploy Destroy, porjadok eto otstoj" + ], + [ + 9.0, + "Krushi, lomaj, trjasi bashkoju pustoj" + ], + [ + 17.0, + "Dopej, razbej i novuju otkryvaj" + ], + [ + 25.0, + "Davaj-davaj!" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -48.0, + 0.0 + ], + [ + -46.0, + 0.7 + ], + [ + -42.0, + 0.0 + ], + [ + 16.0, + 0.0 + ], + [ + 19.0, + 0.3 + ], + [ + 23.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#217F87", + "#BAFF00", + "#73BE25", + "#78AB4E", + "#FFFF00" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "DiscoKapot", + "Artist": "Дискотека Авария", + "Song": "Новогодняя", + "IsExplicit": false, + "Season": "New Year", + "Language": "Russian", + "WindUpTimer": 30.3, + "Bpm": 67.01337, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 33.933, + "FileDurationLoop": 28.651, + "FileNameIntro": "DiscoKapotIntro.ogg", + "FileNameLoop": "DiscoKapotLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.6, + "ColorTransitionEasing": "InOutExpo", + "FlickerLightsTimeSeries": [ + -32.0, + -24.0, + -16.0, + 16.0, + 32.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 0.0, + 0.0 + ], + [ + 0.25, + 0.5 + ], + [ + 6.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#0B6623", + "#FF2D2D", + "#FFD700", + "#00BFFF", + "#9400D3", + "#00FF7F" + ], + "GameOverText": "[NEXT YEAR -- DEFINITELY]" + }, + { + "Enabled": true, + "Name": "Durochka", + "Artist": "Би-2", + "Song": "Дурочка", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 37.0, + "Bpm": 129.9686, + "Beats": 40, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 38.833, + "FileDurationLoop": 18.466, + "FileNameIntro": "DurochkaIntro.ogg", + "FileNameLoop": "DurochkaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -7.0, + "FadeOutDuration": 7.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -9.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#5986FE", + "#FEFEDC", + "#FF4FDF", + "#FEFEDC", + "#FFAA23", + "#FEFEDC", + "#F95A5A", + "#FEFEDC" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "GodMode", + "Artist": "Fall Out Boy", + "Song": "Immortals", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 40.38, + "Bpm": 108.016876, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 42.6, + "FileDurationLoop": 35.55, + "FileNameIntro": "GodModeIntro.ogg", + "FileNameLoop": "GodModeLoop.ogg", + "BeatsOffset": 0.1, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.5, + "ColorTransitionOut": 0.5, + "ColorTransitionEasing": "OutCubic", + "FlickerLightsTimeSeries": [ + -5.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + 0.0, + 0.7 + ], + [ + 8.0, + 0.0 + ], + [ + 63.5, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FBDBDB", + "#4B81FF", + "#564242", + "#C90AE2", + "#FBDBDB", + "#61CBE3", + "#564242", + "#ED3131" + ], + "GameOverText": "[COULD'VE BEEN: IMMORTAL]" + }, + { + "Enabled": true, + "Name": "Gorgorod", + "Artist": "Oxxxymiron", + "Song": "Город под подошвой", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 43.2, + "Bpm": 90.0, + "Beats": 24, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 47.866, + "FileDurationLoop": 16.0, + "FileNameIntro": "GorgorodIntro.ogg", + "FileNameLoop": "GorgorodLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -2.0, + "FadeOutDuration": 2.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.25, + "ColorTransitionEasing": "InExpo", + "FlickerLightsTimeSeries": [ + 20.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#42367E", + "#FF9400", + "#932A04", + "#FF9400", + "#932A04", + "#42367E", + "#FF9400", + "#932A04" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "HighLow", + "Artist": "Nirvana", + "Song": "Smells Like Teen Spirit", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 37.12, + "Bpm": 117.873367, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 40.3, + "FileDurationLoop": 24.433, + "FileNameIntro": "HighLowIntro.ogg", + "FileNameLoop": "HighLowLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -1.5, + "FadeOutDuration": 1.5, + "ColorTransitionIn": 0.75, + "ColorTransitionOut": 0.25, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -33.0, + 39.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -2.0, + 0.0 + ], + [ + -1.0, + 0.5 + ], + [ + 6.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + -2.0, + 0.0 + ], + [ + -1.0, + 0.5 + ], + [ + 6.0, + 0.0 + ] + ], + "Palette": [ + "#2E2E28", + "#DFA24D", + "#2E2E28", + "#DFA24D", + "#2E2E28", + "#DFA24D", + "#2E2E28", + "#DFA24D" + ], + "GameOverText": "[LIFE SUPORT: NIRVANA]" + }, + { + "Enabled": true, + "Name": "IkWilJe", + "Artist": "My Chemical Romance", + "Song": "All I Want for Christmas Is You", + "IsExplicit": false, + "Season": "New Year", + "Language": "English", + "WindUpTimer": 43.03, + "Bpm": 82.11054, + "Beats": 54, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 63.815, + "FileDurationLoop": 39.459, + "FileNameIntro": "IkWilJeIntro.ogg", + "FileNameLoop": "IkWilJeLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -14.0, + "FadeOutDuration": 12.0, + "ColorTransitionIn": 0.01, + "ColorTransitionOut": 0.99, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + 31.45 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 0.0, + 0.0 + ], + [ + 0.25, + 0.5 + ], + [ + 6.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#0B6623", + "#FF2D2D", + "#FFD700", + "#00BFFF", + "#9400D3", + "#00FF7F" + ], + "GameOverText": "[NEXT YEAR -- DEFINITELY]" + }, + { + "Enabled": true, + "Name": "Kach", + "Artist": "Black Eyed Peas", + "Song": "Pump It", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 47.3, + "Bpm": 153.6, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 48.866, + "FileDurationLoop": 18.75, + "FileNameIntro": "KachIntro.ogg", + "FileNameLoop": "KachLoop.ogg", + "BeatsOffset": 0.4, + "FadeOutBeat": -6.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.8, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -120.5, + -105.0, + -89.0, + -8.0, + 44.0, + 45.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#7774DE", + "#1EA59A", + "#3BC457", + "#3BC457", + "#CA6935", + "#A82615", + "#A7AA43", + "#A7AA43", + "#4C2B81", + "#2E802B", + "#C952E7", + "#C952E7" + ], + "GameOverText": "[DIDN'T PUMP IT: LOUDER]" + }, + { + "Enabled": true, + "Name": "MoyaZhittya", + "Artist": "Bon Jovi", + "Song": "It's My Life", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 34.53, + "Bpm": 120.0, + "Beats": 32, + "LoopOffset": 32, + "Ext": "ogg", + "FileDurationIntro": 43.533, + "FileDurationLoop": 16.0, + "FileNameIntro": "MoyaZhittyaIntro.ogg", + "FileNameLoop": "MoyaZhittyaLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -35.0, + "FadeOutDuration": 3.3, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.5, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -100.5, + -99.5, + -92.5, + -91.5, + -76.5, + -75.5, + -60.5, + -59.5, + -37.0, + -36.0, + -4.5, + -3.5, + 27.5, + 28.5 + ], + "Lyrics": [ + [ + -84.0, + "This ain't a song for the broken-hearted" + ], + [ + -68.0, + "No silent prayer for the faith-departed" + ], + [ + -52.0, + "I ain't gonna be" + ], + [ + -48.0, + "I ain't gonna be\njust a face in the crowd" + ], + [ + -45.0, + "YOU'RE" + ], + [ + -44.0, + "you're GONNA" + ], + [ + -43.5, + "you're gonna HEAR" + ], + [ + -43.0, + "you're gonna hear\nMY" + ], + [ + -42.0, + "you're gonna hear\nmy VOICE" + ], + [ + -41.0, + "WHEN I" + ], + [ + -40.0, + "When I SHOUT IT" + ], + [ + -39.0, + "When I shout it\nOUT LOUD" + ], + [ + -34.0, + "IT'S MY" + ], + [ + -32.0, + "IT'S MY\nLIIIIIFE" + ], + [ + -28.0, + "And it's now or never" + ], + [ + -22.0, + "I ain't gonna" + ], + [ + -20.0, + "I ain't gonna\nlive forever" + ], + [ + -14.0, + "I just want to live" + ], + [ + -10.0, + "I just want to live\nwhile I'm alive" + ], + [ + -2.0, + "IT'S MY" + ], + [ + 0.0, + "IT'S MY\nLIIIIIFE" + ], + [ + 2.0, + "My heart is like" + ], + [ + 4.0, + "My heart is like\nan open highway" + ], + [ + 10.0, + "Like Frankie said," + ], + [ + 12.0, + "Like Frankie said,\n\"I did it my way\"" + ], + [ + 18.0, + "I just want to live" + ], + [ + 22.0, + "I just want to live\nwhile I'm alive" + ], + [ + 30.0, + "IT'S MY" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -33.0, + 0.0 + ], + [ + -31.0, + 0.7 + ], + [ + -1.0, + 0.0 + ], + [ + 1.0, + 0.7 + ], + [ + 8.0, + 0.0 + ], + [ + 24.0, + 0.0 + ], + [ + 31.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#A8C480", + "#3ABBBE", + "#6E9855", + "#4C6846", + "#748084", + "#058099" + ], + "GameOverText": "[LIFE IS: NOW OR NEVER]" + }, + { + "Enabled": true, + "Name": "MuzikaGromche", + "Artist": "Пошлая Молли", + "Song": "Нон стоп", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 46.3, + "Bpm": 129.729721, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 50.283, + "FileDurationLoop": 29.6, + "FileNameIntro": "MuzikaGromcheIntro.ogg", + "FileNameLoop": "MuzikaGromcheLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -3.0, + "FadeOutDuration": 3.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.25, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -5.0, + 29.0, + 61.0 + ], + "Lyrics": [ + [ + -68.0, + "Devchata pljashut pod spidami" + ], + [ + -60.0, + "A ty stoish', kak vkopannyj" + ], + [ + -52.0, + "Krossovkami lomajut pol" + ], + [ + -44.0, + "A ty stoish', kak vkopannyj" + ], + [ + -36.0, + "Ja-ja-ja znaju, chto ty hochesh'," + ], + [ + -32.0, + "Ja-ja-ja znaju, chto ty hochesh',\nTy hochesh' tancevat'" + ], + [ + -28.0, + "Nu-nu zhe, nu davaj zhe," + ], + [ + -24.0, + "Nu-nu zhe, nu davaj zhe,\nNu-nu zhe, nu davaj zhe" + ], + [ + -20.0, + "Ja znaju, chto ty znaesh'\nJetot trek, gotov'sja podpevat'" + ], + [ + -12.0, + "1) RAZ" + ], + [ + -10.0, + "raz, DVA" + ], + [ + -8.0, + "raz, 2wo,\nTRI" + ], + [ + -6.0, + "ras, dva,\n7ri, 4ETYRE" + ], + [ + -1.0, + "Muzyka Gromche\nGlaza zakryty >_<" + ], + [ + 6.0, + "This is NON-STOP,\nNoch'ju otkrytij" + ], + [ + 12.0, + "Delaj chto hochesh', ja zabyvajus'" + ], + [ + 22.0, + "This is NON-STOP,\nne prekrashhajas'" + ], + [ + 31.0, + "Muzyka Gromche\nGlaza zakryty -.-" + ], + [ + 38.0, + "This is NON-STOP,\nNoch'ju otkrytij" + ], + [ + 46.0, + "Budu s toboju,\nsamoj primernoju" + ], + [ + 54.0, + "Utro v okne\nyi my budem pervye" + ], + [ + 63.0, + "Muzyka Gromche\nGlaza zakryty >_<" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -2.0, + 0.0 + ], + [ + 0.0, + 0.4 + ], + [ + 1.0, + 0.6 + ], + [ + 3.0, + 0.0 + ], + [ + 30.0, + 0.0 + ], + [ + 32.0, + 0.5 + ], + [ + 33.0, + 0.7 + ], + [ + 35.0, + 0.0 + ], + [ + 62.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#B300FF", + "#FFF100", + "#00FF51", + "#474747", + "#FF00B3", + "#0070FF" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "OnePartiyaUdar", + "Artist": "One-Punch Man", + "Song": "Opening", + "IsExplicit": false, + "Season": null, + "Language": "Japanese", + "WindUpTimer": 41.27, + "Bpm": 130.06955, + "Beats": 48, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 44.983, + "FileDurationLoop": 22.142, + "FileNameIntro": "OnePartiyaUdarIntro.ogg", + "FileNameLoop": "OnePartiyaUdarLoop.ogg", + "BeatsOffset": 0.3, + "FadeOutBeat": -8.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.6, + "ColorTransitionOut": 0.15, + "ColorTransitionEasing": "InOutExpo", + "FlickerLightsTimeSeries": [ + -68.5, + -16.5, + 30.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#9C3C37", + "#E9BF5C", + "#B5E3EA", + "#662422", + "#EBC3A8", + "#AA8238" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Paarden", + "Artist": "Элизиум", + "Song": "Три белых коня", + "IsExplicit": false, + "Season": "New Year", + "Language": "Russian", + "WindUpTimer": 36.12, + "Bpm": 93.05482, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 41.45, + "FileDurationLoop": 20.633, + "FileNameIntro": "PaardenIntro.ogg", + "FileNameLoop": "PaardenLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutCubic", + "FlickerLightsTimeSeries": [ + 31.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 0.0, + 0.0 + ], + [ + 0.25, + 0.5 + ], + [ + 6.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#F0FBFF", + "#9ED9FF", + "#0B95FF", + "#66C7FF", + "#CAE8FF", + "#3BB6FF" + ], + "GameOverText": "[NEXT YEAR -- DEFINITELY]" + }, + { + "Enabled": true, + "Name": "Peretasovka", + "Artist": "LMFAO", + "Song": "Party Rock Anthem", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 39.68, + "Bpm": 130.612244, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 40.6, + "FileDurationLoop": 14.7, + "FileNameIntro": "PeretasovkaIntro.ogg", + "FileNameLoop": "PeretasovkaLoop.ogg", + "BeatsOffset": 0.3, + "FadeOutBeat": -6.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -8.0, + 31.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#65C7FA", + "#FCEB3C", + "#89FC8F", + "#FEE9E9", + "#FC3C9D", + "#FCEB3C", + "#89FC8F", + "#FC3C9D" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "PickUpSticks1", + "Artist": "t.A.T.u.", + "Song": "Show Me Love", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 38.5, + "Bpm": 99.89074, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 43.413, + "FileDurationLoop": 38.442, + "FileNameIntro": "PickUpSticks1Intro.ogg", + "FileNameLoop": "PickUpSticksLoop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -2.0, + "FadeOutDuration": 2.0, + "ColorTransitionIn": 0.6, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InOutCubic", + "FlickerLightsTimeSeries": [ + -36.0, + -4.0, + 32.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 0.0, + 0.0 + ], + [ + 0.5, + 0.5 + ], + [ + 3.0, + 0.0 + ], + [ + 32.0, + 0.0 + ], + [ + 34.0, + 0.3 + ], + [ + 40.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + 23.0, + 0.0 + ], + [ + 28.0, + 0.6 + ], + [ + 31.0, + 0.0 + ], + [ + 34.0, + 0.0 + ], + [ + 38.0, + 0.7 + ], + [ + 52.0, + 0.0 + ] + ], + "Palette": [ + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#EEA0A5", + "#EEA0A5" + ], + "GameOverText": "[LOVE SUPPORT: OFFLINE]" + }, + { + "Enabled": true, + "Name": "PickUpSticks2", + "Artist": "t.A.T.u.", + "Song": "Show Me Love", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 38.47, + "Bpm": 99.89074, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 43.404, + "FileDurationLoop": 38.442, + "FileNameIntro": "PickUpSticks2Intro.ogg", + "FileNameLoop": "PickUpSticksLoop.ogg", + "BeatsOffset": 0.2, + "FadeOutBeat": -2.0, + "FadeOutDuration": 2.0, + "ColorTransitionIn": 0.6, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InOutCubic", + "FlickerLightsTimeSeries": [ + -36.0, + -4.0, + 32.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + 0.0, + 0.0 + ], + [ + 0.5, + 0.5 + ], + [ + 3.0, + 0.0 + ], + [ + 32.0, + 0.0 + ], + [ + 34.0, + 0.3 + ], + [ + 40.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + 23.0, + 0.0 + ], + [ + 28.0, + 0.5 + ], + [ + 31.0, + 0.0 + ], + [ + 34.0, + 0.0 + ], + [ + 38.0, + 0.5 + ], + [ + 52.0, + 0.0 + ] + ], + "Palette": [ + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#EEA0A5", + "#CA71FC", + "#D01760", + "#FC933C", + "#FC3C9D", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#FC933C", + "#FC933C", + "#FC3C9D", + "#FC3C9D", + "#EEA0A5", + "#EEA0A5", + "#CA71FC", + "#CA71FC", + "#D01760", + "#D01760", + "#EEA0A5", + "#EEA0A5" + ], + "GameOverText": "[LOVE SUPPORT: OFFLINE]" + }, + { + "Enabled": true, + "Name": "PWNED", + "Artist": "CYBEЯIA", + "Song": "Russian Hackers", + "IsExplicit": true, + "Season": null, + "Language": "English", + "WindUpTimer": 39.73, + "Bpm": 289.8113, + "Beats": 128, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 59.633, + "FileDurationLoop": 26.5, + "FileNameIntro": "PWNEDIntro.ogg", + "FileNameLoop": "PWNEDLoop.ogg", + "BeatsOffset": -0.2, + "FadeOutBeat": -8.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.5, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InExpo", + "FlickerLightsTimeSeries": [ + -136.0, + -72.0, + -12.0, + 88.0 + ], + "Lyrics": [ + [ + -190.0, + "These Russian hackers have been" + ], + [ + -184.0, + "in these US governments\nsince March" + ], + [ + -172.0, + "and it is an extraordinary invasion of our cyberspace" + ], + [ + -152.0, + "Russian hackers got access to sensitive" + ], + [ + -142.0, + "parts of the White House email system..." + ], + [ + -134.0, + "[They began to recognize...]" + ], + [ + -126.0, + "" + ], + [ + -118.0, + "\n X__X" + ], + [ + -110.0, + "Gonna crack your" + ], + [ + -102.0, + "Gonna crack your\nStrongest pa$$words%123" + ], + [ + -94.0, + "You popped online" + ], + [ + -86.0, + "You popped online\nTo look for sneakers" + ], + [ + -78.0, + "My hand just popped" + ], + [ + -70.0, + "My hand just popped\nRight in your knickers >_< " + ], + [ + -62.0, + "Keystrokes like Uzi" + ], + [ + -54.0, + "Keystrokes like Uzi\nWill make you go all goosey" + ], + [ + -46.0, + "Kicking down your backdoor" + ], + [ + -38.0, + "Kicking down your backdoor\nCount down before you lose it" + ], + [ + -30.0, + "Keystrokes like Uzi" + ], + [ + -22.0, + "Keystrokes like Uzi\nWill make you go all goosey" + ], + [ + -14.0, + "Kicking down your backdoor" + ], + [ + -6.0, + "Kicking down your backdoor\nCount down before you lose it" + ], + [ + 0.0, + "C:\\> $Ru55ian hack3rs" + ], + [ + 4.0, + "C:\\> $Ru55ian hack3rs\n O__o" + ], + [ + 8.0, + "Infamous White House attackers" + ], + [ + 16.0, + "Stealing your cookies\nto this beat" + ], + [ + 24.0, + "Counting crypto to\nembarrass Wall Street" + ], + [ + 32.0, + "Russi?n ^hackers\tЯushan h@ckers###" + ], + [ + 34.0, + "\tЯushan h@ckers###\n X_X" + ], + [ + 36.0, + "Russi?n ^hackers\n--.--\tЯushan h@ckers###\n X___X" + ], + [ + 38.0, + "\tЯushan h@ckers###\n X_____X" + ], + [ + 40.0, + "Infamous White House attackers" + ], + [ + 48.0, + "Stealing your cookies\nto this beat" + ], + [ + 56.0, + "Counting crypto to\nembarrass Wall Street" + ], + [ + 80.0, + "Instling min3r.exe\t\t\tresolving ur private IP\n/" + ], + [ + 82.0, + "Instling min3r.exe\n00% [8=D ]\tHenllo ${username = \"user\"}\t\tresolving ur private IP\n-" + ], + [ + 84.0, + "Instling min3r.exe\n34% [8====D ]\t\t\tresolving ur private IP\n\\" + ], + [ + 86.0, + "Instling min3r.exe\n69% [8=========D ]\t\t\tresolving ur private IP\n| Trying... 127.0.0.1" + ], + [ + 88.0, + "Instling min3r.exe\n95% [8============D ]\t\tWhere did you download\nthis < mod / dll > from?\tresolving ur private IP\n Trying... 127.0.0.1/" + ], + [ + 90.0, + "Instling min3r.exe\n99% [8=============D]\t\t\tresolving ur private IP\n- Trying... 127.0.0.1" + ], + [ + 92.0, + "Encrpt1ng f!les.. \n99% [8=============D]\t\t\tresolving ur private IP\n\\ Trying... 127.0.0.1" + ], + [ + 94.0, + "Encrpt1ng f!les...\n100% enj0y \\o/\t\t\tresolving ur private IP\n| Trying... 127.0.0.1" + ], + [ + 96.0, + "\t\t\tresolving ur private IP\n/ Trying... 127.0.0.1" + ], + [ + 98.0, + "\t\t\tresolving ur private IP\nP_WNED" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -128.0, + 0.0 + ], + [ + -127.0, + 0.7 + ], + [ + -116.0, + 0.0 + ], + [ + 68.0, + 0.0 + ], + [ + 72.0, + 0.3 + ], + [ + 88.0, + 0.5 + ], + [ + 98.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FFFFFF", + "#0032A0", + "#DA291C", + "#000000", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#8E8E8E", + "#8E8E8E", + "#1D1D1D", + "#1D1D1D", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#FFFFFF", + "#0032A0", + "#DA291C", + "#000000", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#8E8E8E", + "#8E8E8E", + "#1D1D1D", + "#1D1D1D", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#9E9E9E", + "#9E9E9E", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#4B4B4B", + "#4B4B4B", + "#8E8E8E", + "#8E8E8E", + "#8E8E8E", + "#8E8E8E", + "#1D1D1D", + "#1D1D1D", + "#1D1D1D", + "#1D1D1D", + "#9E9E9E", + "#9E9E9E", + "#9E9E9E", + "#9E9E9E", + "#383838", + "#383838", + "#383838", + "#383838", + "#5E5E5E", + "#5E5E5E", + "#5E5E5E", + "#5E5E5E", + "#2E2E2E", + "#2E2E2E", + "#2E2E2E", + "#2E2E2E", + "#666666", + "#666666", + "#666666", + "#666666", + "#4B4B4B", + "#4B4B4B", + "#4B4B4B", + "#4B4B4B", + "#8E8E8E", + "#8E8E8E", + "#8E8E8E", + "#8E8E8E", + "#1D1D1D", + "#1D1D1D", + "#1D1D1D", + "#1D1D1D" + ], + "GameOverText": "[HACK3D BY: RUSSI4NS]" + }, + { + "Enabled": true, + "Name": "ReelGoon", + "Artist": "John Shanks and Sheryl Crow", + "Song": "Real Gone", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 45.15, + "Bpm": 117.997726, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 47.45, + "FileDurationLoop": 32.543, + "FileNameIntro": "ReelGoonIntro.ogg", + "FileNameLoop": "ReelGoonLoop.ogg", + "BeatsOffset": -0.35, + "FadeOutBeat": -2.0, + "FadeOutDuration": 2.0, + "ColorTransitionIn": 0.1, + "ColorTransitionOut": 0.35, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -41.0, + 61.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + -0.05, + 0.5 + ], + [ + 6.0, + 0.0 + ], + [ + 60.0, + 0.0 + ], + [ + 61.0, + 0.5 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#DE1C31", + "#F7E26B", + "#3D3D3D", + "#FBB040", + "#ED4E4A", + "#F0BD37", + "#E41E2E", + "#2E2D2B" + ], + "GameOverText": "[LIFE SUPPORT: REAL GONE]" + }, + { + "Enabled": true, + "Name": "RiseAndShine", + "Artist": "Fall Out Boy", + "Song": "The Phoenix", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 59.87, + "Bpm": 137.8815, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 61.616, + "FileDurationLoop": 27.85, + "FileNameIntro": "RiseAndShineIntro.ogg", + "FileNameLoop": "RiseAndShineLoop.ogg", + "BeatsOffset": 0.1, + "FadeOutBeat": -4.5, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.5, + "ColorTransitionOut": 0.5, + "ColorTransitionEasing": "OutCubic", + "FlickerLightsTimeSeries": [ + -5.5, + 31.0, + 63.9 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [ + [ + -0.5, + 0.0 + ], + [ + 0.0, + 0.7 + ], + [ + 8.0, + 0.0 + ], + [ + 63.5, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FC6F3C", + "#3CB0FC", + "#FCD489", + "#564242", + "#FC6F3C", + "#3CB0FC", + "#63E98C", + "#866868" + ], + "GameOverText": "[ HEY, YOUNG BLOOD ]" + }, + { + "Enabled": true, + "Name": "Song2", + "Artist": "Витас", + "Song": "Опера #2", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 38.63, + "Bpm": 50.0, + "Beats": 34, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 43.433, + "FileDurationLoop": 40.8, + "FileNameIntro": "Song2Intro.ogg", + "FileNameLoop": "Song2Loop.ogg", + "BeatsOffset": 0.1, + "FadeOutBeat": -2.0, + "FadeOutDuration": 2.0, + "ColorTransitionIn": 0.3, + "ColorTransitionOut": 0.3, + "ColorTransitionEasing": "InCubic", + "FlickerLightsTimeSeries": [ + 2.5 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FFD3E3", + "#78A0FF", + "#FFD3E3", + "#74A392", + "#FFD3E3", + "#E4B082", + "#FFD3E3", + "#E277AA" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "TwoFastTuFurious", + "Artist": "t.A.T.u.", + "Song": "Not Gonna Get Us / Нас не догонят", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 36.08, + "Bpm": 130.034317, + "Beats": 96, + "LoopOffset": 48, + "Ext": "ogg", + "FileDurationIntro": 39.308, + "FileDurationLoop": 44.296, + "FileNameIntro": "TwoFastTuFuriousIntro.ogg", + "FileNameLoop": "TwoFastTuFuriousLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -54.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.6, + "ColorTransitionEasing": "InOutCubic", + "FlickerLightsTimeSeries": [ + -80.0, + -14.0, + 34.0, + 82.0 + ], + "Lyrics": [ + [ + -126.0, + "Starting from here,\nlet's make a promise" + ], + [ + -110.0, + "You and me, let's just be honest" + ], + [ + -100.0, + "We're gonna run,\nnothing can stop us" + ], + [ + -89.0, + "Even the night,\nthat falls all around us" + ], + [ + -80.0, + "Soon there will be\nlaughter and voices" + ], + [ + -70.0, + "Beyond the clouds,\nover the mountains" + ], + [ + -62.0, + "We'll run away,\non roads that are empty" + ], + [ + -55.0, + "Lights from the airfield,\nshining upon you" + ], + [ + -48.0, + "Nothing can stop this" + ], + [ + -44.0, + "Nothing can stop this,\nnot now, I love you" + ], + [ + -40.0, + "They're not gonna get us" + ], + [ + -36.0, + "They're not gonna get us\nTHEY'RE NOT GONNA GET US" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -48.0, + 0.0 + ], + [ + -47.75, + 0.5 + ], + [ + -42.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.25, + 0.5 + ], + [ + 6.0, + 0.0 + ], + [ + 48.0, + 0.0 + ], + [ + 48.25, + 0.5 + ], + [ + 54.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [ + [ + -24.0, + 0.0 + ], + [ + -23.75, + 0.5 + ], + [ + -18.0, + 0.0 + ], + [ + 24.0, + 0.0 + ], + [ + 24.25, + 0.5 + ], + [ + 30.0, + 0.0 + ], + [ + 72.0, + 0.0 + ], + [ + 72.25, + 0.5 + ], + [ + 78.0, + 0.0 + ] + ], + "Palette": [ + "#F0FBFF", + "#9ED9FF", + "#0B95FF", + "#66C7FF", + "#CAE8FF", + "#3BB6FF" + ], + "GameOverText": "[ O NOES, THEY GOT US ]" + }, + { + "Enabled": true, + "Name": "VseVZale", + "Artist": "Дискотека Авария", + "Song": " Х.Х.Х.И.Р.Н.Р.", + "IsExplicit": false, + "Season": null, + "Language": "Russian", + "WindUpTimer": 38.28, + "Bpm": 137.965729, + "Beats": 64, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 40.016, + "FileDurationLoop": 27.833, + "FileNameIntro": "VseVZaleIntro.ogg", + "FileNameLoop": "VseVZaleLoop.ogg", + "BeatsOffset": 0.25, + "FadeOutBeat": -3.0, + "FadeOutDuration": 2.5, + "ColorTransitionIn": 0.25, + "ColorTransitionOut": 0.25, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -5.0, + 29.0, + 59.0 + ], + "Lyrics": [ + [ + -30.0, + "VSE V ZALE\nDvigajtes' s nami" + ], + [ + -24.0, + "Chtob sotrjasalis'\nSami my, steny i pol!" + ], + [ + -14.0, + "Vse znaem - jeto examen na dom nam zadan" + ], + [ + -4.0, + "HIP-HOP, HOUSE & ROCK-N-ROLL" + ], + [ + 2.0, + "VSE V ZALE\nDvigajtes' s nami" + ], + [ + 8.0, + "Chtob sotrjasalis'\nSami my, steny i pol!" + ], + [ + 18.0, + "Vse znaem - jeto examen na dom nam zadan" + ], + [ + 28.0, + "HIP-HOP, HOUSE & ROCK-N-ROLL" + ], + [ + 32.0, + "O-o-o-o! Zdes' startuet hip-hop party" + ], + [ + 44.0, + "Tolstyj paren', nam igraj!" + ], + [ + 48.0, + "O-o-o-o! Pesen i devchonok hvatit!" + ], + [ + 60.0, + "Everybody shake your body" + ] + ], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#FF7F00", + "#FFB600", + "#FFED00", + "#00D1FF", + "#6696FB", + "#704DF8", + "#FF7F00", + "#FFB600", + "#FFED00", + "#00D1FF", + "#6696FB", + "#704DF8", + "#FF7F00", + "#FFB600", + "#FFED00", + "#00D1FF", + "#6696FB", + "#704DF8", + "#FF7F00", + "#FFB600", + "#FFED00", + "#00D1FF", + "#6696FB", + "#704DF8", + "#FF7F00", + "#FFB600", + "#FFED00", + "#00D1FF", + "#6696FB", + "#704DF8", + "#FF7F00", + "#FFB600", + "#FFED00", + "#FFED00", + "#00D1FF", + "#00D1FF", + "#6696FB", + "#6696FB", + "#704DF8", + "#704DF8", + "#FF7F00", + "#FF7F00", + "#FFB600", + "#FFB600", + "#FFED00", + "#FFED00", + "#00D1FF", + "#00D1FF", + "#6696FB", + "#6696FB", + "#704DF8", + "#704DF8", + "#FF7F00", + "#FF7F00", + "#FFB600", + "#FFB600", + "#FFED00", + "#FFED00", + "#00D1FF", + "#00D1FF", + "#6696FB", + "#6696FB", + "#704DF8", + "#704DF8" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "Whistle", + "Artist": "Flo Rida", + "Song": "Whistle", + "IsExplicit": false, + "Season": null, + "Language": "English", + "WindUpTimer": 41.27, + "Bpm": 104.016182, + "Beats": 48, + "LoopOffset": 16, + "Ext": "ogg", + "FileDurationIntro": 52.433, + "FileDurationLoop": 27.688, + "FileNameIntro": "WhistleIntro.ogg", + "FileNameLoop": "WhistleLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -22.0, + "FadeOutDuration": 6.0, + "ColorTransitionIn": 0.5, + "ColorTransitionOut": 0.2, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -20.0, + 12.0 + ], + "Lyrics": [ + [ + -40.0, + "Can you blow my whistle, baby, whistle, baby?" + ], + [ + -36.0, + "Can you blow my whistle, baby, whistle, baby? Let me know" + ], + [ + -33.5, + "Girl, I'm gonna show you how to\ndo it" + ], + [ + -30.5, + "Girl, I'm gonna show you how to\ndo it and we start real slow" + ], + [ + -27.0, + "You just put your lips together" + ], + [ + -24.0, + "You just put your lips together and you come real close" + ], + [ + -21.0, + "Can you blow my whistle, baby, whistle, baby?" + ], + [ + -17.0, + "HERE WE GO" + ], + [ + 10.0, + "Yeah, baby, make that whistle" + ], + [ + 12.0, + "Yeah, baby, make that whistle\nblow oh oh oh" + ], + [ + 15.0, + "Can you blow my whistle, baby, whistle, baby?" + ], + [ + 20.0, + "Can you blow my whistle, baby, whistle, baby? Let me know" + ], + [ + 23.0, + "Girl, I'm gonna show you how to\ndo it" + ], + [ + 28.0, + "Girl, I'm gonna show you how to\ndo it and we start real slow" + ], + [ + 32.0, + "You just put your lips together" + ], + [ + 36.0, + "You just put your lips together and you come real close" + ], + [ + 39.0, + "Can you blow my whistle, baby, whistle, baby?" + ], + [ + 46.0, + "HERE" + ], + [ + 47.0, + "Here WE" + ], + [ + 48.0, + "Here we GO" + ] + ], + "DrunknessLoopOffsetTimeSeries": [ + [ + -16.0, + 0.0 + ], + [ + -15.25, + 0.7 + ], + [ + -12.0, + 0.0 + ], + [ + 9.0, + 0.0 + ], + [ + 15.0, + 0.4 + ], + [ + 16.0, + 0.7 + ], + [ + 18.0, + 0.4 + ], + [ + 21.0, + 0.0 + ] + ], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#8DDEDD", + "#98DE28", + "#E8DB4B", + "#F060A8", + "#EEC263", + "#725DEB" + ], + "GameOverText": null + }, + { + "Enabled": false, + "Name": "Yalgaar", + "Artist": "Ajey Nagar and Wily Frenzy", + "Song": "Yalgaar", + "IsExplicit": false, + "Season": null, + "Language": "Hindi", + "WindUpTimer": 52.17, + "Bpm": 92.0157242, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 53.466, + "FileDurationLoop": 20.866, + "FileNameIntro": "YalgaarIntro.ogg", + "FileNameLoop": "YalgaarLoop.ogg", + "BeatsOffset": 0.0, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.1, + "ColorTransitionOut": 0.35, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -5.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#C0402D", + "#906F0B", + "#DC8044", + "#70190A", + "#929FAF", + "#4248A2", + "#AE2727", + "#2D2D42" + ], + "GameOverText": null + }, + { + "Enabled": true, + "Name": "ZmeiGorynich", + "Artist": "aespa", + "Song": "Black Mamba", + "IsExplicit": false, + "Season": null, + "Language": "Korean", + "WindUpTimer": 46.13, + "Bpm": 90.0014, + "Beats": 32, + "LoopOffset": 0, + "Ext": "ogg", + "FileDurationIntro": 48.8, + "FileDurationLoop": 21.333, + "FileNameIntro": "ZmeiGorynichIntro.ogg", + "FileNameLoop": "ZmeiGorynichLoop.ogg", + "BeatsOffset": 0.1, + "FadeOutBeat": -4.0, + "FadeOutDuration": 4.0, + "ColorTransitionIn": 0.4, + "ColorTransitionOut": 0.4, + "ColorTransitionEasing": "OutExpo", + "FlickerLightsTimeSeries": [ + -5.0, + 31.0 + ], + "Lyrics": [], + "DrunknessLoopOffsetTimeSeries": [], + "CondensationLoopOffsetTimeSeries": [], + "Palette": [ + "#4C8AC5", + "#AF326A", + "#0B1666", + "#AFD2FC", + "#C55297", + "#540070" + ], + "GameOverText": "[MUZIKA: K-POP GROMCHE]" + } + ] +} \ No newline at end of file diff --git a/Frontend/src/assets/fonts/3270-Regular.woff b/Frontend/src/assets/fonts/3270-Regular.woff new file mode 100644 index 0000000..d74887d Binary files /dev/null and b/Frontend/src/assets/fonts/3270-Regular.woff differ diff --git a/Frontend/src/assets/playhead-main.png b/Frontend/src/assets/playhead-main.png new file mode 100644 index 0000000..1e43c43 Binary files /dev/null and b/Frontend/src/assets/playhead-main.png differ diff --git a/Frontend/src/assets/playhead-top.png b/Frontend/src/assets/playhead-top.png new file mode 100644 index 0000000..15c38dd Binary files /dev/null and b/Frontend/src/assets/playhead-top.png differ diff --git a/Frontend/src/audio/AudioEngine.ts b/Frontend/src/audio/AudioEngine.ts new file mode 100644 index 0000000..0d274c6 --- /dev/null +++ b/Frontend/src/audio/AudioEngine.ts @@ -0,0 +1,554 @@ +/* + AudioEngine.ts + A small singleton wrapper around the WebAudio AudioContext that: + - lazily creates the AudioContext + - provides fetch/decode + simple caching + - schedules intro and loop buffers to play seamlessly + - exposes play/pause/stop and a volume control via a master GainNode + - provides a short fade-in/out GainNode to avoid clicks (few ms) + - exposes getPosition() to read current playback time relative to intro start +*/ + +import type { ConfigurableWindow } from '@vueuse/core' +import type { MaybeRefOrGetter, Ref } from 'vue' +import type { AudioTrack } from '@/lib/AudioTrack' +import type { Seconds } from '@/lib/units' +import { + + tryOnScopeDispose, + useRafFn, + useThrottleFn, + watchImmediate, +} from '@vueuse/core' +import { + + shallowRef, + toValue, + watch, +} from 'vue' +import { useWrapTime, wrapTimeFn } from '@/lib/AudioTrack' + +export const VOLUME_MAX: number = 1.5 + +interface PlayerHandle { + /** + * The `stop()` method schedules a sound to cease playback at the specified time. + */ + stop: (when?: Seconds) => void +} + +interface AudioTrackBuffersHandle extends PlayerHandle { + /** + * Time in AudioContext coordinate system of a moment which lines up with the start of the intro audio buffer. + * If the startPosition was greater than zero, this time is already in the past when the function returns. + */ + readonly introStartTime: Seconds +} + +/** + * Start playing intro + loop buffers at given position. + * + * @returns Handle with introStartTime and stop() method. + */ +function playAudioTrackBuffers( + audioCtx: AudioContext, + destinationNode: AudioNode, + audioTrack: AudioTrack, + /** + * Position in seconds from the start of the intro + */ + startPosition: Seconds = 0, +): AudioTrackBuffersHandle { + const now = audioCtx.currentTime + + const introBuffer = audioTrack.loadedIntro! + const loopBuffer = audioTrack.loadedLoop! + + const introDuration = introBuffer.duration + const loopDuration = loopBuffer.duration + + const wrapper = wrapTimeFn(audioTrack) + startPosition = wrapper(startPosition) + + let currentIntro: AudioBufferSourceNode | null + let currentLoop: AudioBufferSourceNode | null + let introStartTime: Seconds + + // figure out where to start + if (startPosition < introDuration) { + // start intro with offset, schedule loop after remaining intro time + const introOffset = startPosition + const timeUntilLoop = introDuration - introOffset + + const introNode = audioCtx.createBufferSource() + introNode.buffer = introBuffer + introNode.connect(destinationNode) + introNode.start(now, introOffset) + + const loopNode = audioCtx.createBufferSource() + loopNode.buffer = loopBuffer + loopNode.loop = true + loopNode.connect(destinationNode) + loopNode.start(now + timeUntilLoop, 0) + + currentIntro = introNode + currentLoop = loopNode + introStartTime = now - startPosition + } + else { + // start directly in loop with proper offset into loop + const loopOffset = (startPosition - introDuration) % loopDuration + const loopNode = audioCtx.createBufferSource() + loopNode.buffer = loopBuffer + loopNode.loop = true + loopNode.connect(destinationNode) + loopNode.start(now, loopOffset) + + currentIntro = null + currentLoop = loopNode + // Note: using wrapping loop breaks logical position when starting playback from the second loop repetition onward. + // introStartTime = now - introDuration - loopOffset; + introStartTime = now - startPosition + } + + function stop(when?: Seconds) { + try { + currentIntro?.stop(when) + } + catch { + /* ignore */ + } + try { + currentLoop?.stop(when) + } + catch { + /* ignore */ + } + currentIntro = null + currentLoop = null + } + + return { introStartTime, stop } +} + +interface PlayWithFadeInOut extends PlayerHandle { + playerResult: Omit +} + +/** + * 25 ms for fade-in/fade-out + */ +const DEFAULT_FADE_DURATION = 0.025 + +/** + * Wrap the given player function with a Gain node. Applies fade in effect on start and fade out on stop. + * + * @returns Handle with introStartTime and stop() method. + */ +function playWithFadeInOut( + audioCtx: AudioContext, + destinationNode: AudioNode, + player: (destinationNode: AudioNode) => T, + /** + * Duration of fade in/out in seconds. Fade out extends past the stop() call. + */ + fadeDuration: Seconds = DEFAULT_FADE_DURATION, +): PlayWithFadeInOut { + const GAIN_MIN = 0.0001 + const GAIN_MAX = 1.0 + + const fadeGain = audioCtx.createGain() + fadeGain.connect(destinationNode) + fadeGain.gain.value = GAIN_MIN + + const playerHandle = player(fadeGain) + + // fade in + const now = audioCtx.currentTime + const fadeEnd = now + fadeDuration + fadeGain.gain.setValueAtTime(GAIN_MIN, now) + fadeGain.gain.linearRampToValueAtTime(GAIN_MAX, fadeEnd) + + // TODO: setTimeout to actually stop after `when`? + function stop(_when?: Seconds) { + // fade out + const now = audioCtx.currentTime + const fadeEnd = now + fadeDuration + fadeGain.gain.cancelScheduledValues(now) + fadeGain.gain.setValueAtTime(GAIN_MAX, now) + fadeGain.gain.linearRampToValueAtTime(GAIN_MIN, fadeEnd) + + playerHandle.stop(fadeEnd) + } + + return { playerResult: playerHandle, stop } +} + +/** + * Properties relates to the state of playback. + */ +export interface PlaybackState { + /** + * Readonly reference to whether audio is currently playing. + */ + readonly isPlaying: Readonly> + /** + * Readonly reference to the last remembered start-of-playback position. + * + * Will only update if stop(rememberPosition=true) or seek() is called. + */ + readonly startPosition: Readonly> + /** + * Returns current playback position in seconds based on AudioContext time. + * + * Hook it up to requestAnimationFrame while isPlaying is true for live updates. + */ + getCurrentPosition: () => Seconds +} + +export interface StopOptions { + /** + * If true, update remembered playback position to current position, otherwise revert to last remembered one. + * + * Defaults to false. + */ + rememberPosition?: boolean +} + +export interface SeekOptions { + /** + * If scrub is requested, plays a short sample at that position. + * + * Defaults to false. + */ + scrub?: boolean + // TODO: optionally keep playing after seeking? +} + +/** + * Player controls and properties relates to the state of playback. + */ +export interface PlayerControls { + /** + * Start playing audio buffers from the last remembered position. + */ + play: () => void + /** + * Stop playing audio buffers. + * + * If rememberPosition is true, update remembered playback position, otherwise revert to the last remembered one. + */ + stop: (options?: StopOptions) => void + /** + * Seek to given position in seconds. + * + * - Stop the playback. + * - If scrub is requested, plays a short sample at that position. + */ + seek: (position: Seconds, options?: SeekOptions) => void + /** + * Properties relates to the state of playback. + */ + readonly playback: PlaybackState +} + +interface ReusableAudioBuffersTrackPlayer extends PlayerControls { +} + +function reusableAudioBuffersTrackPlayer( + audioCtx: AudioContext, + destinationNode: AudioNode, + audioTrack: AudioTrack, +): ReusableAudioBuffersTrackPlayer { + let currentHandle: PlayWithFadeInOut | null = null + const isPlaying = shallowRef(false) + const wrapper = wrapTimeFn(audioTrack) + const startPosition = useWrapTime(audioTrack, 0) + + function play() { + if (currentHandle) { + return + } + currentHandle = playWithFadeInOut( + audioCtx, + destinationNode, + destinationNode => + playAudioTrackBuffers( + audioCtx, + destinationNode, + audioTrack, + startPosition.value, + ), + ) + isPlaying.value = true + } + + function stop(options?: { rememberPosition?: boolean }) { + const { + rememberPosition = false, + } = options ?? {} + + if (currentHandle) { + isPlaying.value = false + + if (rememberPosition) { + startPosition.value = getCurrentPosition() + } + + // stop and discard current handle + currentHandle.stop() + currentHandle = null + } + } + + // Scrub is subject to debouncing/throttling, so it doesn't start + // playing samples too often before previous ones could stop. + const doThrottledScrub = useThrottleFn(() => { + // play a short sample at the seeked position + const scrubHandle = playWithFadeInOut( + audioCtx, + destinationNode, + destinationNode => + playAudioTrackBuffers( + audioCtx, + destinationNode, + audioTrack, + startPosition.value, + ), + 0.01, // short fade of 10 ms + ) + setTimeout(() => { + scrubHandle.stop(0.01) + }, 80) // stop after N ms + }, 80) + + function seek(seekPosition: Seconds, options?: SeekOptions) { + const { + scrub = false, + } = options ?? {} + + stop({ rememberPosition: false }) + + startPosition.value = seekPosition + + if (scrub) { + doThrottledScrub() + } + } + + function getCurrentPosition(): Seconds { + if (!currentHandle) { + return startPosition.value + } + + const elapsed = audioCtx.currentTime + - currentHandle.playerResult.introStartTime + + return wrapper(elapsed) + } + + return { + play, + stop, + seek, + playback: { + isPlaying, + startPosition, + getCurrentPosition, + }, + } +} + +interface LivePlaybackPositionOptions extends ConfigurableWindow { +} + +interface LivePlaybackPositionReturn { + stop: () => void + position: Readonly> +} + +export function useLivePlaybackPosition( + playback: MaybeRefOrGetter, + options?: LivePlaybackPositionOptions, +): LivePlaybackPositionReturn { + const cleanups: (() => void)[] = [] + const cleanup = () => { + cleanups.forEach(fn => fn()) + cleanups.length = 0 + } + + const getPosition = () => { + return toValue(playback)?.getCurrentPosition() ?? 0 + } + + const position = shallowRef(getPosition()) + + const updatePosition = () => { + position.value = getPosition() + } + + const raf = useRafFn(() => { + updatePosition() + }, { + ...options, + immediate: false, + once: false, + }) + + const stopWatch = watchImmediate(() => [ + toValue(playback), + ], ([playback]) => { + cleanup() + + updatePosition() + + if (!playback) { + return + } + + cleanups.push(watch(playback.isPlaying, (isPlaying) => { + if (isPlaying) { + raf.resume() + } + else { + raf.pause() + updatePosition() + } + })) + + cleanups.push(watch(playback.startPosition, () => { + raf.pause() + updatePosition() + if (playback.isPlaying.value) { + raf.resume() + } + })) + + cleanups.push(() => raf.pause()) + }) + + const stop = () => { + stopWatch() + cleanup() + } + + tryOnScopeDispose(cleanup) + + return { stop, position } +} + +export function togglePlayStop( + player: PlayerControls | null, + options?: StopOptions, +) { + if (!player) { + return + } + if (player.playback.isPlaying.value) { + player.stop(options) + } + else { + player.play() + } +} + +class AudioEngine { + audioCtx: AudioContext | null = null + masterGain: GainNode | null = null // controlled by UI volume slider + // fadeGain: GainNode | null = null; // tiny fade to avoid clicks + + // cache of decoded buffers by URL + bufferCache = new Map() + + private _player: Ref = shallowRef(null) + // readonly player: Readonly> = this._player; + + // settings + fadeDuration = 0.025 // 25 ms for fade-in/fade-out + + init() { + if (this.audioCtx) { + return + } + this.audioCtx + = new (window.AudioContext || (window as any).webkitAudioContext)() + + this.masterGain = this.audioCtx.createGain() + + // routing: sources -> fadeGain -> masterGain -> destination + this.masterGain.connect(this.audioCtx.destination) + // default full volume + this.masterGain.gain.value = 1 + } + + shutdown() { + this.stopPlayer() + this.audioCtx?.close() + this.audioCtx = null + this.masterGain = null + } + + async fetchAudioBuffer( + url: string, + signal?: AbortSignal, + ): Promise { + this.init() + if (this.bufferCache.has(url)) { + return this.bufferCache.get(url)! + } + const res = await fetch(url, { signal }) + if (!res.ok) { + throw new Error(`Network error ${res.status} when fetching ${url}`) + } + const arrayBuffer = await res.arrayBuffer() + const audioBuffer = await this.audioCtx!.decodeAudioData(arrayBuffer) + this.bufferCache.set(url, audioBuffer) + return audioBuffer + } + + // set UI volume 0..VOLUME_MAX + setVolume(value: number) { + this.init() + if (!this.masterGain || !this.audioCtx) { + return + } + const now = this.audioCtx.currentTime + // small linear ramp to avoid jumps + this.masterGain.gain.cancelScheduledValues(now) + this.masterGain.gain.setValueAtTime(this.masterGain.gain.value, now) + this.masterGain.gain.linearRampToValueAtTime(value, now + 0.05) + } + + initPlayer( + audioTrack: AudioTrack, + ): PlayerControls | null { + this.init() + if (!this.audioCtx || !this.masterGain) { + return null + } + + this.stopPlayer() + + if (!audioTrack.loadedIntro || !audioTrack.loadedLoop) { + return null + } + + const player = reusableAudioBuffersTrackPlayer( + this.audioCtx, + this.masterGain, + audioTrack, + ) + this._player.value = player + return player + } + + private stopPlayer() { + if (this._player.value) { + this._player.value.stop() + this._player.value = null + } + } +} + +const audioEngine = new AudioEngine() +export default audioEngine diff --git a/Frontend/src/audio/AudioWaveform.ts b/Frontend/src/audio/AudioWaveform.ts new file mode 100644 index 0000000..7bf5164 --- /dev/null +++ b/Frontend/src/audio/AudioWaveform.ts @@ -0,0 +1,190 @@ +import type { Fn } from '@vueuse/core' +import type { MaybeRefOrGetter, Ref } from 'vue' +import type { Px } from '@/lib/units' +import { tryOnScopeDispose, watchImmediate } from '@vueuse/core' +import { computed, shallowRef, toValue, triggerRef } from 'vue' +import { useWeakCache } from '@/lib/useWeakCache' + +// Result of async computation +interface UseWaveform { + readonly isDone: Readonly> + readonly peaks: Readonly> + stop: () => void +} + +interface WaveformComputation { + readonly isDone: Readonly> + readonly peaks: Readonly> + /** Start or continue asynchronous computation. */ + run: () => void + /** Stops any ongoing asynchronous computation. */ + stop: () => void +} + +const waveformsCache = useWeakCache>( + () => new Map(), +) + +const WAVEFORM_MIN_WIDTH = 10 + +const emptyComputation: WaveformComputation = { + isDone: shallowRef(false), + peaks: shallowRef(new Float32Array(0)), + run() {}, + stop() {}, +} + +export function useWaveform( + buffer: MaybeRefOrGetter, + width: MaybeRefOrGetter, +): UseWaveform { + const cleanups: Fn[] = [] + const cleanup = () => { + cleanups.forEach(fn => fn()) + cleanups.length = 0 + } + + const compRef: Ref = shallowRef(emptyComputation) + + const stopWatch = watchImmediate( + () => + [ + toValue(buffer), + toValue(width), + ] as const, + ([b, w]) => { + cleanup() + + const map = waveformsCache.getOrNew(b) + + if (w < WAVEFORM_MIN_WIDTH) { + compRef.value = emptyComputation + return + } + + let comp = map.get(w) + if (!comp) { + comp = useWaveformComputation(b, w) + map.set(w, comp) + } + compRef.value = comp + comp.run() + cleanups.push(() => { + compRef.value = emptyComputation + comp.stop() + }) + }, + ) + + const stop = () => { + stopWatch() + cleanup() + } + + tryOnScopeDispose(stop) + + return { + isDone: computed(() => compRef.value.isDone.value), + peaks: computed(() => compRef.value.peaks.value), + stop, + } +} + +function useWaveformComputation(buffer: AudioBuffer, width: Px): WaveformComputation { + // How many times run() has been called without stop(). + // This whole computation should not stop until there is at least one user out there. + let users = 0 + + // How many pixels of `width` have been processed so far + let progress = 0 + + let timeoutID: ReturnType | undefined + + // Waveform data, length shall be equal to the requested width + const waveform = new Float32Array(width) + + const isDone = shallowRef(false) + const peaks = shallowRef(waveform) + + const nChannels = buffer.numberOfChannels + + const samplesPerPx = buffer.length / width + const blocksPerChannel: Float32Array[] = [] + for (let channel = 0; channel < nChannels; channel++) { + blocksPerChannel[channel] = new Float32Array(Math.ceil(samplesPerPx)) + } + + const areWeDoneYet = () => progress >= width + + function stepBlock() { + const blockStart = Math.floor(progress * samplesPerPx) + const blockEnd = Math.floor((progress + 1) * samplesPerPx) + const blockSize = blockEnd - blockStart + + for (let channel = 0; channel < nChannels; channel++) { + buffer.copyFromChannel(blocksPerChannel[channel]!, channel, blockStart) + } + + waveform[progress] = compressBlock(blocksPerChannel, blockSize) + progress += 1 + } + + function stepBatchOfBlocks() { + // run blocks for up to ~10ms to keep UI responsive + const start = performance.now() + const progressStart = progress + while (!areWeDoneYet()) { + stepBlock() + if (performance.now() - start >= 10 || progress - progressStart > 100) { + break + } + } + + triggerRef(peaks) + // triggerRef may as well not trigger refs + // https://github.com/vuejs/core/issues/9579 + // Combined with a throttled drawing function, + // this is a slightly better-than-worse workaround. + peaks.value = new Float32Array(0) + peaks.value = waveform + + if (areWeDoneYet()) { + isDone.value = true + timeoutID = undefined + } + else { + timeoutID = setTimeout(stepBatchOfBlocks, 1) + } + } + + return { + isDone, + peaks, + run() { + users += 1 + + if (timeoutID === undefined && users === 1) { + timeoutID = setTimeout(stepBatchOfBlocks, 0) + } + }, + stop() { + users -= 1 + + if (!timeoutID === undefined && users === 0) { + window.clearTimeout(timeoutID) + timeoutID = undefined + } + }, + } +}; + +function compressBlock(channels: Float32Array[], blockSize: number): number { + let peak = 0.0 + + for (let i = 0; i < blockSize; i++) { + for (let channel = 0; channel < channels.length; channel++) { + peak = Math.max(peak, Math.abs(channels[channel]![i]!)) + } + } + return peak +} diff --git a/Frontend/src/components/ErrorScreen.vue b/Frontend/src/components/ErrorScreen.vue new file mode 100644 index 0000000..460cc57 --- /dev/null +++ b/Frontend/src/components/ErrorScreen.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/Frontend/src/components/Footer.vue b/Frontend/src/components/Footer.vue new file mode 100644 index 0000000..406601b --- /dev/null +++ b/Frontend/src/components/Footer.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/Frontend/src/components/LoadingScreen.vue b/Frontend/src/components/LoadingScreen.vue new file mode 100644 index 0000000..5ef03fb --- /dev/null +++ b/Frontend/src/components/LoadingScreen.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/Frontend/src/components/ScreenTransition.vue b/Frontend/src/components/ScreenTransition.vue new file mode 100644 index 0000000..21251cf --- /dev/null +++ b/Frontend/src/components/ScreenTransition.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/Frontend/src/components/SearchField.vue b/Frontend/src/components/SearchField.vue new file mode 100644 index 0000000..c8e74ad --- /dev/null +++ b/Frontend/src/components/SearchField.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/Frontend/src/components/editor/PreviewScnene.vue b/Frontend/src/components/editor/PreviewScnene.vue new file mode 100644 index 0000000..f20eb77 --- /dev/null +++ b/Frontend/src/components/editor/PreviewScnene.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/Frontend/src/components/editor/TrackInfo.vue b/Frontend/src/components/editor/TrackInfo.vue new file mode 100644 index 0000000..108d8b1 --- /dev/null +++ b/Frontend/src/components/editor/TrackInfo.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/Frontend/src/components/inspector/InspectorPanel.vue b/Frontend/src/components/inspector/InspectorPanel.vue new file mode 100644 index 0000000..6f7ed65 --- /dev/null +++ b/Frontend/src/components/inspector/InspectorPanel.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/Control.vue b/Frontend/src/components/inspector/controls/Control.vue new file mode 100644 index 0000000..f0a36da --- /dev/null +++ b/Frontend/src/components/inspector/controls/Control.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/ControlsView.vue b/Frontend/src/components/inspector/controls/ControlsView.vue new file mode 100644 index 0000000..c885507 --- /dev/null +++ b/Frontend/src/components/inspector/controls/ControlsView.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/BaseNamedControlView.vue b/Frontend/src/components/inspector/controls/impl/BaseNamedControlView.vue new file mode 100644 index 0000000..b6a2f07 --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/BaseNamedControlView.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/ButtonControlView.vue b/Frontend/src/components/inspector/controls/impl/ButtonControlView.vue new file mode 100644 index 0000000..823b508 --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/ButtonControlView.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/CheckboxControlView.vue b/Frontend/src/components/inspector/controls/impl/CheckboxControlView.vue new file mode 100644 index 0000000..9f3482a --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/CheckboxControlView.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/DropDownControlView.vue b/Frontend/src/components/inspector/controls/impl/DropDownControlView.vue new file mode 100644 index 0000000..23eb6cc --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/DropDownControlView.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/HrControlView.vue b/Frontend/src/components/inspector/controls/impl/HrControlView.vue new file mode 100644 index 0000000..75baf9e --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/HrControlView.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/NotImplementedControlView.vue b/Frontend/src/components/inspector/controls/impl/NotImplementedControlView.vue new file mode 100644 index 0000000..5bf2206 --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/NotImplementedControlView.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/NumberControlView.vue b/Frontend/src/components/inspector/controls/impl/NumberControlView.vue new file mode 100644 index 0000000..74f02d1 --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/NumberControlView.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/RangeControlView.vue b/Frontend/src/components/inspector/controls/impl/RangeControlView.vue new file mode 100644 index 0000000..f1367ab --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/RangeControlView.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/Frontend/src/components/inspector/controls/impl/TextAreaControlView.vue b/Frontend/src/components/inspector/controls/impl/TextAreaControlView.vue new file mode 100644 index 0000000..7f5ebae --- /dev/null +++ b/Frontend/src/components/inspector/controls/impl/TextAreaControlView.vue @@ -0,0 +1,28 @@ + + +