added everything
.
This commit is contained in:
parent
dcae12453c
commit
fcd279884c
15 changed files with 309 additions and 136 deletions
|
@ -26,15 +26,26 @@
|
||||||
#main {
|
#main {
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#main.tiny {
|
||||||
|
min-height: initial;
|
||||||
|
height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export let tiny = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
<div id='content'>
|
<div id='content'>
|
||||||
<div id='header'>
|
<div id='header'>
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
Header
|
Header
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div id='main'>
|
<div id='main' class='{tiny ? "tiny" : ""}'>
|
||||||
<slot name="main">
|
<slot name="main">
|
||||||
<p>Content</p>
|
<p>Content</p>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<script>
|
|
||||||
import Area from '$lib/Area.svelte';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Area>
|
|
||||||
<p slot="header">
|
|
||||||
Welcome to SvelteKit
|
|
||||||
</p>
|
|
||||||
<p slot="main">
|
|
||||||
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
|
||||||
</p>
|
|
||||||
<p slot="footer">
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</Area>
|
|
|
@ -1,15 +1,75 @@
|
||||||
<script>
|
<script>
|
||||||
import Area from '$lib/Area.svelte';
|
import Area from '$lib/Area.svelte';
|
||||||
|
|
||||||
|
export let success, username, content, upvotes, downvotes, id;
|
||||||
|
|
||||||
|
let query = (id) ? `/post/${id}` : '';
|
||||||
|
|
||||||
|
let contentSplit = content.split('\n');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.button {
|
||||||
|
width: auto;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
.votes {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.vote-area {
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if success}
|
||||||
<Area>
|
<Area>
|
||||||
<p slot="header">
|
<p slot="header">
|
||||||
Welcome to SvelteKit
|
Error
|
||||||
</p>
|
</p>
|
||||||
<p slot="main">
|
<p slot="main">
|
||||||
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
{success}
|
||||||
</p>
|
</p>
|
||||||
<p slot="footer">
|
<p slot="footer">
|
||||||
|
Failed to get post.
|
||||||
</p>
|
</p>
|
||||||
</Area>
|
</Area>
|
||||||
|
{:else}
|
||||||
|
<Area tiny='{!!id}'>
|
||||||
|
<span slot="header">
|
||||||
|
<a href='/users/{username}'>
|
||||||
|
{username}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span slot="main">
|
||||||
|
{#each contentSplit as line}
|
||||||
|
<p>{line}</p>
|
||||||
|
{/each}
|
||||||
|
</span>
|
||||||
|
<span slot="footer">
|
||||||
|
<span class='vote-area'>
|
||||||
|
<a data-sveltekit-reload href='{query}?vote=up'>
|
||||||
|
<img src='/upvote.svg' class='button' alt='Upvote'>
|
||||||
|
</a>
|
||||||
|
<span class='votes'>
|
||||||
|
{upvotes + 0}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class='vote-area'>
|
||||||
|
<a data-sveltekit-reload href='{query}?vote=down'>
|
||||||
|
<img src='/downvote.svg' class='button' alt='Downvote'>
|
||||||
|
</a>
|
||||||
|
<span class='votes'>
|
||||||
|
{downvotes + 0}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
{#if id}
|
||||||
|
<span class='vote-area'>
|
||||||
|
<a href='/post/{id}'>
|
||||||
|
<img src='/view.svg' class='button' alt='View'>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</Area>
|
||||||
|
{/if}
|
|
@ -1,6 +1,7 @@
|
||||||
import sqlite3 from 'sqlite3'
|
import sqlite3 from 'sqlite3'
|
||||||
import { open } from 'sqlite'
|
import { open } from 'sqlite'
|
||||||
import { hash, compare } from 'bcrypt'
|
import { hash, compare } from 'bcrypt'
|
||||||
|
import { calcVote } from './util.js';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
randomBytes
|
randomBytes
|
||||||
|
@ -15,7 +16,7 @@ async function initDb() {
|
||||||
|
|
||||||
await db.run('CREATE TABLE IF NOT EXISTS auth (username CHAR(64), password CHAR(1024))');
|
await db.run('CREATE TABLE IF NOT EXISTS auth (username CHAR(64), password CHAR(1024))');
|
||||||
await db.run('CREATE TABLE IF NOT EXISTS token (username CHAR(64), token CHAR(1024))');
|
await db.run('CREATE TABLE IF NOT EXISTS token (username CHAR(64), token CHAR(1024))');
|
||||||
await db.run('CREATE TABLE IF NOT EXISTS post (username CHAR(64), id CHAR(64), content CHAR(10240), upvotes INTEGER, downvotes INTEGER)');
|
await db.run('CREATE TABLE IF NOT EXISTS post (username CHAR(64), id CHAR(64), content CHAR(10240), upvotes INTEGER, downvotes INTEGER, rating REAL)');
|
||||||
await db.run('CREATE TABLE IF NOT EXISTS vote (id CHAR(64), username CHAR(64), type INTEGER)');
|
await db.run('CREATE TABLE IF NOT EXISTS vote (id CHAR(64), username CHAR(64), type INTEGER)');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +68,11 @@ async function loginBackend({user, pass}) {
|
||||||
async function postCreateBackend({user, content}) {
|
async function postCreateBackend({user, content}) {
|
||||||
var id = randomBytes(10).toString('hex');
|
var id = randomBytes(10).toString('hex');
|
||||||
|
|
||||||
await db.run('INSERT INTO post (username, id, content) VALUES (?, ?, ?)', [
|
await db.run('INSERT INTO post (username, id, content, rating) VALUES (?, ?, ?, ?)', [
|
||||||
user,
|
user,
|
||||||
id,
|
id,
|
||||||
content
|
content,
|
||||||
|
calcVote(0,0)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +88,46 @@ async function postGetBackend({id}) {
|
||||||
return posts[0];
|
return posts[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function postGetBulkBackend({page, rows}) {
|
||||||
|
var posts = await db.all('SELECT * from post ORDER BY rating DESC LIMIT ?, ?', [
|
||||||
|
page*rows,
|
||||||
|
rows
|
||||||
|
])
|
||||||
|
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function voteBackend({user, id, vote}) {
|
||||||
|
if (!user || !id || user == '' || (vote != 'down' && vote != 'up')) return {};
|
||||||
|
|
||||||
|
await db.run('DELETE FROM vote WHERE username = ? AND id = ?', [
|
||||||
|
user,
|
||||||
|
id
|
||||||
|
]);
|
||||||
|
|
||||||
|
await db.run('INSERT INTO vote (id, username, type) VALUES (?,?,?)', [
|
||||||
|
id,
|
||||||
|
user,
|
||||||
|
vote == 'up' ? 1 : 2
|
||||||
|
]);
|
||||||
|
|
||||||
|
var votes = await db.all('SELECT type from vote WHERE id = ?', [
|
||||||
|
id
|
||||||
|
]) || [];
|
||||||
|
|
||||||
|
var up = votes.filter(x => x.type == 1).length;
|
||||||
|
var down = votes.filter(x => x.type == 2).length;
|
||||||
|
|
||||||
|
await db.run('UPDATE post SET upvotes = ?, downvotes = ?, rating = ? WHERE id = ?', [
|
||||||
|
up,
|
||||||
|
down,
|
||||||
|
calcVote(up,down),
|
||||||
|
id
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
async function tokenBackend({token}) {
|
async function tokenBackend({token}) {
|
||||||
if (!db) await initDb();
|
if (!db) await initDb();
|
||||||
|
|
||||||
|
@ -104,5 +146,7 @@ export {
|
||||||
loginBackend,
|
loginBackend,
|
||||||
tokenBackend,
|
tokenBackend,
|
||||||
postCreateBackend,
|
postCreateBackend,
|
||||||
postGetBackend
|
postGetBackend,
|
||||||
|
voteBackend,
|
||||||
|
postGetBulkBackend
|
||||||
}
|
}
|
|
@ -20,7 +20,23 @@ let checkRegex = function(string, field, regex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let calcVote = function(up,down) {
|
||||||
|
var upPadded = up + 3;
|
||||||
|
var downPadded = down + 3;
|
||||||
|
var totalPadded = Math.max(up + down, 3);
|
||||||
|
|
||||||
|
var rating = -Math.log((1 / ((((upPadded - downPadded) / (upPadded + downPadded)) + 1) / 2)) - 1) / Math.log(Math.E);
|
||||||
|
|
||||||
|
rating = Math.min(rating,10);
|
||||||
|
rating = Math.max(rating,-10);
|
||||||
|
|
||||||
|
rating = (rating + 10) / 2;
|
||||||
|
|
||||||
|
return rating * Math.log(totalPadded);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
checkLength,
|
checkLength,
|
||||||
checkRegex
|
checkRegex,
|
||||||
|
calcVote
|
||||||
};
|
};
|
|
@ -46,6 +46,9 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#logo a {
|
#logo a {
|
||||||
|
|
15
src/routes/+page.js
Normal file
15
src/routes/+page.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/** @type {import('./$types').PageLoad} */
|
||||||
|
export async function load({ fetch, params, url }) {
|
||||||
|
var search = url.searchParams;
|
||||||
|
|
||||||
|
var voteType = search.get('vote');
|
||||||
|
|
||||||
|
var id = search.get('page') * 1;
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
|
const res = await fetch(`/api/explore?page=${id}`);
|
||||||
|
const postJson = await res.json();
|
||||||
|
|
||||||
|
return { postJson, id };
|
||||||
|
}
|
|
@ -1,15 +1,22 @@
|
||||||
<script>
|
<script>
|
||||||
import Area from '$lib/Area.svelte';
|
import Post from '$lib/Post.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Area>
|
{#each data.postJson as post}
|
||||||
<p slot="header">
|
<Post
|
||||||
Welcome to SvelteKit
|
success={post.success}
|
||||||
</p>
|
username={post.username}
|
||||||
<p slot="main">
|
content={post.content}
|
||||||
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
upvotes={post.upvotes}
|
||||||
</p>
|
downvotes={post.downvotes}
|
||||||
<p slot="footer">
|
id={post.id}
|
||||||
|
></Post>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a data-sveltekit-reload href='?page={data.id+1}'>Next page</a>
|
||||||
</p>
|
</p>
|
||||||
</Area>
|
<p></p>
|
10
src/routes/api/explore/+server.js
Normal file
10
src/routes/api/explore/+server.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { postGetBulkBackend } from '../../../lib/db.js';
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function GET({ url, cookies }) {
|
||||||
|
var page = url.searchParams.get('page') * 1;
|
||||||
|
|
||||||
|
var postData = await postGetBulkBackend({ rows: 5, page });
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(postData));
|
||||||
|
};
|
17
src/routes/api/vote/+server.js
Normal file
17
src/routes/api/vote/+server.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { tokenBackend, voteBackend } from '../../../lib/db.js';
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function GET({ url, cookies }) {
|
||||||
|
var token = cookies.get('token') || '';
|
||||||
|
|
||||||
|
var user = await tokenBackend({token});
|
||||||
|
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
var id = url.searchParams.get('post');
|
||||||
|
var vote = url.searchParams.get('vote');
|
||||||
|
|
||||||
|
voteBackend({user,id,vote});
|
||||||
|
|
||||||
|
return new Response();
|
||||||
|
};
|
|
@ -1,12 +1,19 @@
|
||||||
/** @type {import('./$types').PageLoad} */
|
/** @type {import('./$types').PageLoad} */
|
||||||
export async function load({ fetch, params, url }) {
|
export async function load({ fetch, params, url }) {
|
||||||
|
var search = url.searchParams;
|
||||||
|
|
||||||
|
var voteType = search.get('vote');
|
||||||
|
|
||||||
var id = params.post;
|
var id = params.post;
|
||||||
|
|
||||||
|
if (voteType) {
|
||||||
|
await fetch(`/api/vote?post=${id}&vote=${voteType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
const res = await fetch(`/api/post?post=${id}`);
|
const res = await fetch(`/api/post?post=${id}`);
|
||||||
const postJson = await res.json();
|
const postJson = await res.json();
|
||||||
|
|
||||||
var search = url.searchParams;
|
return postJson;
|
||||||
|
|
||||||
var voteType = (search.get('upvote')) ? 1 : ((search.get('downvote')) ? 2 : 0);
|
|
||||||
|
|
||||||
return { postJson };
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import Area from '$lib/Area.svelte';
|
import Post from '$lib/Post.svelte';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
@ -7,59 +7,10 @@
|
||||||
export let form;
|
export let form;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<Post
|
||||||
.button {
|
success={data.success}
|
||||||
width: auto;
|
username={data.username}
|
||||||
height: 75px;
|
content={data.content}
|
||||||
}
|
upvotes={data.upvotes}
|
||||||
.votes {
|
downvotes={data.downvotes}
|
||||||
font-weight: bold;
|
></Post>
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
.vote-area {
|
|
||||||
margin-right: 30px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{#if data.postJson.success}
|
|
||||||
<Area>
|
|
||||||
<p slot="header">
|
|
||||||
Error
|
|
||||||
</p>
|
|
||||||
<p slot="main">
|
|
||||||
{data.postJson.success}
|
|
||||||
</p>
|
|
||||||
<p slot="footer">
|
|
||||||
Failed to get post.
|
|
||||||
</p>
|
|
||||||
</Area>
|
|
||||||
{:else}
|
|
||||||
<Area>
|
|
||||||
<p slot="header">
|
|
||||||
<a href='/users/{data.postJson.username}'>
|
|
||||||
{data.postJson.username}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p slot="main">
|
|
||||||
{data.postJson.content}
|
|
||||||
</p>
|
|
||||||
<p slot="footer">
|
|
||||||
<span class='vote-area'>
|
|
||||||
<a href='?upvote'>
|
|
||||||
<img src='/upvote.svg' class='button' alt='Upvote'>
|
|
||||||
</a>
|
|
||||||
<span class='votes'>
|
|
||||||
{data.postJson.upvotes + 0}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span class='vote-area'>
|
|
||||||
<a href='?downvote'>
|
|
||||||
<img src='/downvote.svg' class='button' alt='Downvote'>
|
|
||||||
</a>
|
|
||||||
<span class='votes'>
|
|
||||||
{data.postJson.downvotes + 0}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</Area>
|
|
||||||
{/if}
|
|
|
@ -2,9 +2,9 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="47.87009mm"
|
width="38.195164mm"
|
||||||
height="89.159485mm"
|
height="62.605831mm"
|
||||||
viewBox="0 0 47.87009 89.159485"
|
viewBox="0 0 38.195163 62.605831"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg14062"
|
id="svg14062"
|
||||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
@ -24,9 +24,9 @@
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="1.0280428"
|
inkscape:zoom="2.0560856"
|
||||||
inkscape:cx="129.37205"
|
inkscape:cx="0.48636107"
|
||||||
inkscape:cy="99.704021"
|
inkscape:cy="32.829372"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="996"
|
inkscape:window-height="996"
|
||||||
inkscape:window-x="-8"
|
inkscape:window-x="-8"
|
||||||
|
@ -39,15 +39,14 @@
|
||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-45.765321,-111.54473)">
|
transform="translate(-48.929905,-129.52741)">
|
||||||
<path
|
<path
|
||||||
id="rect15084"
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:11.90625;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
d="m 56.684592,149.59814 10.887303,12.1325 13.600048,-26.2501"
|
||||||
d="m 45.765322,189.40887 11.967521,11.29534 H 81.667887 L 93.635409,189.40886 69.700367,140.35985 Z"
|
id="path3462" />
|
||||||
sodipodi:nodetypes="cccccc" />
|
|
||||||
<path
|
<path
|
||||||
id="rect15091"
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:11.90625;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
d="M 79.370381,172.06252 68.483078,159.93002 54.88303,186.18012"
|
||||||
d="m 58.540445,153.71391 v -42.16918 h 22.31984 v 42.16886 L 69.700364,130.84435 Z" />
|
id="path8000" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -2,9 +2,9 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="47.87009mm"
|
width="32.42485mm"
|
||||||
height="89.159485mm"
|
height="34.187305mm"
|
||||||
viewBox="0 0 47.87009 89.159485"
|
viewBox="0 0 32.42485 34.187306"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg14062"
|
id="svg14062"
|
||||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
@ -24,9 +24,9 @@
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="1.0280428"
|
inkscape:zoom="2.0560856"
|
||||||
inkscape:cx="129.37205"
|
inkscape:cx="58.84969"
|
||||||
inkscape:cy="99.704021"
|
inkscape:cy="76.601869"
|
||||||
inkscape:window-width="1920"
|
inkscape:window-width="1920"
|
||||||
inkscape:window-height="996"
|
inkscape:window-height="996"
|
||||||
inkscape:window-x="-8"
|
inkscape:window-x="-8"
|
||||||
|
@ -39,16 +39,10 @@
|
||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-45.765321,-111.54473)">
|
transform="translate(-47.715969,-129.48962)">
|
||||||
<path
|
<path
|
||||||
id="rect15084"
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:7.9375;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
d="m 51.684719,147.57597 10.887303,12.1325 13.600048,-26.2501"
|
||||||
transform="matrix(0.43855232,-0.89870566,0.43855232,0.89870566,0,0)"
|
id="path3462" />
|
||||||
d="m -16.165047,120.52049 19.9285745,7.36012 27.2886965,27.2887 7.360122,19.92858 -54.577393,0 z"
|
|
||||||
sodipodi:nodetypes="cccccc" />
|
|
||||||
<path
|
|
||||||
id="rect15091"
|
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
|
||||||
d="m 58.540445,158.53503 v 42.16918 h 22.31984 v -42.16886 l -11.159921,22.86924 z" />
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
54
static/view.svg
Normal file
54
static/view.svg
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="84.203423mm"
|
||||||
|
height="84.203423mm"
|
||||||
|
viewBox="0 0 84.203423 84.203423"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="view.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
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="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.72693603"
|
||||||
|
inkscape:cx="-20.634553"
|
||||||
|
inkscape:cy="273.06392"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-53.804537,-76.370715)">
|
||||||
|
<path
|
||||||
|
style="color:#000000;fill:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;-inkscape-stroke:none"
|
||||||
|
d="m 95.90625,76.370863 c -23.173772,0 -42.101563,18.92779 -42.101563,42.101567 0,23.17377 18.927791,42.10156 42.101563,42.10156 23.17377,0 42.10156,-18.92779 42.10156,-42.10156 0,-23.173777 -18.92779,-42.101567 -42.10156,-42.101567 z m 0,13.228515 c 16.02419,0 28.87305,12.848862 28.87305,28.873052 0,16.02419 -12.84886,28.87304 -28.87305,28.87304 -16.024189,0 -28.873047,-12.84885 -28.873047,-28.87304 0,-16.02419 12.848858,-28.873052 28.873047,-28.873052 z"
|
||||||
|
id="path234" />
|
||||||
|
<circle
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path3020"
|
||||||
|
cx="95.90625"
|
||||||
|
cy="118.47243"
|
||||||
|
r="9.6452198" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
Loading…
Reference in a new issue