diff --git a/examples/sveltekit-sse/.eslintignore b/examples/sveltekit-sse/.eslintignore new file mode 100644 index 0000000..3897265 --- /dev/null +++ b/examples/sveltekit-sse/.eslintignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/examples/sveltekit-sse/.eslintrc.cjs b/examples/sveltekit-sse/.eslintrc.cjs new file mode 100644 index 0000000..fab32bf --- /dev/null +++ b/examples/sveltekit-sse/.eslintrc.cjs @@ -0,0 +1,15 @@ +module.exports = { + root: true, + extends: ['eslint:recommended', 'prettier'], + plugins: ['svelte3'], + overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2020 + }, + env: { + browser: true, + es2017: true, + node: true + } +}; diff --git a/examples/sveltekit-sse/.gitignore b/examples/sveltekit-sse/.gitignore new file mode 100644 index 0000000..6635cf5 --- /dev/null +++ b/examples/sveltekit-sse/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/examples/sveltekit-sse/.npmrc b/examples/sveltekit-sse/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/examples/sveltekit-sse/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/examples/sveltekit-sse/.prettierignore b/examples/sveltekit-sse/.prettierignore new file mode 100644 index 0000000..3897265 --- /dev/null +++ b/examples/sveltekit-sse/.prettierignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/examples/sveltekit-sse/.prettierrc b/examples/sveltekit-sse/.prettierrc new file mode 100644 index 0000000..a77fdde --- /dev/null +++ b/examples/sveltekit-sse/.prettierrc @@ -0,0 +1,9 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte"], + "pluginSearchDirs": ["."], + "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] +} diff --git a/examples/sveltekit-sse/README.md b/examples/sveltekit-sse/README.md new file mode 100644 index 0000000..b501d2c --- /dev/null +++ b/examples/sveltekit-sse/README.md @@ -0,0 +1,13 @@ +# SvelteKit SSE Example + +A simple SvelteKit example that implements the SSE protocol and works with multiple users. Each user is assigned a cookie with a random ID using `crypto.randomUUID()` to identify each client and limit the number of connections. + +## `lib/sse-manager.server.js` + +This file keeps track of all `ReadableStream`s/SSE connections and allows you to emit events to all or only specific clients. The code is portable and works in all JavaScript envionments that accept `ReadableStream`s as HTTP responses including SvelteKit, Deno and Bun. + +## `lib/sse-store.js` + +This file contains a custom store that opens the SSE connection, listens for events emitted from the server and updates the store's value accordingly. + +**Note:** SSE requires a contionously open HTTP connection so in order to use `sse-manager.server.js` it needs to be deployed to Edge functions, a server using `adapter-node` or as a separate Deno or Bun app. Serverless functions have an execution limit of only a few seconds and therefore don't work. \ No newline at end of file diff --git a/examples/sveltekit-sse/jsconfig.json b/examples/sveltekit-sse/jsconfig.json new file mode 100644 index 0000000..fe45e13 --- /dev/null +++ b/examples/sveltekit-sse/jsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/sveltekit-sse/package.json b/examples/sveltekit-sse/package.json new file mode 100644 index 0000000..db85f12 --- /dev/null +++ b/examples/sveltekit-sse/package.json @@ -0,0 +1,28 @@ +{ + "name": "sveltekit-sse", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", + "lint": "prettier --plugin-search-dir . --check . && eslint .", + "format": "prettier --plugin-search-dir . --write ." + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/kit": "^1.15.7", + "eslint": "^8.38.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-svelte3": "^4.0.0", + "prettier": "^2.8.7", + "prettier-plugin-svelte": "^2.10.0", + "svelte": "^3.58.0", + "svelte-check": "^3.2.0", + "typescript": "^5.0.4", + "vite": "^4.3.0" + }, + "type": "module" +} diff --git a/examples/sveltekit-sse/src/app.d.ts b/examples/sveltekit-sse/src/app.d.ts new file mode 100644 index 0000000..f59b884 --- /dev/null +++ b/examples/sveltekit-sse/src/app.d.ts @@ -0,0 +1,12 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} + } +} + +export {}; diff --git a/examples/sveltekit-sse/src/app.html b/examples/sveltekit-sse/src/app.html new file mode 100644 index 0000000..effe0d0 --- /dev/null +++ b/examples/sveltekit-sse/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/sveltekit-sse/src/hooks.server.js b/examples/sveltekit-sse/src/hooks.server.js new file mode 100644 index 0000000..956d9e1 --- /dev/null +++ b/examples/sveltekit-sse/src/hooks.server.js @@ -0,0 +1,13 @@ +/** @type {import('@sveltejs/kit').Handle} */ +export async function handle({ event, resolve }) { + let id = event.cookies.get('id'); + + if (!id) { + id = crypto.randomUUID(); + event.cookies.set('id', id); + } + + event.locals.id = id; + + return await resolve(event); +} diff --git a/examples/sveltekit-sse/src/lib/global.css b/examples/sveltekit-sse/src/lib/global.css new file mode 100644 index 0000000..f006da6 --- /dev/null +++ b/examples/sveltekit-sse/src/lib/global.css @@ -0,0 +1,106 @@ +/* RESET */ + +*, +*::before, +*::after { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +html, +body { + height: 100%; + font-family: sans-serif; +} + +html:focus-within { + scroll-behavior: smooth; +} + +body { + line-height: 1.5; +} + +a:not([class]) { + text-decoration-skip-ink: auto; +} + +img, +picture, +video, +canvas { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select, +input[type='file']::file-selector-button { + font: inherit; +} + +label, +textarea, +progress, +input:where( + [type='email'], + [type='password'], + [type='search'], + [type='tel'], + [type='text'], + [type='url'], + [type='file'] + ) { + display: block; + width: 100%; +} + +textarea { + box-sizing: content-box; + min-height: 5em; + resize: block; + resize: vertical; +} + +/* THEME */ + +h1 { + margin-block-start: 3rem; + margin-block-end: 2rem; +} + +h2, +h3 { + margin-block-start: 2rem; + margin-block-end: 1rem; +} + +label { + font-weight: 700; + margin-block-end: 0.25rem; +} + +button, +input[type='file']::file-selector-button { + padding-inline: 0.5rem; + padding-block: 0.2rem; + cursor: pointer; +} + +button:hover { + filter: brightness(1.1); +} + +button.--loading { + cursor: wait; + opacity: 0.6; +} + +.box { + padding: 1rem; + border-radius: 7px; + background-color: hsla(0, 0%, 0%, 0.07); +} diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js new file mode 100644 index 0000000..d1834fa --- /dev/null +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -0,0 +1,129 @@ +/** + * @typedef {Object} Message - https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format + * @property {string} data - The data field for the message. + * @property {string} [event] - A string identifying the type of event described. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the website source code should use addEventListener() to listen for named events. The onmessage handler is called if no event name is specified for a message. + * @property {string | number} [id] - The event ID to set the EventSource object's last event ID value. + * @property {number} [retry] - The reconnection time. If the connection to the server is lost, the browser will wait for the specified time before attempting to reconnect. This must be an integer, specifying the reconnection time in milliseconds. + */ + +/** + * @callback ConnectionCallback + * @param {string | number} id + * @param {Set} controllers + * @returns {void} + */ + +/** @param {Message} message */ +function create_message_string(message) { + return ( + Object.entries(message) + .map(([key, value]) => `${key}: ${value}`) + .join('\n') + '\n\n' + ); +} + +function create_sse_manager({ max_clients = 1_000, max_connections_per_client = 3 } = {}) { + /** @type {Map>} */ + const clients = new Map(); + /** @type {Set} */ + const on_connected_callbacks = new Set(); + /** @type {Set} */ + const on_disconnected_callbacks = new Set(); + + return { + /** + * @param {string | number} id + * @returns {ReadableStream | void} + */ + connect(id) { + if (clients.size >= max_clients) { + return; + } + + if (clients.has(id) === false) { + clients.set(id, new Set()); + } + + const controllers = /** @type {Set} */ ( + clients.get(id) + ); + + if (controllers.size >= max_connections_per_client) { + return; + } + + /** @type {ReadableStreamDefaultController} */ + let controller; + + const stream = new ReadableStream({ + start(_controller) { + controller = _controller; + controllers.add(controller); + + on_connected_callbacks.forEach((cb) => cb(id, controllers)); + }, + cancel() { + controllers.delete(controller); + + if (controllers.size === 0) { + clients.delete(id); + } + + on_disconnected_callbacks.forEach((cb) => cb(id, controllers)); + } + }); + + return stream; + }, + + /** @param {ConnectionCallback} cb */ + on_connected(cb) { + on_connected_callbacks.add(cb); + }, + + /** @param {ConnectionCallback} cb */ + on_disconnected(cb) { + on_disconnected_callbacks.add(cb); + }, + + /** + * @param {string | number | Array} id + * @param {Message} message + */ + emit_to(id, message) { + const ids = Array.isArray(id) ? id : [id]; + + const message_string = create_message_string(message); + + for (const id of ids) { + const controllers = clients.get(id); + + if (!controllers) continue; + + controllers.forEach((c) => c.enqueue(message_string)); + } + }, + + /** + * @param {Message} message + * @param {Array} [exclude=[]] + */ + emit_to_all(message, exclude = []) { + const message_string = create_message_string(message); + + for (const [id, controllers] of clients) { + if (exclude.includes(id)) continue; + + controllers.forEach((c) => c.enqueue(message_string)); + } + }, + + get_all_clients() { + return clients; + } + }; +} + +const sse_manager = create_sse_manager(); + +export default sse_manager; diff --git a/examples/sveltekit-sse/src/lib/sse-store.js b/examples/sveltekit-sse/src/lib/sse-store.js new file mode 100644 index 0000000..c4efeb2 --- /dev/null +++ b/examples/sveltekit-sse/src/lib/sse-store.js @@ -0,0 +1,52 @@ +import { browser } from '$app/environment'; +import { writable } from 'svelte/store'; + +function create_sse_store(init = true) { + /** @type {EventSource | undefined} */ + let event_source; + + const { subscribe, update } = writable({ clients: [], messages: [], status: 'closed' }, () => { + if (init) open(); + + return close; + }); + + function open() { + event_source = new EventSource('/sse'); + + event_source.addEventListener('error', (event) => { + update((value) => ({ ...value, status: 'error' })); + }); + + event_source.addEventListener('open', (event) => { + update((value) => ({ ...value, status: 'open' })); + }); + + event_source.addEventListener('client:list', (event) => { + const json = JSON.parse(event.data); + + update((value) => ({ ...value, ...json })); + }); + + event_source.addEventListener('client:message', (event) => { + const json = JSON.parse(event.data); + + update((value) => { + value.messages.push(json); + return value; + }); + }); + } + + function close() { + event_source?.close(); + } + + return { + subscribe + }; +} + +const sse_store = create_sse_store(browser); + +export default sse_store; diff --git a/examples/sveltekit-sse/src/routes/+page.server.js b/examples/sveltekit-sse/src/routes/+page.server.js new file mode 100644 index 0000000..eefa400 --- /dev/null +++ b/examples/sveltekit-sse/src/routes/+page.server.js @@ -0,0 +1,21 @@ +import sse from '$lib/sse-manager.server.js'; + +/** @type {import('./$types').Actions} */ +export const actions = { + async emit_to_all(event) { + const data = await event.request.formData(); + + sse.emit_to_all({ + event: 'client:message', + data: JSON.stringify({ text: data.get('text') }) + }); + }, + async emit_to(event) { + const data = await event.request.formData(); + + sse.emit_to(data.get('id'), { + event: 'client:message', + data: JSON.stringify({ text: data.get('text') }) + }); + } +}; diff --git a/examples/sveltekit-sse/src/routes/+page.svelte b/examples/sveltekit-sse/src/routes/+page.svelte new file mode 100644 index 0000000..509e612 --- /dev/null +++ b/examples/sveltekit-sse/src/routes/+page.svelte @@ -0,0 +1,118 @@ + + +
+

