diff --git a/src/app.d.ts b/src/app.d.ts index 7564bf3..8f4d638 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,7 +1,6 @@ // See https://kit.svelte.dev/docs/types#app // for information about these interfaces // and what to do when importing types - declare namespace App { // interface Locals {} // interface PageData {} diff --git a/src/app.postcss b/src/app.postcss index e279a82..2b81492 100644 --- a/src/app.postcss +++ b/src/app.postcss @@ -24,12 +24,6 @@ body { src: url('/fonts/Quicksand.ttf'); font-display: swap; } - -.prose { - font-family: 'Cooper Hewitt', sans-serif; - letter-spacing: 0.25px; -} - /* @font-face { font-family: 'Magilio'; diff --git a/src/content/blog/Dockerizing apps.txt b/src/content/blog/Dockerizing apps.txt deleted file mode 100644 index c90ec11..0000000 --- a/src/content/blog/Dockerizing apps.txt +++ /dev/null @@ -1,12 +0,0 @@ - -tldr: -I started by containerizing my SvelteKit and Strapi apps, then Pushed these to Docker Hub and AWS ECR, -leveraging 1 free private image on docker hub and free-tier 500mb limit on AWS ECR, thereby minimizing costs and exploring each option. - -1. Conteinerization - a. Sveltekit -Keeping in mind that dev, build, test and lint, etc. scripts are handled by turborepo, we use these when containerizing. - -Step 1. - - b. Strapi diff --git a/src/content/blog/Setup.txt b/src/content/blog/Setup.txt deleted file mode 100644 index 85eb3bb..0000000 --- a/src/content/blog/Setup.txt +++ /dev/null @@ -1,7 +0,0 @@ -choosing a package manager - -I tried to abstain from the community battles between pms and looked at the performance of the top 3 used - npm, yarn and pnpm. https://pnpm.io/benchmarks -I've got experience with each and would like to use pnpm as it is the much faster than NPM, -however Strapi doesn't officialy support it so I ended up choosing yarn as in most cases it is a bit faster than npm, has some better handling with monorepos and I personally like it. -I used Turborepo with npm and there were some problems with setting dependencies in workspaces vs the root of monorepo and private packages, which required workarounds. -In terms of CI performance can have significant consequences. \ No newline at end of file diff --git a/src/content/blog/aws iam.txt b/src/content/blog/aws iam.txt deleted file mode 100644 index 8caba07..0000000 --- a/src/content/blog/aws iam.txt +++ /dev/null @@ -1,15 +0,0 @@ -AWS set up - -A thing I learned using linux is user management, specifically don't do everything as root :D. -When using AWS first I didn't care about IAM roles, but I think I learned the same lesson... - -Anyways I used this process, when configuring accounts: - -When starting login as root user and access IAM dashboard, -Set up Multi-factor Auth as root user (prefferably with Yubikey or some OTP in a secure device) -Later on, like in linux, the root account access can be minimized for a better decentralized privilege system, even when being the only admin. - -Go to services then IAM Identity center -Select identity source -> In my case stick with the default Identity Center directory, bigger organizations or ones using other sources can connect to external ones. -In Multi-account permissions select permission sets and create a permission set. -Then go to AWS accounts, select the account you wish and assign the permission set to them. \ No newline at end of file diff --git a/src/content/blog/ec2 & rds.txt b/src/content/blog/ec2 & rds.txt deleted file mode 100644 index d72f145..0000000 --- a/src/content/blog/ec2 & rds.txt +++ /dev/null @@ -1,62 +0,0 @@ -Namecheap -Saw mattmor.in and just bought it, no questions asked. - -I immediately created a cloudflare account, because of their great certificate management, security checks, analytics and mostly DNS. - - - - -Setting up AWS EC2 & RDS instances - -EC2 setup -I've got a great opportunity to set up a "free-tier" instance, of course the limitations are quite interesting - 750 hrs/m and some compute limiting factors. -Let's use this opportunity, it is a better deal than GCP with 300$/3mos and my experience with GCP while dealing with Auth API was pretty bad. - -Made SSH keys -got an Elastic IP and connected it with my EC2 instance to be accessible publicly on a stable IP. -added DNS records to cloudflare - - -Log in via SSH, update, upgrade everything, restart. -Then I configured fail2ban with some custom responses and enabled it, I also configured the seemingly redundant ufw and allowed ssh, https - -And with that I am ready to roll onto installing necessary software like nginx, jenkins, docker for now. - -RDS setup - -I've already configured Strapi for my backend, I selected PostgreSQL, because while theoretically the default SQLite db would be sufficient and very easy to manage. -I know it's scalability is limited and is not suitable for multiple user access, which I might need in other projects with the same tech stack. -The main reason for choosing PostgreSQL is I can showcase it and learn with it on a project using AWS. -I've worked mainly with MariaDB before, and used PostgreSQL only on some ancient Wordpress projects back in the day. - -As I already set up a free-tier EC2 instance, I can also setup AWS RDS with Aurora(PostgreSQL compatible) or PostgreSQL also on free-tier, which is awesome! -Let's choose PostgreSQL, because that's simpler and more than sufficient. - -The Free Tier is limited to the same time frame for RDS... -If I really wanted to make this completely free I could use AWS Lambda, which is also free up to 1 million requests/month :D, to turn off both the EC2 and RDS instances at night. Gotta think when do recruiters go to sleep... - - -Now seriously, to actualy set this up: - -Select: -burstable class db.t4g.micro -General Purpose SSD (gp3) 20GiB -I disabled autoscaling as it's not possible I would use more than this in this use-case. - -Strapi recommends PostgreSQL v14.0 at the time of writing -AWS offers 14.5 above, let's choose 14.9 R1, should be backwards compatible. -Template -> Free tier - -Security: -As my OpSec dictates I choose passwords with high entropy so you can't hack me. - -Backup & Maintenance: -Setup Backup and Amazon auto-maintenance windows, I am not a maniac to not backup. - -Connectivity: -I will not connect this to my EC2 instance, because I will be testing this on localhost. -I need public access and in this case I do not think accessing by a private network is necessary. -I will make a new VPC security group, then we can access it via an internet gateway. - - -https://docs.aws.amazon.com/images/AmazonRDS/latest/UserGuide/images/GS-VPC-network.png \ No newline at end of file diff --git a/src/content/blog/first-post.md b/src/content/blog/first-post.md index 6720740..c8d07a2 100644 --- a/src/content/blog/first-post.md +++ b/src/content/blog/first-post.md @@ -1,26 +1,18 @@ --- title: First post -type: blog excerpt: First post +date: 2021-01-01 tags: - - Blog - - Linux - - Declarative + - first + - post +published: true image: Feature.jpg -postTitle: 'Best Medium Format Camera for Starting Out' -focusKeyphrase: 'best medium format camera' -datePublished: '2023-04-07T16:04:42.000+0100' -lastUpdated: '2023-04-14T10:17:52.000+0100' -seoMetaDescription: "Let's take a look." -featuredImage: '' -featuredImageAlt: 'Our own pcb' -publicImageId: '' --- ## Svelte Media inside the **Svelte** folder is served from the `static` folder. -```python showLines +```python input_text = ''' "yahooapis.com", "hotmail.com", @@ -38,112 +30,3 @@ output_text = '\n'.join(formatted_lines) print(output_text) ``` - -## Turborepo [see 1st source] -I will use turborepo as I have experience with it from previous projects, I prefer the centralized, more orderly handling of repositories. -Because our CMS and webapp are workspaces that need to be configured differently, we need to extend the root config of Turborepo to each app individually by creating a turbo.json in each workspace. - -For Strapi this will be: -$root/apps/cms/turbo.json - -``` json - -{ - "extends": ["//"], - "pipeline": { - "build": { - // custom configuration for the build task in this workspace - }, - // new tasks only available in this workspace - "special-task": {}, - } -} -``` - -For Sveltekit Webapp: -$root/apps/web/turbo.json - -``` json -{ - "extends": ["//"], - "pipeline": { - "build": { - "outputs": [".svelte-kit/**"] - } - } -} -``` - -Key notes about this setup: - -Docker: - Base Layer: Installs container dependencies and Turborepo globally. - Pruned Layer: Copies project files and runs turbo prune to exclude unnecessary dependencies. - Installer Layer: Copies pruned workspace and runs yarn to install dependencies. - Runner Layer: Starts the app. - -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` - -Learned - -Used sources: - -1. https://turbo.build/repo/docs -2. https://dev.to/moofoo/creating-a-development-dockerfile-and-docker-composeyml-for-yarn-122-monorepos-using-turborepo-896 - - -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` -## Docker - -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` diff --git a/src/content/blog/monitoring.txt b/src/content/blog/monitoring.txt deleted file mode 100644 index abf90e1..0000000 --- a/src/content/blog/monitoring.txt +++ /dev/null @@ -1,18 +0,0 @@ -install Grafana, Prometheus, ELK Stack, and Jenkins on a single server and use them to monitor other EC2 instances or cloud resources. There are trade-offs: - -Pros: - - Simplified Management: All tools in one place. - Lower Costs: Fewer servers to maintain. - -Cons: - - Resource Contention: These tools can be resource-intensive. - Single Point of Failure: If the server goes down, all tools are affected. - Security Risks: Multiple services on one server can increase the attack surface. - -Recommendations: - - Use containerization (Docker) for easier management and isolation. - Set up a robust backup and recovery strategy. - Ensure adequate resource allocation and scaling capabilities. \ No newline at end of file diff --git a/src/content/blog/postwa.md b/src/content/blog/postwa.md index 8ccdedc..f9e4fa3 100644 --- a/src/content/blog/postwa.md +++ b/src/content/blog/postwa.md @@ -1,19 +1,12 @@ --- -title: First post -type: blog -excerpt: First post +title: w post +excerpt: w post +date: 2021-01-01 tags: - - NixOS - - Linux - - Declarative + - first + - post +published: true image: Feature.jpg -postTitle: 'Best Medium Format Camera for Starting Out' -focusKeyphrase: 'best medium format camera' -datePublished: '2022-04-07T16:04:42.000+0100' -lastUpdated: '2022-04-14T10:17:52.000+0100' -seoMetaDescription: "Let's take a look." -featuredImage: '' -featuredImageAlt: 'Our own pcb' -publicImageId: '' --- -## Svelte + +## Svelte \ No newline at end of file diff --git a/src/content/blog/project description.txt b/src/content/blog/project description.txt deleted file mode 100644 index 196e765..0000000 --- a/src/content/blog/project description.txt +++ /dev/null @@ -1,76 +0,0 @@ -The goal of this project is to showcase my skillset both as a portfolio site and showcase how I used devops and web development practices to build it. -The tech stack and feature set is meant to: -legitimize the goal of the portfolio site, which is mentioned above -Use modern DevOps and web development practices that I know of so I can build it as fast as possible. -minimize costs and be potentially scalable and feature-upgradeable. -be secure and be build using my evolving OpSec and limited cybersecurity knowledge. -show proficiency in using new tools. - -As such the current cloud stack is: -1. AWS EC2 t3.micro - For: Jenkins - Why: CI/CD pipeline, free tier, 1GB RAM sufficient for Jenkins. -2. AWS EC2 t3.micro - For: docker-compose SvelteKit app - Why: Frontend, free tier, 1GB RAM sufficient for SvelteKit. - -3. Amazon ECS Anywhere - - For: docker-compose Strapi - Why: Container orchestration, 2200 free hours, scalable. - -4. AWS Lambda - - For: Automated tasks - Why: 1 million free requests, event-driven architecture. - -5. Amazon RDS - - For: Database - Why: 750 free hours, managed service, 20GB storage. - -6. Amazon S3 - - For: File storage, backups - Why: 5GB free storage, durable. - -7. Amazon CloudWatch - - For: Monitoring - Why: 10 free custom metrics and alarms. - -8. AWS Secrets Manager - - For: Secrets - Why: Secure, but consider alternatives due to cost. - -9. Amazon API Gateway - - For: APIs - Why: 1 million free API calls, secure. - -10. Terraform and Ansible - - For: IaC and Configuration - Why: Version control, automation. - -11. Documentation - - For: READMEs - Why: Clarity, onboarding, and best practices. - -12. GitHub and AWS ECR - - For: Code and container repositories - Why: Version control, Docker Hub limitations. - -Cost Analysis - - EC2 t3.micro: Free tier - ECS Anywhere: Free tier (2200 hours) - Lambda: Free tier (1 million requests) - RDS: Free tier (750 hours) - S3: Free tier (5GB) - CloudWatch: Free tier (10 metrics) - Secrets Manager: $0.40/secret, consider alternatives - API Gateway: Free tier (1 million calls) \ No newline at end of file diff --git a/src/content/blog/second-post.md b/src/content/blog/second-post.md index f985f1e..930f194 100644 --- a/src/content/blog/second-post.md +++ b/src/content/blog/second-post.md @@ -1,20 +1,13 @@ --- -title: First post -type: blog -excerpt: First post +title: Second post +excerpt: Second post +date: 2023-01-01 tags: - - NixOS - - Linux - - Declarative + - first + - post +published: true image: Feature.jpg -postTitle: 'Best Medium Format Camera for Starting Out' -focusKeyphrase: 'best medium format camera' -datePublished: '2024-04-07T16:04:42.000+0100' -lastUpdated: '2021-04-14T10:17:52.000+0100' -seoMetaDescription: "Let's take a look." -featuredImage: '' -featuredImageAlt: 'Our own pcb' -publicImageId: '' + --- @@ -30,4 +23,5 @@ Media inside the **Svelte** folder is server from the `static` folder. I am ditching the societal value of having a contributions table on my profile, you should view it on git.mattmor.in ---- If my contributions in 3d do not work, Github made breaking changes to their frontend and I can't scrape it anymore. + +--- If my contributions in 3d do not work, Github made breaking changes to their frontend and I can't scrape it anymore. \ No newline at end of file diff --git a/src/content/blog/skillset.txt b/src/content/blog/skillset.txt deleted file mode 100644 index 397823d..0000000 --- a/src/content/blog/skillset.txt +++ /dev/null @@ -1,74 +0,0 @@ -Hard skills in SW: -HTML, CSS, JS, TS, Svelte, Sveltekit, Vite, - -WebDev (meta)frameworks: Svelte (and sveltekit), a theoretical knowledge of reactjs (and next.js) and vue (and nuxt) -WebDev langs: HTML, CSS, tailwindcss, postcss (basics), JS, TS (basics), multiple ui libraries and billions of packages :D -WebDev linting: eslint -WebDev testing: Playwright - -Languages: JS, Python, Micropython, C and C++ (both basics with microcontrollers), I really want to code in OstraJava and Brainf*ck - - - -OS: -Linux [Ubuntu, Debian (Rpi OS, Kali - basics), QubesOS, Arch (Manjaro)], WSL, -Windows :D, advanced as a power user of XP,Vista,7,8,10,11 in my life, caused deep trauma. Haven't used win servers and don't plan to. - -Terminal: -Process Monitoring -Performance Monitoring -Networking Tools -Text Manipulation - -Scripting: -Bash -Power Shell (for user tasks) - -Editors: -Nano, Emacs, VS Code, Notepad :D and Jupyter notebook - - - -Version control: Git - - -VCS Hosting: Github, Gitlab -CI/CD: -Jenkins In progress -Gitlab CI In progress - -Infrastructure Provisioning: -Terraform: In progress - -Cloud Providers: -AWS - Preffered -DigitalOcean -Google Cloud (I did auth, api, company set up and some bots with spreadsheet) - -CDN: Cloudinary - -Networking, Security and Protocols: -FTP / SFTP -SSL / TLS -HTTP / HTTPS -DNS -SSH (putty and linux) - -Serverless: AWS Lambda (0), Cloudflare, Vercel - -Monorepo (with pipelines): all yarn, npm, pnpm with turborepo - - - -Containerization: docker (dockerfile, docker-compose, ran many apps with it), DockerHub, AWS RCD - -Container Orchestration: Docker swarm(basics) -K8s/K3s: In progress... - -Orchestration: Terraform (0) - -GitOps: In progress ArgoCD - -Application monitoring: New Relic, Prometheus, Grafana, Elk stack - -Logs Management: \ No newline at end of file diff --git a/src/content/blog/turbo and docker.txt b/src/content/blog/turbo and docker.txt deleted file mode 100644 index db09887..0000000 --- a/src/content/blog/turbo and docker.txt +++ /dev/null @@ -1,56 +0,0 @@ - -## Turborepo [see 1st source] -I will use turborepo as I have experience with it from previous projects, I prefer the centralized, more orderly handling of repositories. -Because our CMS and webapp are workspaces that need to be configured differently, we need to extend the root config of Turborepo to each app individually by creating a turbo.json in each workspace. - -For Strapi this will be: -$root/apps/cms/turbo.json -``` -{ - "extends": ["//"], - "pipeline": { - "build": { - // custom configuration for the build task in this workspace - }, - // new tasks only available in this workspace - "special-task": {}, - } -} -``` - -For Sveltekit Webapp: -$root/apps/web/turbo.json -``` -{ - "extends": ["//"], - "pipeline": { - "build": { - "outputs": [".svelte-kit/**"] - } - } -} -``` - - -Key notes about this setup: - -Docker: - Base Layer: Installs container dependencies and Turborepo globally. - Pruned Layer: Copies project files and runs turbo prune to exclude unnecessary dependencies. - Installer Layer: Copies pruned workspace and runs yarn to install dependencies. - Runner Layer: Starts the app. - -## Docker -Alpine is more lightweight than Ubuntu, I will stick to the inspiration blog post [see 2nd source], which has a similar setup. -The blog post creates intermediate images 'base', 'pruned' etc. that can be used in subsequent stages. - -To push images to docker hub: - -```docker push mando42/portfolio:tagname``` - - -Learned - -Used sources: -1. https://turbo.build/repo/docs -2. https://dev.to/moofoo/creating-a-development-dockerfile-and-docker-composeyml-for-yarn-122-monorepos-using-turborepo-896 \ No newline at end of file diff --git a/src/lib/assets/code.css b/src/lib/assets/code.css deleted file mode 100644 index 8492174..0000000 --- a/src/lib/assets/code.css +++ /dev/null @@ -1,40 +0,0 @@ -.code-highlight { - position: relative; - font-family: 'Fira Mono', monospace; - overflow-x: hidden; - overflow-y: auto; - max-height: 60vh; - margin: 1rem auto; - box-shadow: var(--shadow); - border-radius: 0.5rem; - font-size: 1.5rem; - max-width: 90%; -} - -.code-highlight > .code-language { - position: absolute; - top: 0; - right: 0; - border-top-right-radius: 0.5rem; - border-bottom-left-radius: 0.5rem; - background: rgba(127, 127, 127, 0.3); - padding: 0 0.25rem; -} - -.code-highlight > code { - display: inline-block; - padding: 1rem; -} - -.code-highlight > code.numbered { - margin-left: 2rem; - padding-left: 0.5rem; - border-left: 1px solid rgba(127, 127, 127, 0.5); - counter-reset: line; -} - -.code-highlight > code > .line-of-code { - white-space: pre-wrap; - display: inline-block; - min-height: 1em; -} diff --git a/src/lib/assets/global.css b/src/lib/assets/global.css deleted file mode 100644 index 62cd6b8..0000000 --- a/src/lib/assets/global.css +++ /dev/null @@ -1,120 +0,0 @@ -:root { - --light: #f1f4f8; - --dark: #2c2d2f; - --primary: #ff3e00; - --fg: var(--light); - --bg: var(--dark); - --color-scrollbar: rgba(0, 0, 0, 0.3); - --shadow: 0 0.5rem 0.5rem 0 rgba(0, 0, 0, 0.2), 0 0.25rem 1rem 0 rgba(0, 0, 0, 0.2), - 0 0.5rem 0.25rem -0.25rem rgba(0, 0, 0, 0.2); -} - -@media only screen and (prefers-color-scheme: dark) { - :root { - --fg: var(--light); - --bg: var(--dark); - --color-scrollbar: rgba(255, 255, 255, 0.3); - } - - body.light { - --fg: var(--dark); - --bg: var(--light); - --color-scrollbar: rgba(0, 0, 0, 0.3); - } -} - -@media only screen and (prefers-color-scheme: light) { - :root { - --fg: var(--dark); - --bg: var(--light); - --color-scrollbar: rgba(0, 0, 0, 0.3); - } - - body.dark { - --fg: var(--light); - --bg: var(--dark); - --color-scrollbar: rgba(255, 255, 255, 0.3); - } -} - -body { - color: var(--fg); - background-color: var(--bg); - font-family: 'Fira Mono', monospace; - font-size: 1.5rem; - height: 1080px; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: 'Fira Mono', monospace; -} - -p, -.prose { - font-family: 'Cooper Hewitt', sans-serif; - letter-spacing: 0.25px; -} - -.container { - margin: 0 auto; - padding: 0; - width: calc(100vw - 2rem); - max-width: 1920px; -} - -a { - color: currentColor; - transition: color 200ms ease-in-out; -} - -* { - scrollbar-width: thin; - scrollbar-color: var(--color-scrollbar) transparent; - -webkit-overflow-scrolling: touch; -} - -*::-webkit-scrollbar { - width: 0.5rem; -} - -*::-webkit-scrollbar-track { - background: transparent; -} - -*::-webkit-scrollbar-thumb { - background-color: var(--color-scrollbar); - border-radius: 0.25rem; -} - -html { - height: 100%; -} -body { - height: 100%; -} - -.shadow { - box-shadow: var(--shadow); -} - -h1, -h2, -h3, -h4 { - margin-top: 0; -} - -h1 { - margin-bottom: 0.5rem; -} -h2 { - margin-bottom: 0.25rem; -} -h3 { - margin-bottom: 0.1rem; -} diff --git a/src/lib/cloudinary.ts b/src/lib/cloudinary.ts deleted file mode 100644 index 001381a..0000000 --- a/src/lib/cloudinary.ts +++ /dev/null @@ -1,12 +0,0 @@ -// src/lib/cloudinary.ts -import { v2 as cloudinary } from 'cloudinary'; -import { PUBLIC_CLOUDINARY_NAME } from '$env/static/public'; -import { CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET } from '$env/static/private'; - -cloudinary.config({ - cloud_name: PUBLIC_CLOUDINARY_NAME, - api_key: CLOUDINARY_API_KEY, - api_secret: CLOUDINARY_API_SECRET -}); - -export default cloudinary; diff --git a/src/lib/components/home/QuickCards.svelte b/src/lib/components/home/QuickCards.svelte index d59a98c..b8ee942 100644 --- a/src/lib/components/home/QuickCards.svelte +++ b/src/lib/components/home/QuickCards.svelte @@ -1,26 +1,26 @@
-
- -

