Init
13
.eslintignore
Normal file
@ -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
|
30
.eslintrc.cjs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:svelte/recommended',
|
||||||
|
'prettier'
|
||||||
|
],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: ['@typescript-eslint'],
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
extraFileExtensions: ['.svelte']
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2017: true,
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['*.svelte'],
|
||||||
|
parser: 'svelte-eslint-parser',
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@typescript-eslint/parser'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
vite.config.js.timestamp-*
|
||||||
|
vite.config.ts.timestamp-*
|
13
.prettierignore
Normal file
@ -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
|
9
.prettierrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"useTabs": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"printWidth": 100,
|
||||||
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
|
"pluginSearchDirs": ["."],
|
||||||
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
|
}
|
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.
|
3763
package-lock.json
generated
Normal file
37
package.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "fredboniface.co.uk-svelte",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"test": "npm run test:integration && npm run test:unit",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||||
|
"format": "prettier --plugin-search-dir . --write .",
|
||||||
|
"test:integration": "playwright test",
|
||||||
|
"test:unit": "vitest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.28.1",
|
||||||
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
|
"@sveltejs/kit": "^1.20.4",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
|
"eslint": "^8.28.0",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-plugin-svelte": "^2.30.0",
|
||||||
|
"mdsvex": "^0.11.0",
|
||||||
|
"prettier": "^2.8.0",
|
||||||
|
"prettier-plugin-svelte": "^2.10.1",
|
||||||
|
"svelte": "^4.0.5",
|
||||||
|
"svelte-check": "^3.4.3",
|
||||||
|
"tslib": "^2.4.1",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"vite": "^4.4.2",
|
||||||
|
"vitest": "^0.32.2"
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
|
}
|
12
playwright.config.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||||
|
|
||||||
|
const config: PlaywrightTestConfig = {
|
||||||
|
webServer: {
|
||||||
|
command: 'npm run build && npm run preview',
|
||||||
|
port: 4173
|
||||||
|
},
|
||||||
|
testDir: 'tests',
|
||||||
|
testMatch: /(.+\.)?(test|spec)\.[jt]s/
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
12
src/app.d.ts
vendored
Normal file
@ -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 {};
|
12
src/app.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
src/index.test.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
describe('sum test', () => {
|
||||||
|
it('adds 1 + 2 to equal 3', () => {
|
||||||
|
expect(1 + 2).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
39
src/lib/footer.svelte
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
const currentYear: number = new Date().getFullYear()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
© Fred Boniface 2022-{currentYear}
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
footer {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
height: 30px;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
footer p {
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 5px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 9px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--main-text-color);
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
@media screen and (min-height: 600px) {
|
||||||
|
footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
footer p {
|
||||||
|
padding-top: 0px;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
21
src/lib/global.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
:root {
|
||||||
|
--main-bg-color: lightslategrey;
|
||||||
|
--accent-color: darkslategrey;
|
||||||
|
--overlay-color: #2f4f4fb8;
|
||||||
|
--main-text-color: azure;
|
||||||
|
--link-color: cyan;
|
||||||
|
--link-visited-color: rgb(189, 0, 189);
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-color: var(--main-bg-color);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--link-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: var(--link-visited-color)
|
||||||
|
}
|
23
src/lib/lang.svelte
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let langs: string[]
|
||||||
|
export let plats: string[]
|
||||||
|
|
||||||
|
import { platforms } from "./logos"
|
||||||
|
import { languages } from "./logos"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each langs as lang}
|
||||||
|
<img src="{languages.get(lang)}" alt="{lang}">
|
||||||
|
{/each}
|
||||||
|
<br>
|
||||||
|
{#each plats as plat}
|
||||||
|
<img src="{platforms.get(plat)}" alt="{plat}">
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
height: 25px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
15
src/lib/logos.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export const languages = new Map([
|
||||||
|
['js', '/logos/js.svg'],
|
||||||
|
['ts', '/logos/ts.svg'],
|
||||||
|
['go', '/logos/go.png'],
|
||||||
|
['py', '/logos/py.svg'],
|
||||||
|
['html', '/logos/html.svg'],
|
||||||
|
['css', '/logos/css.svg'],
|
||||||
|
])
|
||||||
|
|
||||||
|
export const platforms = new Map([
|
||||||
|
['svelte', '/logos/svelte.png'],
|
||||||
|
['express', '/logos/express.png'],
|
||||||
|
['node', '/logos/node.png'],
|
||||||
|
['mongo', '/logos/mongo.png'],
|
||||||
|
])
|
58
src/lib/navigation.svelte
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
name: "Home",
|
||||||
|
link: "/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Projects",
|
||||||
|
link: "/projects",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
function isActive(link: string): string {
|
||||||
|
if (link === $page.url.pathname) {
|
||||||
|
return "active"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
{#each links as link}
|
||||||
|
<a href="{link.link}" class={isActive(link.link)}>{link.name}</a>
|
||||||
|
{/each}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
nav {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 41px;
|
||||||
|
background-color: var(--overlay-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
float: left;
|
||||||
|
display: block;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--main-text-color);
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin-right: 1px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a:active {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
18
src/routes/+layout.svelte
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Footer from "$lib/footer.svelte";
|
||||||
|
import Navigation from "$lib/navigation.svelte";
|
||||||
|
import "$lib/global.css"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Navigation />
|
||||||
|
<main>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
padding-top: 42px;
|
||||||
|
color: var(--main-text-color)
|
||||||
|
}
|
||||||
|
</style>
|
13
src/routes/+page.svelte
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<h1>Hi, I'm Fred</h1>
|
||||||
|
<h2>I make stuff</h2>
|
||||||
|
<p>Visit <a href="https://fredboniface.co.uk">fredboniface.co.uk</a> for the current website</p>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin-top: 0px
|
||||||
|
}
|
||||||
|
</style>
|
1
src/routes/articles/+page.svelte
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h1>Posts</h1>
|
11
src/routes/articles/[slug]/+page.svelte
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let data;
|
||||||
|
const {title, date, author, Content} = data
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<h1>{ title }</h1>
|
||||||
|
<p>Published: { date }</p>
|
||||||
|
<p>Author: { author }</p>
|
||||||
|
<Content />
|
||||||
|
</article>
|
27
src/routes/articles/[slug]/+page.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
interface PostData {
|
||||||
|
Content: ConstructorOfATypedSvelteComponent;
|
||||||
|
title: string;
|
||||||
|
date: string;
|
||||||
|
author: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultSlug = "notFound"
|
||||||
|
|
||||||
|
export async function load({ params }){
|
||||||
|
let post
|
||||||
|
try {
|
||||||
|
post = await import(`../markdown/${params.slug}.md`)
|
||||||
|
} catch {
|
||||||
|
post = await import(`../markdown/${defaultSlug}.md`)
|
||||||
|
}
|
||||||
|
const { title, date, author } = post.metadata
|
||||||
|
const Content = post.default
|
||||||
|
|
||||||
|
const postData: PostData = {
|
||||||
|
Content,
|
||||||
|
title,
|
||||||
|
date,
|
||||||
|
author
|
||||||
|
}
|
||||||
|
return postData
|
||||||
|
}
|
18
src/routes/articles/markdown/map-dots.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: map-dots
|
||||||
|
author: Frederick Boniface
|
||||||
|
date: '2023-08-16'
|
||||||
|
---
|
||||||
|
[map-dots Repo](https://git.fjla.uk/fred.boniface/map-dots) [map-dots-fetch Repo](https://git.fjla.uk/fred.boniface/map-dots-fetch)
|
||||||
|
|
||||||
|
I'm someone who likes to gather data – a bit of a data hoarder. But truth be told, having the data doesn't mean I always know what to do with it.
|
||||||
|
|
||||||
|
You know those monthly emails from Google that break down your location history? I used to find them fascinating. But, handing over all that info to Google didn't sit right with me. So, I took matters into my own hands and set up a Traccar instance at home, connecting my mobile devices to it.
|
||||||
|
|
||||||
|
Now, my location history is kept under my own roof. I even turned off Google's location history feature.
|
||||||
|
|
||||||
|
However, the downside was losing those monthly reports. You see, Traccar isn't exactly built for that; it's more focused on fleet tracking.
|
||||||
|
|
||||||
|
That's when "map-dots" came into play. It's a Go-based application that can be run through the command line or as an API server. While it's still a work in progress, it's got potential. Currently, it can take in HTTP requests, connect to a Traccar server, retrieve location history data, and turn it into an image.
|
||||||
|
|
||||||
|
To keep things ticking, I created the "map-dots-fetch" script in Python. It fetches a new image at regular intervals, and I've set that image as the wallpaper on my devices.
|
9
src/routes/articles/markdown/notFound.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: Not Found
|
||||||
|
date: "2023-08-16"
|
||||||
|
author: Frederick Boniface
|
||||||
|
---
|
||||||
|
|
||||||
|
**404 - The post you requested cannot be found**
|
||||||
|
|
||||||
|
If you came here from a search engine, maybe the post has been removed or renamed. If you got here from a link on my website then there may be a server error.
|
25
src/routes/articles/markdown/owlboard.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
title: OwlBoard
|
||||||
|
author: Frederick Boniface
|
||||||
|
date: '2023-08-16'
|
||||||
|
---
|
||||||
|
|
||||||
|
[Git Organisation](https://git.fjla.uk/owlboard) [Live Website](https://owlboard.info)
|
||||||
|
|
||||||
|
OwlBoard came about because I was sick of dealing with clunky tools that were slow, outdated, and not user-friendly.
|
||||||
|
|
||||||
|
I had a clear goal in mind: make something smoother, faster, and more modern to shake up the tool landscape.
|
||||||
|
|
||||||
|
I decided to take control of the data side of things and built a Python-based db-manager app. It works on a schedule to handle database collections, polish data from different sources, and neatly store it all in the database.
|
||||||
|
|
||||||
|
db-manager eventually grew to pull data from Network Rail's CORPUS and TIMETABLE feeds, as well as downloading PIS and Reason Code data from a git repository.
|
||||||
|
|
||||||
|
OwlBoard started with a simple idea: real-time station departure boards. I used an Express backend alongside a basic HTML/CSS/JS frontend PWA. But as I added more features, it became obvious that a sturdier framework was needed. Both users and developers were struggling with more menus and messier code.
|
||||||
|
|
||||||
|
Enter Svelte, especially SvelteKit. I wasn't just hopping on a trend – I liked that it allowed me to work with plain JS, HTML, and CSS in components. This made my learning curve easier and sped up improvements for users.
|
||||||
|
|
||||||
|
When API responses got lengthy, I turned to TypeScript. It was like flipping a switch, helping me understand what's happening behind the scenes and reducing how much I relied on console.log.
|
||||||
|
|
||||||
|
Later on, I integrated VSTP data from Network Rail using Go. I set up a message handler, subscribed to the VSTP feed using a STOMP library, and processed messages like the db-manager does. This ensured that the database's timetable collection was always up to date, thanks to how I managed transactions.
|
||||||
|
|
||||||
|
Looking ahead, I'm focused on fine-tuning the interactions between the backend and frontend. I want to make things smoother by sending less data, especially important when dealing with shaky data connections.
|
19
src/routes/projects/+page.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Lang from "$lib/lang.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h1>Stuff I've made</h1>
|
||||||
|
|
||||||
|
<a href="/articles/owlboard">OwlBoard</a><br>
|
||||||
|
<Lang langs={['js','ts','py','go', 'html', 'css']} plats={['svelte','express','mongo']} />
|
||||||
|
<p>Working full time on the 'iron road', left me wanting a faster way to get the information
|
||||||
|
I needed. OwlBoard evolved from <a href="/articles/athena">Athena</a> and grew to provide
|
||||||
|
more information that frontline rail colleagues need.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="/articles/map-dots">map-dots</a><br>
|
||||||
|
<Lang langs={['go','py']} plats={[]} />
|
||||||
|
<p>I like to collect data, I am just not always sure what to do with that data. map-dots
|
||||||
|
takes in location history data and produces imagery. It can also run as a server and
|
||||||
|
the map-dots-fetch script can be used to fetch and save configurable images.
|
||||||
|
</p>
|
BIN
static/favicon.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
31
static/logos/css.svg
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#1F72B5;}
|
||||||
|
.st1{fill:#51A3DC;}
|
||||||
|
.st2{fill:#EBEBEB;}
|
||||||
|
.st3{fill:#CECECE;}
|
||||||
|
</style>
|
||||||
|
<g id="XMLID_1_">
|
||||||
|
<polygon id="XMLID_11_" class="st0" points="107.66,470.9 74.67,100.55 437.33,100.55 404.34,470.76 255.72,512 "/>
|
||||||
|
<polygon id="XMLID_10_" class="st1" points="256,480.57 376.04,447.29 404.34,130.84 256,130.84 "/>
|
||||||
|
<polygon id="XMLID_35_" class="st2" points="138.1,216.32 133.69,173.51 378.31,173.51 375.47,223.15 272.07,268.8 371.2,268.8
|
||||||
|
360.53,409.6 260.55,436.48 156.87,411.31 150.47,339.91 196.27,339.91 198.83,377.6 258.84,388.84 314.31,371.77 316.87,311.47
|
||||||
|
146.49,311.47 143.36,266.67 256,217.32 "/>
|
||||||
|
<g id="XMLID_2_">
|
||||||
|
<polygon id="XMLID_39_" class="st3" points="143.36,266.67 146.49,311.47 256,311.47 256,217.32 "/>
|
||||||
|
<polygon id="XMLID_40_" class="st3" points="198.83,377.6 196.27,339.91 150.47,339.91 156.87,411.31 256,435.34 256,388.27 "/>
|
||||||
|
<polygon id="XMLID_41_" class="st3" points="133.69,173.51 138.1,216.32 256,217.32 256,173.51 "/>
|
||||||
|
</g>
|
||||||
|
<g id="XMLID_36_">
|
||||||
|
<polygon id="XMLID_34_" points="290.13,17.07 290.13,0 221.87,0 221.87,39.82 268.8,39.82 268.8,52.62 220.44,52.62 220.44,68.27
|
||||||
|
288.71,68.27 288.71,27.02 240.36,27.02 240.36,17.07 "/>
|
||||||
|
<polygon id="XMLID_38_" points="166.4,40.25 166.4,52.62 214.76,52.62 214.76,68.27 146.49,68.27 146.49,27.45 146.49,0 213.33,0
|
||||||
|
213.33,17.07 166.4,17.07 "/>
|
||||||
|
<polygon id="XMLID_37_" points="365.51,17.07 365.51,0 297.24,0 297.24,39.82 344.18,39.82 344.18,52.62 295.82,52.62
|
||||||
|
295.82,68.27 364.09,68.27 364.09,27.02 315.73,27.02 315.73,17.07 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
static/logos/express.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
static/logos/go.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
28
static/logos/html.svg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#E44D26;}
|
||||||
|
.st1{fill:#F16529;}
|
||||||
|
.st2{fill:#EBEBEB;}
|
||||||
|
.st3{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g id="XMLID_1_">
|
||||||
|
<polygon id="XMLID_11_" class="st0" points="107.66,470.9 74.67,100.55 437.33,100.55 404.34,470.76 255.72,512 "/>
|
||||||
|
<polygon id="XMLID_10_" class="st1" points="256,480.57 376.04,447.29 404.34,130.84 256,130.84 "/>
|
||||||
|
<polygon id="XMLID_9_" class="st2" points="256,268.23 195.84,268.23 191.72,221.72 256,221.72 256,176.36 255.86,176.36
|
||||||
|
142.08,176.36 143.22,188.44 154.31,313.6 256,313.6 "/>
|
||||||
|
<polygon id="XMLID_8_" class="st2" points="256,386.13 255.86,386.28 205.23,372.48 201.96,336.36 177.35,336.36 156.44,336.36
|
||||||
|
162.7,407.61 255.86,433.49 256,433.35 "/>
|
||||||
|
<path id="XMLID_7_" d="M108.37,0h23.04v22.76h21.05V0h23.04v68.98h-23.04V45.8h-21.05v23.18h-23.04V0L108.37,0z"/>
|
||||||
|
<path id="XMLID_6_" d="M205.94,22.9H185.6V0h63.72v22.9h-20.34v46.08h-23.04V22.9L205.94,22.9z"/>
|
||||||
|
<path id="XMLID_5_" d="M259.56,0h24.04l14.79,24.32L313.17,0h24.04v68.98h-22.9V34.84l-15.93,24.6h-0.43l-15.93-24.6v34.28h-22.61
|
||||||
|
V0H259.56z"/>
|
||||||
|
<path id="XMLID_4_" d="M348.73,0h23.04v46.22h32.43v22.76h-55.47V0z"/>
|
||||||
|
<polygon id="XMLID_3_" class="st3" points="255.86,268.23 255.86,313.6 311.75,313.6 306.49,372.48 255.86,386.13 255.86,433.49
|
||||||
|
348.87,407.61 349.58,399.93 360.25,280.46 361.39,268.23 349.16,268.23 "/>
|
||||||
|
<polygon id="XMLID_2_" class="st3" points="255.86,176.36 255.86,204.52 255.86,221.58 255.86,221.72 365.37,221.72 365.37,221.72
|
||||||
|
365.51,221.72 366.51,211.48 368.5,188.44 369.64,176.36 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
18
static/logos/js.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#F7DF1E;}
|
||||||
|
</style>
|
||||||
|
<g id="XMLID_1_">
|
||||||
|
<rect id="XMLID_2_" class="st0" width="512" height="512"/>
|
||||||
|
<path id="XMLID_3_" d="M134.66,427.84l39.14-23.71c7.57,13.47,14.45,24.69,30.86,24.69c15.85,0,25.81-6.17,25.81-30.3V235.1h48.11
|
||||||
|
v164.26c0,49.8-29.18,72.52-71.82,72.52C168.33,471.88,146.03,451.96,134.66,427.84"/>
|
||||||
|
<path id="XMLID_4_" d="M304.82,422.65l39.14-22.72c10.38,16.83,23.71,29.18,47.41,29.18c19.92,0,32.68-9.96,32.68-23.71
|
||||||
|
c0-16.55-13.05-22.3-35.07-31.98l-12.06-5.19c-34.65-14.73-57.79-33.39-57.79-72.52c0-36.05,27.49-63.54,70.42-63.54
|
||||||
|
c30.58,0,52.6,10.66,68.45,38.44l-37.45,23.99c-8.28-14.73-17.11-20.62-30.86-20.62c-14.03,0-23,8.98-23,20.62
|
||||||
|
c0,14.45,8.98,20.34,29.6,29.18l12.06,5.19c40.96,17.53,63.96,35.35,63.96,75.61c0,43.34-34.09,67.05-79.68,67.05
|
||||||
|
C347.74,471.88,318.84,450.56,304.82,422.65"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/logos/mongo.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
static/logos/node.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
28
static/logos/py.svg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:url(#SVGID_1_);}
|
||||||
|
.st1{fill:url(#SVGID_2_);}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="0.2852" y1="511.0804" x2="2.2901" y2="511.0804" gradientTransform="matrix(126.2799 125.5782 -125.2988 126.5615 64049.7422 -64670.543)">
|
||||||
|
<stop offset="0" style="stop-color:#387EB8"/>
|
||||||
|
<stop offset="1" style="stop-color:#366994"/>
|
||||||
|
</linearGradient>
|
||||||
|
<path class="st0" d="M254.2,1.3c-130,0-121.9,56.4-121.9,56.4l0.1,58.4h124v17.5H83.2c0,0-83.2-9.4-83.2,121.7
|
||||||
|
c0,131.1,72.6,126.5,72.6,126.5h43.3V321c0,0-2.3-72.6,71.4-72.6h123c0,0,69.1,1.1,69.1-66.8V69.3C379.5,69.3,390,1.3,254.2,1.3z
|
||||||
|
M185.8,40.6c12.3,0,22.3,10,22.3,22.3c0,12.3-10,22.3-22.3,22.3s-22.3-10-22.3-22.3C163.4,50.6,173.4,40.6,185.8,40.6z"/>
|
||||||
|
|
||||||
|
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="0.8921" y1="511.1571" x2="2.8969" y2="511.1571" gradientTransform="matrix(135.625 128.783 -128.4964 135.9275 65764.5781 -69385.4766)">
|
||||||
|
<stop offset="0" style="stop-color:#FFE052"/>
|
||||||
|
<stop offset="1" style="stop-color:#FFC331"/>
|
||||||
|
</linearGradient>
|
||||||
|
<path class="st1" d="M257.8,510.7c130,0,121.9-56.4,121.9-56.4l-0.1-58.4h-124v-17.5h173.3c0,0,83.2,9.4,83.2-121.7
|
||||||
|
c0-131.1-72.6-126.5-72.6-126.5h-43.3V191c0,0,2.3,72.6-71.4,72.6h-123c0,0-69.1-1.1-69.1,66.8v112.3
|
||||||
|
C132.5,442.7,122,510.7,257.8,510.7z M326.2,471.4c-12.3,0-22.3-10-22.3-22.3c0-12.3,10-22.3,22.3-22.3s22.3,10,22.3,22.3
|
||||||
|
C348.6,461.4,338.6,471.4,326.2,471.4z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/logos/svelte.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
23
static/logos/ts.svg
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#007ACC;}
|
||||||
|
.st1{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g id="XMLID_1_">
|
||||||
|
<polygon id="XMLID_2_" class="st0" points="0,256 0,512 256,512 512,512 512,256 512,0 256,0 0,0 "/>
|
||||||
|
<path id="XMLID_3_" class="st1" d="M113.2,257.68l-0.14,20.9h33.39h33.39v94.68v94.68h23.57h23.57v-94.68v-94.68h33.24h33.39
|
||||||
|
v-20.62c0-11.36-0.28-20.9-0.56-21.18c-0.28-0.28-40.82-0.42-89.92-0.42l-89.49,0.28L113.2,257.68z"/>
|
||||||
|
<path id="XMLID_4_" class="st1" d="M413.11,236.22c13.05,3.23,22.86,8.98,31.98,18.52c4.77,5.05,11.64,14.17,12.2,16.41
|
||||||
|
c0.14,0.7-22.16,15.57-35.63,23.99c-0.42,0.28-2.38-1.82-4.63-5.05c-6.59-9.54-13.47-13.75-23.99-14.45
|
||||||
|
c-15.57-1.12-25.53,7.01-25.39,20.62c0,3.93,0.56,6.31,2.24,9.54c3.37,7.01,9.82,11.36,29.6,19.92
|
||||||
|
c36.61,15.71,52.32,26.23,62.14,40.96c10.94,16.55,13.33,42.78,5.89,62.42c-8.14,21.32-28.34,35.77-56.67,40.54
|
||||||
|
c-8.84,1.54-29.6,1.26-39-0.42c-20.62-3.65-40.12-13.75-52.04-27.21c-4.77-5.19-13.89-18.8-13.33-19.78
|
||||||
|
c0.28-0.28,2.38-1.68,4.77-2.95c2.24-1.26,10.94-6.31,19.08-10.94l14.73-8.56l3.09,4.49c4.35,6.59,13.75,15.57,19.36,18.66
|
||||||
|
c16.27,8.56,38.72,7.43,49.8-2.52c4.77-4.35,6.73-8.84,6.73-15.29c0-5.89-0.7-8.56-3.79-13.05c-3.93-5.75-12.06-10.52-35.21-20.48
|
||||||
|
c-26.37-11.36-37.73-18.52-48.25-29.6c-6.03-6.45-11.64-16.97-14.03-25.53c-1.96-7.29-2.38-25.39-0.84-32.68
|
||||||
|
c5.47-25.53,24.69-43.34,52.46-48.53C383.37,233.42,404.27,233.98,413.11,236.22z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
23
svelte.config.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import adapter from '@sveltejs/adapter-auto';
|
||||||
|
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||||
|
import { mdsvex } from 'mdsvex';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
|
// for more information about preprocessors
|
||||||
|
extensions: ['.svelte', '.md', '.svx'],
|
||||||
|
preprocess: [
|
||||||
|
vitePreprocess(),
|
||||||
|
mdsvex({extensions: ['.md', '.svx']}),
|
||||||
|
],
|
||||||
|
|
||||||
|
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;
|
6
tests/test.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
test('index page has expected h1', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
|
||||||
|
});
|
17
tsconfig.json
Normal file
@ -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
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
}
|
9
vite.config.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [sveltekit()],
|
||||||
|
test: {
|
||||||
|
include: ['src/**/*.{test,spec}.{js,ts}']
|
||||||
|
}
|
||||||
|
});
|