Compare commits

..

10 Commits

Author SHA1 Message Date
d144d1f989
Update README.md 2023-05-09 19:00:14 +03:00
77ed4a6de6
fix: stuff 2023-05-09 18:41:58 +03:00
eba9e8b5d0
fix: correct url copy 2023-05-09 18:01:56 +03:00
2fc154f8a4
feat: add opengraph metadata 2023-05-09 17:57:53 +03:00
54ddf32e21
fix: dont copy scheme in share 2023-05-09 17:32:21 +03:00
9a0d05df94
fix: dynamic -> static 2023-05-09 17:23:30 +03:00
fff0144fd4
fix: use public mq url for public stuff 2023-05-09 17:21:47 +03:00
76021dcf70
fix: use separate env var for server side address of musikquad 2023-05-09 17:17:46 +03:00
d72b4214b8
refactor: use deno adapter 2023-05-09 17:06:28 +03:00
d9e5a64e52
feat: implement share support 2023-05-09 16:38:04 +03:00
30 changed files with 860 additions and 516 deletions

View File

@ -6,6 +6,8 @@ node_modules
.env .env
.env.* .env.*
!.env.example !.env.example
/result
/.direnv
# Ignore files for PNPM, NPM and YARN # Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml pnpm-lock.yaml

View File

@ -1,4 +1,4 @@
{ {
"svelte.enable-ts-plugin": true, "svelte.enable-ts-plugin": true,
"editor.tabSize": 2 "editor.tabSize": 2
} }

View File

@ -1,4 +1,6 @@
`musikspider` is a web client that works with `musikquadrupled`. It is made using SvelteKit. `musikspider` is a web client that works with `musikquadrupled`. It is made using SvelteKit. WIP.
![image](https://github.com/yusdacra/musikspider/assets/19897088/d5b407cf-ea14-4c62-af79-453fed84bace)
# Development # Development
@ -17,4 +19,4 @@ A production build is also available at `packages.x86_64-linux.musikspider`.
- [ ] implement persistence of music data, playlists and such - [ ] implement persistence of music data, playlists and such
- [ ] implement scrobbling (last.fm, etc) - [ ] implement scrobbling (last.fm, etc)
- [ ] implement discord status - [ ] implement discord status
- [ ] add tauri app? - [ ] add tauri app?

View File

@ -20,11 +20,7 @@
}: { }: {
devShells.default = config.mk-naked-shell.lib.mkNakedShell { devShells.default = config.mk-naked-shell.lib.mkNakedShell {
name = "musikspider-devshell"; name = "musikspider-devshell";
packages = with pkgs; [ packages = with pkgs; [nodejs yarn deno];
nodejs
yarn
yarn2nix
];
}; };
packages.musikspider = pkgs.mkYarnPackage { packages.musikspider = pkgs.mkYarnPackage {
src = ./.; src = ./.;

View File

@ -15,8 +15,6 @@
"@iconify-json/line-md": "^1.1.24", "@iconify-json/line-md": "^1.1.24",
"@iconify-json/mdi": "^1.1.50", "@iconify-json/mdi": "^1.1.50",
"@skeletonlabs/skeleton": "^1.2.5", "@skeletonlabs/skeleton": "^1.2.5",
"@sveltejs/adapter-auto": "^2.0.1",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "^1.15.9", "@sveltejs/kit": "^1.15.9",
"@typescript-eslint/eslint-plugin": "^5.59.1", "@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1", "@typescript-eslint/parser": "^5.59.1",
@ -28,6 +26,7 @@
"prettier": "^2.8.8", "prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.0", "prettier-plugin-svelte": "^2.10.0",
"svelte": "^3.58.0", "svelte": "^3.58.0",
"svelte-adapter-deno": "^0.9.0",
"svelte-check": "^3.2.0", "svelte-check": "^3.2.0",
"tailwindcss": "^3.3.2", "tailwindcss": "^3.3.2",
"tslib": "^2.5.0", "tslib": "^2.5.0",

View File

@ -1,6 +1,6 @@
export default { export default {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {}
}, }
} };

View File

@ -1,15 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="dark" lang="en"> <html class="dark" lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<head> <body data-sveltekit-preload-data="hover" data-theme="crimson">
<meta charset="utf-8" /> <div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> </body>
<meta name="viewport" content="width=device-width" /> </html>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" data-theme="crimson">
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

View File

@ -1,2 +1,7 @@
html, body { @apply h-full overflow-hidden; } html,
.card { @apply shadow shadow-black; } body {
@apply h-full overflow-hidden;
}
.card {
@apply shadow shadow-black;
}

View File

@ -1,174 +1,176 @@
import { dev } from '$app/environment'; import { dev } from '$app/environment';
import type { TrackWithId } from "./types"; import type { TrackWithId } from './types';
const API_VERSION: number = 20; const API_VERSION: number = 20;
const HTTP_DISABLED_ERROR: string = const HTTP_DISABLED_ERROR: string =
"server does not have HTTP resources enabled, you will not be able to stream music"; 'server does not have HTTP resources enabled, you will not be able to stream music';
const SERVER_API_INCOMPATIBLE_ERROR: (serverApi: number) => string = const SERVER_API_INCOMPATIBLE_ERROR: (serverApi: number) => string = (serverApi) =>
(serverApi) => `server API version (${serverApi}) is different from our supported version (${API_VERSION})`; `server API version (${serverApi}) is different from our supported version (${API_VERSION})`;
interface Message { interface Message {
name: string; name: string;
id: string; id: string;
device_id: string; device_id: string;
type: MessageType; type: MessageType;
options: any; options: any;
}; }
type MessageType = 'request' | 'response' | 'broadcast'; type MessageType = 'request' | 'response' | 'broadcast';
type RequestCallback = (arg0: Message | null) => void; type RequestCallback = (arg0: Message | null) => void;
interface Callbacks { interface Callbacks {
onDisconnect: (authenticated: boolean, reason: string) => void; onDisconnect: (authenticated: boolean, reason: string) => void;
onConnect: (initial: Message) => void; onConnect: (initial: Message) => void;
onIncompatible: (reason: string) => void; onIncompatible: (reason: string) => void;
} }
export class MetadataCommunicator { export class MetadataCommunicator {
ws: WebSocket | null; ws: WebSocket | null;
deviceId: string; deviceId: string;
callbacks: Map<string, RequestCallback>; callbacks: Map<string, RequestCallback>;
authenticated: boolean; authenticated: boolean;
eventCallbacks: Callbacks; eventCallbacks: Callbacks;
onConnectCallbacks: (() => void)[]; onConnectCallbacks: (() => void)[];
constructor() { constructor() {
this.callbacks = new Map(); this.callbacks = new Map();
this.deviceId = crypto.randomUUID(); this.deviceId = crypto.randomUUID();
this.authenticated = false; this.authenticated = false;
this.eventCallbacks = { this.eventCallbacks = {
onDisconnect: () => { }, onDisconnect: () => {},
onConnect: () => { }, onConnect: () => {},
onIncompatible: () => { }, onIncompatible: () => {}
}; };
this.onConnectCallbacks = []; this.onConnectCallbacks = [];
this.ws = null; this.ws = null;
} }
setCallbacks(callbacks: Callbacks) { setCallbacks(callbacks: Callbacks) {
this.eventCallbacks = callbacks; this.eventCallbacks = callbacks;
} }
connect(address: string, password: string) { connect(address: string, password: string) {
this.close(); this.close();
const scheme = dev ? "ws" : "wss"; const scheme = dev ? 'ws' : 'wss';
this.ws = new WebSocket(`${scheme}://${address}`); this.ws = new WebSocket(`${scheme}://${address}`);
this.ws.addEventListener('open', (event) => { this.ws.addEventListener('open', (event) => {
this.makeRequest("authenticate", 'request', { password }, (msg) => { this.makeRequest('authenticate', 'request', { password }, (msg) => {
if (msg!.options.authenticated) { if (msg!.options.authenticated) {
this.authenticated = true; this.authenticated = true;
this.eventCallbacks.onConnect(msg!); this.eventCallbacks.onConnect(msg!);
this.onConnectCallbacks.forEach((f) => f()); this.onConnectCallbacks.forEach((f) => f());
this.onConnectCallbacks = []; this.onConnectCallbacks = [];
if (!msg!.options.environment.http_server_enabled) { if (!msg!.options.environment.http_server_enabled) {
this.eventCallbacks.onIncompatible(HTTP_DISABLED_ERROR); this.eventCallbacks.onIncompatible(HTTP_DISABLED_ERROR);
} }
const serverApiVersion = msg!.options.environment.api_version; const serverApiVersion = msg!.options.environment.api_version;
if (serverApiVersion != API_VERSION) { if (serverApiVersion != API_VERSION) {
this.eventCallbacks.onIncompatible(SERVER_API_INCOMPATIBLE_ERROR(serverApiVersion)); this.eventCallbacks.onIncompatible(SERVER_API_INCOMPATIBLE_ERROR(serverApiVersion));
} }
} }
}); });
}); });
this.ws.addEventListener('close', (event) => { this.ws.addEventListener('close', (event) => {
this.eventCallbacks.onDisconnect(this.authenticated, `${event.reason} (code ${event.code})`); this.eventCallbacks.onDisconnect(this.authenticated, `${event.reason} (code ${event.code})`);
this.authenticated = false; this.authenticated = false;
}); });
this.ws.addEventListener('message', (event) => { this.ws.addEventListener('message', (event) => {
const parsed: Message = JSON.parse(event.data); const parsed: Message = JSON.parse(event.data);
const maybeCallback = this.callbacks.get(parsed.id); const maybeCallback = this.callbacks.get(parsed.id);
if (maybeCallback) { if (maybeCallback) {
maybeCallback(parsed); maybeCallback(parsed);
this.callbacks.delete(parsed.id); this.callbacks.delete(parsed.id);
} }
}); });
} }
fetchTracksCount(): Promise<number> { fetchTracksCount(): Promise<number> {
const options = { count_only: true }; const options = { count_only: true };
const th = this; const th = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
th.makeRequest("query_tracks", "request", options, (resp) => { th.makeRequest('query_tracks', 'request', options, (resp) => {
if (resp) { if (resp) {
resolve(resp.options.count); resolve(resp.options.count);
} else { } else {
reject(null); reject(null);
} }
}); });
}); });
} }
fetchTracks(limit: number, offset: number, filter: string | null = null): Promise<TrackWithId[]> { fetchTracks(limit: number, offset: number, filter: string | null = null): Promise<TrackWithId[]> {
const options: any = { limit, offset }; const options: any = { limit, offset };
if (filter !== null) options.filter = filter; if (filter !== null) options.filter = filter;
const th = this; const th = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
th.makeRequest("query_tracks", "request", options, (resp) => { th.makeRequest('query_tracks', 'request', options, (resp) => {
if (resp) { if (resp) {
const data: any[] = resp.options.data; const data: any[] = resp.options.data;
resolve(data.map((t) => ({ resolve(
id: t.external_id, data.map((t) => ({
track: { id: t.external_id,
id: t.id, track: {
title: t.title, id: t.id,
track_num: t.track, title: t.title,
album_title: t.album, track_num: t.track,
album_id: t.album_id, album_title: t.album,
artist_name: t.artist, album_id: t.album_id,
artist_id: t.artist_id, artist_name: t.artist,
thumbnail_id: t.thumbnail_id, artist_id: t.artist_id,
} thumbnail_id: t.thumbnail_id
}))); }
} else { }))
reject(null); );
} } else {
}); reject(null);
}); }
} });
});
}
private makeRequest(name: string, type: MessageType, options: object, callback: RequestCallback) { private makeRequest(name: string, type: MessageType, options: object, callback: RequestCallback) {
// return if not authenticated, allow authentication messages // return if not authenticated, allow authentication messages
if (this.isClosed() || !this.authenticated && name != "authenticate") { if (this.isClosed() || (!this.authenticated && name != 'authenticate')) {
callback(null); callback(null);
return; return;
} }
// Unique enough for our purposes (as request ID) // Unique enough for our purposes (as request ID)
const id = Math.random().toString(36).substring(2) + Date.now().toString(36); const id = Math.random().toString(36).substring(2) + Date.now().toString(36);
this.callbacks.set(id, callback); this.callbacks.set(id, callback);
const payload = JSON.stringify({ const payload = JSON.stringify({
name, name,
type, type,
options, options,
device_id: this.deviceId, device_id: this.deviceId,
id, id
}); });
console.trace("sending metadata message: " + payload); console.trace('sending metadata message: ' + payload);
this.ws!.send(payload); this.ws!.send(payload);
} }
close() { close() {
if (this.isClosed()) return; if (this.isClosed()) return;
this.ws!.close(); this.ws!.close();
this.authenticated = false; this.authenticated = false;
this.callbacks.clear(); this.callbacks.clear();
} }
isClosed() { isClosed() {
return ( return (
this.ws === null this.ws === null ||
|| this.ws.readyState === WebSocket.CLOSED this.ws.readyState === WebSocket.CLOSED ||
|| this.ws.readyState === WebSocket.CLOSING this.ws.readyState === WebSocket.CLOSING
); );
} }
onConnect(cb: () => Promise<void>) { onConnect(cb: () => Promise<void>) {
if (!this.isClosed() && this.authenticated) { if (!this.isClosed() && this.authenticated) {
cb(); cb();
} else { } else {
this.onConnectCallbacks = [...this.onConnectCallbacks, cb]; this.onConnectCallbacks = [...this.onConnectCallbacks, cb];
} }
} }
} }

