diff --git a/package-lock.json b/package-lock.json index bec42ae..21b50d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "osu", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -804,7 +804,6 @@ "version": "6.12.5", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -930,6 +929,11 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, + "atomically": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.3.2.tgz", + "integrity": "sha512-MAiqx5ir1nOoMeG2vLXJnj4oFROJYB1hMqa2aAo6GQVIkPdkIcrq9W9SR0OaRtvEowO7Y2bsXqKFuDMTO4iOAQ==" + }, "author-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", @@ -1509,6 +1513,23 @@ } } }, + "conf": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/conf/-/conf-7.1.2.tgz", + "integrity": "sha512-r8/HEoWPFn4CztjhMJaWNAe5n+gPUCSaJ0oufbqDLFKsA1V8JjAG7G+p0pgoDFAws9Bpk2VtVLLXqOBA7WxLeg==", + "requires": { + "ajv": "^6.12.2", + "atomically": "^1.3.1", + "debounce-fn": "^4.0.0", + "dot-prop": "^5.2.0", + "env-paths": "^2.2.0", + "json-schema-typed": "^7.0.3", + "make-dir": "^3.1.0", + "onetime": "^5.1.0", + "pkg-up": "^3.1.0", + "semver": "^7.3.2" + } + }, "config-chain": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", @@ -1605,6 +1626,21 @@ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==" }, + "debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "requires": { + "mimic-fn": "^3.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1695,6 +1731,30 @@ "dev": true, "optional": true }, + "discord-rpc": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.1.4.tgz", + "integrity": "sha512-QaBu+gHica2SzgRAmTpuJ4J8DX9+fDwAqhvaie3hcbkU9WPqewEPh21pWdd/7vTI/JNuapU7PFm2ZKg3BTkbGg==", + "requires": { + "node-fetch": "^2.6.1", + "ws": "^7.3.1" + }, + "dependencies": { + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" + } + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + } + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -2038,6 +2098,22 @@ "debug": "^2.2.0" } }, + "electron-store": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-6.0.0.tgz", + "integrity": "sha512-ujb0a/6gxMxb9vOQ2BjOehK9VCyq5OKvttekd9v/tohA9oBHnAdV+Vxu4eoRh+/F9ShPFhcvDZkMdqO5i+TXUw==", + "requires": { + "conf": "^7.1.1", + "type-fest": "^0.16.0" + }, + "dependencies": { + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" + } + } + }, "electron-winstaller": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-4.0.1.tgz", @@ -2159,8 +2235,7 @@ "env-paths": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", - "dev": true + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==" }, "error-ex": { "version": "1.3.2", @@ -2335,14 +2410,12 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fd-slicer": { "version": "1.1.0", @@ -3041,6 +3114,11 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -3164,8 +3242,12 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" }, "json-stringify-safe": { "version": "5.0.1", @@ -3341,6 +3423,21 @@ "sourcemap-codec": "^1.4.4" } }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -3505,8 +3602,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mimic-response": { "version": "1.0.1", @@ -3596,8 +3692,7 @@ "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-gyp": { "version": "7.1.0", @@ -3749,7 +3844,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -4040,6 +4134,54 @@ } } }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + } + } + }, "plist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", @@ -4124,8 +4266,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { "version": "6.5.2", @@ -4445,8 +4586,7 @@ "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" }, "semver-compare": { "version": "1.0.0", @@ -5042,7 +5182,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", - "dev": true, "requires": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index a39c9d1..9601755 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "osu", "productName": "osu", - "version": "0.1.0", + "version": "0.2.0", "description": "Osu! visualizer", "main": "src/index.js", "scripts": { @@ -48,9 +48,11 @@ }, "dependencies": { "concurrently": "^5.3.0", + "discord-rpc": "^3.1.4", "electron-is-dev": "^1.2.0", "electron-reload": "^1.5.0", "electron-squirrel-startup": "^1.0.0", + "electron-store": "^6.0.0", "osu-db-parser": "^1.0.35", "osu-parser": "^0.3.3", "sirv-cli": "^1.0.0", diff --git a/public/build/bundle.css b/public/build/bundle.css index 3587ebe..a897e30 100644 --- a/public/build/bundle.css +++ b/public/build/bundle.css @@ -1,5 +1,6 @@ main.svelte-5atqf{position:relative;width:100vw;height:100vh}.background.svelte-5atqf{position:fixed;z-index:0;left:0;right:0;width:100vw;height:100vh}.menu.svelte-5atqf{position:absolute;z-index:1;left:0;right:0;width:100vw;height:100vh} -.info.svelte-1j9fr45.svelte-1j9fr45{opacity:1;position:relative;top:0;left:0;width:100vw;height:80px;transition:opacity 0.6s;z-index:1}.volume.svelte-1j9fr45.svelte-1j9fr45{opacity:1;position:fixed;z-index:2;right:0;bottom:0;border-radius:50%;color:black;font-size:30px}.hidden.svelte-1j9fr45.svelte-1j9fr45{opacity:0;transition:opacity 1s}.info.svelte-1j9fr45 .song.svelte-1j9fr45{color:white;position:absolute;padding:5px 5px 5px 25px;top:0;right:0;text-align:right;background:black;background:linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 15%, rgba(0,0,0,0.5) 100%)}.info.svelte-1j9fr45 .song h2.svelte-1j9fr45{margin:0}.info.svelte-1j9fr45 .controls.svelte-1j9fr45{height:50px;display:flex}.info.svelte-1j9fr45 .controls div.svelte-1j9fr45{height:100%}.info.svelte-1j9fr45 .controls img.svelte-1j9fr45{height:100%;filter:invert(100%)} -.main.svelte-yh70k3.svelte-yh70k3{width:100%;height:100%;background-size:cover;background-repeat:no-repeat}@keyframes svelte-yh70k3-bpm{from{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}to{width:525px;height:525px;top:calc(50vh - 262.5px);left:calc(50vw - 262.5px)}}@keyframes svelte-yh70k3-bpmShadow{0%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}70%{width:510px;height:510px;top:calc(50vh - 255px);left:calc(50vw - 255px)}100%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}}.main.svelte-yh70k3 img.svelte-yh70k3{position:fixed;width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}.main.svelte-yh70k3 .logo.svelte-yh70k3{animation-name:svelte-yh70k3-bpm;animation-iteration-count:infinite;animation-direction:alternate}.main.svelte-yh70k3 .shadow.svelte-yh70k3{opacity:0.2;animation-name:svelte-yh70k3-bpmShadow;animation-iteration-count:infinite;animation-delay:50ms} +.info.svelte-1qt5obi.svelte-1qt5obi{opacity:1;position:relative;top:0;left:0;width:100vw;height:80px;transition:opacity 0.6s;z-index:2}.volume.svelte-1qt5obi.svelte-1qt5obi{opacity:1;position:fixed;z-index:5;right:0;bottom:0;border-radius:50%;font-size:30px;color:white;background-color:black;width:100px;height:100px}.volume.svelte-1qt5obi .slider.svelte-1qt5obi{position:relative;top:0;left:0;width:100%;height:100%}.percent.svelte-1qt5obi.svelte-1qt5obi{position:absolute;top:25px;left:0;width:100%;height:100%;text-align:center}.progress-ring.svelte-1qt5obi.svelte-1qt5obi{position:absolute;top:0;left:0;width:100%;height:100%}.progress-ring.svelte-1qt5obi circle.svelte-1qt5obi{transition:stroke-dashoffset 0.32s;transform:rotate(-90deg);transform-origin:50% 50%;position:absolute;top:1px;left:1px;width:100%;height:100%}.hidden.svelte-1qt5obi.svelte-1qt5obi{opacity:0;transition:opacity 1s}.info.svelte-1qt5obi .song.svelte-1qt5obi{color:white;position:absolute;padding:5px 5px 5px 25px;top:0;right:0;text-align:right;background:black;background:linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 15%, rgba(0,0,0,0.5) 100%)}.info.svelte-1qt5obi .song h2.svelte-1qt5obi{margin:0}.info.svelte-1qt5obi .controls.svelte-1qt5obi{height:50px;display:flex}.info.svelte-1qt5obi .controls div.svelte-1qt5obi{height:100%}.info.svelte-1qt5obi .controls img.svelte-1qt5obi{height:100%;filter:invert(100%)}.info.svelte-1qt5obi .controls .settings img.svelte-1qt5obi{height:65%;padding-top:25%} +.main.svelte-18bmol8.svelte-18bmol8{width:100%;height:100%;background-size:cover;background-repeat:no-repeat}@keyframes svelte-18bmol8-bpm{from{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}to{width:525px;height:525px;top:calc(50vh - 262.5px);left:calc(50vw - 262.5px)}}@keyframes svelte-18bmol8-bpmShadow{0%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}70%{width:510px;height:510px;top:calc(50vh - 255px);left:calc(50vw - 255px)}100%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}}video.svelte-18bmol8.svelte-18bmol8{position:fixed;z-index:0;top:0;left:0;width:100vw;height:100vh}.main.svelte-18bmol8 img.svelte-18bmol8{position:fixed;width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px);z-index:1}.main.svelte-18bmol8 .logo.svelte-18bmol8{animation-name:svelte-18bmol8-bpm;animation-direction:alternate}.main.svelte-18bmol8 .shadow.svelte-18bmol8{opacity:0.2;animation-name:svelte-18bmol8-bpmShadow;animation-delay:50ms}.main.svelte-18bmol8 .repeat.svelte-18bmol8{animation-iteration-count:infinite} +.bg.svelte-1895ym0{position:fixed;display:none;width:100vw;height:100vh;top:0;left:0;z-index:3}.bg.visible.svelte-1895ym0{display:block}nav.svelte-1895ym0{position:fixed;height:100vh;width:400px;top:0;left:-400px;opacity:0;background:rgba(0,0,0,0.4);color:white;z-index:4;transition:opacity 0.3s, left 0.3s}nav.visible.svelte-1895ym0{left:0;opacity:1} /*# sourceMappingURL=bundle.css.map */ \ No newline at end of file diff --git a/public/build/bundle.css.map b/public/build/bundle.css.map index 0acd2de..bbca840 100644 --- a/public/build/bundle.css.map +++ b/public/build/bundle.css.map @@ -4,13 +4,15 @@ "sources": [ "App.svelte", "Menu.svelte", - "Visualizer.svelte" + "Visualizer.svelte", + "options.svelte" ], "sourcesContent": [ - "\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n", - "\r\n\r\n last = Date.now()} on:wheel={e => updateVolume(e)} />\r\n\r\n\r\n 2000}>\r\n {#if song}\r\n \r\n {song.artist} - {song.song}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n {#if now - lastVolumeUpdate < 4000 && song && song.audio}\r\n 2000}>\r\n \r\n \r\n {Math.round(song.audio.volume * 100)}%\r\n \r\n \r\n \r\n {/if}\r\n\r\n\r\n", - "\r\n\r\n\r\n\r\n\r\n \r\n \r\n\r\n\r\n" + "\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n", + "\r\n\r\n last = Date.now()} on:wheel={e => updateVolume(e)} />\r\n\r\n\r\n {#if now - last < config.autohide.info + 1000}\r\n config.autohide.info}>\r\n {#if song}\r\n \r\n {song.artist} - {song.song}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n settingsOpen = !settingsOpen}>\r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n {/if}\r\n {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio}\r\n config.autohide.volume}>\r\n \r\n \r\n {Math.round(song.audio.volume * 100)}%\r\n \r\n \r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n\r\n\r\n", + "\r\n\r\n\r\n\r\n\r\n {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground}\r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n \r\n\r\n\r\n", + "\r\n\r\n\r\n visible = false}>\r\n \r\n Options\r\n\r\n \r\n Parallax\r\n \r\n Enable parallax\r\n \r\n \r\n \r\n Parallax treshold\r\n \r\n \r\n \r\n \r\n Integrations\r\n \r\n Discord Rich Presence\r\n \r\n \r\n \r\n MediaSession (system-wide controls)\r\n \r\n \r\n \r\n \r\n Backgrounds\r\n \r\n Osu!wallpapers\r\n Beatmap wallpapers\r\n \r\n \r\n Video backgrounds\r\n \r\n \r\n \r\n \r\n UI\r\n \r\n Song info hide timeout\r\n \r\n \r\n \r\n Volume hide timeout\r\n \r\n \r\n \r\n \r\n\r\n \r\n" ], "names": [], - "mappings": "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" + "mappings": "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" } \ No newline at end of file diff --git a/public/build/bundle.js b/public/build/bundle.js index 96648c2..f86fd5a 100644 --- a/public/build/bundle.js +++ b/public/build/bundle.js @@ -40,6 +40,9 @@ var app = (function () { function element(name) { return document.createElement(name); } + function svg_element(name) { + return document.createElementNS('http://www.w3.org/2000/svg', name); + } function text(data) { return document.createTextNode(data); } @@ -56,12 +59,31 @@ var app = (function () { else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } + function to_number(value) { + return value === '' ? null : +value; + } function children(element) { return Array.from(element.childNodes); } + function set_input_value(input, value) { + input.value = value == null ? '' : value; + } function set_style(node, key, value, important) { node.style.setProperty(key, value, important ? 'important' : ''); } + function select_option(select, value) { + for (let i = 0; i < select.options.length; i += 1) { + const option = select.options[i]; + if (option.__value === value) { + option.selected = true; + return; + } + } + } + function select_value(select) { + const selected_option = select.querySelector(':checked') || select.options[0]; + return selected_option && selected_option.__value; + } function toggle_class(element, name, toggle) { element.classList[toggle ? 'add' : 'remove'](name); } @@ -80,19 +102,8 @@ var app = (function () { throw new Error(`Function called outside component initialization`); return current_component; } - function createEventDispatcher() { - const component = get_current_component(); - return (type, detail) => { - const callbacks = component.$$.callbacks[type]; - if (callbacks) { - // TODO are there situations where events could be dispatched - // in a server (non-DOM) environment? - const event = custom_event(type, detail); - callbacks.slice().forEach(fn => { - fn.call(component, event); - }); - } - }; + function onMount(fn) { + get_current_component().$$.on_mount.push(fn); } const dirty_components = []; @@ -387,258 +398,356 @@ var app = (function () { $inject_state() { } } - /* src\Menu.svelte generated by Svelte v3.25.1 */ + /* src\components\options.svelte generated by Svelte v3.25.1 */ const { console: console_1 } = globals; - const file = "src\\Menu.svelte"; - - // (99:8) {#if song} - function create_if_block_1(ctx) { - let div3; - let h2; - let t0_value = /*song*/ ctx[0].artist + ""; - let t0; - let t1; - let t2_value = /*song*/ ctx[0].song + ""; - let t2; - let t3; - let div2; - let div0; - let img0; - let img0_src_value; - let img0_alt_value; - let img0_title_value; - let t4; - let div1; - let img1; - let img1_src_value; - let mounted; - let dispose; - - const block = { - c: function create() { - div3 = element("div"); - h2 = element("h2"); - t0 = text(t0_value); - t1 = text(" - "); - t2 = text(t2_value); - t3 = space(); - div2 = element("div"); - div0 = element("div"); - img0 = element("img"); - t4 = space(); - div1 = element("div"); - img1 = element("img"); - attr_dev(h2, "class", "svelte-1j9fr45"); - add_location(h2, file, 100, 16, 3079); - if (img0.src !== (img0_src_value = "images/music_" + (/*playing*/ ctx[4] ? "pause" : "play") + ".svg")) attr_dev(img0, "src", img0_src_value); - attr_dev(img0, "alt", img0_alt_value = "" + ((/*playing*/ ctx[4] ? "Pause" : "Play") + " music")); - attr_dev(img0, "title", img0_title_value = "" + ((/*playing*/ ctx[4] ? "Pause" : "Play") + " music")); - attr_dev(img0, "class", "svelte-1j9fr45"); - add_location(img0, file, 103, 24, 3243); - attr_dev(div0, "class", "play svelte-1j9fr45"); - add_location(div0, file, 102, 20, 3177); - if (img1.src !== (img1_src_value = "images/music_forward.svg")) attr_dev(img1, "src", img1_src_value); - attr_dev(img1, "alt", "Skip the song"); - attr_dev(img1, "title", "Skip the song"); - attr_dev(img1, "class", "svelte-1j9fr45"); - add_location(img1, file, 106, 24, 3501); - attr_dev(div1, "class", "forward svelte-1j9fr45"); - add_location(div1, file, 105, 20, 3434); - attr_dev(div2, "class", "controls svelte-1j9fr45"); - add_location(div2, file, 101, 16, 3133); - attr_dev(div3, "class", "song svelte-1j9fr45"); - add_location(div3, file, 99, 12, 3043); - }, - m: function mount(target, anchor) { - insert_dev(target, div3, anchor); - append_dev(div3, h2); - append_dev(h2, t0); - append_dev(h2, t1); - append_dev(h2, t2); - append_dev(div3, t3); - append_dev(div3, div2); - append_dev(div2, div0); - append_dev(div0, img0); - append_dev(div2, t4); - append_dev(div2, div1); - append_dev(div1, img1); - - if (!mounted) { - dispose = [ - listen_dev(div0, "click", /*togglePlay*/ ctx[6], false, false, false), - listen_dev(div1, "click", /*playNext*/ ctx[5], false, false, false) - ]; - - mounted = true; - } - }, - p: function update(ctx, dirty) { - if (dirty & /*song*/ 1 && t0_value !== (t0_value = /*song*/ ctx[0].artist + "")) set_data_dev(t0, t0_value); - if (dirty & /*song*/ 1 && t2_value !== (t2_value = /*song*/ ctx[0].song + "")) set_data_dev(t2, t2_value); - - if (dirty & /*playing*/ 16 && img0.src !== (img0_src_value = "images/music_" + (/*playing*/ ctx[4] ? "pause" : "play") + ".svg")) { - attr_dev(img0, "src", img0_src_value); - } - - if (dirty & /*playing*/ 16 && img0_alt_value !== (img0_alt_value = "" + ((/*playing*/ ctx[4] ? "Pause" : "Play") + " music"))) { - attr_dev(img0, "alt", img0_alt_value); - } - - if (dirty & /*playing*/ 16 && img0_title_value !== (img0_title_value = "" + ((/*playing*/ ctx[4] ? "Pause" : "Play") + " music"))) { - attr_dev(img0, "title", img0_title_value); - } - }, - d: function destroy(detaching) { - if (detaching) detach_dev(div3); - mounted = false; - run_all(dispose); - } - }; - - dispatch_dev("SvelteRegisterBlock", { - block, - id: create_if_block_1.name, - type: "if", - source: "(99:8) {#if song}", - ctx - }); - - return block; - } - - // (113:4) {#if now - lastVolumeUpdate < 4000 && song && song.audio} - function create_if_block(ctx) { - let div2; - let div1; - let div0; - let t0_value = Math.round(/*song*/ ctx[0].audio.volume * 100) + ""; - let t0; - let t1; - - const block = { - c: function create() { - div2 = element("div"); - div1 = element("div"); - div0 = element("div"); - t0 = text(t0_value); - t1 = text("%"); - attr_dev(div0, "class", "percent"); - add_location(div0, file, 115, 16, 3868); - attr_dev(div1, "class", "slider"); - add_location(div1, file, 114, 12, 3830); - attr_dev(div2, "class", "volume svelte-1j9fr45"); - toggle_class(div2, "hidden", /*now*/ ctx[3] - /*lastVolumeUpdate*/ ctx[2] > 2000); - add_location(div2, file, 113, 8, 3751); - }, - m: function mount(target, anchor) { - insert_dev(target, div2, anchor); - append_dev(div2, div1); - append_dev(div1, div0); - append_dev(div0, t0); - append_dev(div0, t1); - }, - p: function update(ctx, dirty) { - if (dirty & /*song*/ 1 && t0_value !== (t0_value = Math.round(/*song*/ ctx[0].audio.volume * 100) + "")) set_data_dev(t0, t0_value); - - if (dirty & /*now, lastVolumeUpdate*/ 12) { - toggle_class(div2, "hidden", /*now*/ ctx[3] - /*lastVolumeUpdate*/ ctx[2] > 2000); - } - }, - d: function destroy(detaching) { - if (detaching) detach_dev(div2); - } - }; - - dispatch_dev("SvelteRegisterBlock", { - block, - id: create_if_block.name, - type: "if", - source: "(113:4) {#if now - lastVolumeUpdate < 4000 && song && song.audio}", - ctx - }); - - return block; - } + const file = "src\\components\\options.svelte"; function create_fragment(ctx) { - let div1; + let div12; let div0; - let t; + let t0; + let nav; + let h2; + let t2; + let div3; + let h30; + let t4; + let div1; + let span0; + let t6; + let input0; + let t7; + let div2; + let span1; + let t9; + let input1; + let t10; + let div6; + let h31; + let t12; + let div4; + let span2; + let t14; + let input2; + let t15; + let div5; + let span3; + let t17; + let input3; + let t18; + let div8; + let h32; + let t20; + let select; + let option0; + let option0_value_value; + let option1; + let option1_value_value; + let t23; + let div7; + let span4; + let t25; + let input4; + let t26; + let div11; + let h33; + let t28; + let div9; + let span5; + let t30; + let input5; + let t31; + let div10; + let span6; + let t33; + let input6; let mounted; let dispose; - let if_block0 = /*song*/ ctx[0] && create_if_block_1(ctx); - let if_block1 = /*now*/ ctx[3] - /*lastVolumeUpdate*/ ctx[2] < 4000 && /*song*/ ctx[0] && /*song*/ ctx[0].audio && create_if_block(ctx); const block = { c: function create() { - div1 = element("div"); + div12 = element("div"); div0 = element("div"); - if (if_block0) if_block0.c(); - t = space(); - if (if_block1) if_block1.c(); - attr_dev(div0, "class", "info svelte-1j9fr45"); - toggle_class(div0, "hidden", /*now*/ ctx[3] - /*last*/ ctx[1] > 2000); - add_location(div0, file, 97, 4, 2958); - attr_dev(div1, "class", "menu"); - add_location(div1, file, 96, 0, 2934); + t0 = space(); + nav = element("nav"); + h2 = element("h2"); + h2.textContent = "Options"; + t2 = space(); + div3 = element("div"); + h30 = element("h3"); + h30.textContent = "Parallax"; + t4 = space(); + div1 = element("div"); + span0 = element("span"); + span0.textContent = "Enable parallax"; + t6 = space(); + input0 = element("input"); + t7 = space(); + div2 = element("div"); + span1 = element("span"); + span1.textContent = "Parallax treshold"; + t9 = space(); + input1 = element("input"); + t10 = space(); + div6 = element("div"); + h31 = element("h3"); + h31.textContent = "Integrations"; + t12 = space(); + div4 = element("div"); + span2 = element("span"); + span2.textContent = "Discord Rich Presence"; + t14 = space(); + input2 = element("input"); + t15 = space(); + div5 = element("div"); + span3 = element("span"); + span3.textContent = "MediaSession (system-wide controls)"; + t17 = space(); + input3 = element("input"); + t18 = space(); + div8 = element("div"); + h32 = element("h3"); + h32.textContent = "Backgrounds"; + t20 = space(); + select = element("select"); + option0 = element("option"); + option0.textContent = "Osu!wallpapers"; + option1 = element("option"); + option1.textContent = "Beatmap wallpapers"; + t23 = space(); + div7 = element("div"); + span4 = element("span"); + span4.textContent = "Video backgrounds"; + t25 = space(); + input4 = element("input"); + t26 = space(); + div11 = element("div"); + h33 = element("h3"); + h33.textContent = "UI"; + t28 = space(); + div9 = element("div"); + span5 = element("span"); + span5.textContent = "Song info hide timeout"; + t30 = space(); + input5 = element("input"); + t31 = space(); + div10 = element("div"); + span6 = element("span"); + span6.textContent = "Volume hide timeout"; + t33 = space(); + input6 = element("input"); + attr_dev(div0, "class", "bg svelte-1895ym0"); + toggle_class(div0, "visible", /*visible*/ ctx[1]); + add_location(div0, file, 8, 4, 140); + add_location(h2, file, 10, 8, 264); + add_location(h30, file, 13, 12, 325); + add_location(span0, file, 15, 16, 391); + attr_dev(input0, "type", "checkbox"); + add_location(input0, file, 16, 16, 437); + attr_dev(div1, "class", "row"); + add_location(div1, file, 14, 12, 356); + add_location(span1, file, 19, 16, 608); + attr_dev(input1, "type", "range"); + attr_dev(input1, "min", "1"); + attr_dev(input1, "max", "30"); + add_location(input1, file, 20, 16, 656); + attr_dev(div2, "class", "row"); + toggle_class(div2, "enabled", /*config*/ ctx[0].parallax.enabled); + add_location(div2, file, 18, 12, 533); + attr_dev(div3, "class", "group"); + add_location(div3, file, 12, 8, 292); + add_location(h31, file, 24, 12, 810); + add_location(span2, file, 26, 16, 880); + attr_dev(input2, "type", "checkbox"); + add_location(input2, file, 27, 16, 932); + attr_dev(div4, "class", "row"); + add_location(div4, file, 25, 12, 845); + add_location(span3, file, 30, 16, 1050); + attr_dev(input3, "type", "checkbox"); + add_location(input3, file, 31, 16, 1116); + attr_dev(div5, "class", "row"); + add_location(div5, file, 29, 12, 1015); + attr_dev(div6, "class", "group"); + add_location(div6, file, 23, 8, 777); + add_location(h32, file, 35, 12, 1253); + option0.__value = option0_value_value = 0; + option0.value = option0.__value; + add_location(option0, file, 37, 16, 1345); + option1.__value = option1_value_value = 1; + option1.value = option1.__value; + add_location(option1, file, 38, 16, 1404); + if (/*config*/ ctx[0].backgrounds === void 0) add_render_callback(() => /*select_change_handler*/ ctx[7].call(select)); + add_location(select, file, 36, 12, 1287); + add_location(span4, file, 41, 16, 1521); + attr_dev(input4, "type", "checkbox"); + add_location(input4, file, 42, 16, 1569); + attr_dev(div7, "class", "row"); + add_location(div7, file, 40, 12, 1486); + attr_dev(div8, "class", "group"); + add_location(div8, file, 34, 8, 1220); + add_location(h33, file, 46, 12, 1709); + add_location(span5, file, 48, 16, 1769); + attr_dev(input5, "type", "range"); + attr_dev(input5, "min", "1000"); + attr_dev(input5, "max", "15000"); + attr_dev(input5, "step", "500"); + add_location(input5, file, 49, 16, 1822); + attr_dev(div9, "class", "row"); + add_location(div9, file, 47, 12, 1734); + add_location(span6, file, 52, 16, 1979); + attr_dev(input6, "type", "range"); + attr_dev(input6, "min", "1000"); + attr_dev(input6, "max", "15000"); + attr_dev(input6, "step", "500"); + add_location(input6, file, 53, 16, 2029); + attr_dev(div10, "class", "row"); + add_location(div10, file, 51, 12, 1944); + attr_dev(div11, "class", "group"); + add_location(div11, file, 45, 8, 1676); + attr_dev(nav, "class", "svelte-1895ym0"); + toggle_class(nav, "visible", /*visible*/ ctx[1]); + add_location(nav, file, 9, 4, 225); + attr_dev(div12, "class", "options"); + add_location(div12, file, 7, 0, 113); }, l: function claim(nodes) { throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); }, m: function mount(target, anchor) { - insert_dev(target, div1, anchor); - append_dev(div1, div0); - if (if_block0) if_block0.m(div0, null); - append_dev(div1, t); - if (if_block1) if_block1.m(div1, null); + insert_dev(target, div12, anchor); + append_dev(div12, div0); + append_dev(div12, t0); + append_dev(div12, nav); + append_dev(nav, h2); + append_dev(nav, t2); + append_dev(nav, div3); + append_dev(div3, h30); + append_dev(div3, t4); + append_dev(div3, div1); + append_dev(div1, span0); + append_dev(div1, t6); + append_dev(div1, input0); + input0.checked = /*config*/ ctx[0].parallax.enabled; + append_dev(div3, t7); + append_dev(div3, div2); + append_dev(div2, span1); + append_dev(div2, t9); + append_dev(div2, input1); + set_input_value(input1, /*config*/ ctx[0].parallax.treshold); + append_dev(nav, t10); + append_dev(nav, div6); + append_dev(div6, h31); + append_dev(div6, t12); + append_dev(div6, div4); + append_dev(div4, span2); + append_dev(div4, t14); + append_dev(div4, input2); + input2.checked = /*config*/ ctx[0].rpc; + append_dev(div6, t15); + append_dev(div6, div5); + append_dev(div5, span3); + append_dev(div5, t17); + append_dev(div5, input3); + input3.checked = /*config*/ ctx[0].mediaSession; + append_dev(nav, t18); + append_dev(nav, div8); + append_dev(div8, h32); + append_dev(div8, t20); + append_dev(div8, select); + append_dev(select, option0); + append_dev(select, option1); + select_option(select, /*config*/ ctx[0].backgrounds); + append_dev(div8, t23); + append_dev(div8, div7); + append_dev(div7, span4); + append_dev(div7, t25); + append_dev(div7, input4); + input4.checked = /*config*/ ctx[0].videoBackground; + append_dev(nav, t26); + append_dev(nav, div11); + append_dev(div11, h33); + append_dev(div11, t28); + append_dev(div11, div9); + append_dev(div9, span5); + append_dev(div9, t30); + append_dev(div9, input5); + set_input_value(input5, /*config*/ ctx[0].autohide.info); + append_dev(div11, t31); + append_dev(div11, div10); + append_dev(div10, span6); + append_dev(div10, t33); + append_dev(div10, input6); + set_input_value(input6, /*config*/ ctx[0].autohide.volume); if (!mounted) { dispose = [ - listen_dev(window, "mousemove", /*mousemove_handler*/ ctx[9], false, false, false), - listen_dev(window, "wheel", /*wheel_handler*/ ctx[10], false, false, false) + listen_dev(div0, "click", /*click_handler*/ ctx[2], false, false, false), + listen_dev(input0, "change", /*input0_change_handler*/ ctx[3]), + listen_dev(input1, "change", /*input1_change_input_handler*/ ctx[4]), + listen_dev(input1, "input", /*input1_change_input_handler*/ ctx[4]), + listen_dev(input2, "change", /*input2_change_handler*/ ctx[5]), + listen_dev(input3, "change", /*input3_change_handler*/ ctx[6]), + listen_dev(select, "change", /*select_change_handler*/ ctx[7]), + listen_dev(input4, "change", /*input4_change_handler*/ ctx[8]), + listen_dev(input5, "change", /*input5_change_input_handler*/ ctx[9]), + listen_dev(input5, "input", /*input5_change_input_handler*/ ctx[9]), + listen_dev(input6, "change", /*input6_change_input_handler*/ ctx[10]), + listen_dev(input6, "input", /*input6_change_input_handler*/ ctx[10]) ]; mounted = true; } }, p: function update(ctx, [dirty]) { - if (/*song*/ ctx[0]) { - if (if_block0) { - if_block0.p(ctx, dirty); - } else { - if_block0 = create_if_block_1(ctx); - if_block0.c(); - if_block0.m(div0, null); - } - } else if (if_block0) { - if_block0.d(1); - if_block0 = null; + if (dirty & /*visible*/ 2) { + toggle_class(div0, "visible", /*visible*/ ctx[1]); } - if (dirty & /*now, last*/ 10) { - toggle_class(div0, "hidden", /*now*/ ctx[3] - /*last*/ ctx[1] > 2000); + if (dirty & /*config*/ 1) { + input0.checked = /*config*/ ctx[0].parallax.enabled; } - if (/*now*/ ctx[3] - /*lastVolumeUpdate*/ ctx[2] < 4000 && /*song*/ ctx[0] && /*song*/ ctx[0].audio) { - if (if_block1) { - if_block1.p(ctx, dirty); - } else { - if_block1 = create_if_block(ctx); - if_block1.c(); - if_block1.m(div1, null); - } - } else if (if_block1) { - if_block1.d(1); - if_block1 = null; + if (dirty & /*config*/ 1) { + set_input_value(input1, /*config*/ ctx[0].parallax.treshold); + } + + if (dirty & /*config*/ 1) { + toggle_class(div2, "enabled", /*config*/ ctx[0].parallax.enabled); + } + + if (dirty & /*config*/ 1) { + input2.checked = /*config*/ ctx[0].rpc; + } + + if (dirty & /*config*/ 1) { + input3.checked = /*config*/ ctx[0].mediaSession; + } + + if (dirty & /*config*/ 1) { + select_option(select, /*config*/ ctx[0].backgrounds); + } + + if (dirty & /*config*/ 1) { + input4.checked = /*config*/ ctx[0].videoBackground; + } + + if (dirty & /*config*/ 1) { + set_input_value(input5, /*config*/ ctx[0].autohide.info); + } + + if (dirty & /*config*/ 1) { + set_input_value(input6, /*config*/ ctx[0].autohide.volume); + } + + if (dirty & /*visible*/ 2) { + toggle_class(nav, "visible", /*visible*/ ctx[1]); } }, i: noop, o: noop, d: function destroy(detaching) { - if (detaching) detach_dev(div1); - if (if_block0) if_block0.d(); - if (if_block1) if_block1.d(); + if (detaching) detach_dev(div12); mounted = false; run_all(dispose); } @@ -656,27 +765,579 @@ var app = (function () { } function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Options", slots, []); + var { config } = $$props; + var { visible } = $$props; + const writable_props = ["config", "visible"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(` was created with unknown prop '${key}'`); + }); + + const click_handler = () => $$invalidate(1, visible = false); + + function input0_change_handler() { + config.parallax.enabled = this.checked; + $$invalidate(0, config); + } + + function input1_change_input_handler() { + config.parallax.treshold = to_number(this.value); + $$invalidate(0, config); + } + + function input2_change_handler() { + config.rpc = this.checked; + $$invalidate(0, config); + } + + function input3_change_handler() { + config.mediaSession = this.checked; + $$invalidate(0, config); + } + + function select_change_handler() { + config.backgrounds = select_value(this); + $$invalidate(0, config); + } + + function input4_change_handler() { + config.videoBackground = this.checked; + $$invalidate(0, config); + } + + function input5_change_input_handler() { + config.autohide.info = to_number(this.value); + $$invalidate(0, config); + } + + function input6_change_input_handler() { + config.autohide.volume = to_number(this.value); + $$invalidate(0, config); + } + + $$self.$$set = $$props => { + if ("config" in $$props) $$invalidate(0, config = $$props.config); + if ("visible" in $$props) $$invalidate(1, visible = $$props.visible); + }; + + $$self.$capture_state = () => ({ config, visible }); + + $$self.$inject_state = $$props => { + if ("config" in $$props) $$invalidate(0, config = $$props.config); + if ("visible" in $$props) $$invalidate(1, visible = $$props.visible); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + $$self.$$.update = () => { + if ($$self.$$.dirty & /*config*/ 1) { + console.log("Config", config); + } + }; + + return [ + config, + visible, + click_handler, + input0_change_handler, + input1_change_input_handler, + input2_change_handler, + input3_change_handler, + select_change_handler, + input4_change_handler, + input5_change_input_handler, + input6_change_input_handler + ]; + } + + class Options extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance, create_fragment, safe_not_equal, { config: 0, visible: 1 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Options", + options, + id: create_fragment.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*config*/ ctx[0] === undefined && !("config" in props)) { + console_1.warn(" was created without expected prop 'config'"); + } + + if (/*visible*/ ctx[1] === undefined && !("visible" in props)) { + console_1.warn(" was created without expected prop 'visible'"); + } + } + + get config() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set config(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get visible() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set visible(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src\Menu.svelte generated by Svelte v3.25.1 */ + + const { console: console_1$1, window: window_1 } = globals; + const file$1 = "src\\Menu.svelte"; + + // (146:4) {#if now - last < config.autohide.info + 1000} + function create_if_block_1(ctx) { + let div; + let if_block = /*song*/ ctx[0] && create_if_block_2(ctx); + + const block = { + c: function create() { + div = element("div"); + if (if_block) if_block.c(); + attr_dev(div, "class", "info svelte-1qt5obi"); + toggle_class(div, "hidden", /*now*/ ctx[5] - /*last*/ ctx[2] > /*config*/ ctx[1].autohide.info); + add_location(div, file$1, 146, 8, 4944); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + if (if_block) if_block.m(div, null); + }, + p: function update(ctx, dirty) { + if (/*song*/ ctx[0]) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block_2(ctx); + if_block.c(); + if_block.m(div, null); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + + if (dirty & /*now, last, config*/ 38) { + toggle_class(div, "hidden", /*now*/ ctx[5] - /*last*/ ctx[2] > /*config*/ ctx[1].autohide.info); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + if (if_block) if_block.d(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block_1.name, + type: "if", + source: "(146:4) {#if now - last < config.autohide.info + 1000}", + ctx + }); + + return block; + } + + // (148:12) {#if song} + function create_if_block_2(ctx) { + let div4; + let h2; + let t0_value = /*song*/ ctx[0].artist + ""; + let t0; + let t1; + let t2_value = /*song*/ ctx[0].song + ""; + let t2; + let t3; + let div3; + let div0; + let img0; + let img0_src_value; + let img0_alt_value; + let img0_title_value; + let t4; + let div1; + let img1; + let img1_src_value; + let t5; + let div2; + let img2; + let img2_src_value; + let mounted; + let dispose; + + const block = { + c: function create() { + div4 = element("div"); + h2 = element("h2"); + t0 = text(t0_value); + t1 = text(" - "); + t2 = text(t2_value); + t3 = space(); + div3 = element("div"); + div0 = element("div"); + img0 = element("img"); + t4 = space(); + div1 = element("div"); + img1 = element("img"); + t5 = space(); + div2 = element("div"); + img2 = element("img"); + attr_dev(h2, "class", "svelte-1qt5obi"); + add_location(h2, file$1, 149, 20, 5093); + if (img0.src !== (img0_src_value = "images/music_" + (/*song*/ ctx[0].playing ? "pause" : "play") + ".svg")) attr_dev(img0, "src", img0_src_value); + attr_dev(img0, "alt", img0_alt_value = "" + ((/*song*/ ctx[0].playing ? "Pause" : "Play") + " music")); + attr_dev(img0, "title", img0_title_value = "" + ((/*song*/ ctx[0].playing ? "Pause" : "Play") + " music")); + attr_dev(img0, "class", "svelte-1qt5obi"); + add_location(img0, file$1, 152, 28, 5269); + attr_dev(div0, "class", "play svelte-1qt5obi"); + add_location(div0, file$1, 151, 24, 5199); + if (img1.src !== (img1_src_value = "images/music_forward.svg")) attr_dev(img1, "src", img1_src_value); + attr_dev(img1, "alt", "Skip the song"); + attr_dev(img1, "title", "Skip the song"); + attr_dev(img1, "class", "svelte-1qt5obi"); + add_location(img1, file$1, 155, 28, 5554); + attr_dev(div1, "class", "forward svelte-1qt5obi"); + add_location(div1, file$1, 154, 24, 5483); + if (img2.src !== (img2_src_value = "images/settings.svg")) attr_dev(img2, "src", img2_src_value); + attr_dev(img2, "alt", "Settings"); + attr_dev(img2, "title", "Open settings"); + attr_dev(img2, "class", "svelte-1qt5obi"); + add_location(img2, file$1, 158, 28, 5788); + attr_dev(div2, "class", "settings svelte-1qt5obi"); + add_location(div2, file$1, 157, 24, 5690); + attr_dev(div3, "class", "controls svelte-1qt5obi"); + add_location(div3, file$1, 150, 20, 5151); + attr_dev(div4, "class", "song svelte-1qt5obi"); + add_location(div4, file$1, 148, 16, 5053); + }, + m: function mount(target, anchor) { + insert_dev(target, div4, anchor); + append_dev(div4, h2); + append_dev(h2, t0); + append_dev(h2, t1); + append_dev(h2, t2); + append_dev(div4, t3); + append_dev(div4, div3); + append_dev(div3, div0); + append_dev(div0, img0); + append_dev(div3, t4); + append_dev(div3, div1); + append_dev(div1, img1); + append_dev(div3, t5); + append_dev(div3, div2); + append_dev(div2, img2); + + if (!mounted) { + dispose = [ + listen_dev(div0, "click", /*togglePlay*/ ctx[7], false, false, false), + listen_dev(div1, "click", /*playNext*/ ctx[6], false, false, false), + listen_dev(div2, "click", /*click_handler*/ ctx[12], false, false, false) + ]; + + mounted = true; + } + }, + p: function update(ctx, dirty) { + if (dirty & /*song*/ 1 && t0_value !== (t0_value = /*song*/ ctx[0].artist + "")) set_data_dev(t0, t0_value); + if (dirty & /*song*/ 1 && t2_value !== (t2_value = /*song*/ ctx[0].song + "")) set_data_dev(t2, t2_value); + + if (dirty & /*song*/ 1 && img0.src !== (img0_src_value = "images/music_" + (/*song*/ ctx[0].playing ? "pause" : "play") + ".svg")) { + attr_dev(img0, "src", img0_src_value); + } + + if (dirty & /*song*/ 1 && img0_alt_value !== (img0_alt_value = "" + ((/*song*/ ctx[0].playing ? "Pause" : "Play") + " music"))) { + attr_dev(img0, "alt", img0_alt_value); + } + + if (dirty & /*song*/ 1 && img0_title_value !== (img0_title_value = "" + ((/*song*/ ctx[0].playing ? "Pause" : "Play") + " music"))) { + attr_dev(img0, "title", img0_title_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div4); + mounted = false; + run_all(dispose); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block_2.name, + type: "if", + source: "(148:12) {#if song}", + ctx + }); + + return block; + } + + // (166:4) {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio} + function create_if_block(ctx) { + let div2; + let div1; + let div0; + let t0_value = Math.round(/*song*/ ctx[0].audio.volume * 100) + ""; + let t0; + let t1; + let t2; + let svg; + let circle; + let circle_stroke_dasharray_value; + let circle_stroke_dashoffset_value; + let circle_r_value; + let circle_cx_value; + let circle_cy_value; + + const block = { + c: function create() { + div2 = element("div"); + div1 = element("div"); + div0 = element("div"); + t0 = text(t0_value); + t1 = text("%"); + t2 = space(); + svg = svg_element("svg"); + circle = svg_element("circle"); + attr_dev(div0, "class", "percent svelte-1qt5obi"); + add_location(div0, file$1, 168, 16, 6219); + attr_dev(circle, "stroke-width", volumeStroke); + attr_dev(circle, "fill", "transparent"); + attr_dev(circle, "stroke", "blue"); + attr_dev(circle, "stroke-dasharray", circle_stroke_dasharray_value = volumeRadius * 2 * Math.PI + " " + volumeRadius * 2 * Math.PI); + attr_dev(circle, "stroke-dashoffset", circle_stroke_dashoffset_value = volumeRadius * 2 * Math.PI - /*song*/ ctx[0].audio.volume * volumeRadius * 2 * Math.PI); + attr_dev(circle, "r", circle_r_value = volumeRadius - 1); + attr_dev(circle, "cx", circle_cx_value = volumeRadius - 1); + attr_dev(circle, "cy", circle_cy_value = volumeRadius + 1); + attr_dev(circle, "class", "svelte-1qt5obi"); + add_location(circle, file$1, 172, 20, 6432); + attr_dev(svg, "class", "progress-ring svelte-1qt5obi"); + attr_dev(svg, "width", volumeWidth); + attr_dev(svg, "height", volumeWidth); + add_location(svg, file$1, 171, 16, 6342); + attr_dev(div1, "class", "slider svelte-1qt5obi"); + add_location(div1, file$1, 167, 12, 6181); + attr_dev(div2, "class", "volume svelte-1qt5obi"); + toggle_class(div2, "hidden", /*now*/ ctx[5] - /*lastVolumeUpdate*/ ctx[3] > /*config*/ ctx[1].autohide.volume); + add_location(div2, file$1, 166, 8, 6084); + }, + m: function mount(target, anchor) { + insert_dev(target, div2, anchor); + append_dev(div2, div1); + append_dev(div1, div0); + append_dev(div0, t0); + append_dev(div0, t1); + append_dev(div1, t2); + append_dev(div1, svg); + append_dev(svg, circle); + }, + p: function update(ctx, dirty) { + if (dirty & /*song*/ 1 && t0_value !== (t0_value = Math.round(/*song*/ ctx[0].audio.volume * 100) + "")) set_data_dev(t0, t0_value); + + if (dirty & /*song*/ 1 && circle_stroke_dashoffset_value !== (circle_stroke_dashoffset_value = volumeRadius * 2 * Math.PI - /*song*/ ctx[0].audio.volume * volumeRadius * 2 * Math.PI)) { + attr_dev(circle, "stroke-dashoffset", circle_stroke_dashoffset_value); + } + + if (dirty & /*now, lastVolumeUpdate, config*/ 42) { + toggle_class(div2, "hidden", /*now*/ ctx[5] - /*lastVolumeUpdate*/ ctx[3] > /*config*/ ctx[1].autohide.volume); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div2); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block.name, + type: "if", + source: "(166:4) {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio}", + ctx + }); + + return block; + } + + function create_fragment$1(ctx) { + let div; + let t0; + let t1; + let options; + let updating_config; + let updating_visible; + let current; + let mounted; + let dispose; + let if_block0 = /*now*/ ctx[5] - /*last*/ ctx[2] < /*config*/ ctx[1].autohide.info + 1000 && create_if_block_1(ctx); + let if_block1 = /*now*/ ctx[5] - /*lastVolumeUpdate*/ ctx[3] < /*config*/ ctx[1].autohide.volume + 1000 && /*song*/ ctx[0] && /*song*/ ctx[0].audio && create_if_block(ctx); + + function options_config_binding(value) { + /*options_config_binding*/ ctx[13].call(null, value); + } + + function options_visible_binding(value) { + /*options_visible_binding*/ ctx[14].call(null, value); + } + + let options_props = {}; + + if (/*config*/ ctx[1] !== void 0) { + options_props.config = /*config*/ ctx[1]; + } + + if (/*settingsOpen*/ ctx[4] !== void 0) { + options_props.visible = /*settingsOpen*/ ctx[4]; + } + + options = new Options({ props: options_props, $$inline: true }); + binding_callbacks.push(() => bind(options, "config", options_config_binding)); + binding_callbacks.push(() => bind(options, "visible", options_visible_binding)); + + const block = { + c: function create() { + div = element("div"); + if (if_block0) if_block0.c(); + t0 = space(); + if (if_block1) if_block1.c(); + t1 = space(); + create_component(options.$$.fragment); + attr_dev(div, "class", "menu"); + add_location(div, file$1, 144, 0, 4864); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div, anchor); + if (if_block0) if_block0.m(div, null); + append_dev(div, t0); + if (if_block1) if_block1.m(div, null); + append_dev(div, t1); + mount_component(options, div, null); + current = true; + + if (!mounted) { + dispose = [ + listen_dev(window_1, "mousemove", /*mousemove_handler*/ ctx[10], false, false, false), + listen_dev(window_1, "wheel", /*wheel_handler*/ ctx[11], false, false, false) + ]; + + mounted = true; + } + }, + p: function update(ctx, [dirty]) { + if (/*now*/ ctx[5] - /*last*/ ctx[2] < /*config*/ ctx[1].autohide.info + 1000) { + if (if_block0) { + if_block0.p(ctx, dirty); + } else { + if_block0 = create_if_block_1(ctx); + if_block0.c(); + if_block0.m(div, t0); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } + + if (/*now*/ ctx[5] - /*lastVolumeUpdate*/ ctx[3] < /*config*/ ctx[1].autohide.volume + 1000 && /*song*/ ctx[0] && /*song*/ ctx[0].audio) { + if (if_block1) { + if_block1.p(ctx, dirty); + } else { + if_block1 = create_if_block(ctx); + if_block1.c(); + if_block1.m(div, t1); + } + } else if (if_block1) { + if_block1.d(1); + if_block1 = null; + } + + const options_changes = {}; + + if (!updating_config && dirty & /*config*/ 2) { + updating_config = true; + options_changes.config = /*config*/ ctx[1]; + add_flush_callback(() => updating_config = false); + } + + if (!updating_visible && dirty & /*settingsOpen*/ 16) { + updating_visible = true; + options_changes.visible = /*settingsOpen*/ ctx[4]; + add_flush_callback(() => updating_visible = false); + } + + options.$set(options_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(options.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(options.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div); + if (if_block0) if_block0.d(); + if (if_block1) if_block1.d(); + destroy_component(options); + mounted = false; + run_all(dispose); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$1.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + const volumeWidth = 100; + const volumeStroke = 4; + const volumeRadius = 50; + + function instance$1($$self, $$props, $$invalidate) { let { $$slots: slots = {}, $$scope } = $$props; validate_slots("Menu", slots, []); + const fs = require("fs"); + const osuParser = require("./lib/osu-parser.js"); var { osuData } = $$props; var { song } = $$props; + var { config } = $$props; var last = Date.now(); var lastVolumeUpdate = Date.now() - 5000; - var dialogActive = false; + var settingsOpen = false; var now = Date.now(); setInterval( () => { - $$invalidate(3, now = Date.now()); + $$invalidate(5, now = Date.now()); }, - 500 + 800 ); - var playing = true; - function resetPool() { if (!osuData.songs) return false; - $$invalidate(8, osuData.songPool = osuData.songs.filter(v => true), osuData); + $$invalidate(9, osuData.songPool = osuData.songs.filter(v => true), osuData); let a = osuData.songPool; for (let i = a.length - 1; i > 0; i--) { @@ -686,6 +1347,12 @@ var app = (function () { [a[i], a[j]] = [a[j], a[i]]; } + osuData.songPool.forEach(v => { + delete v.audio; + delete v.video; + v.playing = true; + }); + $$invalidate(0, song = osuData.songPool.shift()); } @@ -702,66 +1369,88 @@ var app = (function () { } function togglePlay() { - $$invalidate(4, playing = !playing); + $$invalidate(0, song.playing = !song.playing, song); + if (!song.audio) return; - if (playing) { + if (song.playing) { song.audio.play(); } else { song.audio.pause(); } } + var volume = 1; + function updateVolume(e) { if (!song || !song.audio || !e.altKey) return; - $$invalidate(2, lastVolumeUpdate = Date.now()); - var volume = song.audio.volume; - volume += e.deltaY * -0.0005; - $$invalidate(0, song.audio.volume = Math.min(1, Math.max(volume, 0)), song); + $$invalidate(3, lastVolumeUpdate = Date.now()); + $$invalidate(15, volume += e.deltaY * -0.0005); + $$invalidate(15, volume = Math.min(1, Math.max(volume, 0))); } setTimeout( () => { - $$invalidate(0, song); + playNext(); }, 200 ); - const writable_props = ["osuData", "song"]; + const writable_props = ["osuData", "song", "config"]; Object.keys($$props).forEach(key => { - if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(` was created with unknown prop '${key}'`); + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1$1.warn(` was created with unknown prop '${key}'`); }); - const mousemove_handler = () => $$invalidate(1, last = Date.now()); + const mousemove_handler = () => $$invalidate(2, last = Date.now()); const wheel_handler = e => updateVolume(e); + const click_handler = () => $$invalidate(4, settingsOpen = !settingsOpen); + + function options_config_binding(value) { + config = value; + $$invalidate(1, config); + } + + function options_visible_binding(value) { + settingsOpen = value; + $$invalidate(4, settingsOpen); + } $$self.$$set = $$props => { - if ("osuData" in $$props) $$invalidate(8, osuData = $$props.osuData); + if ("osuData" in $$props) $$invalidate(9, osuData = $$props.osuData); if ("song" in $$props) $$invalidate(0, song = $$props.song); + if ("config" in $$props) $$invalidate(1, config = $$props.config); }; $$self.$capture_state = () => ({ + Options, + fs, + osuParser, osuData, song, + config, last, lastVolumeUpdate, - dialogActive, + settingsOpen, now, - playing, resetPool, playNext, togglePlay, - updateVolume + volume, + updateVolume, + volumeWidth, + volumeStroke, + volumeRadius }); $$self.$inject_state = $$props => { - if ("osuData" in $$props) $$invalidate(8, osuData = $$props.osuData); + if ("osuData" in $$props) $$invalidate(9, osuData = $$props.osuData); if ("song" in $$props) $$invalidate(0, song = $$props.song); - if ("last" in $$props) $$invalidate(1, last = $$props.last); - if ("lastVolumeUpdate" in $$props) $$invalidate(2, lastVolumeUpdate = $$props.lastVolumeUpdate); - if ("dialogActive" in $$props) dialogActive = $$props.dialogActive; - if ("now" in $$props) $$invalidate(3, now = $$props.now); - if ("playing" in $$props) $$invalidate(4, playing = $$props.playing); + if ("config" in $$props) $$invalidate(1, config = $$props.config); + if ("last" in $$props) $$invalidate(2, last = $$props.last); + if ("lastVolumeUpdate" in $$props) $$invalidate(3, lastVolumeUpdate = $$props.lastVolumeUpdate); + if ("settingsOpen" in $$props) $$invalidate(4, settingsOpen = $$props.settingsOpen); + if ("now" in $$props) $$invalidate(5, now = $$props.now); + if ("volume" in $$props) $$invalidate(15, volume = $$props.volume); }; if ($$props && "$$inject" in $$props) { @@ -769,112 +1458,155 @@ var app = (function () { } $$self.$$.update = () => { - if ($$self.$$.dirty & /*osuData*/ 256) { + if ($$self.$$.dirty & /*osuData*/ 512) { resetPool(osuData.songs); } - if ($$self.$$.dirty & /*song*/ 1) { + if ($$self.$$.dirty & /*song, config*/ 3) { { - if (song && song.folder && !song.audio) { - $$invalidate(0, song.audio = new Audio(process.env.USERPROFILE + "/AppData/Local/osu!/Songs/" + song.folder + "/" + song.audioFile), song); - song.audio.play(); + (() => { + if (song && song.folder && !song.audio) { + // var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + // song.context = audioCtx; + // song.analyser = audioCtx.createAnalyser(); + $$invalidate(0, song.audio = new Audio(process.env.USERPROFILE + "/AppData/Local/osu!/Songs/" + song.folder + "/" + song.audioFile), song); - $$invalidate( - 0, - song.audio.onended = () => { - playNext(); - }, - song - ); + // song.source = audioCtx.createMediaElementSource(song.audio); + // song.source.connect(song.analyser); + // song.analyser.connect(audioCtx.destination); + song.audio.play(); - $$invalidate( - 0, - song.audio.onpause = () => { - $$invalidate(4, playing = false); - }, - song - ); + $$invalidate( + 0, + song.audio.onended = () => { + playNext(); + }, + song + ); - $$invalidate( - 0, - song.audio.onplay = () => { - $$invalidate(4, playing = true); - }, - song - ); + $$invalidate( + 0, + song.audio.onpause = () => { + $$invalidate(0, song.playing = false, song); + if (song.video) song.video.pause(); + }, + song + ); - if ("mediaSession" in navigator) { - navigator.mediaSession.metadata = new MediaMetadata({ - title: song.song, - artist: song.artist, - album: "Osu! visualizer", - artwork: [ - { - src: process.env.USERPROFILE + "/AppData/Local/osu!/Data/bt/" + song.id + ".jpg", - type: "image/jpeg" - } - ] + $$invalidate( + 0, + song.audio.onplay = () => { + $$invalidate(0, song.playing = true, song); + if (song.video) song.video.play(); + }, + song + ); + + if ("mediaSession" in navigator && config.mediaSession) { + navigator.mediaSession.metadata = new MediaMetadata({ + title: song.song, + artist: song.artist, + album: "Osu! visualizer", + artwork: [], // { src: process.env.USERPROFILE + "/AppData/Local/osu!/Data/bt/" + song.id + ".jpg", type: 'image/jpeg' }, + + }); + + navigator.mediaSession.setActionHandler("play", function () { + $$invalidate(0, song.playing = true, song); + song.audio.play(); }); - navigator.mediaSession.setActionHandler("play", function () { - $$invalidate(4, playing = true); - song.audio.play(); - }); + navigator.mediaSession.setActionHandler("pause", function () { + $$invalidate(0, song.playing = false, song); + song.audio.pause(); + }); - navigator.mediaSession.setActionHandler("pause", function () { - $$invalidate(4, playing = false); - song.audio.pause(); - }); - - navigator.mediaSession.setActionHandler("nexttrack", function () { - playNext(); - }); + navigator.mediaSession.setActionHandler("nexttrack", function () { + playNext(); + }); + } } - } + })(); } } + if ($$self.$$.dirty & /*song, volume*/ 32769) { + if (song.audio) $$invalidate(0, song.audio.volume = volume, song); + } + if ($$self.$$.dirty & /*song*/ 1) { console.log(song); } + + if ($$self.$$.dirty & /*song, config*/ 3) { + if (song && song.audio && config.rpc) { + if (song.playing) { + window.songActivity = { + state: "Listening to osu! beatmaps", + details: `${song.artist} - ${song.song}`, + startTimestamp: Date.now(), + endTimestamp: Date.now() + song.audio.duration * 1000, + instance: false, + largeImageKey: "logo", + largeImageText: "Osu!visualizer" + }; + } else { + window.songActivity = { + state: "Paused", + details: `${song.artist} - ${song.song}`, + instance: false, + largeImageKey: "logo", + largeImageText: "Osu!visualizer" + }; + } + } + } }; return [ song, + config, last, lastVolumeUpdate, + settingsOpen, now, - playing, playNext, togglePlay, updateVolume, osuData, mousemove_handler, - wheel_handler + wheel_handler, + click_handler, + options_config_binding, + options_visible_binding ]; } class Menu extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, instance, create_fragment, safe_not_equal, { osuData: 8, song: 0 }); + init(this, options, instance$1, create_fragment$1, safe_not_equal, { osuData: 9, song: 0, config: 1 }); dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "Menu", options, - id: create_fragment.name + id: create_fragment$1.name }); const { ctx } = this.$$; const props = options.props || {}; - if (/*osuData*/ ctx[8] === undefined && !("osuData" in props)) { - console_1.warn(" was created without expected prop 'osuData'"); + if (/*osuData*/ ctx[9] === undefined && !("osuData" in props)) { + console_1$1.warn(" was created without expected prop 'osuData'"); } if (/*song*/ ctx[0] === undefined && !("song" in props)) { - console_1.warn(" was created without expected prop 'song'"); + console_1$1.warn(" was created without expected prop 'song'"); + } + + if (/*config*/ ctx[1] === undefined && !("config" in props)) { + console_1$1.warn(" was created without expected prop 'config'"); } } @@ -893,94 +1625,205 @@ var app = (function () { set song(value) { throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); } + + get config() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set config(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } } /* src\Visualizer.svelte generated by Svelte v3.25.1 */ - const { console: console_1$1, window: window_1 } = globals; - const file$1 = "src\\Visualizer.svelte"; + const { console: console_1$2, window: window_1$1 } = globals; + const file$2 = "src\\Visualizer.svelte"; - function create_fragment$1(ctx) { + // (155:4) {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground} + function create_if_block$1(ctx) { + let video; + let source; + let source_src_value; + + const block = { + c: function create() { + video = element("video"); + source = element("source"); + if (source.src !== (source_src_value = "file:///" + process.env.USERPROFILE.replace(/\\/g, "/") + "/AppData/Local/osu!/Songs/" + /*songData*/ ctx[0].folder + "/" + /*songData*/ ctx[0].beatmap.video)) attr_dev(source, "src", source_src_value); + add_location(source, file$2, 162, 12, 6027); + + set_style(video, "width", /*isWidthSmaller*/ ctx[5] + ? "auto" + : `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); + + set_style(video, "height", !/*isWidthSmaller*/ ctx[5] + ? "auto" + : `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); + + set_style(video, "top", /*mouse*/ ctx[3].y + "px"); + set_style(video, "left", /*mouse*/ ctx[3].x + "px"); + attr_dev(video, "class", "svelte-18bmol8"); + add_location(video, file$2, 156, 8, 5710); + }, + m: function mount(target, anchor) { + insert_dev(target, video, anchor); + append_dev(video, source); + /*video_binding*/ ctx[11](video); + }, + p: function update(ctx, dirty) { + if (dirty & /*songData*/ 1 && source.src !== (source_src_value = "file:///" + process.env.USERPROFILE.replace(/\\/g, "/") + "/AppData/Local/osu!/Songs/" + /*songData*/ ctx[0].folder + "/" + /*songData*/ ctx[0].beatmap.video)) { + attr_dev(source, "src", source_src_value); + } + + if (dirty & /*isWidthSmaller, parallaxTreshold*/ 48) { + set_style(video, "width", /*isWidthSmaller*/ ctx[5] + ? "auto" + : `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); + } + + if (dirty & /*isWidthSmaller, parallaxTreshold*/ 48) { + set_style(video, "height", !/*isWidthSmaller*/ ctx[5] + ? "auto" + : `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); + } + + if (dirty & /*mouse*/ 8) { + set_style(video, "top", /*mouse*/ ctx[3].y + "px"); + } + + if (dirty & /*mouse*/ 8) { + set_style(video, "left", /*mouse*/ ctx[3].x + "px"); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(video); + /*video_binding*/ ctx[11](null); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$1.name, + type: "if", + source: "(155:4) {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground}", + ctx + }); + + return block; + } + + function create_fragment$2(ctx) { let div; + let t0; let img0; let img0_src_value; - let t; + let t1; let img1; let img1_src_value; let mounted; let dispose; + let if_block = /*songData*/ ctx[0] && /*songData*/ ctx[0].beatmap && /*songData*/ ctx[0].beatmap.video && /*config*/ ctx[1].videoBackground && create_if_block$1(ctx); const block = { c: function create() { div = element("div"); + if (if_block) if_block.c(); + t0 = space(); img0 = element("img"); - t = space(); + t1 = space(); img1 = element("img"); if (img0.src !== (img0_src_value = "images/logo.svg")) attr_dev(img0, "src", img0_src_value); attr_dev(img0, "alt", "logo"); - attr_dev(img0, "class", "logo svelte-yh70k3"); - set_style(img0, "animation-duration", /*animDuration*/ ctx[3] + "ms"); - add_location(img0, file$1, 108, 4, 3650); + attr_dev(img0, "class", "logo svelte-18bmol8"); + set_style(img0, "animation-duration", /*animDuration*/ ctx[6] + "ms"); + toggle_class(img0, "repeat", /*songData*/ ctx[0].playing); + add_location(img0, file$2, 165, 4, 6198); if (img1.src !== (img1_src_value = "images/logo.svg")) attr_dev(img1, "src", img1_src_value); attr_dev(img1, "alt", ""); - attr_dev(img1, "class", "shadow svelte-yh70k3"); - set_style(img1, "animation-duration", /*animDuration*/ ctx[3] * 2 + "ms"); - add_location(img1, file$1, 109, 4, 3753); - attr_dev(div, "class", "main svelte-yh70k3"); - set_style(div, "background-image", "url('" + process.env.USERPROFILE.replace(/\\/g, "/") + "/AppData/Local/osu!/Data/bg/" + /*wallpaper*/ ctx[0] + "')"); + attr_dev(img1, "class", "shadow svelte-18bmol8"); + set_style(img1, "animation-duration", /*animDuration*/ ctx[6] * 2 + "ms"); + toggle_class(img1, "repeat", /*songData*/ ctx[0].playing); + add_location(img1, file$2, 166, 4, 6333); + attr_dev(div, "class", "main svelte-18bmol8"); + set_style(div, "background-image", "url('" + /*wallpaper*/ ctx[2] + "')"); - set_style(div, "background-size", !/*isWidthSmaller*/ ctx[2] - ? `calc(100% + ${parallaxTreshold * 1.5}px) auto` - : `auto calc(100% + ${parallaxTreshold * 1.5}px)`); + set_style(div, "background-size", !/*isWidthSmaller*/ ctx[5] + ? `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px) auto` + : `auto calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); - set_style(div, "background-position", /*mouse*/ ctx[1].x + "px " + /*mouse*/ ctx[1].y + "px"); - add_location(div, file$1, 100, 0, 3279); + set_style(div, "background-position", /*mouse*/ ctx[3].x + "px " + /*mouse*/ ctx[3].y + "px"); + add_location(div, file$2, 146, 0, 5261); }, l: function claim(nodes) { throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); }, m: function mount(target, anchor) { insert_dev(target, div, anchor); + if (if_block) if_block.m(div, null); + append_dev(div, t0); append_dev(div, img0); - append_dev(div, t); + append_dev(div, t1); append_dev(div, img1); if (!mounted) { dispose = [ - listen_dev(window_1, "mousemove", /*updateMouse*/ ctx[4], false, false, false), - listen_dev(window_1, "resize", /*resize*/ ctx[5], false, false, false) + listen_dev(window_1$1, "mousemove", /*updateMouse*/ ctx[8], false, false, false), + listen_dev(window_1$1, "resize", /*resize*/ ctx[9], false, false, false) ]; mounted = true; } }, p: function update(ctx, [dirty]) { - if (dirty & /*animDuration*/ 8) { - set_style(img0, "animation-duration", /*animDuration*/ ctx[3] + "ms"); + if (/*songData*/ ctx[0] && /*songData*/ ctx[0].beatmap && /*songData*/ ctx[0].beatmap.video && /*config*/ ctx[1].videoBackground) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block$1(ctx); + if_block.c(); + if_block.m(div, t0); + } + } else if (if_block) { + if_block.d(1); + if_block = null; } - if (dirty & /*animDuration*/ 8) { - set_style(img1, "animation-duration", /*animDuration*/ ctx[3] * 2 + "ms"); + if (dirty & /*animDuration*/ 64) { + set_style(img0, "animation-duration", /*animDuration*/ ctx[6] + "ms"); } - if (dirty & /*wallpaper*/ 1) { - set_style(div, "background-image", "url('" + process.env.USERPROFILE.replace(/\\/g, "/") + "/AppData/Local/osu!/Data/bg/" + /*wallpaper*/ ctx[0] + "')"); + if (dirty & /*songData*/ 1) { + toggle_class(img0, "repeat", /*songData*/ ctx[0].playing); } - if (dirty & /*isWidthSmaller*/ 4) { - set_style(div, "background-size", !/*isWidthSmaller*/ ctx[2] - ? `calc(100% + ${parallaxTreshold * 1.5}px) auto` - : `auto calc(100% + ${parallaxTreshold * 1.5}px)`); + if (dirty & /*animDuration*/ 64) { + set_style(img1, "animation-duration", /*animDuration*/ ctx[6] * 2 + "ms"); } - if (dirty & /*mouse*/ 2) { - set_style(div, "background-position", /*mouse*/ ctx[1].x + "px " + /*mouse*/ ctx[1].y + "px"); + if (dirty & /*songData*/ 1) { + toggle_class(img1, "repeat", /*songData*/ ctx[0].playing); + } + + if (dirty & /*wallpaper*/ 4) { + set_style(div, "background-image", "url('" + /*wallpaper*/ ctx[2] + "')"); + } + + if (dirty & /*isWidthSmaller, parallaxTreshold*/ 48) { + set_style(div, "background-size", !/*isWidthSmaller*/ ctx[5] + ? `calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px) auto` + : `auto calc(100% + ${/*parallaxTreshold*/ ctx[4] * 1.5}px)`); + } + + if (dirty & /*mouse*/ 8) { + set_style(div, "background-position", /*mouse*/ ctx[3].x + "px " + /*mouse*/ ctx[3].y + "px"); } }, i: noop, o: noop, d: function destroy(detaching) { if (detaching) detach_dev(div); + if (if_block) if_block.d(); mounted = false; run_all(dispose); } @@ -988,7 +1831,7 @@ var app = (function () { dispatch_dev("SvelteRegisterBlock", { block, - id: create_fragment$1.name, + id: create_fragment$2.name, type: "component", source: "", ctx @@ -997,16 +1840,15 @@ var app = (function () { return block; } - const parallaxTreshold = 10; - - function instance$1($$self, $$props, $$invalidate) { + function instance$2($$self, $$props, $$invalidate) { let { $$slots: slots = {}, $$scope } = $$props; validate_slots("Visualizer", slots, []); const fs = require("fs"); const OsuDBParser = require("osu-db-parser"); - const osuParser = require("osu-parser"); + const osuParser = require("./lib/osu-parser.js"); var { osuData } = $$props; var { songData } = $$props; + var { config } = $$props; var wallpapers = []; try { @@ -1028,7 +1870,8 @@ var app = (function () { song: v.song_title, song_u: v.song_title_unicode, id: v.beatmapset_id, - dataFile: `${v.artist_name} - ${v.song_title} (${v.creator_name}) [${v.difficulty}].osu` + dataFile: `${v.artist_name} - ${v.song_title} (${v.creator_name}) [${v.difficulty}].osu`.replace(/\/|\*|"|:|\?/g, ""), + playing: true })).filter((v, i, a) => a.findIndex(x => x.id === v.id) === i); } catch(e) { console.error("Osu DB weren't found. You must have osu installed and started at least once.", e); @@ -1038,20 +1881,42 @@ var app = (function () { var wallpaper; function shuffleWallpapers() { - $$invalidate(0, wallpaper = wallpapers[Math.floor(Math.random() * wallpapers.length)]); + switch (config.backgrounds) { + case 0: + $$invalidate(2, wallpaper = `${process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Data/bg/${wallpapers[Math.floor(Math.random() * wallpapers.length)]}`); + break; + case 1: + if (songData.beatmap) { + $$invalidate(2, wallpaper = `${process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Songs/${songData.folder}/${songData.beatmap.bgFilename}`); + } else { + $$invalidate(2, wallpaper = `${process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Data/bg/${wallpapers[Math.floor(Math.random() * wallpapers.length)]}`); + } + break; + default: + $$invalidate(2, wallpaper = `${process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Data/bg/${wallpapers[Math.floor(Math.random() * wallpapers.length)]}`); + } } + shuffleWallpapers(); var lastSong = null; + var lastBackgroundOption = null; function fetchBeatmap() { let file = fs.readFileSync(process.env.USERPROFILE + "/AppData/Local/osu!/Songs/" + songData.folder + "/" + songData.dataFile); - $$invalidate(7, songData.beatmap = osuParser.parseContent(file), songData); + $$invalidate(0, songData.beatmap = osuParser.parseContent(file), songData); + + if (config.backgrounds === 1) { + $$invalidate(2, wallpaper = `${process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Songs/${songData.folder}/${songData.beatmap.bgFilename}`); + } } var mouse = { x: 0.5, y: 0.5 }; + var parallaxTreshold; function updateMouse(e) { - $$invalidate(1, mouse = { + if (!config.parallax.enabled) return; + + $$invalidate(3, mouse = { x: -(e.clientX / window.innerWidth) * parallaxTreshold - parallaxTreshold / 2, y: -(e.clientY / window.innerHeight) * parallaxTreshold - parallaxTreshold / 2 }); @@ -1060,7 +1925,7 @@ var app = (function () { var isWidthSmaller = false; function resize() { - $$invalidate(2, isWidthSmaller = window.innerWidth * 9 < window.innerHeight * 16); + $$invalidate(5, isWidthSmaller = window.innerWidth * 9 < window.innerHeight * 16); } resize(); @@ -1071,7 +1936,7 @@ var app = (function () { () => { if (!songData) return; if (!songData.beatmap && songData.dataFile) fetchBeatmap(); - if (!songData.beatmap) return; + if (!songData.beatmap || !songData.audio) return; var tp = null; for (var t of songData.beatmap.timingPoints) { @@ -1080,39 +1945,50 @@ var app = (function () { } if (!tp) { - $$invalidate(3, animDuration = 0); + $$invalidate(6, animDuration = 0); kiaiTime = false; return; } - if (tp.beatLength / 2 !== animDuration) $$invalidate(3, animDuration = tp.beatLength / 2); + if (tp.beatLength / 2 !== animDuration) $$invalidate(6, animDuration = tp.beatLength / 2); kiaiTime = tp.kiaiTimeActive; }, 50 ); - const writable_props = ["osuData", "songData"]; + var backgroundVideo; + const writable_props = ["osuData", "songData", "config"]; Object.keys($$props).forEach(key => { - if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1$1.warn(` was created with unknown prop '${key}'`); + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1$2.warn(` was created with unknown prop '${key}'`); }); + function video_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + backgroundVideo = $$value; + $$invalidate(7, backgroundVideo); + }); + } + $$self.$$set = $$props => { - if ("osuData" in $$props) $$invalidate(6, osuData = $$props.osuData); - if ("songData" in $$props) $$invalidate(7, songData = $$props.songData); + if ("osuData" in $$props) $$invalidate(10, osuData = $$props.osuData); + if ("songData" in $$props) $$invalidate(0, songData = $$props.songData); + if ("config" in $$props) $$invalidate(1, config = $$props.config); }; $$self.$capture_state = () => ({ - createEventDispatcher, + onMount, fs, OsuDBParser, osuParser, osuData, songData, + config, wallpapers, wallpaper, shuffleWallpapers, lastSong, + lastBackgroundOption, fetchBeatmap, mouse, parallaxTreshold, @@ -1120,19 +1996,24 @@ var app = (function () { isWidthSmaller, resize, animDuration, - kiaiTime + kiaiTime, + backgroundVideo }); $$self.$inject_state = $$props => { - if ("osuData" in $$props) $$invalidate(6, osuData = $$props.osuData); - if ("songData" in $$props) $$invalidate(7, songData = $$props.songData); + if ("osuData" in $$props) $$invalidate(10, osuData = $$props.osuData); + if ("songData" in $$props) $$invalidate(0, songData = $$props.songData); + if ("config" in $$props) $$invalidate(1, config = $$props.config); if ("wallpapers" in $$props) wallpapers = $$props.wallpapers; - if ("wallpaper" in $$props) $$invalidate(0, wallpaper = $$props.wallpaper); - if ("lastSong" in $$props) $$invalidate(9, lastSong = $$props.lastSong); - if ("mouse" in $$props) $$invalidate(1, mouse = $$props.mouse); - if ("isWidthSmaller" in $$props) $$invalidate(2, isWidthSmaller = $$props.isWidthSmaller); - if ("animDuration" in $$props) $$invalidate(3, animDuration = $$props.animDuration); + if ("wallpaper" in $$props) $$invalidate(2, wallpaper = $$props.wallpaper); + if ("lastSong" in $$props) $$invalidate(13, lastSong = $$props.lastSong); + if ("lastBackgroundOption" in $$props) $$invalidate(14, lastBackgroundOption = $$props.lastBackgroundOption); + if ("mouse" in $$props) $$invalidate(3, mouse = $$props.mouse); + if ("parallaxTreshold" in $$props) $$invalidate(4, parallaxTreshold = $$props.parallaxTreshold); + if ("isWidthSmaller" in $$props) $$invalidate(5, isWidthSmaller = $$props.isWidthSmaller); + if ("animDuration" in $$props) $$invalidate(6, animDuration = $$props.animDuration); if ("kiaiTime" in $$props) kiaiTime = $$props.kiaiTime; + if ("backgroundVideo" in $$props) $$invalidate(7, backgroundVideo = $$props.backgroundVideo); }; if ($$props && "$$inject" in $$props) { @@ -1140,53 +2021,96 @@ var app = (function () { } $$self.$$.update = () => { - if ($$self.$$.dirty & /*songData, lastSong*/ 640) { + if ($$self.$$.dirty & /*backgroundVideo, songData*/ 129) { + { + if (backgroundVideo) { + $$invalidate(0, songData.video = backgroundVideo, songData); + + if (songData && songData.audio && songData.video) { + $$invalidate(0, songData.video.currentTime = songData.audio.currentTime, songData); + } + } + } + } + + if ($$self.$$.dirty & /*songData, lastSong, config, lastBackgroundOption*/ 24579) { { if (songData !== lastSong) { - $$invalidate(9, lastSong = songData); + $$invalidate(13, lastSong = songData); + shuffleWallpapers(); + } + + if (config.backgrounds !== lastBackgroundOption) { + $$invalidate(14, lastBackgroundOption = config.backgrounds); shuffleWallpapers(); } } } - if ($$self.$$.dirty & /*songData*/ 128) { + if ($$self.$$.dirty & /*songData*/ 1) { if (songData && songData.dataFile && !songData.beatmap) fetchBeatmap(); } + + if ($$self.$$.dirty & /*config*/ 2) { + $$invalidate(4, parallaxTreshold = config.parallax.treshold); + } + + if ($$self.$$.dirty & /*songData, config*/ 3) { + { + if (!songData || !songData.beatmap || !songData.beatmap.video || !config.videoBackground) window.backgroundVideo = null; + } + } + + if ($$self.$$.dirty & /*wallpaper*/ 4) { + console.log("Wallpaper", wallpaper); + } + + if ($$self.$$.dirty & /*songData*/ 1) { + console.log("Beatmap", songData.beatmap); + } }; return [ + songData, + config, wallpaper, mouse, + parallaxTreshold, isWidthSmaller, animDuration, + backgroundVideo, updateMouse, resize, osuData, - songData + video_binding ]; } class Visualizer extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, instance$1, create_fragment$1, safe_not_equal, { osuData: 6, songData: 7 }); + init(this, options, instance$2, create_fragment$2, safe_not_equal, { osuData: 10, songData: 0, config: 1 }); dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "Visualizer", options, - id: create_fragment$1.name + id: create_fragment$2.name }); const { ctx } = this.$$; const props = options.props || {}; - if (/*osuData*/ ctx[6] === undefined && !("osuData" in props)) { - console_1$1.warn(" was created without expected prop 'osuData'"); + if (/*osuData*/ ctx[10] === undefined && !("osuData" in props)) { + console_1$2.warn(" was created without expected prop 'osuData'"); } - if (/*songData*/ ctx[7] === undefined && !("songData" in props)) { - console_1$1.warn(" was created without expected prop 'songData'"); + if (/*songData*/ ctx[0] === undefined && !("songData" in props)) { + console_1$2.warn(" was created without expected prop 'songData'"); + } + + if (/*config*/ ctx[1] === undefined && !("config" in props)) { + console_1$2.warn(" was created without expected prop 'config'"); } } @@ -1205,12 +2129,20 @@ var app = (function () { set songData(value) { throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); } + + get config() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set config(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } } /* src\App.svelte generated by Svelte v3.25.1 */ - const file$2 = "src\\App.svelte"; + const file$3 = "src\\App.svelte"; - function create_fragment$2(ctx) { + function create_fragment$3(ctx) { let main; let div0; let visualizer; @@ -1221,24 +2153,25 @@ var app = (function () { let menu; let updating_song; let updating_osuData_1; + let updating_config; let current; function visualizer_songData_binding(value) { - /*visualizer_songData_binding*/ ctx[2].call(null, value); + /*visualizer_songData_binding*/ ctx[3].call(null, value); } function visualizer_osuData_binding(value) { - /*visualizer_osuData_binding*/ ctx[3].call(null, value); + /*visualizer_osuData_binding*/ ctx[4].call(null, value); } - let visualizer_props = {}; + let visualizer_props = { config: /*config*/ ctx[1] }; if (/*songData*/ ctx[0] !== void 0) { visualizer_props.songData = /*songData*/ ctx[0]; } - if (/*osuData*/ ctx[1] !== void 0) { - visualizer_props.osuData = /*osuData*/ ctx[1]; + if (/*osuData*/ ctx[2] !== void 0) { + visualizer_props.osuData = /*osuData*/ ctx[2]; } visualizer = new Visualizer({ props: visualizer_props, $$inline: true }); @@ -1246,11 +2179,15 @@ var app = (function () { binding_callbacks.push(() => bind(visualizer, "osuData", visualizer_osuData_binding)); function menu_song_binding(value) { - /*menu_song_binding*/ ctx[4].call(null, value); + /*menu_song_binding*/ ctx[5].call(null, value); } function menu_osuData_binding(value) { - /*menu_osuData_binding*/ ctx[5].call(null, value); + /*menu_osuData_binding*/ ctx[6].call(null, value); + } + + function menu_config_binding(value) { + /*menu_config_binding*/ ctx[7].call(null, value); } let menu_props = {}; @@ -1259,13 +2196,18 @@ var app = (function () { menu_props.song = /*songData*/ ctx[0]; } - if (/*osuData*/ ctx[1] !== void 0) { - menu_props.osuData = /*osuData*/ ctx[1]; + if (/*osuData*/ ctx[2] !== void 0) { + menu_props.osuData = /*osuData*/ ctx[2]; + } + + if (/*config*/ ctx[1] !== void 0) { + menu_props.config = /*config*/ ctx[1]; } menu = new Menu({ props: menu_props, $$inline: true }); binding_callbacks.push(() => bind(menu, "song", menu_song_binding)); binding_callbacks.push(() => bind(menu, "osuData", menu_osuData_binding)); + binding_callbacks.push(() => bind(menu, "config", menu_config_binding)); const block = { c: function create() { @@ -1276,11 +2218,11 @@ var app = (function () { div1 = element("div"); create_component(menu.$$.fragment); attr_dev(div0, "class", "background svelte-5atqf"); - add_location(div0, file$2, 10, 4, 176); + add_location(div0, file$3, 51, 4, 1440); attr_dev(div1, "class", "menu svelte-5atqf"); - add_location(div1, file$2, 13, 4, 268); + add_location(div1, file$3, 54, 4, 1542); attr_dev(main, "class", "svelte-5atqf"); - add_location(main, file$2, 9, 0, 164); + add_location(main, file$3, 50, 0, 1428); }, l: function claim(nodes) { throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); @@ -1296,6 +2238,7 @@ var app = (function () { }, p: function update(ctx, [dirty]) { const visualizer_changes = {}; + if (dirty & /*config*/ 2) visualizer_changes.config = /*config*/ ctx[1]; if (!updating_songData && dirty & /*songData*/ 1) { updating_songData = true; @@ -1303,9 +2246,9 @@ var app = (function () { add_flush_callback(() => updating_songData = false); } - if (!updating_osuData && dirty & /*osuData*/ 2) { + if (!updating_osuData && dirty & /*osuData*/ 4) { updating_osuData = true; - visualizer_changes.osuData = /*osuData*/ ctx[1]; + visualizer_changes.osuData = /*osuData*/ ctx[2]; add_flush_callback(() => updating_osuData = false); } @@ -1318,12 +2261,18 @@ var app = (function () { add_flush_callback(() => updating_song = false); } - if (!updating_osuData_1 && dirty & /*osuData*/ 2) { + if (!updating_osuData_1 && dirty & /*osuData*/ 4) { updating_osuData_1 = true; - menu_changes.osuData = /*osuData*/ ctx[1]; + menu_changes.osuData = /*osuData*/ ctx[2]; add_flush_callback(() => updating_osuData_1 = false); } + if (!updating_config && dirty & /*config*/ 2) { + updating_config = true; + menu_changes.config = /*config*/ ctx[1]; + add_flush_callback(() => updating_config = false); + } + menu.$set(menu_changes); }, i: function intro(local) { @@ -1346,7 +2295,7 @@ var app = (function () { dispatch_dev("SvelteRegisterBlock", { block, - id: create_fragment$2.name, + id: create_fragment$3.name, type: "component", source: "", ctx @@ -1355,11 +2304,46 @@ var app = (function () { return block; } - function instance$2($$self, $$props, $$invalidate) { + function instance$3($$self, $$props, $$invalidate) { let { $$slots: slots = {}, $$scope } = $$props; validate_slots("App", slots, []); + const Store = require("electron-store"); + const store = new Store(); var songData = {}; + var config = store.get("config"); var osuData = {}; + + (() => { + const configTemplate = { + parallax: { enabled: true, treshold: 10 }, + rpc: true, + backgrounds: 0, + mediaSession: true, + videoBackground: true, + autohide: { info: 2000, volume: 2000 } + }; + + function checkSettings(value, template) { + if (value === undefined) return template; + if (typeof value !== "object") return value; + var out = {}; + + for (var key in template) { + if (value[key] === undefined || typeof value[key] === "undefined") { + out[key] = template[key]; + continue; + } + + if (typeof value[key] === "object") out[key] = checkSettings(value[key], template[key]); + if (typeof value[key] !== "object") out[key] = value[key]; + } + + return out; + } + + $$invalidate(1, config = checkSettings(config, configTemplate)); + })(); + const writable_props = []; Object.keys($$props).forEach(key => { @@ -1373,7 +2357,7 @@ var app = (function () { function visualizer_osuData_binding(value) { osuData = value; - $$invalidate(1, osuData); + $$invalidate(2, osuData); } function menu_song_binding(value) { @@ -1383,40 +2367,62 @@ var app = (function () { function menu_osuData_binding(value) { osuData = value; - $$invalidate(1, osuData); + $$invalidate(2, osuData); } - $$self.$capture_state = () => ({ Menu, Visualizer, songData, osuData }); + function menu_config_binding(value) { + config = value; + $$invalidate(1, config); + } + + $$self.$capture_state = () => ({ + Menu, + Visualizer, + Store, + store, + songData, + config, + osuData + }); $$self.$inject_state = $$props => { if ("songData" in $$props) $$invalidate(0, songData = $$props.songData); - if ("osuData" in $$props) $$invalidate(1, osuData = $$props.osuData); + if ("config" in $$props) $$invalidate(1, config = $$props.config); + if ("osuData" in $$props) $$invalidate(2, osuData = $$props.osuData); }; if ($$props && "$$inject" in $$props) { $$self.$inject_state($$props.$$inject); } + $$self.$$.update = () => { + if ($$self.$$.dirty & /*config*/ 2) { + store.set("config", config); + } + }; + return [ songData, + config, osuData, visualizer_songData_binding, visualizer_osuData_binding, menu_song_binding, - menu_osuData_binding + menu_osuData_binding, + menu_config_binding ]; } class App extends SvelteComponentDev { constructor(options) { super(options); - init(this, options, instance$2, create_fragment$2, safe_not_equal, {}); + init(this, options, instance$3, create_fragment$3, safe_not_equal, {}); dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "App", options, - id: create_fragment$2.name + id: create_fragment$3.name }); } } diff --git a/public/build/bundle.js.map b/public/build/bundle.js.map index 51cb071..5236ad3 100644 --- a/public/build/bundle.js.map +++ b/public/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"bundle.js","sources":["../../node_modules/svelte/internal/index.mjs","../../src/Menu.svelte","../../src/Visualizer.svelte","../../src/App.svelte","../../src/svelte.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value = ret) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction claim_element(nodes, name, attributes, svg) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeName === name) {\n let j = 0;\n const remove = [];\n while (j < node.attributes.length) {\n const attribute = node.attributes[j++];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n for (let k = 0; k < remove.length; k++) {\n node.removeAttribute(remove[k]);\n }\n return nodes.splice(i, 1)[0];\n }\n }\n return svg ? svg_element(name) : element(name);\n}\nfunction claim_text(nodes, data) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 3) {\n node.data = '' + data;\n return nodes.splice(i, 1)[0];\n }\n }\n return text(data);\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n const z_index = (parseInt(computed_style.zIndex) || 0) - 1;\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', `display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ` +\n `overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: ${z_index};`);\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = `data:text/html,`;\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, false, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor(anchor = null) {\n this.a = anchor;\n this.e = this.n = null;\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.h(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = node.ownerDocument;\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ``}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error(`Function called outside component initialization`);\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n callbacks.slice().forEach(fn => fn(event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = program.b - t;\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n info.blocks[i] = null;\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error(`Cannot have duplicate keys in a keyed each`);\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += \" \" + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += \" \" + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${String(value).replace(/\"/g, '"').replace(/'/g, ''')}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '"',\n \"'\": ''',\n '&': '&',\n '<': '<',\n '>': '>'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, options = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, options);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : ``;\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const prop_values = options.props || {};\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false\n };\n let ready = false;\n $$.ctx = instance\n ? instance(component, prop_values, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor);\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.25.1' }, detail)));\n}\nfunction append_dev(target, node) {\n dispatch_dev(\"SvelteDOMInsert\", { target, node });\n append(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev(\"SvelteDOMInsert\", { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev(\"SvelteDOMRemove\", { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? [\"capture\"] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev(\"SvelteDOMAddEventListener\", { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev(\"SvelteDOMRemoveEventListener\", { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev(\"SvelteDOMRemoveAttribute\", { node, attribute });\n else\n dispatch_dev(\"SvelteDOMSetAttribute\", { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev(\"SvelteDOMSetProperty\", { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev(\"SvelteDOMSetDataset\", { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev(\"SvelteDOMSetData\", { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(`'target' is a required option`);\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn(`Component was already destroyed`); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error(`Infinite loop detected`);\n }\n };\n}\n\nexport { HtmlTag, SvelteComponent, SvelteComponentDev, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, assign, attr, attr_dev, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_space, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, escape, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getContext, get_binding_group_value, get_current_component, get_slot_changes, get_slot_context, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, has_prop, identity, init, insert, insert_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, update_keyed_each, update_slot, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","\r\n\r\n last = Date.now()} on:wheel={e => updateVolume(e)} />\r\n\r\n\r\n 2000}>\r\n {#if song}\r\n \r\n {song.artist} - {song.song}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n {#if now - lastVolumeUpdate < 4000 && song && song.audio}\r\n 2000}>\r\n \r\n \r\n {Math.round(song.audio.volume * 100)}%\r\n \r\n \r\n \r\n {/if}\r\n\r\n\r\n","\r\n\r\n\r\n\r\n\r\n \r\n \r\n\r\n\r\n","\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n","import App from './App.svelte';\r\n\r\nconst app = new App({\r\n\ttarget: document.body\r\n});\r\n\r\nexport default app;"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"bundle.js","sources":["../../node_modules/svelte/internal/index.mjs","../../src/components/options.svelte","../../src/Menu.svelte","../../src/Visualizer.svelte","../../src/App.svelte","../../src/svelte.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value = ret) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction claim_element(nodes, name, attributes, svg) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeName === name) {\n let j = 0;\n const remove = [];\n while (j < node.attributes.length) {\n const attribute = node.attributes[j++];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n for (let k = 0; k < remove.length; k++) {\n node.removeAttribute(remove[k]);\n }\n return nodes.splice(i, 1)[0];\n }\n }\n return svg ? svg_element(name) : element(name);\n}\nfunction claim_text(nodes, data) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 3) {\n node.data = '' + data;\n return nodes.splice(i, 1)[0];\n }\n }\n return text(data);\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n const z_index = (parseInt(computed_style.zIndex) || 0) - 1;\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', `display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ` +\n `overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: ${z_index};`);\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = `data:text/html,`;\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, false, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor(anchor = null) {\n this.a = anchor;\n this.e = this.n = null;\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.h(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = node.ownerDocument;\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ``}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error(`Function called outside component initialization`);\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n callbacks.slice().forEach(fn => fn(event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = program.b - t;\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n info.blocks[i] = null;\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error(`Cannot have duplicate keys in a keyed each`);\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += \" \" + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += \" \" + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${String(value).replace(/\"/g, '"').replace(/'/g, ''')}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '"',\n \"'\": ''',\n '&': '&',\n '<': '<',\n '>': '>'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, options = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, options);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : ``;\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const prop_values = options.props || {};\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false\n };\n let ready = false;\n $$.ctx = instance\n ? instance(component, prop_values, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor);\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.25.1' }, detail)));\n}\nfunction append_dev(target, node) {\n dispatch_dev(\"SvelteDOMInsert\", { target, node });\n append(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev(\"SvelteDOMInsert\", { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev(\"SvelteDOMRemove\", { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? [\"capture\"] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev(\"SvelteDOMAddEventListener\", { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev(\"SvelteDOMRemoveEventListener\", { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev(\"SvelteDOMRemoveAttribute\", { node, attribute });\n else\n dispatch_dev(\"SvelteDOMSetAttribute\", { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev(\"SvelteDOMSetProperty\", { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev(\"SvelteDOMSetDataset\", { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev(\"SvelteDOMSetData\", { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(`'target' is a required option`);\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn(`Component was already destroyed`); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error(`Infinite loop detected`);\n }\n };\n}\n\nexport { HtmlTag, SvelteComponent, SvelteComponentDev, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, assign, attr, attr_dev, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_space, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, escape, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getContext, get_binding_group_value, get_current_component, get_slot_changes, get_slot_context, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, has_prop, identity, init, insert, insert_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, update_keyed_each, update_slot, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","\r\n\r\n\r\n visible = false}>\r\n \r\n Options\r\n\r\n \r\n Parallax\r\n \r\n Enable parallax\r\n \r\n \r\n \r\n Parallax treshold\r\n \r\n \r\n \r\n \r\n Integrations\r\n \r\n Discord Rich Presence\r\n \r\n \r\n \r\n MediaSession (system-wide controls)\r\n \r\n \r\n \r\n \r\n Backgrounds\r\n \r\n Osu!wallpapers\r\n Beatmap wallpapers\r\n \r\n \r\n Video backgrounds\r\n \r\n \r\n \r\n \r\n UI\r\n \r\n Song info hide timeout\r\n \r\n \r\n \r\n Volume hide timeout\r\n \r\n \r\n \r\n \r\n\r\n \r\n","\r\n\r\n last = Date.now()} on:wheel={e => updateVolume(e)} />\r\n\r\n\r\n {#if now - last < config.autohide.info + 1000}\r\n config.autohide.info}>\r\n {#if song}\r\n \r\n {song.artist} - {song.song}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n settingsOpen = !settingsOpen}>\r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n {/if}\r\n {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio}\r\n config.autohide.volume}>\r\n \r\n \r\n {Math.round(song.audio.volume * 100)}%\r\n \r\n \r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n\r\n\r\n","\r\n\r\n\r\n\r\n\r\n {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground}\r\n \r\n \r\n \r\n \r\n {/if}\r\n \r\n \r\n\r\n\r\n","\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n\r\n","import App from './App.svelte';\r\n\r\nconst app = new App({\r\n\ttarget: document.body\r\n});\r\n\r\nexport default app;"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..82a7928 Binary files /dev/null and b/public/images/logo.png differ diff --git a/public/images/settings.svg b/public/images/settings.svg new file mode 100644 index 0000000..43f063e --- /dev/null +++ b/public/images/settings.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/public/lib/osu-parser.js b/public/lib/osu-parser.js new file mode 100644 index 0000000..00185f1 --- /dev/null +++ b/public/lib/osu-parser.js @@ -0,0 +1,515 @@ +var fs = require('fs'); +var slidercalc = require('osu-parser/lib/slidercalc.js'); + +function beatmapParser() { + var beatmap = { + nbCircles: 0, + nbSliders: 0, + nbSpinners: 0, + timingPoints: [], + breakTimes: [], + hitObjects: [] + }; + + var osuSection; + var bpmMin; + var bpmMax; + var members; + + var timingLines = []; + var objectLines = []; + var eventsLines = []; + var sectionReg = /^\[([a-zA-Z0-9]+)\]$/; + var keyValReg = /^([a-zA-Z0-9]+)[ ]*:[ ]*(.+)$/; + var curveTypes = { + C: "catmull", + B: "bezier", + L: "linear", + P: "pass-through" + }; + + /** + * Get the timing point affecting a specific offset + * @param {Integer} offset + * @return {Object} timingPoint + */ + var getTimingPoint = function (offset) { + for (var i = beatmap.timingPoints.length - 1; i >= 0; i--) { + if (beatmap.timingPoints[i].offset <= offset) { return beatmap.timingPoints[i]; } + } + return beatmap.timingPoints[0]; + }; + + /** + * Parse additions member + * @param {String} str additions member (sample:add:customSampleIndex:Volume:hitsound) + * @return {Object} additions a list of additions + */ + var parseAdditions = function (str) { + if (!str) return {}; + + var additions = {}; + var adds = str.split(':'); + + if (adds[0] && adds[0] !== '0') { + var sample; + switch (adds[0]) { + case '1': + sample = 'normal'; + break; + case '2': + sample = 'soft'; + break; + case '3': + sample = 'drum'; + break; + } + additions.sample = sample; + } + + if (adds[1] && adds[1] !== '0') { + var addSample; + switch (adds[1]) { + case '1': + addSample = 'normal'; + break; + case '2': + addSample = 'soft'; + break; + case '3': + addSample = 'drum'; + break; + } + additions.additionalSample = addSample; + } + + if (adds[2] && adds[2] !== '0') { additions.customSampleIndex = parseInt(adds[2]); } + if (adds[3] && adds[3] !== '0') { additions.hitsoundVolume = parseInt(adds[3]); } + if (adds[4]) { additions.hitsound = adds[4]; } + + return additions; + }; + + /** + * Parse a timing line + * @param {String} line + */ + var parseTimingPoint = function (line) { + members = line.split(','); + + var timingPoint = { + offset: parseInt(members[0]), + beatLength: parseFloat(members[1]), + velocity: 1, + timingSignature: parseInt(members[2]), + sampleSetId: parseInt(members[3]), + customSampleIndex: parseInt(members[4]), + sampleVolume: parseInt(members[5]), + timingChange: (members[6] == 1), + kiaiTimeActive: (members[7] == 1) + }; + + if (!isNaN(timingPoint.beatLength) && timingPoint.beatLength !== 0) { + if (timingPoint.beatLength > 0) { + // If positive, beatLength is the length of a beat in milliseconds + var bpm = Math.round(60000 / timingPoint.beatLength); + beatmap.bpmMin = beatmap.bpmMin ? Math.min(beatmap.bpmMin, bpm) : bpm; + beatmap.bpmMax = beatmap.bpmMax ? Math.max(beatmap.bpmMax, bpm) : bpm; + timingPoint.bpm = bpm; + } else { + // If negative, beatLength is a velocity factor + timingPoint.velocity = Math.abs(100 / timingPoint.beatLength); + } + } + + beatmap.timingPoints.push(timingPoint); + }; + + /** + * Parse an object line + * @param {String} line + */ + var parseHitObject = function (line) { + members = line.split(','); + + var soundType = members[4]; + var objectType = members[3]; + + var hitObject = { + startTime: parseInt(members[2]), + newCombo: ((objectType & 4) == 4), + soundTypes: [], + position: [ + parseInt(members[0]), + parseInt(members[1]) + ] + }; + + /** + * sound type is a bitwise flag enum + * 0 : normal + * 2 : whistle + * 4 : finish + * 8 : clap + */ + if ((soundType & 2) == 2) { hitObject.soundTypes.push('whistle'); } + if ((soundType & 4) == 4) { hitObject.soundTypes.push('finish'); } + if ((soundType & 8) == 8) { hitObject.soundTypes.push('clap'); } + if (hitObject.soundTypes.length === 0) { hitObject.soundTypes.push('normal'); } + + /** + * object type is a bitwise flag enum + * 1: circle + * 2: slider + * 8: spinner + */ + if ((objectType & 1) == 1) { + // Circle + beatmap.nbCircles++; + hitObject.objectName = 'circle'; + hitObject.additions = parseAdditions(members[5]); + } else if ((objectType & 8) == 8) { + // Spinner + beatmap.nbSpinners++; + hitObject.objectName = 'spinner'; + hitObject.endTime = parseInt(members[5]); + hitObject.additions = parseAdditions(members[6]); + } else if ((objectType & 2) == 2) { + // Slider + beatmap.nbSliders++; + hitObject.objectName = 'slider'; + hitObject.repeatCount = parseInt(members[6]); + hitObject.pixelLength = parseInt(members[7]); + hitObject.additions = parseAdditions(members[10]); + hitObject.edges = []; + hitObject.points = [ + [hitObject.position[0], hitObject.position[1]] + ]; + + /** + * Calculate slider duration + */ + var timing = getTimingPoint(hitObject.startTime); + + if (timing) { + var pxPerBeat = beatmap.SliderMultiplier * 100 * timing.velocity; + var beatsNumber = (hitObject.pixelLength * hitObject.repeatCount) / pxPerBeat; + hitObject.duration = Math.ceil(beatsNumber * timing.beatLength); + hitObject.endTime = hitObject.startTime + hitObject.duration; + } + /** + * Parse slider points + */ + var points = (members[5] || '').split('|'); + if (points.length) { + hitObject.curveType = curveTypes[points[0]] || 'unknown'; + + for (var i = 1, l = points.length; i < l; i++) { + var coordinates = points[i].split(':'); + hitObject.points.push([ + parseInt(coordinates[0]), + parseInt(coordinates[1]) + ]); + } + } + + var edgeSounds = []; + var edgeAdditions = []; + if (members[8]) { edgeSounds = members[8].split('|'); } + if (members[9]) { edgeAdditions = members[9].split('|'); } + + /** + * Get soundTypes and additions for each slider edge + */ + for (var j = 0, lgt = hitObject.repeatCount + 1; j < lgt; j++) { + var edge = { + soundTypes: [], + additions: parseAdditions(edgeAdditions[j]) + }; + + if (edgeSounds[j]) { + var sound = edgeSounds[j]; + if ((sound & 2) == 2) { edge.soundTypes.push('whistle'); } + if ((sound & 4) == 4) { edge.soundTypes.push('finish'); } + if ((sound & 8) == 8) { edge.soundTypes.push('clap'); } + if (edge.soundTypes.length === 0) { edge.soundTypes.push('normal'); } + } else { + edge.soundTypes.push('normal'); + } + + hitObject.edges.push(edge); + } + + // get coordinates of the slider endpoint + var endPoint = slidercalc.getEndPoint(hitObject.curveType, hitObject.pixelLength, hitObject.points); + if (endPoint && endPoint[0] && endPoint[1]) { + hitObject.endPosition = [ + Math.round(endPoint[0]), + Math.round(endPoint[1]) + ]; + } else { + // If endPosition could not be calculated, approximate it by setting it to the last point + hitObject.endPosition = hitObject.points[hitObject.points.length - 1]; + } + } else { + // Unknown + hitObject.objectName = 'unknown'; + } + + beatmap.hitObjects.push(hitObject); + }; + + /** + * Parse an event line + * @param {String} line + */ + var parseEvent = function (line) { + /** + * Background line : 0,0,"bg.jpg" + * TODO: confirm that the second member is always zero + * + * Breaktimes lines : 2,1000,2000 + * second integer is start offset + * third integer is end offset + */ + members = line.split(','); + + if (members[0] == '0' && members[1] == '0' && members[2]) { + var bgName = members[2].trim(); + + if (bgName.charAt(0) == '"' && bgName.charAt(bgName.length - 1) == '"') { + beatmap.bgFilename = bgName.substring(1, bgName.length - 1); + } else { + beatmap.bgFilename = bgName; + } + } else if (members[0] == 'Video' && members[2]) { + var bgName = members[2].trim(); + + if (bgName.charAt(0) == '"' && bgName.charAt(bgName.length - 1) == '"') { + beatmap.video = bgName.substring(1, bgName.length - 1); + } else { + beatmap.video = bgName; + } + } else if (members[0] == '2' && /^[0-9]+$/.test(members[1]) && /^[0-9]+$/.test(members[2])) { + beatmap.breakTimes.push({ + startTime: parseInt(members[1]), + endTime: parseInt(members[2]) + }); + } + }; + + /** + * Compute the total time and the draining time of the beatmap + */ + var computeDuration = function () { + var firstObject = beatmap.hitObjects[0]; + var lastObject = beatmap.hitObjects[beatmap.hitObjects.length - 1]; + + var totalBreakTime = 0; + + beatmap.breakTimes.forEach(function (breakTime) { + totalBreakTime += (breakTime.endTime - breakTime.startTime); + }); + + if (firstObject && lastObject) { + beatmap.totalTime = Math.floor(lastObject.startTime / 1000); + beatmap.drainingTime = Math.floor((lastObject.startTime - firstObject.startTime - totalBreakTime) / 1000); + } else { + beatmap.totalTime = 0; + beatmap.drainingTime = 0; + } + }; + + /** + * Browse objects and compute max combo + */ + var computeMaxCombo = function () { + if (beatmap.timingPoints.length === 0) { return; } + + var maxCombo = 0; + var sliderMultiplier = parseFloat(beatmap.SliderMultiplier); + var sliderTickRate = parseInt(beatmap.SliderTickRate, 10); + + var timingPoints = beatmap.timingPoints; + var currentTiming = timingPoints[0]; + var nextOffset = timingPoints[1] ? timingPoints[1].offset : Infinity; + var i = 1; + + beatmap.hitObjects.forEach(function (hitObject) { + if (hitObject.startTime >= nextOffset) { + currentTiming = timingPoints[i++]; + nextOffset = timingPoints[i] ? timingPoints[i].offset : Infinity; + } + + var osupxPerBeat = sliderMultiplier * 100 * currentTiming.velocity; + var tickLength = osupxPerBeat / sliderTickRate; + + switch (hitObject.objectName) { + case 'spinner': + case 'circle': + maxCombo++; + break; + case 'slider': + var tickPerSide = Math.ceil((Math.floor(hitObject.pixelLength / tickLength * 100) / 100) - 1); + maxCombo += (hitObject.edges.length - 1) * (tickPerSide + 1) + 1; // 1 combo for each tick and endpoint + } + }); + + beatmap.maxCombo = maxCombo; + }; + + /** + * Read a single line, parse when key/value, store when further parsing needed + * @param {String|Buffer} line + */ + var readLine = function (line) { + line = line.toString().trim(); + if (!line) { return; } + + var match = sectionReg.exec(line); + if (match) { + osuSection = match[1].toLowerCase(); + return; + } + if(line.startsWith("//")) return; + + switch (osuSection) { + case 'timingpoints': + timingLines.push(line); + break; + case 'hitobjects': + objectLines.push(line); + break; + case 'events': + eventsLines.push(line); + break; + default: + if (!osuSection) { + match = /^osu file format (v[0-9]+)$/.exec(line); + if (match) { + beatmap.fileFormat = match[1]; + return; + } + } + + /** + * Apart from events, timingpoints and hitobjects sections, lines are "key: value" + */ + match = keyValReg.exec(line); + if (match) { beatmap[match[1]] = match[2]; } + } + }; + + /** + * Compute everything that require the file to be completely parsed and return the beatmap + * @return {Object} beatmap + */ + var buildBeatmap = function () { + if (beatmap.Tags) { + beatmap.tagsArray = beatmap.Tags.split(' '); + } + + eventsLines.forEach(parseEvent); + beatmap.breakTimes.sort(function (a, b) { return (a.startTime > b.startTime ? 1 : -1); }); + + timingLines.forEach(parseTimingPoint); + beatmap.timingPoints.sort(function (a, b) { return (a.offset > b.offset ? 1 : -1); }); + + var timingPoints = beatmap.timingPoints; + + for (var i = 1, l = timingPoints.length; i < l; i++) { + if (!timingPoints[i].hasOwnProperty('bpm')) { + timingPoints[i].beatLength = timingPoints[i - 1].beatLength; + timingPoints[i].bpm = timingPoints[i - 1].bpm; + } + } + + objectLines.forEach(parseHitObject); + beatmap.hitObjects.sort(function (a, b) { return (a.startTime > b.startTime ? 1 : -1); }); + + computeMaxCombo(); + computeDuration(); + + return beatmap; + }; + + return { + readLine: readLine, + buildBeatmap: buildBeatmap + }; +} + + + +/** + * Parse a .osu file + * @param {String} file path to the file + * @param {Function} callback(err, beatmap) + */ +exports.parseFile = function (file, callback) { + if (!fs.existsSync(file)) { + callback(new Error('File does not exist')); + return; + } + + var parser = beatmapParser(); + var stream = fs.createReadStream(file); + var buffer = ''; + + + stream.on('data', function (chunk) { + buffer += chunk; + var lines = buffer.split(/\r?\n/); + buffer = lines.pop() || ''; + lines.forEach(parser.readLine); + }); + + stream.on('error', function (err) { + callback(err); + }); + + stream.on('end', function () { + buffer.split(/\r?\n/).forEach(parser.readLine); + callback(null, parser.buildBeatmap()); + }); +}; + +/** + * Parse a stream containing .osu content + * @param {Stream} stream + * @param {Function} callback(err, beatmap) + */ +exports.parseStream = function (stream, callback) { + var parser = beatmapParser(); + var buffer = ''; + + stream.on('data', function (chunk) { + buffer += chunk.toString(); + var lines = buffer.split(/\r?\n/); + buffer = lines.pop() || ''; + lines.forEach(parser.readLine); + }); + + stream.on('error', function (err) { + callback(err); + }); + + stream.on('end', function () { + buffer.split(/\r?\n/).forEach(parser.readLine); + callback(null, parser.buildBeatmap()); + }); +}; + +/** + * Parse the content of a .osu + * @param {String|Buffer} content + * @return {Object} beatmap + */ +exports.parseContent = function (content) { + var parser = beatmapParser(); + content.toString().split(/[\n\r]+/).forEach(function (line) { + parser.readLine(line); + }); + + return parser.buildBeatmap(); +}; \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte index a93dc29..c595481 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -1,18 +1,59 @@ - + - + diff --git a/src/Menu.svelte b/src/Menu.svelte index a2b1d31..367900e 100644 --- a/src/Menu.svelte +++ b/src/Menu.svelte @@ -1,17 +1,20 @@ last = Date.now()} on:wheel={e => updateVolume(e)} /> - 2000}> - {#if song} - - {song.artist} - {song.song} - - - - - - + {#if now - last < config.autohide.info + 1000} + config.autohide.info}> + {#if song} + + {song.artist} - {song.song} + + + + + + + + settingsOpen = !settingsOpen}> + + - - {/if} - - {#if now - lastVolumeUpdate < 4000 && song && song.audio} - 2000}> + {/if} + + {/if} + {#if now - lastVolumeUpdate < config.autohide.volume + 1000 && song && song.audio} + config.autohide.volume}> {Math.round(song.audio.volume * 100)}% + + + {/if} + \ No newline at end of file diff --git a/src/Visualizer.svelte b/src/Visualizer.svelte index a0bc2f3..dc24a80 100644 --- a/src/Visualizer.svelte +++ b/src/Visualizer.svelte @@ -1,10 +1,11 @@ @@ -101,13 +147,24 @@ - - + {#if songData && songData.beatmap && songData.beatmap.video && config.videoBackground} + + + + + {/if} + + \ No newline at end of file diff --git a/src/components/options.svelte b/src/components/options.svelte new file mode 100644 index 0000000..9ec5cc8 --- /dev/null +++ b/src/components/options.svelte @@ -0,0 +1,89 @@ + + + + visible = false}> + + Options + + + Parallax + + Enable parallax + + + + Parallax treshold + + + + + Integrations + + Discord Rich Presence + + + + MediaSession (system-wide controls) + + + + + Backgrounds + + Osu!wallpapers + Beatmap wallpapers + + + Video backgrounds + + + + + UI + + Song info hide timeout + + + + Volume hide timeout + + + + + + + \ No newline at end of file diff --git a/src/index.js b/src/index.js index 2b07f8a..7544a9d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,38 +1,43 @@ const { app, BrowserWindow } = require('electron'); const isDev = require('electron-is-dev'); +const RPC = require("discord-rpc"); +const rpc = new RPC.Client({ transport: "ipc" }); const path = require('path'); // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (require('electron-squirrel-startup')) { // eslint-disable-line global-require - app.quit(); + app.quit(); } -if(!isDev) require('update-electron-app')() +if (!isDev) require('update-electron-app')() app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required'); +var mainWindow; + const createWindow = () => { - // Create the browser window. - const mainWindow = new BrowserWindow({ - width: 800, - height: 600, - webPreferences: { - nodeIntegration: true - }, - autoHideMenuBar: true - }); - mainWindow.setMenu(null); + // Create the browser window. + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: true, + enableRemoteModule: true + }, + autoHideMenuBar: true + }); + mainWindow.setMenu(null); - // and load the index.html of the app. - mainWindow.loadFile(path.join(__dirname, '../public/index.html')); + // and load the index.html of the app. + mainWindow.loadFile(path.join(__dirname, '../public/index.html')); - // Open the DevTools. - mainWindow.webContents.openDevTools(); + // Open the DevTools. + if(isDev) mainWindow.webContents.openDevTools(); }; require('electron-reload')(__dirname, { - electron: path.join(__dirname, '../node_modules', '.bin', 'electron'), - awaitWriteFinish: true, + electron: path.join(__dirname, '../node_modules', '.bin', 'electron'), + awaitWriteFinish: true, }); // This method will be called when Electron has finished @@ -44,18 +49,39 @@ app.on('ready', createWindow); // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { - app.quit(); - } + if (process.platform !== 'darwin') { + app.quit(); + } }); app.on('activate', () => { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } }); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and import them here. + +async function setActivity() { + if (!rpc || !mainWindow) { + return; + } + + const activity = await mainWindow.webContents.executeJavaScript('window.songActivity'); + + rpc.setActivity(activity); +} + +rpc.on('ready', () => { + setActivity(); + + // activity can only be set every 15 seconds + setInterval(() => { + setActivity(); + }, 15e3); +}); + +rpc.login({ clientId: "756806736106618951" }); \ No newline at end of file