initial commit
This commit is contained in:
commit
a384da0f9d
39 changed files with 6193 additions and 0 deletions
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.vercel
|
||||||
|
.output
|
1
.npmrc
Normal file
1
.npmrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
engine-strict=true
|
38
README.md
Normal file
38
README.md
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# create-svelte
|
||||||
|
|
||||||
|
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
||||||
|
|
||||||
|
## Creating a project
|
||||||
|
|
||||||
|
If you're seeing this, you've probably already done this step. Congrats!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create a new project in the current directory
|
||||||
|
npm create svelte@latest
|
||||||
|
|
||||||
|
# create a new project in my-app
|
||||||
|
npm create svelte@latest my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Developing
|
||||||
|
|
||||||
|
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# or start the server and open the app in a new browser tab
|
||||||
|
npm run dev -- --open
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To create a production version of your app:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
You can preview the production build with `npm run preview`.
|
||||||
|
|
||||||
|
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
4567
package-lock.json
generated
Normal file
4567
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
27
package.json
Normal file
27
package.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"name": "allof-space",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"server": "node build/index.js --port 3000",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@fontsource/fira-mono": "^4.5.0",
|
||||||
|
"@neoconfetti/svelte": "^1.0.0",
|
||||||
|
"@sveltejs/adapter-auto": "next",
|
||||||
|
"@sveltejs/kit": "next",
|
||||||
|
"svelte": "^3.46.0",
|
||||||
|
"vite": "^3.1.0"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@sveltejs/adapter-node": "^1.0.0-next.96",
|
||||||
|
"bcrypt": "^5.0.1",
|
||||||
|
"cookie": "^0.5.0",
|
||||||
|
"sqlite": "^4.1.2",
|
||||||
|
"sqlite3": "^5.1.1",
|
||||||
|
"svelte-preprocess": "^4.10.7"
|
||||||
|
}
|
||||||
|
}
|
24
src/app.html
Normal file
24
src/app.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel="icon" href="/img/logo.svg">
|
||||||
|
|
||||||
|
<title>Aloreia</title>
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||||
|
<meta name="description" content="Create your community's hub on Aloreia" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/css/index.css">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700;900&display=swap" rel="stylesheet">
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body data-sveltekit-prefetch>
|
||||||
|
%sveltekit.body%
|
||||||
|
</body>
|
||||||
|
</html>
|
5
src/lib/components/Footer.svelte
Normal file
5
src/lib/components/Footer.svelte
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="footer">
|
||||||
|
<div class='header-section button-section'>
|
||||||
|
<a href="/about">About Us</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
56
src/lib/components/Form.svelte
Normal file
56
src/lib/components/Form.svelte
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<script>
|
||||||
|
export let params, header, data;
|
||||||
|
export let action = '';
|
||||||
|
export let id = '';
|
||||||
|
export let form = '';
|
||||||
|
|
||||||
|
export let submit = function(e) {
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
|
||||||
|
request.addEventListener('load', function() {
|
||||||
|
form = request.responseText;
|
||||||
|
});
|
||||||
|
|
||||||
|
request.open('POST', this.action, true);
|
||||||
|
request.send(new FormData(e.target));
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<div class="content-main form">
|
||||||
|
<div>
|
||||||
|
{#if form?.success == 'login'}
|
||||||
|
<p><i>Account successfully created. <a href='/login'>Log into an account to use it.</a></i></p>
|
||||||
|
{:else if form == 'exists'}
|
||||||
|
<p><i>Account already exists.</i></p>
|
||||||
|
{:else if form == 'missing'}
|
||||||
|
<p><i>Some parameters are missing.</i></p>
|
||||||
|
{:else if form == 'long'}
|
||||||
|
<p><i>Some parameters exceed the character limit.</i></p>
|
||||||
|
{:else if form == 'nouser'}
|
||||||
|
<p><i>This user does not exist.</i></p>
|
||||||
|
{:else if form == 'loggedin'}
|
||||||
|
<p><i>Successfully logged in.</i></p>
|
||||||
|
{:else if form == 'wrongpass'}
|
||||||
|
<p><i>Password is incorrect.</i></p>
|
||||||
|
{:else if form == 'invalid'}
|
||||||
|
<p><i>Username uses invalid characters.</i></p>
|
||||||
|
{:else if form == 'noauth'}
|
||||||
|
<p><i>User is not properly authenticated.</i></p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<form on:submit='{submit}' method="POST" id='{id}' action="{action}">
|
||||||
|
<h1>{header}</h1>
|
||||||
|
{#each params as param}
|
||||||
|
<p class='formleft'><input type='{param.type}' name='{param.name}' placeholder='{param.desc}'></p>
|
||||||
|
{/each}
|
||||||
|
<p class='formleft'><input type='submit' class='button' value='Submit'></p>
|
||||||
|
<slot name='extraInfo' />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<slot />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
31
src/lib/components/Header.svelte
Normal file
31
src/lib/components/Header.svelte
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<script>
|
||||||
|
import { dev } from '$app/environment';
|
||||||
|
var authJson = "";
|
||||||
|
async function main() {
|
||||||
|
if (dev) {
|
||||||
|
var authUser = await fetch('http://localhost:5173/api/auth/session',{method: 'POST'});
|
||||||
|
} else {
|
||||||
|
var authUser = await fetch('https://allof.space/api/auth/session',{method: 'POST'});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
authJson = await authUser.text();
|
||||||
|
} catch(error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
</script>
|
||||||
|
<div class="header">
|
||||||
|
<div class='header-section button-section'>
|
||||||
|
<img src="/img/logo-alt.svg" align="left" class="icon-logo">
|
||||||
|
<a href="/">Aloreia</a>
|
||||||
|
</div>
|
||||||
|
<div class='header-section button-section'>
|
||||||
|
{#if authJson == ""}
|
||||||
|
<a href="/register">Register</a>
|
||||||
|
<a href="/login">Login</a>
|
||||||
|
{:else}
|
||||||
|
<a href='/hub'>Explore</a>
|
||||||
|
<a href="/user/{authJson}">{authJson}</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
101
src/lib/components/Hub.svelte
Normal file
101
src/lib/components/Hub.svelte
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<script>
|
||||||
|
import Form from '$lib/components/Form.svelte';
|
||||||
|
import { dev } from '$app/environment';
|
||||||
|
|
||||||
|
let newhub, joinhub;
|
||||||
|
let popup = "nodisplay";
|
||||||
|
let hubJson = [];
|
||||||
|
|
||||||
|
function openForm() {
|
||||||
|
popup = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeForm() {
|
||||||
|
popup = 'nodisplay';
|
||||||
|
}
|
||||||
|
|
||||||
|
let upload;
|
||||||
|
let icon = '/img/logo.svg';
|
||||||
|
|
||||||
|
function changeProfile(e) {
|
||||||
|
upload.dispatchEvent(new MouseEvent('click'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function newIcon(e) {
|
||||||
|
icon = URL.createObjectURL(upload.files[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitFunc(e, url, form) {
|
||||||
|
e.preventDefault();
|
||||||
|
const dataArray = new FormData(e.submitter.parentElement.parentElement);
|
||||||
|
for (const file of upload.files) {
|
||||||
|
dataArray.append('img', file);
|
||||||
|
}
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: dataArray
|
||||||
|
});
|
||||||
|
closeForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
if (dev) {
|
||||||
|
var hubFetch = await fetch('http://localhost:5173/api/hub/list',{method: 'POST'});
|
||||||
|
} else {
|
||||||
|
var hubFetch = await fetch('https://allof.space/api/hub/list',{method: 'POST'});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
hubJson = await hubFetch.json();
|
||||||
|
} catch(error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class='content-wrapper'>
|
||||||
|
<div class='content-main'>
|
||||||
|
<h1><div class='button-section sbig'>
|
||||||
|
Your Hubs
|
||||||
|
<a href='#'><img src="/img/new.svg" class="icon-player" on:click={openForm}></a>
|
||||||
|
</div>
|
||||||
|
{#each hubJson as hubEntry}
|
||||||
|
<a href='#'><img src="/api/hub/img?q={hubEntry.hub}" class="icon-hub pfp"></a>
|
||||||
|
{/each}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class='content-main'>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
<div class='content-main'>
|
||||||
|
<h1><div class='button-sections sbig'>
|
||||||
|
Directories
|
||||||
|
</div></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='popup {popup}' on:click|self={closeForm}>
|
||||||
|
<Form params="{[
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"name": 'name',
|
||||||
|
'desc': 'Name of hub'
|
||||||
|
}
|
||||||
|
]}" submit='{(e) => submitFunc(e,"/api/hub/new")}' action='/api/hub/new' id='newhub' header="Create a hub...">
|
||||||
|
<input slot='extraInfo' form='newhub' type='file' accept='image/png' name='img' on:change='{newIcon}' bind:this='{upload}'>
|
||||||
|
|
||||||
|
<img src="{icon}" align='right' class="image-inline pfp" on:click={changeProfile}>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
|
||||||
|
<Form params="{[
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"name": 'invite',
|
||||||
|
'desc': 'Invite code'
|
||||||
|
}
|
||||||
|
]}" submit='{(e) => submitFunc(e,"/api/hub/join")}' bind:this='{joinhub}' action='/api/hub/join' header="Or join a hub">
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
</div>
|
61
src/lib/components/Video.svelte
Normal file
61
src/lib/components/Video.svelte
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<script>
|
||||||
|
export let videoSource = "/";
|
||||||
|
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
let displayPlay = 'block', displayPause = 'none';
|
||||||
|
let prog = 0, duration = 0, time = 0;
|
||||||
|
let video;
|
||||||
|
|
||||||
|
function play() {
|
||||||
|
displayPause = 'none';
|
||||||
|
displayPlay = 'block';
|
||||||
|
|
||||||
|
video.pause();
|
||||||
|
};
|
||||||
|
function pause() {
|
||||||
|
displayPause = 'block';
|
||||||
|
displayPlay = 'none';
|
||||||
|
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
function bar(e) {
|
||||||
|
var pos = (e.pageX - (this.offsetLeft + this.offsetParent.offsetLeft)) / this.offsetWidth;
|
||||||
|
video.currentTime = pos * video.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTime(time) {
|
||||||
|
let h = Math.floor(time / 60 / 60) + "";
|
||||||
|
let m = Math.floor(time / 60 % 60) + "";
|
||||||
|
let s = Math.floor(time % 60) + "";
|
||||||
|
|
||||||
|
var outString = s.padStart(2,"0");
|
||||||
|
outString = m.padStart(2,"0") + ":" + outString;
|
||||||
|
outString = h.padStart(2,"0") + ":" + outString;
|
||||||
|
|
||||||
|
return outString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function progress() {
|
||||||
|
prog = video.currentTime / video.duration * 100;
|
||||||
|
duration = parseTime(video.duration);
|
||||||
|
time = parseTime(video.currentTime);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class='content-main center'><div class='video-wrapper'>
|
||||||
|
<video class='video' bind:this='{video}' on:timeupdate='{progress}'>
|
||||||
|
<source
|
||||||
|
src="{videoSource}">
|
||||||
|
</video>
|
||||||
|
<div class='button-section'>
|
||||||
|
<img on:click='{pause}' src='/img/play.svg' class='icon-player' style='display: {displayPlay};'>
|
||||||
|
<img on:click='{play}' src='/img/pause.svg' class='icon-player' style='display: {displayPause};'>
|
||||||
|
<div on:click='{bar}' class='progress'>
|
||||||
|
<div class='progress-bar' style='width: {prog}%'></div>
|
||||||
|
<div class='progress-text'>
|
||||||
|
{time} / {duration}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
14
src/lib/db/auth.js
Normal file
14
src/lib/db/auth.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
export async function auth(event,db) {
|
||||||
|
var token = event.cookies.get('token');
|
||||||
|
var user = await db.all("SELECT user FROM token WHERE token = ?",token);
|
||||||
|
|
||||||
|
if (user && user.length > 0) {
|
||||||
|
user = user[0].user;
|
||||||
|
} else {
|
||||||
|
user = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
21
src/lib/db/db.js
Normal file
21
src/lib/db/db.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { open } from 'sqlite'
|
||||||
|
import sqlite3 from 'sqlite3'
|
||||||
|
|
||||||
|
var initDb = async _ => {
|
||||||
|
var db = await open({
|
||||||
|
filename: '../space-data/main.sql',
|
||||||
|
driver: sqlite3.Database
|
||||||
|
});
|
||||||
|
|
||||||
|
db.run("CREATE TABLE IF NOT EXISTS auth (user TEXT, email TEXT, password TEXT)");
|
||||||
|
db.run("CREATE TABLE IF NOT EXISTS token (user TEXT, token TEXT)");
|
||||||
|
db.run("CREATE TABLE IF NOT EXISTS hubpairs (hub TEXT, user TEXT)");
|
||||||
|
db.run("CREATE TABLE IF NOT EXISTS hub (hub TEXT, invite TEXT)");
|
||||||
|
|
||||||
|
return db;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export {initDb};
|
||||||
|
|
||||||
|
|
12
src/routes/+layout.svelte
Normal file
12
src/routes/+layout.svelte
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<script>
|
||||||
|
import Header from '$lib/components/Header.svelte'
|
||||||
|
import Footer from '$lib/components/Footer.svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<div class='main'>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
26
src/routes/+page.svelte
Normal file
26
src/routes/+page.svelte
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<h1 class='big'>Create Your Hub</h1>
|
||||||
|
<div class="landing-wrapper">
|
||||||
|
<div class='sbig'>
|
||||||
|
<p>
|
||||||
|
We are a platform where anyone can build up their community and chat with others. This isn't just another basic messaging application, a wide array of features (i.e. Videos, Forms, Websites, Chat, Permissions, Automation) will also present for you to take advantage of.
|
||||||
|
</p>
|
||||||
|
<p><i>
|
||||||
|
This network is in an extremely early stage of development (pre-beta), most features will be missing or barely usable.
|
||||||
|
</i></p>
|
||||||
|
</div><div class='landing-logo'>
|
||||||
|
<img src='/img/logo.svg' class='image-inline' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-main">
|
||||||
|
<h1>Socialize with others</h1>
|
||||||
|
<p>
|
||||||
|
Hubs on Aloreia feature chat rooms, where anyone can discuss their favorite topics.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="content-main">
|
||||||
|
<h1>Easily design a website</h1>
|
||||||
|
<p>
|
||||||
|
With the Website feature, anyone can make their community have a public facing source of information that will stand out to the world.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
46
src/routes/api/account/register/+server.js
Normal file
46
src/routes/api/account/register/+server.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {hash} from 'bcrypt';
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
const saltRounds = 10;
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var data = await event.request.formData();
|
||||||
|
var user = data.get("username");
|
||||||
|
|
||||||
|
var rows = await db.all(
|
||||||
|
"SELECT * from auth WHERE user = ?",
|
||||||
|
[user]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows.length == 0) {
|
||||||
|
var state = await register(data);
|
||||||
|
return {success: state};
|
||||||
|
} else {
|
||||||
|
return {success: 'exists'};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function register(data) {
|
||||||
|
var user = data.get("username");
|
||||||
|
var email = data.get("email");
|
||||||
|
var password = data.get("password");
|
||||||
|
|
||||||
|
if (!password || !email || !user) return 'missing';
|
||||||
|
if (password.length > 256 || email.length > 64 || user.length > 32) return 'long';
|
||||||
|
|
||||||
|
const userTest = new RegExp("^[A-Za-z0-9_-]+$");
|
||||||
|
if (!userTest.test(user)) return 'invalid';
|
||||||
|
|
||||||
|
var passHash = await hash(password,saltRounds);
|
||||||
|
|
||||||
|
await db.run(
|
||||||
|
"INSERT INTO auth (user,email,password) VALUES (?,?,?)",
|
||||||
|
[user,email,passHash]
|
||||||
|
);
|
||||||
|
|
||||||
|
return 'login';
|
||||||
|
}
|
44
src/routes/api/auth/login/+server.js
Normal file
44
src/routes/api/auth/login/+server.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {compare} from 'bcrypt';
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
import {randomBytes} from 'crypto';
|
||||||
|
import { serialize } from 'cookie';
|
||||||
|
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var data = await event.request.formData();
|
||||||
|
var user = data.get("username");
|
||||||
|
var password = data.get("password");
|
||||||
|
|
||||||
|
var rows = await db.all(
|
||||||
|
"SELECT * from auth WHERE user = ?",
|
||||||
|
[user]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rows && rows.length > 0) {
|
||||||
|
var isPass = await compare(password,rows[0].password);
|
||||||
|
} else {
|
||||||
|
return new Response('nouser');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPass) {
|
||||||
|
var token = randomBytes(64).toString('hex');
|
||||||
|
await db.run("DELETE FROM token WHERE user = ?",user);
|
||||||
|
await db.run("INSERT INTO token (user,token) VALUES (?,?)",user,token);
|
||||||
|
|
||||||
|
event.cookies.set('token',token,{
|
||||||
|
path: '/',
|
||||||
|
httpOnly: true,
|
||||||
|
sameSite: 'strict',
|
||||||
|
secure: true,
|
||||||
|
maxAge: 60 * 60 * 24 * 7
|
||||||
|
})
|
||||||
|
return new Response('loggedin');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return new Response('wrongpass');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
14
src/routes/api/auth/session/+server.js
Normal file
14
src/routes/api/auth/session/+server.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
import {auth} from '$lib/db/auth.js';
|
||||||
|
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var user = await auth(event,db);
|
||||||
|
|
||||||
|
return new Response(user);
|
||||||
|
}
|
||||||
|
|
13
src/routes/api/hub/img/+server.js
Normal file
13
src/routes/api/hub/img/+server.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {readFileSync} from 'fs';
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function GET(event) {
|
||||||
|
let hub = event.url.searchParams.get('q') + '.png';
|
||||||
|
return new Response(readFileSync(`${process.cwd()}/../space-data/hub/${hub}`));
|
||||||
|
}
|
||||||
|
|
29
src/routes/api/hub/join/+server.js
Normal file
29
src/routes/api/hub/join/+server.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
import {auth} from '$lib/db/auth.js';
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var user = await auth(event,db);
|
||||||
|
if (!user) return new Response('authfail');
|
||||||
|
|
||||||
|
const dat = await event.request.formData();
|
||||||
|
var name = '';
|
||||||
|
dat.forEach(async (file, key) => {
|
||||||
|
if (key == 'invite') {
|
||||||
|
name = file.trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var hub = await db.all("SELECT hub FROM hub WHERE invite = ?",name);
|
||||||
|
|
||||||
|
if (!hub || hub.length < 1) return new Response('nohub');
|
||||||
|
|
||||||
|
await db.run("DELETE FROM hubpairs WHERE hub = ? AND user = ?",hub[0].hub,user);
|
||||||
|
await db.run("INSERT INTO hubpairs (hub,user) VALUES (?,?)",hub[0].hub,user);
|
||||||
|
|
||||||
|
|
||||||
|
return new Response('success');
|
||||||
|
};
|
||||||
|
|
13
src/routes/api/hub/list/+server.js
Normal file
13
src/routes/api/hub/list/+server.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
import {auth} from '$lib/db/auth.js';
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var user = await auth(event,db);
|
||||||
|
var hubs = await db.all("SELECT hub FROM hubpairs WHERE user = ?",user);
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(hubs));
|
||||||
|
}
|
46
src/routes/api/hub/new/+server.js
Normal file
46
src/routes/api/hub/new/+server.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
import {auth} from '$lib/db/auth.js';
|
||||||
|
import {initDb} from '$lib/db/db.js';
|
||||||
|
import {writeFileSync} from 'fs';
|
||||||
|
import {randomBytes} from 'crypto';
|
||||||
|
const db = await initDb();
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function POST(event) {
|
||||||
|
var user = await auth(event,db);
|
||||||
|
if (!user) return new Response('authfail');
|
||||||
|
|
||||||
|
const dat = await event.request.formData();
|
||||||
|
var name = '';
|
||||||
|
dat.forEach(async (file, key) => {
|
||||||
|
if (key == 'name') {
|
||||||
|
name = file.trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (name.length > 64) return new Response('long');
|
||||||
|
|
||||||
|
|
||||||
|
const userTest = new RegExp("^[A-Za-z0-9_ -]+$");
|
||||||
|
if (!userTest.test(name)) return new Response('invalid');
|
||||||
|
|
||||||
|
var hubs = await db.all("SELECT hub FROM hubpairs WHERE hub = ?",name);
|
||||||
|
|
||||||
|
if (hubs && hubs.length > 0) return new Response('hubexists');
|
||||||
|
|
||||||
|
const file = '';
|
||||||
|
dat.forEach(async (file, key) => {
|
||||||
|
if (key == 'img' && file.arrayBuffer) {
|
||||||
|
writeFileSync(`${process.cwd()}/../space-data/hub/${name}.png`, Buffer.from(await file.arrayBuffer()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var invite = randomBytes(16).toString('hex');
|
||||||
|
|
||||||
|
await db.run("INSERT INTO hubpairs (hub,user) VALUES (?,?)",name,user);
|
||||||
|
await db.run("INSERT INTO hub (hub,invite) VALUES (?,?)",name,invite);
|
||||||
|
|
||||||
|
|
||||||
|
return new Response('success');
|
||||||
|
};
|
||||||
|
|
9
src/routes/hub/+page.svelte
Normal file
9
src/routes/hub/+page.svelte
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<script>
|
||||||
|
import Hub from '$lib/components/Hub.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Hub>
|
||||||
|
<h1><div class='button-section sbig'>
|
||||||
|
Explore
|
||||||
|
</div></h1>
|
||||||
|
</Hub>
|
6
src/routes/hub/[hub]/+page.svelte
Normal file
6
src/routes/hub/[hub]/+page.svelte
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<div class='content-wrapper'>
|
||||||
|
<div class='content-main'><p>test</p></div>
|
||||||
|
<div class='content-main'><p>test</p></div>
|
||||||
|
<div class='content-main'><p>test</p></div>
|
||||||
|
<div class='content-main'><p>test</p></div>
|
||||||
|
</div>
|
18
src/routes/login/+page.svelte
Normal file
18
src/routes/login/+page.svelte
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
import Form from '$lib/components/Form.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Form params="{[
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"name": 'username',
|
||||||
|
'desc': 'Username'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "password",
|
||||||
|
"name": 'password',
|
||||||
|
'desc': 'Password'
|
||||||
|
},
|
||||||
|
|
||||||
|
]}" action='/api/auth/login' header="Log in">
|
||||||
|
</Form>
|
24
src/routes/register/+page.svelte
Normal file
24
src/routes/register/+page.svelte
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<script>
|
||||||
|
import Form from '$lib/components/Form.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Form params="{[
|
||||||
|
{
|
||||||
|
"type": "email",
|
||||||
|
"name": 'email',
|
||||||
|
'desc': 'Email address'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"name": 'username',
|
||||||
|
'desc': 'Username'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "password",
|
||||||
|
"name": 'password',
|
||||||
|
'desc': 'Password'
|
||||||
|
},
|
||||||
|
|
||||||
|
]}" action="/api/account/register" header="Register">
|
||||||
|
By creating an account, you are consenting to permanently follow the <a href='/tos'>Terms of Service</a> and <a href='/guidelines'>Community Guidelines</a>.
|
||||||
|
</Form>
|
1
src/routes/user/[user]/+page.svelte
Normal file
1
src/routes/user/[user]/+page.svelte
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
353
static/css/index.css
Normal file
353
static/css/index.css
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
:root {
|
||||||
|
--bg-1: #2b2323;
|
||||||
|
--bg-2: #181515;
|
||||||
|
|
||||||
|
--fg-1: #ffffff;
|
||||||
|
|
||||||
|
--shadow-1: rgba(0,0,0,1);
|
||||||
|
|
||||||
|
--primary-1: #cd3030;
|
||||||
|
--primary-2: #2b2323;
|
||||||
|
|
||||||
|
--box-1: #edddab;
|
||||||
|
|
||||||
|
--shadow-box-1: 0 2px 10px -4px var(--shadow-1);
|
||||||
|
font-family: "Noto Sans", sans-serif;
|
||||||
|
|
||||||
|
font-size: 0.85rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
min-height: calc(100vh - 6rem);
|
||||||
|
width: 100vw;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
font-size: 0.8rem;
|
||||||
|
|
||||||
|
background: var(--bg-2);
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
background-size: 1.5rem 1.5rem;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
color: var(--fg-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 1rem;
|
||||||
|
background: var(--bg-1);
|
||||||
|
max-width: 80vw;
|
||||||
|
width: 800px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: var(--shadow-box-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: auto;
|
||||||
|
height: 1rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo {
|
||||||
|
width: auto;
|
||||||
|
height: 3rem;
|
||||||
|
margin-right: 0rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-player {
|
||||||
|
width: auto;
|
||||||
|
height: 2rem;
|
||||||
|
margin: 0.3rem;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-hub {
|
||||||
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
margin: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: var(--primary-1);
|
||||||
|
color: var(--fg-1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 10rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, .button {
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 0.3rem;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-section {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form div {
|
||||||
|
width: 45%;
|
||||||
|
padding: 0 0 0 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formleft {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, .p {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.p {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header, .footer {
|
||||||
|
background: var(--primary-2);
|
||||||
|
justify-content: space-between;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
box-shadow: var(--shadow-box-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: var(--bg-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: 700;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big {
|
||||||
|
font-size: 300%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sbig {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #40acff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header a, .footer a {
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--dark-1);
|
||||||
|
padding-right: 1.0rem;
|
||||||
|
padding-left: 1.0rem;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
|
||||||
|
height: 3rem;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-inline {
|
||||||
|
height: 10rem;
|
||||||
|
width: 10rem;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video {
|
||||||
|
width: 700px;
|
||||||
|
height: auto;
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
max-width: 70vw;
|
||||||
|
margin: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 70vw;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
.landing-wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.landing-logo {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
width: 80%;
|
||||||
|
height: 0.8rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--dark-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
background-color: var(--primary-1);
|
||||||
|
height: 0.8rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
transition: width 0.2s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-text {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
font-weight: bold;
|
||||||
|
top: -3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-wrapper {
|
||||||
|
width: calc(700px+4rem);
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 3fr 1fr;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper .content-main {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
max-width: none;
|
||||||
|
height: 85vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper .content-main::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper .content-main h1 {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
background-color: var(--light-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width:1000px) {
|
||||||
|
.content-wrapper {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.form {
|
||||||
|
}
|
||||||
|
.form div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-section a {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 .button-section {
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(0,0,0,0.7);
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup.nodisplay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-logo {
|
||||||
|
filter: drop-shadow(0 0 20px var(--primary-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="file"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfp {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
0
static/img/favicon.svg
Normal file
0
static/img/favicon.svg
Normal file
100
static/img/logo-alt.svg
Normal file
100
static/img/logo-alt.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9 KiB |
136
static/img/logo-legacy.svg
Normal file
136
static/img/logo-legacy.svg
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="250mm"
|
||||||
|
height="250mm"
|
||||||
|
viewBox="0 0 250 250"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="logo-legacy.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||||
|
inkscape:export-filename="malloc62d-icon.png"
|
||||||
|
inkscape:export-xdpi="24.379999"
|
||||||
|
inkscape:export-ydpi="24.379999"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.77593294"
|
||||||
|
inkscape:cx="459.44692"
|
||||||
|
inkscape:cy="521.30794"
|
||||||
|
inkscape:window-width="1880"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="42"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" /><defs
|
||||||
|
id="defs2"><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2647"><stop
|
||||||
|
style="stop-color:#ffb51f;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2643" /><stop
|
||||||
|
style="stop-color:#efe32f;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2645" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2639"><stop
|
||||||
|
style="stop-color:#ff1f9b;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2635" /><stop
|
||||||
|
style="stop-color:#f42a2a;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2637" /></linearGradient><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="188.97637"
|
||||||
|
height="188.97638"
|
||||||
|
patternTransform="translate(-5.5364173e-6,1.2364665e-5)"
|
||||||
|
id="pattern14822"><rect
|
||||||
|
style="fill:#e5e5e5;fill-opacity:1;stroke:none;stroke-width:50.0001;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect14409"
|
||||||
|
width="94.488182"
|
||||||
|
height="94.48819"
|
||||||
|
x="0"
|
||||||
|
y="0" /><rect
|
||||||
|
style="fill:#e5e5e5;fill-opacity:1;stroke:none;stroke-width:50.0001;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect14456"
|
||||||
|
width="94.488182"
|
||||||
|
height="94.48819"
|
||||||
|
x="94.48819"
|
||||||
|
y="94.48819" /></pattern><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="208.68852"
|
||||||
|
height="146.2949"
|
||||||
|
patternTransform="translate(-328.73275,43.524551)"
|
||||||
|
id="pattern4915"><rect
|
||||||
|
style="fill:#000000;fill-opacity:0.536381;stroke:none;stroke-width:42.081;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect4911"
|
||||||
|
width="79.975555"
|
||||||
|
height="79.07309"
|
||||||
|
x="-11.229265"
|
||||||
|
y="27.470825"
|
||||||
|
transform="matrix(0.92917028,-0.36965198,0.37981747,0.92506145,0,0)" /><rect
|
||||||
|
style="fill:#000000;fill-opacity:0.536381;stroke:none;stroke-width:42.081;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect4913"
|
||||||
|
width="79.975555"
|
||||||
|
height="79.07309"
|
||||||
|
x="68.746323"
|
||||||
|
y="106.54388"
|
||||||
|
transform="matrix(0.92917028,-0.36965198,0.37981747,0.92506145,0,0)" /></pattern><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="151.1811"
|
||||||
|
height="151.18111"
|
||||||
|
patternTransform="translate(1.2322854e-5,-1.0464052e-5)"
|
||||||
|
id="pattern4985"><rect
|
||||||
|
style="opacity:0.475458;fill:#000000;fill-opacity:0.65538;stroke:none;stroke-width:27.4349;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4979"
|
||||||
|
width="75.590553"
|
||||||
|
height="75.590553"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
ry="0" /><rect
|
||||||
|
style="opacity:0.475458;fill:#000000;fill-opacity:0.65538;stroke:none;stroke-width:27.4349;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4983"
|
||||||
|
width="75.590553"
|
||||||
|
height="75.590553"
|
||||||
|
x="75.590546"
|
||||||
|
y="75.590553"
|
||||||
|
ry="0" /></pattern><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2639"
|
||||||
|
id="linearGradient2641"
|
||||||
|
x1="161.15768"
|
||||||
|
y1="210.52983"
|
||||||
|
x2="129.85103"
|
||||||
|
y2="130.7025"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2647"
|
||||||
|
id="linearGradient2649"
|
||||||
|
x1="132.88432"
|
||||||
|
y1="116.86043"
|
||||||
|
x2="108.41238"
|
||||||
|
y2="27.568117"
|
||||||
|
gradientUnits="userSpaceOnUse" /></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"><path
|
||||||
|
id="path4678"
|
||||||
|
style="fill:url(#linearGradient2649);fill-opacity:1;fill-rule:evenodd;stroke-width:2.64583333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke:none;stroke-opacity:1;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
|
d="M 125.00012 23.91792 L 113.24063 35.677409 L 98.837895 27.362154 L 90.52264 41.764376 L 74.459021 37.460246 L 70.154891 53.524382 L 53.524382 53.524382 L 53.524382 70.154891 L 37.460246 74.459021 L 41.764376 90.52264 L 27.362154 98.837895 L 35.677409 113.24063 L 23.91792 125.00012 L 35.677409 136.75961 L 27.362154 151.16183 L 85.23304 135.65529 L 66.777319 125.00012 L 85.23304 114.34444 L 74.57736 95.888721 L 95.888721 95.888721 L 95.888721 74.57736 L 114.34444 85.23304 L 125.00012 66.777319 L 135.65529 85.23304 L 154.11152 74.57736 L 154.11152 95.888721 L 175.42237 95.888721 L 164.7672 114.34444 L 222.63757 98.837895 L 208.23535 90.52264 L 212.53948 74.459021 L 196.47586 70.154891 L 196.47586 53.524382 L 179.84535 53.524382 L 175.54122 37.460246 L 159.47709 41.764893 L 151.16183 27.362154 L 136.75961 35.677409 L 125.00012 23.91792 z " /><path
|
||||||
|
id="path1375"
|
||||||
|
style="fill:url(#linearGradient2641);fill-opacity:1;fill-rule:evenodd;stroke-width:2.64583333;stroke-linecap:round;stroke-miterlimit:10;paint-order:stroke fill markers;stroke:none;stroke-opacity:1;stroke-dasharray:none;stroke-linejoin:round"
|
||||||
|
d="M 222.63757 98.837895 L 164.7672 114.34444 L 183.22292 125.00012 L 164.76669 135.6558 L 175.42237 154.11152 L 154.11152 154.11152 L 154.11152 175.42237 L 135.6558 164.7672 L 125.00012 183.22292 L 114.34444 164.7672 L 95.888721 175.42237 L 95.888721 154.11152 L 74.57736 154.11152 L 85.23304 135.65529 L 27.362154 151.16183 L 41.764376 159.47709 L 37.460246 175.54122 L 53.524382 179.84535 L 53.524382 196.47586 L 70.154891 196.47586 L 74.459021 212.53948 L 90.52264 208.23535 L 98.837895 222.63757 L 113.24063 214.32232 L 125.00012 226.08181 L 136.75961 214.32232 L 151.16183 222.63757 L 159.47709 208.23535 L 175.54122 212.53948 L 179.84535 196.47586 L 196.47586 196.47586 L 196.47586 179.84535 L 212.53948 175.54122 L 208.23535 159.47709 L 222.63757 151.16183 L 214.32232 136.75961 L 226.08181 125.00012 L 214.32232 113.24063 L 222.63757 98.837895 z " /></g></svg>
|
After Width: | Height: | Size: 7.2 KiB |
132
static/img/logo.svg
Normal file
132
static/img/logo.svg
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="250mm"
|
||||||
|
height="250mm"
|
||||||
|
viewBox="0 0 250 250"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="logo.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||||
|
inkscape:export-filename="malloc62d-icon.png"
|
||||||
|
inkscape:export-xdpi="24.379999"
|
||||||
|
inkscape:export-ydpi="24.379999"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.78"
|
||||||
|
inkscape:cx="243.58974"
|
||||||
|
inkscape:cy="496.79487"
|
||||||
|
inkscape:window-width="1880"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="42"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" /><defs
|
||||||
|
id="defs2"><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="188.97637"
|
||||||
|
height="188.97638"
|
||||||
|
patternTransform="translate(-5.5364173e-6,1.2364665e-5)"
|
||||||
|
id="pattern14822"><rect
|
||||||
|
style="fill:#e5e5e5;fill-opacity:1;stroke:none;stroke-width:50.0001;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect14409"
|
||||||
|
width="94.488182"
|
||||||
|
height="94.48819"
|
||||||
|
x="0"
|
||||||
|
y="0" /><rect
|
||||||
|
style="fill:#e5e5e5;fill-opacity:1;stroke:none;stroke-width:50.0001;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect14456"
|
||||||
|
width="94.488182"
|
||||||
|
height="94.48819"
|
||||||
|
x="94.48819"
|
||||||
|
y="94.48819" /></pattern><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="208.68852"
|
||||||
|
height="146.2949"
|
||||||
|
patternTransform="translate(-328.73275,43.524551)"
|
||||||
|
id="pattern4915"><rect
|
||||||
|
style="fill:#000000;fill-opacity:0.536381;stroke:none;stroke-width:42.081;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect4911"
|
||||||
|
width="79.975555"
|
||||||
|
height="79.07309"
|
||||||
|
x="-11.229265"
|
||||||
|
y="27.470825"
|
||||||
|
transform="matrix(0.92917028,-0.36965198,0.37981747,0.92506145,0,0)" /><rect
|
||||||
|
style="fill:#000000;fill-opacity:0.536381;stroke:none;stroke-width:42.081;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect4913"
|
||||||
|
width="79.975555"
|
||||||
|
height="79.07309"
|
||||||
|
x="68.746323"
|
||||||
|
y="106.54388"
|
||||||
|
transform="matrix(0.92917028,-0.36965198,0.37981747,0.92506145,0,0)" /></pattern><pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="151.1811"
|
||||||
|
height="151.18111"
|
||||||
|
patternTransform="translate(1.2322854e-5,-1.0464052e-5)"
|
||||||
|
id="pattern4985"><rect
|
||||||
|
style="opacity:0.475458;fill:#000000;fill-opacity:0.65538;stroke:none;stroke-width:27.4349;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4979"
|
||||||
|
width="75.590553"
|
||||||
|
height="75.590553"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
ry="0" /><rect
|
||||||
|
style="opacity:0.475458;fill:#000000;fill-opacity:0.65538;stroke:none;stroke-width:27.4349;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4983"
|
||||||
|
width="75.590553"
|
||||||
|
height="75.590553"
|
||||||
|
x="75.590546"
|
||||||
|
y="75.590553"
|
||||||
|
ry="0" /></pattern></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"><circle
|
||||||
|
style="fill:#cd4040;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:13.2292;stroke-linecap:square;stroke-miterlimit:10;paint-order:stroke fill markers"
|
||||||
|
id="path1451"
|
||||||
|
cx="124.99999"
|
||||||
|
cy="124.99999"
|
||||||
|
r="93.44413" /><path
|
||||||
|
id="circle1549"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.29166667;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 193.29392,152.89987 C 186.67696,120.42905 158.11878,97.102143 124.98063,97.100146 91.857022,97.120573 63.320135,120.44331 56.706085,152.89987"
|
||||||
|
sodipodi:nodetypes="ccc" /><path
|
||||||
|
id="path2113"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.29166667;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 193.29392,152.89987 C 186.67696,120.42905 158.11878,97.102143 124.98063,97.100146 91.857022,97.120573 63.320135,120.44331 56.706085,152.89987"
|
||||||
|
sodipodi:nodetypes="ccc" /><path
|
||||||
|
id="path2135"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.29166667;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 97.100136,193.29393 C 129.57095,186.67697 152.89786,158.11879 152.89986,124.98063 152.87943,91.857018 129.55669,63.320131 97.100136,56.706076"
|
||||||
|
sodipodi:nodetypes="ccc" /><path
|
||||||
|
id="path2137"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.29166667;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="m 56.706077,97.100146 c 6.616963,32.470814 35.175142,55.797724 68.313313,55.799724 33.12359,-0.0204 61.66048,-23.34317 68.27453,-55.799724"
|
||||||
|
sodipodi:nodetypes="ccc" /><path
|
||||||
|
id="path2139"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.29166667;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="m 152.89986,56.706076 c -32.47081,6.616963 -55.797716,35.175142 -55.799724,68.313314 0.02043,33.1236 23.343164,61.66049 55.799724,68.27454"
|
||||||
|
sodipodi:nodetypes="ccc" /><g
|
||||||
|
id="g2280"
|
||||||
|
transform="matrix(0.27663061,0,0,0.27787109,61.191721,88.428483)"
|
||||||
|
style="stroke-width:19.08625315;stroke-dasharray:none"><path
|
||||||
|
id="path1533"
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:19.08625315;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
|
d="m 267.23201,106.75292 a 36.586533,36.586533 0 0 1 -36.58653,36.58653 36.586533,36.586533 0 0 1 -36.58653,-36.58653 36.586533,36.586533 0 0 1 36.58653,-36.586537 36.586533,36.586533 0 0 1 36.58653,36.586537 z" /><path
|
||||||
|
id="circle1549-3"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:19.08625315;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="m 289.84044,192.58508 c -5.73373,-28.13661 -30.47996,-48.34984 -59.19484,-48.35157 -28.70226,0.0177 -53.43004,20.22732 -59.16125,48.35157"
|
||||||
|
sodipodi:nodetypes="ccc" /></g></g></svg>
|
After Width: | Height: | Size: 7.2 KiB |
81
static/img/new.svg
Normal file
81
static/img/new.svg
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="89.562248mm"
|
||||||
|
height="90.684998mm"
|
||||||
|
viewBox="0 0 89.562248 90.684997"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1433"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||||
|
sodipodi:docname="new.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1435"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.79909512"
|
||||||
|
inkscape:cx="102.61607"
|
||||||
|
inkscape:cy="124.51584"
|
||||||
|
inkscape:window-width="1880"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="42"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="rect1660" />
|
||||||
|
<defs
|
||||||
|
id="defs1430" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-64.066106,-129.18941)">
|
||||||
|
<g
|
||||||
|
id="rect1660"
|
||||||
|
transform="translate(2.835344,-26.818262)">
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:13.2292;stroke-linecap:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect1979"
|
||||||
|
width="64.751602"
|
||||||
|
height="10.947486"
|
||||||
|
x="73.636078"
|
||||||
|
y="195.87643"
|
||||||
|
ry="5.473743" />
|
||||||
|
<path
|
||||||
|
d="m 100.56141,189.28258 m 0,0 c 0,3.70038 -2.978677,6.6795 -6.67905,6.6795 h 6.67905 z m -6.67905,6.6795"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.29169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path1184" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:13.2292;stroke-linecap:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect1998"
|
||||||
|
width="64.751602"
|
||||||
|
height="10.947486"
|
||||||
|
x="168.97438"
|
||||||
|
y="-111.48564"
|
||||||
|
ry="5.473743"
|
||||||
|
transform="rotate(90)" />
|
||||||
|
<path
|
||||||
|
d="m 111.34599,189.24806 m 0,0 c 0,3.70038 2.97867,6.6795 6.67905,6.6795 h -6.67905 z m 6.67905,6.6795"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.29169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path1209" />
|
||||||
|
<path
|
||||||
|
d="m 100.63886,213.22883 m 0,0 c 0,-3.70037 -2.978675,-6.67949 -6.679048,-6.67949 h 6.679048 z m -6.679048,-6.67949"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.29169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path1211" />
|
||||||
|
<path
|
||||||
|
d="m 111.42344,213.26335 m 0,0 c 0,-3.70038 2.97867,-6.67949 6.67905,-6.67949 h -6.67905 z m 6.67905,-6.67949"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.29169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path1213" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
56
static/img/pause.svg
Normal file
56
static/img/pause.svg
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="89.562248mm"
|
||||||
|
height="90.684998mm"
|
||||||
|
viewBox="0 0 89.562248 90.684997"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1433"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||||
|
sodipodi:docname="pause.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1435"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.79909512"
|
||||||
|
inkscape:cx="23.776894"
|
||||||
|
inkscape:cy="95.733284"
|
||||||
|
inkscape:window-width="1880"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="42"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="rect1660" />
|
||||||
|
<defs
|
||||||
|
id="defs1430" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-64.066106,-129.18941)">
|
||||||
|
<g
|
||||||
|
id="rect1660"
|
||||||
|
transform="translate(2.835344,-26.818262)">
|
||||||
|
<path
|
||||||
|
style="color:#000000;fill:#000000;fill-rule:evenodd;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;-inkscape-stroke:none;paint-order:stroke fill markers"
|
||||||
|
d="m 70.822582,158.5625 v 6.61523 70.96485 6.61328 h 24.071635 v -6.61328 -70.96485 -6.61523 z"
|
||||||
|
id="path3217" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;fill:#000000;fill-rule:evenodd;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;-inkscape-stroke:none;paint-order:stroke fill markers"
|
||||||
|
d="m 118.44759,158.5625 v 6.61523 70.96485 6.61328 h 24.07165 v -6.61328 -70.96485 -6.61523 z"
|
||||||
|
id="path5540" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
53
static/img/play.svg
Normal file
53
static/img/play.svg
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="96.923981mm"
|
||||||
|
height="116.49903mm"
|
||||||
|
viewBox="0 0 96.923981 116.49903"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1433"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||||
|
sodipodi:docname="play.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1435"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.1300912"
|
||||||
|
inkscape:cx="-7.963959"
|
||||||
|
inkscape:cy="208.39026"
|
||||||
|
inkscape:window-width="1880"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="42"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="rect1660" />
|
||||||
|
<defs
|
||||||
|
id="defs1430" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-60.400215,-116.38079)">
|
||||||
|
<g
|
||||||
|
id="rect1660"
|
||||||
|
transform="translate(2.835344,-26.818262)">
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:7.9375;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
d="M 76.874192,243.57895 139.0562,202.45448 76.874192,160.46218 Z"
|
||||||
|
id="path3217"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
0
static/js/editor.js
Normal file
0
static/js/editor.js
Normal file
5
static/robots.txt
Normal file
5
static/robots.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /login/
|
||||||
|
Disallow: /register/
|
||||||
|
Disallow: /auth/
|
13
svelte.config.js
Normal file
13
svelte.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import adapter from '@sveltejs/adapter-node';
|
||||||
|
import preprocess from 'svelte-preprocess';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
preprocess: preprocess(),
|
||||||
|
kit: {
|
||||||
|
adapter: adapter({out: 'build'}),
|
||||||
|
csrf: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
7
vite.config.js
Normal file
7
vite.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
plugins: [sveltekit()]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
Loading…
Reference in a new issue