View File

@ -3,8 +3,9 @@
export let href: string; export let href: string;
export let title: string = ''; export let title: string = '';
let targetId = href === '/' ? '/(app)' : `/(app)${href}`;
$: isOnPage = href === $page.route.id; $: isOnPage = targetId === $page.route.id;
</script> </script>
<a <a

View File

@ -18,7 +18,7 @@
<Link title={link.id} href={link.href ?? `/${link.id}`}> <Link title={link.id} href={link.href ?? `/${link.id}`}>
<svelte:component this={link.icon} class="w-7 h-7" /> <svelte:component this={link.icon} class="w-7 h-7" />
</Link> </Link>
{#if link.id === 'search' && $page.route.id === '/'} {#if link.id === 'search' && $page.route.id === '/(app)'}
<input <input
id="search-input" id="search-input"
class="input rounded-none" class="input rounded-none"

View File

@ -7,7 +7,6 @@
muted, muted,
paused, paused,
nextQueuePosition, nextQueuePosition,
getAudioElement,
loop, loop,
queuePosition, queuePosition,
prevQueuePosition prevQueuePosition
@ -17,23 +16,13 @@
import IconMusic from '~icons/mdi/music'; import IconMusic from '~icons/mdi/music';
import { RangeSlider } from '@skeletonlabs/skeleton'; import { RangeSlider } from '@skeletonlabs/skeleton';
import { LoopKind } from '../types'; import { LoopKind } from '../types';
import { calculateMinuteSecond, getAudioElement } from '../utils';
$: track = $currentTrack?.track; $: track = $currentTrack?.track;
$: track_id = $currentTrack?.id; $: track_id = $currentTrack?.id;
$: thumbUrl = track ? makeThumbnailUrl(track.thumbnail_id) : null; $: thumbUrl = track ? makeThumbnailUrl(track.thumbnail_id) : null;
$: audioUrl = track_id ? makeAudioUrl(track_id) : null; $: audioUrl = track_id ? makeAudioUrl(track_id) : null;
function calculateMinuteSecond(seconds: number) {
let secs = Math.floor(seconds);
let secsLeftover = secs % 60;
let minutes = (secs - secsLeftover) / 60;
let secondsFormatted = secsLeftover < 10 ? `0${secsLeftover}` : `${secsLeftover}`;
let minutesFormatted = minutes < 10 ? `0${minutes}` : `${minutes}`;
return `${minutesFormatted}:${secondsFormatted}`;
}
let currentTime = 0; let currentTime = 0;
let duration = 0; let duration = 0;

View File

@ -1,9 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { TrackWithId } from '../types'; import type { TrackWithId } from '../types';
import { makeThumbnailUrl, currentTrack, setQueuePositionTo, getAudioElement } from '../stores'; import {
makeThumbnailUrl,
currentTrack,
setQueuePositionTo,
makeGenScopedTokenUrl
} from '../stores';
import Spinnny from '~icons/line-md/loading-loop'; import Spinnny from '~icons/line-md/loading-loop';
import IconPlay from '~icons/mdi/play'; import IconPlay from '~icons/mdi/play';
import IconMusic from '~icons/mdi/music'; import IconMusic from '~icons/mdi/music';
import { toastStore } from '@skeletonlabs/skeleton';
import { getAudioElement, makeShareUrl } from '../utils';
export let track_with_id: TrackWithId; export let track_with_id: TrackWithId;
let track = track_with_id.track; let track = track_with_id.track;
@ -13,6 +20,23 @@
let showSpinner = false; let showSpinner = false;
let isError = false; let isError = false;
let showPlayIcon = false; let showPlayIcon = false;
async function shareMusic() {
try {
const resp = await fetch(makeGenScopedTokenUrl(track_id));
const shareToken = await resp.text();
await navigator.clipboard.writeText(makeShareUrl(shareToken));
toastStore.trigger({
message: `copied share URL to clipboard`,
background: 'variant-filled-success'
});
} catch (e) {
toastStore.trigger({
message: `error while generating share URL: ${e}`,
background: 'variant-filled-error'
});
}
}
</script> </script>
<div class="flex gap-2 w-fit max-w-full"> <div class="flex gap-2 w-fit max-w-full">
@ -36,22 +60,29 @@
: 'hidden'}" : 'hidden'}"
/> />
<!-- svelte-ignore a11y-missing-attribute --> <!-- svelte-ignore a11y-missing-attribute -->
<img {#if thumbUrl !== null}
src={thumbUrl} <img
class="child {showSpinner || isError ? 'hidden' : ''}" src={thumbUrl}
on:error={() => { class="child {showSpinner || isError ? 'hidden' : ''}"
isError = true; on:error={() => {
showSpinner = false; isError = true;
}} showSpinner = false;
on:loadstart={() => (showSpinner = true)} }}
on:load={() => (showSpinner = false)} on:loadstart={() => (showSpinner = true)}
/> on:load={() => (showSpinner = false)}
/>
{/if}
<IconPlay <IconPlay
class="child play-icon variant-glass-surface {showPlayIcon ? 'opacity-100' : 'opacity-0'}" class="child play-icon variant-glass-surface {showPlayIcon ? 'opacity-100' : 'opacity-0'}"
/> />
</button> </button>
<div class="whitespace-nowrap overflow-ellipsis overflow-hidden"> <div class="whitespace-nowrap overflow-ellipsis overflow-hidden">
<span>#{track.track_num} - {track.title}</span> <span>#{track.track_num} - {track.title}</span>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<span
class="chip variant-soft-secondary hover:variant-filled-secondary py-0.5 px-2"
on:click={shareMusic}>share</span
>
<div class="text-sm whitespace-nowrap overflow-ellipsis overflow-hidden"> <div class="text-sm whitespace-nowrap overflow-ellipsis overflow-hidden">
<span <span
class="badge variant-filled-primary py-0.5 {$currentTrack?.id === track_id class="badge variant-filled-primary py-0.5 {$currentTrack?.id === track_id

View File

@ -3,26 +3,26 @@
import '@skeletonlabs/skeleton/themes/theme-crimson.css'; import '@skeletonlabs/skeleton/themes/theme-crimson.css';
// This contains the bulk of Skeletons required styles: // This contains the bulk of Skeletons required styles:
import '@skeletonlabs/skeleton/styles/all.css'; import '@skeletonlabs/skeleton/styles/all.css';
import '../app.postcss'; import '../../app.postcss';
import { AppShell, Toast, toastStore } from '@skeletonlabs/skeleton'; import { AppShell, Toast, toastStore } from '@skeletonlabs/skeleton';
import { import {
address, address,
changeLoop, changeLoop,
currentTrack, currentTrack,
getAudioElement,
muted, muted,
paused, paused,
queuePosition, queuePosition,
token, token,
tracks, tracks,
tracksSorted tracksSorted
} from '../stores'; } from '../../stores';
import { _metadataComm as comm } from './+layout'; import { _metadataComm as comm } from './+layout';
import Navbar from '../components/navbar.svelte'; import Navbar from '../../components/navbar.svelte';
import PlayingNow from '../components/playingnow.svelte'; import PlayingNow from '../../components/playingnow.svelte';
import VolumeSlider from '../components/volumeSlider.svelte'; import VolumeSlider from '../../components/volumeSlider.svelte';
import LoopButton from '../components/loopButton.svelte'; import LoopButton from '../../components/loopButton.svelte';
import { getAudioElement, interceptKeys } from '../../utils';
$: title = $currentTrack !== null ? `${$currentTrack.track.title} - musikspider` : `musikspider`; $: title = $currentTrack !== null ? `${$currentTrack.track.title} - musikspider` : `musikspider`;
@ -78,45 +78,16 @@
message: `Fetched ${count} tracks`, message: `Fetched ${count} tracks`,
background: 'variant-filled-success' background: 'variant-filled-success'
}); });
comm.close();
}); });
</script> </script>
<svelte:window <svelte:window
on:keydown={(event) => { on:keydown={interceptKeys([
const tagName = document.activeElement?.tagName ?? ''; ['KeyS', () => document.getElementById('search-input')?.focus()],
const actions = new Map([ ['KeyL', changeLoop]
['Space', () => ($paused = !$paused)], ])}
['KeyL', changeLoop],
['KeyM', () => ($muted = !$muted)],
['KeyS', () => document.getElementById('search-input')?.focus()],
[
'ArrowLeft',
() => {
const audio = getAudioElement();
if (audio !== null) {
audio.currentTime -= 5;
}
}
],
[
'ArrowRight',
() => {
const audio = getAudioElement();
if (audio !== null) {
audio.currentTime += 5;
}
}
]
]);
if (tagName !== 'INPUT' && actions.has(event.code)) {
event.preventDefault();
event.stopPropagation();
const action = actions.get(event.code) ?? null;
if (action !== null) {
action();
}
}
}}
/> />
<svelte:head> <svelte:head>