Development

-

- I hone my problem solving and coding skills all the time. I try to learn the underlying - mechanics and use abstractions where relevant. -

-
-
- -

Creativity & Presentation

-

- I try to create better, novel ways to approach problems and give my best to present them - in a clear and concise manner. -

-
-
- -

Teamwork & Stakeholders

-

- From my experience with a wide range of roles I understand the how to communication with - stakeholders across an organization. -

-
+
+ +

Development

+

+ I possess a wide range of skills that enable me to develop visually appealing and + interactive user interfaces for web applications. +

+
+
+ +

Design

+

+ Over the years, I have honed my ability to create visually appealing interfaces that + are both user-friendly and intuitive. +

+
+
+ +

User Experience

+

+ I understand the importance of creating a seamless UX for end-users. Which includes + a solid understanding user behavior. +

+
diff --git a/src/lib/utils/file.js b/src/lib/utils/file.js deleted file mode 100644 index 232deb0..0000000 --- a/src/lib/utils/file.js +++ /dev/null @@ -1,9 +0,0 @@ -import { promises as fsp } from 'fs'; - -export async function makeDirectory(directoryPath) { - fsp.mkdir(directoryPath, { recursive: true }, (err) => { - if (err) { - return console.error(err); - } - }); -} diff --git a/src/lib/utils/shiki-highlighter.js b/src/lib/utils/shiki-highlighter.js deleted file mode 100644 index 344e1d1..0000000 --- a/src/lib/utils/shiki-highlighter.js +++ /dev/null @@ -1,115 +0,0 @@ -import { getHighlighter } from 'shiki'; -import { getTheme, loadTheme } from 'shiki-themes'; - -const escapeChars = { - '<': '<', - '>': '>', - '&': '&', - '{': '{', - '}': '}' -}; - -const escapeRE = new RegExp(`[${Object.keys(escapeChars).join('')}]`, 'g'); - -function escape(str) { - if (str && str.length !== 0) { - return str.replace(escapeRE, (c) => escapeChars[c]); - } - return ''; -} - -function render(lines, options) { - const { fg, bg } = options; - const lineNumbers = options.showLineNumbers(lines.length, options.lang); - const lang = options.lang ? `${options.lang}` : ''; - return `
${lang}${lines.map(lineRenderer(options)).join('\n')}\n
`; -} - -const lineRenderer = (options) => (line) => { - const output = line.map(tokenRenderer(options)).join(''); - const { leadingWS, content, trailingWS } = splitLeadingAndTrailingWS(output); - return `${leadingWS || ''}${content || ''}${ - trailingWS || '' - }`; -}; - -const tokenRenderer = (options) => (token) => { - if (!token.color || token.color.toLowerCase() === options.fg) { - return escape(token.content); - } - const { leadingWS, content, trailingWS } = splitLeadingAndTrailingWS(token.content); - if (!content) { - return leadingWS; - } - - return `${leadingWS}${escape(content)}${trailingWS}`; -}; - -function splitLeadingAndTrailingWS(content) { - const len = content.length; - let start = 0; - let end = len; - - while (start < end && isWS(content.charAt(start))) { - start++; - } - - if (start === end) { - return { - leadingWS: content || '' - }; - } - - while (end > start && isWS(content.charAt(end - 1))) { - end--; - } - - return { - leadingWS: content.slice(0, start), - content: content.slice(start, end), - trailingWS: end < content.length ? content.slice(end) : '' - }; -} - -function isWS(char) { - return char === ' ' || char === '\t'; -} - -function isPlaintext(lang) { - return !lang || ['plaintext', 'txt', 'text'].indexOf(lang) !== -1; -} - -const defaultOpts = { - theme: 'nord', - fg: undefined, - bg: undefined, - showLineNumbers: (numberOfLines) => numberOfLines > 5 -}; - -export default async function createHighlighter(opts) { - const options = { ...defaultOpts, ...opts }; - - if (options.theme.endsWith('.json')) { - options.theme = loadTheme(options.theme); - } else { - options.theme = getTheme(options.theme); - } - const baseSettings = ( - (options.theme['tokenColors'] || []).find((x) => !x.scope) || { settings: {} } - ).settings; - const colors = options.theme.colors || {}; - const getThemeColor = (name) => baseSettings[name] || colors[`editor.${name}`] || colors[name]; - const fg = (options.fg || getThemeColor('foreground') || '#eeeeee').toLowerCase(); - const bg = (options.bg || getThemeColor('background') || '#222222').toLowerCase(); - return getHighlighter(options).then( - (highlighter) => (code, lang) => - render( - isPlaintext(lang) - ? [[{ content: code }]] - : highlighter.codeToTokensBase(code, lang), - { ...options, fg, bg, lang } - ) - ); -} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 27226db..58026c4 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,26 +1,48 @@ Matt Morin - - + + - - + + -
+
+ + - - + +
diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png deleted file mode 100644 index 5abe545..0000000 Binary files a/static/android-chrome-192x192.png and /dev/null differ diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png deleted file mode 100644 index f367ad4..0000000 Binary files a/static/android-chrome-512x512.png and /dev/null differ diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png deleted file mode 100644 index efd842f..0000000 Binary files a/static/apple-touch-icon.png and /dev/null differ diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png deleted file mode 100644 index a5a977e..0000000 Binary files a/static/favicon-16x16.png and /dev/null differ diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png deleted file mode 100644 index 450cb63..0000000 Binary files a/static/favicon-32x32.png and /dev/null differ diff --git a/static/favicon.ico b/static/favicon.ico deleted file mode 100644 index 940cfde..0000000 Binary files a/static/favicon.ico and /dev/null differ diff --git a/static/site.webmanifest b/static/site.webmanifest deleted file mode 100644 index 45dc8a2..0000000 --- a/static/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 22889f8..a776fd4 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -4,9 +4,8 @@ import forms from '@tailwindcss/forms'; import typography from '@tailwindcss/typography'; import { skeleton } from '@skeletonlabs/tw-plugin'; -const defineConfig: Config = { - darkMode: 'media', - +export default { + darkMode: 'class', content: [ './src/**/*.{html,js,svelte,ts}', join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}') @@ -28,6 +27,4 @@ const defineConfig: Config = { } }) ] -}; - -export default defineConfig; +} satisfies Config; diff --git a/vite.config.ts b/vite.config.ts index 82d7044..36be9c6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,7 +3,6 @@ import { purgeCss } from 'vite-plugin-tailwind-purgecss'; import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vitest/config'; import { threeMinifier } from '@yushijinhun/three-minifier-rollup'; -import { imagetools } from 'vite-imagetools'; import path from 'path'; export default defineConfig({ @@ -31,8 +30,7 @@ export default defineConfig({ greedy: [/^hljs-/] } }), - { ...threeMinifier(), enforce: 'pre' }, - imagetools({ removeMetadata: true }) + { ...threeMinifier(), enforce: 'pre' } ], define: { 'process.env.VITE_BUILD_TIME': JSON.stringify(new Date().toISOString())