SvelteKit SSE Example

+ + {#if $sse.status} + + {/if} + +
+

Send a message to all connected clients

+
+
+ + +
+ +
+
+ +

Messages

+ +
    + {#each $sse.messages as message (message)} +
  1. {message.text}
  2. + {/each} +
+ +

Connected clients

+ +
    + {#each $sse.clients as client (client)} +
  • +
    +
    + Connections: {client.connections} +
    +
    + Client ID: {client.id} +
    +
    + +
    +
    + + +
    + + +
    +
  • + {/each} +
+
+ + diff --git a/examples/sveltekit-sse/src/routes/sse/+server.js b/examples/sveltekit-sse/src/routes/sse/+server.js new file mode 100644 index 0000000..f2d3271 --- /dev/null +++ b/examples/sveltekit-sse/src/routes/sse/+server.js @@ -0,0 +1,46 @@ +import sse from '$lib/sse-manager.server.js'; + +sse.on_connected((id, controllers) => { + // Send a list of all currently connected users to the user + const clients = Array.from(sse.get_all_clients(), ([id, controllers]) => ({ + id, + connections: controllers.size + })); + + sse.emit_to_all({ + event: 'client:list', + data: JSON.stringify({ clients }) + }); +}); + +sse.on_disconnected((id, controllers) => { + // Send a list of all currently connected users to the user + const clients = Array.from(sse.get_all_clients(), ([id, controllers]) => ({ + id, + connections: controllers.size + })); + + sse.emit_to_all({ + event: 'client:list', + data: JSON.stringify({ clients }) + }); +}); + +/** @type {import('./$types').RequestHandler} */ +export function GET(event) { + if (!event.locals.id) { + return new Response(null, { status: 401 }); + } + + const stream = sse.connect(event.locals.id); + + if (!stream) { + return new Response(null, { status: 503 }); + } + + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream' + } + }); +} diff --git a/examples/sveltekit-sse/static/favicon.png b/examples/sveltekit-sse/static/favicon.png new file mode 100644 index 0000000..825b9e6 Binary files /dev/null and b/examples/sveltekit-sse/static/favicon.png differ diff --git a/examples/sveltekit-sse/svelte.config.js b/examples/sveltekit-sse/svelte.config.js new file mode 100644 index 0000000..348fa32 --- /dev/null +++ b/examples/sveltekit-sse/svelte.config.js @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-auto'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter() + } +}; + +export default config; diff --git a/examples/sveltekit-sse/vite.config.js b/examples/sveltekit-sse/vite.config.js new file mode 100644 index 0000000..bbf8c7d --- /dev/null +++ b/examples/sveltekit-sse/vite.config.js @@ -0,0 +1,6 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()] +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 344df64..1dcba35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,6 +97,32 @@ importers: typescript: 4.9.5 vite: 4.2.0 + examples/sveltekit-sse: + specifiers: + '@sveltejs/adapter-auto': ^2.0.0 + '@sveltejs/kit': ^1.15.7 + eslint: ^8.38.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-svelte3: ^4.0.0 + prettier: ^2.8.7 + prettier-plugin-svelte: ^2.10.0 + svelte: ^3.58.0 + svelte-check: ^3.2.0 + typescript: ^5.0.4 + vite: ^4.3.0 + devDependencies: + '@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.15.7 + '@sveltejs/kit': 1.15.7_svelte@3.58.0+vite@4.3.0 + eslint: 8.38.0 + eslint-config-prettier: 8.8.0_eslint@8.38.0 + eslint-plugin-svelte3: 4.0.0_a4ckjr7darsrglbip3svgxgxc4 + prettier: 2.8.7 + prettier-plugin-svelte: 2.10.0_ur5pqdgn24bclu6l6i7qojopk4 + svelte: 3.58.0 + svelte-check: 3.2.0_svelte@3.58.0 + typescript: 5.0.4 + vite: 4.3.0 + packages: /@aws-crypto/crc32/3.0.0: @@ -1118,6 +1144,15 @@ packages: dev: true optional: true + /@esbuild/android-arm/0.17.17: + resolution: {integrity: sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64/0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -1136,6 +1171,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64/0.17.17: + resolution: {integrity: sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64/0.16.17: resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} engines: {node: '>=12'} @@ -1154,6 +1198,15 @@ packages: dev: true optional: true + /@esbuild/android-x64/0.17.17: + resolution: {integrity: sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64/0.16.17: resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} engines: {node: '>=12'} @@ -1172,6 +1225,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64/0.17.17: + resolution: {integrity: sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64/0.16.17: resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} engines: {node: '>=12'} @@ -1190,6 +1252,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64/0.17.17: + resolution: {integrity: sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64/0.16.17: resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} engines: {node: '>=12'} @@ -1208,6 +1279,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64/0.17.17: + resolution: {integrity: sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64/0.16.17: resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} engines: {node: '>=12'} @@ -1226,6 +1306,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64/0.17.17: + resolution: {integrity: sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm/0.16.17: resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} engines: {node: '>=12'} @@ -1244,6 +1333,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm/0.17.17: + resolution: {integrity: sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64/0.16.17: resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} engines: {node: '>=12'} @@ -1262,6 +1360,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64/0.17.17: + resolution: {integrity: sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32/0.16.17: resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} engines: {node: '>=12'} @@ -1280,6 +1387,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32/0.17.17: + resolution: {integrity: sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.16.17: resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} engines: {node: '>=12'} @@ -1298,6 +1414,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64/0.17.17: + resolution: {integrity: sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el/0.16.17: resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} engines: {node: '>=12'} @@ -1316,6 +1441,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el/0.17.17: + resolution: {integrity: sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64/0.16.17: resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} engines: {node: '>=12'} @@ -1334,6 +1468,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64/0.17.17: + resolution: {integrity: sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64/0.16.17: resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} engines: {node: '>=12'} @@ -1352,6 +1495,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64/0.17.17: + resolution: {integrity: sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x/0.16.17: resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} engines: {node: '>=12'} @@ -1370,6 +1522,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x/0.17.17: + resolution: {integrity: sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64/0.16.17: resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} engines: {node: '>=12'} @@ -1388,6 +1549,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64/0.17.17: + resolution: {integrity: sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64/0.16.17: resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} engines: {node: '>=12'} @@ -1406,6 +1576,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64/0.17.17: + resolution: {integrity: sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64/0.16.17: resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} engines: {node: '>=12'} @@ -1424,6 +1603,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64/0.17.17: + resolution: {integrity: sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64/0.16.17: resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -1442,6 +1630,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64/0.17.17: + resolution: {integrity: sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64/0.16.17: resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} engines: {node: '>=12'} @@ -1460,6 +1657,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64/0.17.17: + resolution: {integrity: sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32/0.16.17: resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} engines: {node: '>=12'} @@ -1478,6 +1684,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32/0.17.17: + resolution: {integrity: sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64/0.16.17: resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} engines: {node: '>=12'} @@ -1496,6 +1711,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64/0.17.17: + resolution: {integrity: sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint-community/eslint-utils/4.2.0_eslint@8.36.0: resolution: {integrity: sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1506,11 +1730,26 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@eslint-community/eslint-utils/4.4.0_eslint@8.38.0: + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.38.0 + eslint-visitor-keys: 3.4.0 + dev: true + /@eslint-community/regexpp/4.4.0: resolution: {integrity: sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true + /@eslint-community/regexpp/4.5.0: + resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + /@eslint/eslintrc/2.0.1: resolution: {integrity: sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1528,11 +1767,33 @@ packages: - supports-color dev: true + /@eslint/eslintrc/2.0.2: + resolution: {integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.5.1 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@eslint/js/8.36.0: resolution: {integrity: sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@eslint/js/8.38.0: + resolution: {integrity: sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@humanwhocodes/config-array/0.11.8: resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} engines: {node: '>=10.10.0'} @@ -1562,6 +1823,10 @@ packages: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} dev: true + /@jridgewell/sourcemap-codec/1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + /@jridgewell/trace-mapping/0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} dependencies: @@ -1569,6 +1834,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@jridgewell/trace-mapping/0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1663,7 +1935,16 @@ packages: peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@sveltejs/kit': 1.12.0_svelte@3.57.0+vite@4.2.0 + '@sveltejs/kit': 1.12.0_svelte@3.57.0+vite@4.1.3 + import-meta-resolve: 2.2.2 + dev: true + + /@sveltejs/adapter-auto/2.0.0_@sveltejs+kit@1.15.7: + resolution: {integrity: sha512-b+gkHFZgD771kgV3aO4avHFd7y1zhmMYy9i6xOK7m/rwmwaRO8gnF5zBc0Rgca80B2PMU1bKNxyBTHA14OzUAQ==} + peerDependencies: + '@sveltejs/kit': ^1.0.0 + dependencies: + '@sveltejs/kit': 1.15.7_svelte@3.58.0+vite@4.3.0 import-meta-resolve: 2.2.2 dev: true @@ -1716,7 +1997,7 @@ packages: svelte: ^3.54.0 vite: ^4.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 2.0.3_svelte@3.57.0+vite@4.2.0 + '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.57.0+vite@4.2.0 '@types/cookie': 0.5.1 cookie: 0.5.0 devalue: 4.3.0 @@ -1735,6 +2016,34 @@ packages: - supports-color dev: true + /@sveltejs/kit/1.15.7_svelte@3.58.0+vite@4.3.0: + resolution: {integrity: sha512-dgdKExsMJ16X3q8tEcuDlv+QIWAlJcf7IqCU2HWV13nmtTzwSA2n4VtEx9Gy5OGhH0SUAGNIupmlf0TdFSMXbw==} + engines: {node: ^16.14 || >=18} + hasBin: true + requiresBuild: true + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 2.0.4_svelte@3.58.0+vite@4.3.0 + '@types/cookie': 0.5.1 + cookie: 0.5.0 + devalue: 4.3.0 + esm-env: 1.0.0 + kleur: 4.1.5 + magic-string: 0.30.0 + mime: 3.0.0 + sade: 1.8.1 + set-cookie-parser: 2.6.0 + sirv: 2.0.2 + svelte: 3.58.0 + tiny-glob: 0.2.9 + undici: 5.20.0 + vite: 4.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /@sveltejs/package/2.0.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-DkDQrNTNSdGpE9u03tXr+K6BXfdw1jQfmU1EtmXv3o1+OzWei/866wp+1lCAI+8A2bpjAuCNgvI3j0Sy+glhwQ==} engines: {node: ^16.14 || >=18} @@ -1770,8 +2079,8 @@ packages: - supports-color dev: true - /@sveltejs/vite-plugin-svelte/2.0.3_svelte@3.57.0+vite@4.2.0: - resolution: {integrity: sha512-o+cguBFdwIGtRbNkYOyqTM7KvRUffxh5bfK4oJsWKG2obu+v/cbpT03tJrGl58C7tRXo/aEC0/axN5FVHBj0nA==} + /@sveltejs/vite-plugin-svelte/2.0.2_svelte@3.57.0+vite@4.2.0: + resolution: {integrity: sha512-xCEan0/NNpQuL0l5aS42FjwQ6wwskdxC3pW1OeFtEKNZwRg7Evro9lac9HesGP6TdFsTv2xMes5ASQVKbCacxg==} engines: {node: ^14.18.0 || >= 16} peerDependencies: svelte: ^3.54.0 @@ -1780,7 +2089,7 @@ packages: debug: 4.3.4 deepmerge: 4.3.0 kleur: 4.1.5 - magic-string: 0.29.0 + magic-string: 0.27.0 svelte: 3.57.0 svelte-hmr: 0.15.1_svelte@3.57.0 vite: 4.2.0 @@ -1789,6 +2098,25 @@ packages: - supports-color dev: true + /@sveltejs/vite-plugin-svelte/2.0.4_svelte@3.58.0+vite@4.3.0: + resolution: {integrity: sha512-pjqhW00KwK2uzDGEr+yJBwut+D+4XfJO/+bHHdHzPRXn9+1Jeq5JcFHyrUiYaXgHtyhX0RsllCTm4ssAx4ZY7Q==} + engines: {node: ^14.18.0 || >= 16} + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + debug: 4.3.4 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.0 + svelte: 3.58.0 + svelte-hmr: 0.15.1_svelte@3.58.0 + vite: 4.3.0 + vitefu: 0.2.4_vite@4.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /@types/cookie/0.5.1: resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} dev: true @@ -1994,6 +2322,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /deepmerge/4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -2074,6 +2407,36 @@ packages: '@esbuild/win32-x64': 0.17.11 dev: true + /esbuild/0.17.17: + resolution: {integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.17 + '@esbuild/android-arm64': 0.17.17 + '@esbuild/android-x64': 0.17.17 + '@esbuild/darwin-arm64': 0.17.17 + '@esbuild/darwin-x64': 0.17.17 + '@esbuild/freebsd-arm64': 0.17.17 + '@esbuild/freebsd-x64': 0.17.17 + '@esbuild/linux-arm': 0.17.17 + '@esbuild/linux-arm64': 0.17.17 + '@esbuild/linux-ia32': 0.17.17 + '@esbuild/linux-loong64': 0.17.17 + '@esbuild/linux-mips64el': 0.17.17 + '@esbuild/linux-ppc64': 0.17.17 + '@esbuild/linux-riscv64': 0.17.17 + '@esbuild/linux-s390x': 0.17.17 + '@esbuild/linux-x64': 0.17.17 + '@esbuild/netbsd-x64': 0.17.17 + '@esbuild/openbsd-x64': 0.17.17 + '@esbuild/sunos-x64': 0.17.17 + '@esbuild/win32-arm64': 0.17.17 + '@esbuild/win32-ia32': 0.17.17 + '@esbuild/win32-x64': 0.17.17 + dev: true + /escape-string-regexp/4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -2088,6 +2451,25 @@ packages: eslint: 8.36.0 dev: true + /eslint-config-prettier/8.8.0_eslint@8.38.0: + resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.38.0 + dev: true + + /eslint-plugin-svelte3/4.0.0_a4ckjr7darsrglbip3svgxgxc4: + resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} + peerDependencies: + eslint: '>=8.0.0' + svelte: ^3.2.0 + dependencies: + eslint: 8.38.0 + svelte: 3.58.0 + dev: true + /eslint-plugin-svelte3/4.0.0_wzem237sbvnwe7n34ytc5phasy: resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} peerDependencies: @@ -2106,11 +2488,24 @@ packages: estraverse: 5.3.0 dev: true + /eslint-scope/7.2.0: + resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + /eslint-visitor-keys/3.3.0: resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /eslint-visitor-keys/3.4.0: + resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /eslint/8.36.0: resolution: {integrity: sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2160,6 +2555,55 @@ packages: - supports-color dev: true + /eslint/8.38.0: + resolution: {integrity: sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 + '@eslint-community/regexpp': 4.5.0 + '@eslint/eslintrc': 2.0.2 + '@eslint/js': 8.38.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.0 + eslint-visitor-keys: 3.4.0 + espree: 9.5.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.4.0 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /esm-env/1.0.0: resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} dev: true @@ -2173,6 +2617,15 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /espree/9.5.1: + resolution: {integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.2 + acorn-jsx: 5.3.2_acorn@8.8.2 + eslint-visitor-keys: 3.4.0 + dev: true + /esquery/1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -2462,6 +2915,10 @@ packages: resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} dev: true + /js-sdsl/4.4.0: + resolution: {integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==} + dev: true + /js-yaml/4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -2511,21 +2968,14 @@ packages: resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} dependencies: - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /magic-string/0.29.0: - resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/sourcemap-codec': 1.4.15 dev: true /magic-string/0.30.0: resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} engines: {node: '>=12'} dependencies: - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/sourcemap-codec': 1.4.15 dev: true /merge2/1.4.1: @@ -2590,8 +3040,8 @@ packages: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true - /nanoid/3.3.4: - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + /nanoid/3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true @@ -2713,7 +3163,16 @@ packages: resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.4 + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /postcss/8.4.23: + resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true @@ -2723,6 +3182,16 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /prettier-plugin-svelte/2.10.0_ur5pqdgn24bclu6l6i7qojopk4: + resolution: {integrity: sha512-GXMY6t86thctyCvQq+jqElO+MKdB09BkL3hexyGP3Oi8XLKRFaJP1ud/xlWCZ9ZIa2BxHka32zhHfcuU+XsRQg==} + peerDependencies: + prettier: ^1.16.4 || ^2.0.0 + svelte: ^3.2.0 + dependencies: + prettier: 2.8.7 + svelte: 3.58.0 + dev: true + /prettier-plugin-svelte/2.9.0_k23gl6auqwrxgr3e6o2bajswou: resolution: {integrity: sha512-3doBi5NO4IVgaNPtwewvrgPpqAcvNv0NwJNflr76PIGgi9nf1oguQV1Hpdm9TI2ALIQVn/9iIwLpBO5UcD2Jiw==} peerDependencies: @@ -2739,6 +3208,12 @@ packages: hasBin: true dev: true + /prettier/2.8.7: + resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /publint/0.1.9: resolution: {integrity: sha512-O53y7vbePxuGFmEjgcrafMSlDpOJwOkj8YdexOt7yWlv7SB3rXoT3mHknyMJ3lf2UFH5Bmt6tnIkHcOTR6dEoA==} engines: {node: '>=16'} @@ -2814,6 +3289,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup/3.20.6: + resolution: {integrity: sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -2850,6 +3333,10 @@ packages: resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} dev: true + /set-cookie-parser/2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + dev: true + /shebang-command/2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2868,14 +3355,14 @@ packages: dependencies: '@polka/url': 1.0.0-next.21 mrmime: 1.0.1 - totalist: 3.0.0 + totalist: 3.0.1 dev: true /sorcery/0.11.0: resolution: {integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==} hasBin: true dependencies: - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/sourcemap-codec': 1.4.15 buffer-crc32: 0.2.13 minimist: 1.2.8 sander: 0.5.1 @@ -2980,6 +3467,33 @@ packages: - sugarss dev: true + /svelte-check/3.2.0_svelte@3.58.0: + resolution: {integrity: sha512-6ZnscN8dHEN5Eq5LgIzjj07W9nc9myyBH+diXsUAuiY/3rt0l65/LCIQYlIuoFEjp2F1NhXqZiJwV9omPj9tMw==} + hasBin: true + peerDependencies: + svelte: ^3.55.0 + dependencies: + '@jridgewell/trace-mapping': 0.3.18 + chokidar: 3.5.3 + fast-glob: 3.2.12 + import-fresh: 3.3.0 + picocolors: 1.0.0 + sade: 1.8.1 + svelte: 3.58.0 + svelte-preprocess: 5.0.3_kxq5ayp4qfv2n6flkngpsntzw4 + typescript: 5.0.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + dev: true + /svelte-hmr/0.15.1_svelte@3.57.0: resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} engines: {node: ^12.20 || ^14.13.1 || >= 16} @@ -2989,6 +3503,15 @@ packages: svelte: 3.57.0 dev: true + /svelte-hmr/0.15.1_svelte@3.58.0: + resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: '>=3.19.0' + dependencies: + svelte: 3.58.0 + dev: true + /svelte-preprocess/5.0.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-0HXyhCoc9rsW4zGOgtInylC6qj259E1hpFnJMJWTf+aIfeqh4O/QHT31KT2hvPEqQfdjmqBR/kO2JDkkciBLrQ==} engines: {node: '>= 14.10.0'} @@ -3084,11 +3607,63 @@ packages: typescript: 4.9.5 dev: true + /svelte-preprocess/5.0.3_kxq5ayp4qfv2n6flkngpsntzw4: + resolution: {integrity: sha512-GrHF1rusdJVbOZOwgPWtpqmaexkydznKzy5qIC2FabgpFyKN57bjMUUUqPRfbBXK5igiEWn1uO/DXsa2vJ5VHA==} + engines: {node: '>= 14.10.0'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^3.23.0 + typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + detect-indent: 6.1.0 + magic-string: 0.27.0 + sorcery: 0.11.0 + strip-indent: 3.0.0 + svelte: 3.58.0 + typescript: 5.0.4 + dev: true + /svelte/3.57.0: resolution: {integrity: sha512-WMXEvF+RtAaclw0t3bPDTUe19pplMlfyKDsixbHQYgCWi9+O9VN0kXU1OppzrB9gPAvz4NALuoca2LfW2bOjTQ==} engines: {node: '>= 8'} dev: true + /svelte/3.58.0: + resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==} + engines: {node: '>= 8'} + dev: true + /svelte2tsx/0.6.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-O/1+5UyChfmhp1/GUv8b8iveTrn6eZwHxEXc+rw7LMKRidr9KHk5w/EiliLjDUwHa2VA6CoEty+CQylROVU4Sw==} peerDependencies: @@ -3119,8 +3694,8 @@ packages: is-number: 7.0.0 dev: true - /totalist/3.0.0: - resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==} + /totalist/3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} dev: true @@ -3149,6 +3724,19 @@ packages: hasBin: true dev: true + /typescript/5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true + dev: true + + /undici/5.20.0: + resolution: {integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==} + engines: {node: '>=12.18'} + dependencies: + busboy: 1.6.0 + dev: true + /undici/5.21.0: resolution: {integrity: sha512-HOjK8l6a57b2ZGXOcUsI5NLfoTrfmbOl90ixJDl0AEFG4wgHNDQxtZy15/ZQp7HhjkpaGlp/eneMgtsu1dIlUA==} engines: {node: '>=12.18'} @@ -3233,6 +3821,38 @@ packages: fsevents: 2.3.2 dev: true + /vite/4.3.0: + resolution: {integrity: sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.17.17 + postcss: 8.4.23 + rollup: 3.20.6 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vitefu/0.2.4_vite@4.1.3: resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} peerDependencies: @@ -3255,6 +3875,17 @@ packages: vite: 4.2.0 dev: true + /vitefu/0.2.4_vite@4.3.0: + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.3.0 + dev: true + /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'}