View File

@ -0,0 +1,5 @@
import { MetadataCommunicator } from '../../comms';
export const _metadataComm = new MetadataCommunicator();
export const ssr = false;
export const prerender = true;

View File

@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import VirtualList from 'svelte-tiny-virtual-list'; import VirtualList from 'svelte-tiny-virtual-list';
import { queue, tracks, tracksSorted } from '../stores'; import { tracks, tracksSorted } from '../../stores';
import TrackComponent from '../components/track.svelte'; import TrackComponent from '../../components/track.svelte';
import type { Track, TrackWithId } from '../types'; import type { TrackWithId } from '../../types';
$: trackCount = $tracksSorted.length; $: trackCount = $tracksSorted.length;
let trackItemSize = 62; let trackItemSize = 62;

View File

@ -1,10 +1,9 @@
<script lang="ts"> <script lang="ts">
import VirtualList from 'svelte-tiny-virtual-list'; import VirtualList from 'svelte-tiny-virtual-list';
import { currentTrack, queue, queuePosition, tracks } from '../../stores'; import { currentTrack, queue, queuePosition, tracks } from '../../../stores';
import TrackComponent from '../../components/track.svelte'; import TrackComponent from '../../../components/track.svelte';
import type { TrackWithId } from '../../types'; import type { TrackWithId } from '../../../types';
import IconRemove from '~icons/mdi/minus-thick'; import IconRemove from '~icons/mdi/minus-thick';
import { get } from 'svelte/store';
$: trackCount = $queue.length; $: trackCount = $queue.length;
let trackItemSize = 62; let trackItemSize = 62;

View File

@ -1,5 +1,5 @@
<script> <script>
import { token, address } from '../../stores'; import { token, address } from '../../../stores';
import Input from './input.svelte'; import Input from './input.svelte';
import { _metadataComm as comm } from '../+layout'; import { _metadataComm as comm } from '../+layout';

View File

@ -1,6 +0,0 @@
import { MetadataCommunicator } from "../comms";
export const ssr = false;
export const prerender = true;
export const _metadataComm = new MetadataCommunicator();

View File

@ -0,0 +1,2 @@
export const ssr = true;
export const prerender = false;

View File

@ -0,0 +1,31 @@
import { PUBLIC_MUSIKQUAD_SERVER } from '$env/static/public';
import { LOCAL_MUSIKQUAD_SERVER } from '$env/static/private';
import { scheme } from '../../../utils';
interface MusicInfo {
title: string;
album: string;
artist: string;
}
export async function load({ params }) {
const token = params.token;
let color = '#222222';
const resp = await fetch(`${LOCAL_MUSIKQUAD_SERVER}/share/info/${token}`);
const info: MusicInfo = await resp.json();
/*const thumb_resp = await fetch(`${LOCAL_MUSIKQUAD_SERVER}/share/thumbnail/${token}`);
if (thumb_resp.ok) {
const thumb = await thumb_resp.blob();
const rawColor = await getColor(thumb);
color = rgbToHex(rawColor[0], rawColor[1], rawColor[2]);
}*/
return {
info,
color,
thumbnail_url: `${scheme}://${PUBLIC_MUSIKQUAD_SERVER}/share/thumbnail/${token}`,
audio_url: `${scheme}://${PUBLIC_MUSIKQUAD_SERVER}/share/audio/${token}`
};
}

View File

@ -0,0 +1,125 @@
<script lang="ts">
// Your selected Skeleton theme:
import '@skeletonlabs/skeleton/themes/theme-crimson.css';
// This contains the bulk of Skeletons required styles:
import '@skeletonlabs/skeleton/styles/all.css';
import '../../../app.postcss';
import IconMusic from '~icons/mdi/music';
import IconPlay from '~icons/mdi/play';
import IconPause from '~icons/mdi/pause';
import { RangeSlider } from '@skeletonlabs/skeleton';
import { calculateMinuteSecond, getAudioElement, interceptKeys } from '../../../utils';
export let data;
function getAlbumArtistInfo() {
const hasArtist = data.info.artist;
const hasAlbum = data.info.album;
if (hasArtist && hasAlbum) {
return `from ${data.info.album}\nby ${data.info.artist}`;
} else if (hasArtist) {
return `by ${data.info.artist}`;
} else if (hasAlbum) {
return `from ${data.info.album}`;
} else {
return '';
}
}
let showIcon = false;
let isError = false;
let paused = false;
let currentTime = 0;
let duration = 0;
</script>
<svelte:window on:keydown={interceptKeys()} />
<svelte:head>
<title>{data.info.title} {data.info.artist !== '' ? `- ${data.info.artist}` : ''}</title>
<meta property="og:title" content={data.info.title} />
<meta property="og:description" content={getAlbumArtistInfo()} />
<meta property="og:image" content={data.thumbnail_url} />
<meta property="og:audio" content={data.audio_url} />
<meta name="theme-color" content={data.color} />
</svelte:head>
<div
class="
absolute top-[50%] left-[50%] -translate-x-[50%] -translate-y-[50%]
flex w-fit max-w-full p-2 gap-2 rounded
"
>
<audio
id="audio-source"
src={data.audio_url}
autoplay
bind:paused
bind:currentTime
bind:duration
/>
<button
class="relative rounded placeholder w-16 h-16"
on:pointerenter={(_) => (showIcon = true)}
on:pointerleave={(_) => (showIcon = false)}
on:click={(_) => {
let elem = getAudioElement();
if (elem) {
elem.paused ? elem.play() : elem.pause();
}
}}
>
<IconMusic class="absolute top-1 left-1 w-14 h-14" />
<!-- svelte-ignore a11y-missing-attribute -->
<img
src={data.thumbnail_url}
class="child {isError ? 'hidden' : ''}"
on:error={() => (isError = true)}
on:load={() => (isError = false)}
/>
<svelte:component
this={paused ? IconPlay : IconPause}
class="
child play-icon variant-glass-surface
{showIcon ? 'opacity-100' : 'opacity-0'}
"
/>
</button>
<div class="flex flex-col gap-1 w-[24rem] max-md:w-[18rem]">
<div class="text-overflow-ellipsis">
<span>{data.info.title}</span>
<div class="text-sm text-overflow-ellipsis">
<span class="opacity-70">{data.info.album !== '' ? `from ${data.info.album}` : ''}</span>
<span class="opacity-40">{data.info.artist !== '' ? `by ${data.info.artist}` : ''}</span>
</div>
</div>
<div class="flex items-center gap-1">
<RangeSlider
name="progress"
bind:value={currentTime}
max={duration}
step={0.01}
class="w-[22rem] max-md:w-[16rem]"
/>
<span class="text-xs opacity-70 w-[2rem]">{calculateMinuteSecond(currentTime)}</span>
</div>
</div>
</div>
<style lang="postcss">
button :global(.play-icon) {
@apply transition-opacity backdrop-blur-sm;
}
button :global(.child) {
@apply absolute rounded top-0 left-0 w-16 h-16;
}
div :global(.range-content) {
@apply p-0;
}
div :global(.text-overflow-ellipsis) {
@apply whitespace-nowrap overflow-ellipsis overflow-hidden;
}
</style>

View File

@ -1,44 +1,55 @@
import { get, writable } from 'svelte/store'; import { get, writable } from 'svelte/store';
import { type ResourceId, type Track, type TrackId, type TrackWithId, LoopKind } from './types'; import { type Track, type TrackId, type TrackWithId, LoopKind } from './types';
import { dev } from '$app/environment';
import { PUBLIC_MUSIKQUAD_SERVER } from '$env/static/public';
import { scheme } from './utils';
function writableStorage(key: string, defaultValue: string) { function writableStorage(key: string, defaultValue: string) {
const store = writable(localStorage.getItem(key) ?? defaultValue); const store = writable(localStorage.getItem(key) ?? defaultValue);
store.subscribe(value => localStorage.setItem(key, value)); store.subscribe((value) => localStorage.setItem(key, value));
return store; return store;
} }
export const address = writableStorage("address", "127.0.0.1:5505"); export const address = writableStorage('address', PUBLIC_MUSIKQUAD_SERVER);
export const token = writableStorage("token", ""); export const token = writableStorage('token', '');
export function makeThumbnailUrl(id: ResourceId) { export function makeThumbnailUrl(id: number) {
const scheme = dev ? "http" : "https"; if (id === 0) {
return `${scheme}://${get(address)}/thumbnail/${id}?token=${get(token)}`; return null;
}
return `${scheme}://${get(address)}/thumbnail/${id}?token=${get(token)}`;
} }
export function makeAudioUrl(id: TrackId) { export function makeAudioUrl(id: TrackId) {
const scheme = dev ? "http" : "https"; return `${scheme}://${get(address)}/audio/external_id/${id}?token=${get(token)}`;
return `${scheme}://${get(address)}/audio/external_id/${id}?token=${get(token)}`; }
export function makeGenScopedTokenUrl(id: TrackId) {
return `${scheme}://${get(address)}/share/generate/${id}?token=${get(token)}`;
} }
export const currentTrack = writable<TrackWithId | null>(null); export const currentTrack = writable<TrackWithId | null>(null);
export function getCurrentTrack(tracks: Map<TrackId, Track>, queue: TrackId[], position: number | null): TrackWithId | null { export function getCurrentTrack(
if (position === null) { tracks: Map<TrackId, Track>,
return null; queue: TrackId[],
} position: number | null
const id = queue.at(position); ): TrackWithId | null {
if (id === undefined) { if (position === null) {
return null; return null;
} }
const track = tracks.get(id); const id = queue.at(position);
if (track === undefined) { if (id === undefined) {
return null; return null;
} }
return { const track = tracks.get(id);
track, if (track === undefined) {
id, return null;
}; }
return {
track,
id
};
} }
export const queuePosition = writable<number | null>(null); export const queuePosition = writable<number | null>(null);
@ -47,50 +58,53 @@ export const tracks = writable<Map<TrackId, Track>>(new Map());
export const tracksSorted = writable<TrackId[]>([]); export const tracksSorted = writable<TrackId[]>([]);
queuePosition.subscribe((pos) => currentTrack.set(getCurrentTrack(get(tracks), get(queue), pos))); queuePosition.subscribe((pos) => currentTrack.set(getCurrentTrack(get(tracks), get(queue), pos)));
tracks.subscribe((newTracks) => currentTrack.set(getCurrentTrack(newTracks, get(queue), get(queuePosition)))); tracks.subscribe((newTracks) =>
currentTrack.set(getCurrentTrack(newTracks, get(queue), get(queuePosition)))
);
export function setQueuePositionTo(track_id: TrackId) { export function setQueuePositionTo(track_id: TrackId) {
let q = get(queue); let q = get(queue);
const position = q.indexOf(track_id); const position = q.indexOf(track_id);
if (position !== -1) { if (position !== -1) {
queuePosition.set(position); queuePosition.set(position);
} else { } else {
q.push(track_id); q.push(track_id);
queue.set(q); queue.set(q);
queuePosition.set(q.length - 1); queuePosition.set(q.length - 1);
} }
} }
export function getPrevQueuePosition(respectLoop: boolean) { export function getPrevQueuePosition(respectLoop: boolean) {
const pos = get(queuePosition); const pos = get(queuePosition);
if (pos !== null) { if (pos !== null) {
const q = get(queue); const q = get(queue);
const l = get(loop); const l = get(loop);
const _newPos = pos - 1; const _newPos = pos - 1;
const newPos = _newPos > -1 ? _newPos : l === LoopKind.Once || !respectLoop ? q.length - 1 : null; const newPos =
return newPos; _newPos > -1 ? _newPos : l === LoopKind.Once || !respectLoop ? q.length - 1 : null;
} return newPos;
return null; }
return null;
} }
export function getNextQueuePosition(respectLoop: boolean) { export function getNextQueuePosition(respectLoop: boolean) {
const pos = get(queuePosition); const pos = get(queuePosition);
if (pos !== null) { if (pos !== null) {
const q = get(queue); const q = get(queue);
const l = get(loop); const l = get(loop);
const _newPos = pos + 1; const _newPos = pos + 1;
const newPos = _newPos < q.length ? _newPos : l === LoopKind.Once || !respectLoop ? 0 : null; const newPos = _newPos < q.length ? _newPos : l === LoopKind.Once || !respectLoop ? 0 : null;
return newPos; return newPos;
} }
return null; return null;
} }
export function prevQueuePosition(respectLoop: boolean = false) { export function prevQueuePosition(respectLoop: boolean = false) {
queuePosition.set(getPrevQueuePosition(respectLoop)); queuePosition.set(getPrevQueuePosition(respectLoop));
} }
export function nextQueuePosition(respectLoop: boolean = false) { export function nextQueuePosition(respectLoop: boolean = false) {
queuePosition.set(getNextQueuePosition(respectLoop)); queuePosition.set(getNextQueuePosition(respectLoop));
} }
export const paused = writable<boolean>(false); export const paused = writable<boolean>(false);
@ -99,59 +113,51 @@ export const muted = writable<boolean>(false);
export const loop = writable<LoopKind>(LoopKind.Off); export const loop = writable<LoopKind>(LoopKind.Off);
export function changeLoop() { export function changeLoop() {
switch (get(loop)) { switch (get(loop)) {
case LoopKind.Always: case LoopKind.Always:
loop.set(LoopKind.Off); loop.set(LoopKind.Off);
break; break;
case LoopKind.Off: case LoopKind.Off:
loop.set(LoopKind.Once); loop.set(LoopKind.Once);
break; break;
case LoopKind.Once: case LoopKind.Once:
loop.set(LoopKind.Always); loop.set(LoopKind.Always);
break; break;
} }
} }
export const searchText = writable<string>(""); export const searchText = writable<string>('');
export function search(q: string) { export function search(q: string) {
const query = q.trim(); const query = q.trim();
const t = get(tracks); const t = get(tracks);
if (query.length === 0) { if (query.length === 0) {
let result: TrackId[] = []; let result: TrackId[] = [];
t.forEach((_, id) => (result.push(id))); t.forEach((_, id) => result.push(id));
tracksSorted.set(result); tracksSorted.set(result);
return; return;
} }
const smartCase = query.toLowerCase() === query; const smartCase = query.toLowerCase() === query;
let result: TrackId[] = []; let result: TrackId[] = [];
t.forEach((track, id) => { t.forEach((track, id) => {
if (smartCase) { if (smartCase) {
const titleHas = track.title.toLowerCase().includes(query); const titleHas = track.title.toLowerCase().includes(query);
const albumHas = track.album_title.toLowerCase().includes(query); const albumHas = track.album_title.toLowerCase().includes(query);
const artistHas = track.artist_name.toLowerCase().includes(query); const artistHas = track.artist_name.toLowerCase().includes(query);
if (titleHas || albumHas || artistHas) { if (titleHas || albumHas || artistHas) {
result.push(id); result.push(id);
} }
} else { } else {
const titleHas = track.title.includes(query); const titleHas = track.title.includes(query);
const albumHas = track.album_title.includes(query); const albumHas = track.album_title.includes(query);
const artistHas = track.artist_name.includes(query); const artistHas = track.artist_name.includes(query);
if (titleHas || albumHas || artistHas) { if (titleHas || albumHas || artistHas) {
result.push(id); result.push(id);
} }
} }
}); });
tracksSorted.set(result); tracksSorted.set(result);
} }
export function getAudioElement() {
const elem = document.getElementById('audio-source');
if (elem === null) {
return null;
}
return elem as HTMLAudioElement;
}

View File

@ -2,32 +2,32 @@ export type ResourceId = bigint;
export type TrackId = string; export type TrackId = string;
export interface Track { export interface Track {
id: number, id: number;
title: string, title: string;
track_num: number, track_num: number;
album_title: string, album_title: string;
album_id: ResourceId, album_id: ResourceId;
artist_name: string, artist_name: string;
artist_id: ResourceId, artist_id: ResourceId;
thumbnail_id: ResourceId, thumbnail_id: number;
} }
export interface TrackWithId { export interface TrackWithId {
id: TrackId, id: TrackId;
track: Track, track: Track;
} }
export interface Artist { export interface Artist {
name: string, name: string;
} }
export interface Album { export interface Album {
title: string, title: string;
artist_id: ResourceId, artist_id: ResourceId;
} }
export enum LoopKind { export enum LoopKind {
Off, Off,
Once, Once,
Always, Always
} }

89
src/utils.ts Normal file
View File

@ -0,0 +1,89 @@
import { dev } from '$app/environment';
import { PUBLIC_BASEURL } from '$env/static/public';
export const scheme = dev ? 'http' : 'https';
export function makeShareUrl(token: string) {
return `${scheme}://${PUBLIC_BASEURL}/share/${token}`;
}
export function getAudioElement() {
const elem = document.getElementById('audio-source');
if (elem === null) {
return null;
}
return elem as HTMLAudioElement;
}
export function calculateMinuteSecond(seconds: number) {
let secs = Math.floor(seconds);
let secsLeftover = secs % 60;
let minutes = (secs - secsLeftover) / 60;
let secondsFormatted = secsLeftover < 10 ? `0${secsLeftover}` : `${secsLeftover}`;
let minutesFormatted = minutes < 10 ? `0${minutes}` : `${minutes}`;
return `${minutesFormatted}:${secondsFormatted}`;
}
export function interceptKeys(
extraActions: [string, () => void][] = []
): (event: KeyboardEvent) => void {
return (event) => {
const tagName = document.activeElement?.tagName ?? '';
const audio = getAudioElement();
const actions = new Map([
...extraActions,
[
'Space',
() => {
if (audio !== null) {
audio.paused ? audio.play() : audio.pause();
}
}
],
[
'KeyM',
() => {
if (audio !== null) {
audio.muted = !audio.muted;
}
}
],
[
'ArrowLeft',
() => {
if (audio !== null) {
audio.currentTime -= 5;
}
}
],
[
'ArrowRight',
() => {
const audio = getAudioElement();
if (audio !== null) {
audio.currentTime += 5;
}
}
]
]);
if (tagName !== 'INPUT' && actions.has(event.code)) {
event.preventDefault();
event.stopPropagation();
const action = actions.get(event.code) ?? null;
if (action !== null) {
action();
}
}
};
}
function componentToHex(c: number) {
var hex = c.toString(16);
return hex.length == 1 ? '0' + hex : hex;
}
export function rgbToHex(r: number, g: number, b: number) {
return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

View File

@ -1,4 +1,4 @@
import adapter from '@sveltejs/adapter-static'; import adapter from 'svelte-adapter-deno';
import { vitePreprocess } from '@sveltejs/kit/vite'; import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */

View File

@ -1,17 +1,12 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: [ content: [
'./src/**/*.{html,js,svelte,ts}', './src/**/*.{html,js,svelte,ts}',
require('path').join(require.resolve( require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
'@skeletonlabs/skeleton'), ],
'../**/*.{html,js,svelte,ts}' theme: {
), extend: {}
], },
theme: { plugins: [...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()],
extend: {}, darkMode: 'class'
}, };
plugins: [
...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
],
darkMode: 'class',
}

View File

@ -1,12 +1,12 @@
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import Icons from 'unplugin-icons/vite' import Icons from 'unplugin-icons/vite';
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
sveltekit(), sveltekit(),
Icons({ Icons({
compiler: 'svelte', compiler: 'svelte'
}) })
] ]
}); });

332
yarn.lock
View File

@ -142,14 +142,14 @@
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884"
integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==
"@eslint/eslintrc@^2.0.2": "@eslint/eslintrc@^2.0.3":
version "2.0.2" version "2.0.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz#01575e38707add677cf73ca1589abba8da899a02" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331"
integrity sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==
dependencies: dependencies:
ajv "^6.12.4" ajv "^6.12.4"
debug "^4.3.2" debug "^4.3.2"
espree "^9.5.1" espree "^9.5.2"
globals "^13.19.0" globals "^13.19.0"
ignore "^5.2.0" ignore "^5.2.0"
import-fresh "^3.2.1" import-fresh "^3.2.1"
@ -157,10 +157,10 @@
minimatch "^3.1.2" minimatch "^3.1.2"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@eslint/js@8.39.0": "@eslint/js@8.40.0":
version "8.39.0" version "8.40.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.40.0.tgz#3ba73359e11f5a7bd3e407f70b3528abfae69cec"
integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== integrity sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==
"@humanwhocodes/config-array@^0.11.8": "@humanwhocodes/config-array@^0.11.8":
version "0.11.8" version "0.11.8"
@ -275,6 +275,46 @@
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
"@rollup/plugin-commonjs@^24.0.1":
version "24.1.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz#79e54bd83bb64396761431eee6c44152ef322100"
integrity sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==
dependencies:
"@rollup/pluginutils" "^5.0.1"
commondir "^1.0.1"
estree-walker "^2.0.2"
glob "^8.0.3"
is-reference "1.2.1"
magic-string "^0.27.0"
"@rollup/plugin-json@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.0.0.tgz#199fea6670fd4dfb1f4932250569b14719db234a"
integrity sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==
dependencies:
"@rollup/pluginutils" "^5.0.1"
"@rollup/plugin-node-resolve@^15.0.1":
version "15.0.2"
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz#8183a80c2cbf7b471f5ac86b16747997f3b5d185"
integrity sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==
dependencies:
"@rollup/pluginutils" "^5.0.1"
"@types/resolve" "1.20.2"
deepmerge "^4.2.2"
is-builtin-module "^3.2.1"
is-module "^1.0.0"
resolve "^1.22.1"
"@rollup/pluginutils@^5.0.1":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33"
integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==
dependencies:
"@types/estree" "^1.0.0"
estree-walker "^2.0.2"
picomatch "^2.3.1"
"@skeletonlabs/skeleton@^1.2.5": "@skeletonlabs/skeleton@^1.2.5":
version "1.2.5" version "1.2.5"
resolved "https://registry.yarnpkg.com/@skeletonlabs/skeleton/-/skeleton-1.2.5.tgz#e35fb147b8353024c3fd35961ab0f8d63233ee3b" resolved "https://registry.yarnpkg.com/@skeletonlabs/skeleton/-/skeleton-1.2.5.tgz#e35fb147b8353024c3fd35961ab0f8d63233ee3b"
@ -282,22 +322,10 @@
dependencies: dependencies:
svelte "^3.58.0" svelte "^3.58.0"
"@sveltejs/adapter-auto@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@sveltejs/adapter-auto/-/adapter-auto-2.0.1.tgz#86b14efd833d7002e4ab2338d5c1efaddb8729d3"
integrity sha512-anxxYMcQy7HWSKxN4YNaVcgNzCHtNFwygq72EA1Xv7c+5gSECOJ1ez1PYoLciPiFa7A3XBvMDQXUFJ2eqLDtAA==
dependencies:
import-meta-resolve "^3.0.0"
"@sveltejs/adapter-static@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-2.0.2.tgz#49afd27787fb73d789017d002a91031088494139"
integrity sha512-9wYtf6s6ew7DHUHMrt55YpD1FgV7oWql2IGsW5BXquLxqcY9vjrqCFo0TzzDpo+ZPZkW/v77k0eOP6tsAb8HmQ==
"@sveltejs/kit@^1.15.9": "@sveltejs/kit@^1.15.9":
version "1.16.0" version "1.16.3"
resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.16.0.tgz#1aaa154d161ecf880f6137a9aa03b09b580c56d6" resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.16.3.tgz#2b7540dbe08ce5d2eb46a282043c5a345f25691e"
integrity sha512-uCCZuI5MVSAviQFYsts5VHSmvBUp2u/CPeWfwAYxbWZoPg8lsM24JGjLhCh0peQwQjIDXXVDVQI0jdvSGs91Lg== integrity sha512-8uv0udYRpVuE1BweFidcWHfL+u2gAANKmvIal1dN/FWPBl7DJYbt9zYEtr3bNTiXystT8Sn0Wp54RfwpbPqHjQ==
dependencies: dependencies:
"@sveltejs/vite-plugin-svelte" "^2.1.1" "@sveltejs/vite-plugin-svelte" "^2.1.1"
"@types/cookie" "^0.5.1" "@types/cookie" "^0.5.1"
@ -314,9 +342,9 @@
undici "~5.22.0" undici "~5.22.0"
"@sveltejs/vite-plugin-svelte@^2.1.1": "@sveltejs/vite-plugin-svelte@^2.1.1":
version "2.1.1" version "2.2.0"
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.1.1.tgz#df08dba9094208a2048968e329237be6893cf66d" resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.2.0.tgz#6e78e912dc0cff5e92bcb936f194e96b849356f9"
integrity sha512-7YeBDt4us0FiIMNsVXxyaP4Hwyn2/v9x3oqStkHU3ZdIc5O22pGwUwH33wUqYo+7Itdmo8zxJ45Qvfm3H7UUjQ== integrity sha512-KDtdva+FZrZlyug15KlbXuubntAPKcBau0K7QhAIqC5SAy0uDbjZwoexDRx0L0J2T4niEfC6FnA9GuQQJKg+Aw==
dependencies: dependencies:
debug "^4.3.4" debug "^4.3.4"
deepmerge "^4.3.1" deepmerge "^4.3.1"
@ -330,6 +358,11 @@
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.1.tgz#b29aa1f91a59f35e29ff8f7cb24faf1a3a750554" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.1.tgz#b29aa1f91a59f35e29ff8f7cb24faf1a3a750554"
integrity sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g== integrity sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==
"@types/estree@*", "@types/estree@^1.0.0":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194"
integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==
"@types/json-schema@^7.0.9": "@types/json-schema@^7.0.9":
version "7.0.11" version "7.0.11"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
@ -340,20 +373,25 @@
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6" resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6"
integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg== integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==
"@types/resolve@1.20.2":
version "1.20.2"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
"@types/semver@^7.3.12": "@types/semver@^7.3.12":
version "7.3.13" version "7.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"
integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
"@typescript-eslint/eslint-plugin@^5.59.1": "@typescript-eslint/eslint-plugin@^5.59.1":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz#684a2ce7182f3b4dac342eef7caa1c2bae476abd" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz#f156827610a3f8cefc56baeaa93cd4a5f32966b4"
integrity sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A== integrity sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==
dependencies: dependencies:
"@eslint-community/regexpp" "^4.4.0" "@eslint-community/regexpp" "^4.4.0"
"@typescript-eslint/scope-manager" "5.59.2" "@typescript-eslint/scope-manager" "5.59.5"
"@typescript-eslint/type-utils" "5.59.2" "@typescript-eslint/type-utils" "5.59.5"
"@typescript-eslint/utils" "5.59.2" "@typescript-eslint/utils" "5.59.5"
debug "^4.3.4" debug "^4.3.4"
grapheme-splitter "^1.0.4" grapheme-splitter "^1.0.4"
ignore "^5.2.0" ignore "^5.2.0"
@ -362,71 +400,71 @@
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/parser@^5.59.1": "@typescript-eslint/parser@^5.59.1":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.2.tgz#c2c443247901d95865b9f77332d9eee7c55655e8" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.5.tgz#63064f5eafbdbfb5f9dfbf5c4503cdf949852981"
integrity sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ== integrity sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "5.59.2" "@typescript-eslint/scope-manager" "5.59.5"
"@typescript-eslint/types" "5.59.2" "@typescript-eslint/types" "5.59.5"
"@typescript-eslint/typescript-estree" "5.59.2" "@typescript-eslint/typescript-estree" "5.59.5"
debug "^4.3.4" debug "^4.3.4"
"@typescript-eslint/scope-manager@5.59.2": "@typescript-eslint/scope-manager@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz#f699fe936ee4e2c996d14f0fdd3a7da5ba7b9a4c" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz#33ffc7e8663f42cfaac873de65ebf65d2bce674d"
integrity sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA== integrity sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==
dependencies: dependencies:
"@typescript-eslint/types" "5.59.2" "@typescript-eslint/types" "5.59.5"
"@typescript-eslint/visitor-keys" "5.59.2" "@typescript-eslint/visitor-keys" "5.59.5"
"@typescript-eslint/type-utils@5.59.2": "@typescript-eslint/type-utils@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz#0729c237503604cd9a7084b5af04c496c9a4cdcf" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz#485b0e2c5b923460bc2ea6b338c595343f06fc9b"
integrity sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ== integrity sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==
dependencies: dependencies:
"@typescript-eslint/typescript-estree" "5.59.2" "@typescript-eslint/typescript-estree" "5.59.5"
"@typescript-eslint/utils" "5.59.2" "@typescript-eslint/utils" "5.59.5"
debug "^4.3.4" debug "^4.3.4"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/types@5.59.2": "@typescript-eslint/types@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.2.tgz#b511d2b9847fe277c5cb002a2318bd329ef4f655" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.5.tgz#e63c5952532306d97c6ea432cee0981f6d2258c7"
integrity sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w== integrity sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==
"@typescript-eslint/typescript-estree@5.59.2": "@typescript-eslint/typescript-estree@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz#6e2fabd3ba01db5d69df44e0b654c0b051fe9936" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz#9b252ce55dd765e972a7a2f99233c439c5101e42"
integrity sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q== integrity sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==
dependencies: dependencies:
"@typescript-eslint/types" "5.59.2" "@typescript-eslint/types" "5.59.5"
"@typescript-eslint/visitor-keys" "5.59.2" "@typescript-eslint/visitor-keys" "5.59.5"
debug "^4.3.4" debug "^4.3.4"
globby "^11.1.0" globby "^11.1.0"
is-glob "^4.0.3" is-glob "^4.0.3"
semver "^7.3.7" semver "^7.3.7"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/utils@5.59.2": "@typescript-eslint/utils@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.2.tgz#0c45178124d10cc986115885688db6abc37939f4" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.5.tgz#15b3eb619bb223302e60413adb0accd29c32bcae"
integrity sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ== integrity sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==
dependencies: dependencies:
"@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/eslint-utils" "^4.2.0"
"@types/json-schema" "^7.0.9" "@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12" "@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.59.2" "@typescript-eslint/scope-manager" "5.59.5"
"@typescript-eslint/types" "5.59.2" "@typescript-eslint/types" "5.59.5"
"@typescript-eslint/typescript-estree" "5.59.2" "@typescript-eslint/typescript-estree" "5.59.5"
eslint-scope "^5.1.1" eslint-scope "^5.1.1"
semver "^7.3.7" semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.59.2": "@typescript-eslint/visitor-keys@5.59.5":
version "5.59.2" version "5.59.5"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz#37a419dc2723a3eacbf722512b86d6caf7d3b750" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz#ba5b8d6791a13cf9fea6716af1e7626434b29b9b"
integrity sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig== integrity sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==
dependencies: dependencies:
"@typescript-eslint/types" "5.59.2" "@typescript-eslint/types" "5.59.5"
eslint-visitor-keys "^3.3.0" eslint-visitor-keys "^3.3.0"
acorn-jsx@^5.3.2: acorn-jsx@^5.3.2:
@ -519,6 +557,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0" balanced-match "^1.0.0"
concat-map "0.0.1" concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.2, braces@~3.0.2: braces@^3.0.2, braces@~3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@ -541,6 +586,11 @@ buffer-crc32@^0.2.5:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
builtin-modules@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
busboy@^1.6.0: busboy@^1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
@ -559,9 +609,9 @@ camelcase-css@^2.0.1:
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464:
version "1.0.30001482" version "1.0.30001486"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz#8b3fad73dc35b2674a5c96df2d4f9f1c561435de" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz#56a08885228edf62cbe1ac8980f2b5dae159997e"
integrity sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ== integrity sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==
chalk@^4.0.0: chalk@^4.0.0:
version "4.1.2" version "4.1.2"
@ -603,6 +653,11 @@ commander@^4.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
concat-map@0.0.1: concat-map@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -639,7 +694,7 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^4.3.1: deepmerge@^4.2.2, deepmerge@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
@ -679,9 +734,9 @@ doctrine@^3.0.0:
esutils "^2.0.2" esutils "^2.0.2"
electron-to-chromium@^1.4.284: electron-to-chromium@^1.4.284:
version "1.4.384" version "1.4.387"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.384.tgz#5c23b5579930dec9af2a93edafddbe991542eace" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.387.tgz#9a93ef1bd01b5898436026401ea3cabb1dd17d7a"
integrity sha512-I97q0MmRAAqj53+a8vZsDkEXBZki+ehYAOPzwtQzALip52aEp2+BJqHFtTlsfjoqVZYwPpHC8wM6MbsSZQ/Eqw== integrity sha512-tutLf+alr1/0YqJwKPdstVvDLmxmLb5xNyDLNS0RZmenHcEYk9qKfpKDCVZEKJ00JVbnayJm1MZAbYhYDFpcOw==
es6-promise@^3.1.2: es6-promise@^3.1.2:
version "3.3.1" version "3.3.1"
@ -752,20 +807,20 @@ eslint-scope@^7.2.0:
esrecurse "^4.3.0" esrecurse "^4.3.0"
estraverse "^5.2.0" estraverse "^5.2.0"
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
version "3.4.0" version "3.4.1"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994"
integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
eslint@^8.39.0: eslint@^8.39.0:
version "8.39.0" version "8.40.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.40.0.tgz#a564cd0099f38542c4e9a2f630fa45bf33bc42a4"
integrity sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og== integrity sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==
dependencies: dependencies:
"@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.4.0" "@eslint-community/regexpp" "^4.4.0"
"@eslint/eslintrc" "^2.0.2" "@eslint/eslintrc" "^2.0.3"
"@eslint/js" "8.39.0" "@eslint/js" "8.40.0"
"@humanwhocodes/config-array" "^0.11.8" "@humanwhocodes/config-array" "^0.11.8"
"@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8" "@nodelib/fs.walk" "^1.2.8"
@ -776,8 +831,8 @@ eslint@^8.39.0:
doctrine "^3.0.0" doctrine "^3.0.0"
escape-string-regexp "^4.0.0" escape-string-regexp "^4.0.0"
eslint-scope "^7.2.0" eslint-scope "^7.2.0"
eslint-visitor-keys "^3.4.0" eslint-visitor-keys "^3.4.1"
espree "^9.5.1" espree "^9.5.2"
esquery "^1.4.2" esquery "^1.4.2"
esutils "^2.0.2" esutils "^2.0.2"
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
@ -808,14 +863,14 @@ esm-env@^1.0.0:
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.0.0.tgz#b124b40b180711690a4cb9b00d16573391950413" resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.0.0.tgz#b124b40b180711690a4cb9b00d16573391950413"
integrity sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA== integrity sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==
espree@^9.5.1: espree@^9.5.2:
version "9.5.1" version "9.5.2"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b"
integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==
dependencies: dependencies:
acorn "^8.8.0" acorn "^8.8.0"
acorn-jsx "^5.3.2" acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.0" eslint-visitor-keys "^3.4.1"
esquery@^1.4.2: esquery@^1.4.2:
version "1.5.0" version "1.5.0"
@ -841,6 +896,11 @@ estraverse@^5.1.0, estraverse@^5.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
esutils@^2.0.2: esutils@^2.0.2:
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@ -992,6 +1052,17 @@ glob@^7.1.3:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^8.0.3:
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
once "^1.3.0"
globals@^13.19.0: globals@^13.19.0:
version "13.20.0" version "13.20.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82"
@ -1061,11 +1132,6 @@ import-fresh@^3.0.0, import-fresh@^3.2.1:
parent-module "^1.0.0" parent-module "^1.0.0"
resolve-from "^4.0.0" resolve-from "^4.0.0"
import-meta-resolve@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz#94a6aabc623874fbc2f3525ec1300db71c6cbc11"
integrity sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==
imurmurhash@^0.1.4: imurmurhash@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@ -1091,6 +1157,13 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-builtin-module@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169"
integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==
dependencies:
builtin-modules "^3.3.0"
is-core-module@^2.11.0: is-core-module@^2.11.0:
version "2.12.0" version "2.12.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4"
@ -1110,6 +1183,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies: dependencies:
is-extglob "^2.1.1" is-extglob "^2.1.1"
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
is-number@^7.0.0: is-number@^7.0.0:
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
@ -1120,6 +1198,13 @@ is-path-inside@^3.0.3:
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
is-reference@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
dependencies:
"@types/estree" "*"
is-stream@^2.0.0: is-stream@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
@ -1263,6 +1348,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies: dependencies:
brace-expansion "^1.1.7" brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.6: minimist@^1.2.0, minimist@^1.2.6:
version "1.2.8" version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
@ -1535,7 +1627,7 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve@^1.1.7, resolve@^1.22.2: resolve@^1.1.7, resolve@^1.22.1, resolve@^1.22.2:
version "1.22.2" version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
@ -1563,7 +1655,7 @@ rimraf@^3.0.2:
dependencies: dependencies:
glob "^7.1.3" glob "^7.1.3"
rollup@^3.21.0: rollup@^3.12.0, rollup@^3.21.0:
version "3.21.5" version "3.21.5"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.5.tgz#1fbae43dc1079497b04604707f1cf979e51bfe49" resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.5.tgz#1fbae43dc1079497b04604707f1cf979e51bfe49"
integrity sha512-a4NTKS4u9PusbUJcfF4IMxuqjFzjm6ifj76P54a7cKnvVzJaG12BLVR+hgU2YDGHzyMMQNxLAZWuALsn8q2oQg== integrity sha512-a4NTKS4u9PusbUJcfF4IMxuqjFzjm6ifj76P54a7cKnvVzJaG12BLVR+hgU2YDGHzyMMQNxLAZWuALsn8q2oQg==
@ -1706,10 +1798,20 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
svelte-adapter-deno@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/svelte-adapter-deno/-/svelte-adapter-deno-0.9.0.tgz#9f9e0e8a5670f24f5960b8f1812dbe025b8d7664"
integrity sha512-BIo0tb3BXp9kimM9NQYR9+xqUXKFgMzxS8+5Ly256MoHl8F3ENMFDF0yCCyiqtf3M/LuZwQKq7Ko4PhpQZMUAQ==
dependencies:
"@rollup/plugin-commonjs" "^24.0.1"
"@rollup/plugin-json" "^6.0.0"
"@rollup/plugin-node-resolve" "^15.0.1"
rollup "^3.12.0"
svelte-check@^3.2.0: svelte-check@^3.2.0:
version "3.3.0" version "3.3.2"
resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.3.0.tgz#c748a0331c47acb0263ad900bdcbae7577491508" resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-3.3.2.tgz#11831428531cf7c61a91c38929eda11c37b7dcb1"
integrity sha512-wZtOvY8V2fjzCbS4dGjDp0Ebh6VyXg6A39s7TDc8wc0154yqWKu18Rd9Ad+GOs7sXst7dbTmjvOaexjwoqPM7A== integrity sha512-67j3rI0LDc2DvL0ON/2pvCasVVD3nHDrTkZNr4eITNfo2oFXdw7SIyMOiFj4swu+pjmFQAigytBK1IWyik8dBw==
dependencies: dependencies:
"@jridgewell/trace-mapping" "^0.3.17" "@jridgewell/trace-mapping" "^0.3.17"
chokidar "^3.4.1" chokidar "^3.4.1"
@ -1742,9 +1844,9 @@ svelte-tiny-virtual-list@^2.0.5:
integrity sha512-xg9ckb8UeeIme4/5qlwCrl2QNmUZ8SCQYZn3Ji83cUsoASqRNy3KWjpmNmzYvPDqCHSZjruBBsoB7t5hwuzw5g== integrity sha512-xg9ckb8UeeIme4/5qlwCrl2QNmUZ8SCQYZn3Ji83cUsoASqRNy3KWjpmNmzYvPDqCHSZjruBBsoB7t5hwuzw5g==
svelte@^3.58.0: svelte@^3.58.0:
version "3.58.0" version "3.59.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.58.0.tgz#d3e6f103efd6129e51c7d709225ad3b4c052b64e" resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.59.1.tgz#3de3d56b9165748f32f3131589b8d183cabe7449"
integrity sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A== integrity sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==
tailwindcss@^3.3.2: tailwindcss@^3.3.2:
version "3.3.2" version "3.3.2"
@ -1904,9 +2006,9 @@ util-deprecate@^1.0.2:
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vite@^4.3.3: vite@^4.3.3:
version "4.3.4" version "4.3.5"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.4.tgz#1c518d763d5a700d890c3a19ab59220f06e7a7d5" resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.5.tgz#3871fe0f4b582ea7f49a85386ac80e84826367d9"
integrity sha512-f90aqGBoxSFxWph2b39ae2uHAxm5jFBBdnfueNxZAT1FTpM13ccFQExCaKbR2xFW5atowjleRniQ7onjJ22QEg== integrity sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==
dependencies: dependencies:
esbuild "^0.17.5" esbuild "^0.17.5"
postcss "^8.4.23" postcss "^8.4.23"