diff --git a/.gitignore b/.gitignore index 2309cc8..c98dfc5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,138 +1,8 @@ -# ---> Node -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# vitepress build output -**/.vitepress/dist - -# vitepress cache directory -**/.vitepress/cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - +.svelte-kit/ +node_modules/ +bun.lockb +build/ +.env +package-lock.json + +bun.lock \ No newline at end of file diff --git a/CustomTheme.ts b/CustomTheme.ts new file mode 100644 index 0000000..4eaf054 --- /dev/null +++ b/CustomTheme.ts @@ -0,0 +1,103 @@ + +import type { CustomThemeConfig } from '@skeletonlabs/tw-plugin'; + +export const myCustomTheme: CustomThemeConfig = { + name: 'my-custom-theme', + properties: { + // =~= Theme Properties =~= + "--theme-font-family-base": `Montserrat`, + "--theme-font-family-heading": `Montserrat`, + "--theme-font-color-base": "0 0 0", + "--theme-font-color-dark": "255 255 255", + "--theme-rounded-base": "4px", + "--theme-rounded-container": "8px", + "--theme-border-base": "1px", + // =~= Theme On-X Colors =~= + "--on-primary": "255 255 255", + "--on-secondary": "255 255 255", + "--on-tertiary": "0 0 0", + "--on-success": "0 0 0", + "--on-warning": "0 0 0", + "--on-error": "255 255 255", + "--on-surface": "255 255 255", + // =~= Theme Colors =~= + // primary | #2b273f + "--color-primary-50": "223 223 226", // #dfdfe2 + "--color-primary-100": "213 212 217", // #d5d4d9 + "--color-primary-200": "202 201 207", // #cac9cf + "--color-primary-300": "170 169 178", // #aaa9b2 + "--color-primary-400": "107 104 121", // #6b6879 + "--color-primary-500": "43 39 63", // #2b273f + "--color-primary-600": "39 35 57", // #272339 + "--color-primary-700": "32 29 47", // #201d2f + "--color-primary-800": "26 23 38", // #1a1726 + "--color-primary-900": "21 19 31", // #15131f + // secondary | #454545 + "--color-secondary-50": "227 227 227", // #e3e3e3 + "--color-secondary-100": "218 218 218", // #dadada + "--color-secondary-200": "209 209 209", // #d1d1d1 + "--color-secondary-300": "181 181 181", // #b5b5b5 + "--color-secondary-400": "125 125 125", // #7d7d7d + "--color-secondary-500": "69 69 69", // #454545 + "--color-secondary-600": "62 62 62", // #3e3e3e + "--color-secondary-700": "52 52 52", // #343434 + "--color-secondary-800": "41 41 41", // #292929 + "--color-secondary-900": "34 34 34", // #222222 + // tertiary | #0EA5E9 + "--color-tertiary-50": "219 242 252", // #dbf2fc + "--color-tertiary-100": "207 237 251", // #cfedfb + "--color-tertiary-200": "195 233 250", // #c3e9fa + "--color-tertiary-300": "159 219 246", // #9fdbf6 + "--color-tertiary-400": "86 192 240", // #56c0f0 + "--color-tertiary-500": "14 165 233", // #0EA5E9 + "--color-tertiary-600": "13 149 210", // #0d95d2 + "--color-tertiary-700": "11 124 175", // #0b7caf + "--color-tertiary-800": "8 99 140", // #08638c + "--color-tertiary-900": "7 81 114", // #075172 + // success | #00b336 + "--color-success-50": "217 244 225", // #d9f4e1 + "--color-success-100": "204 240 215", // #ccf0d7 + "--color-success-200": "191 236 205", // #bfeccd + "--color-success-300": "153 225 175", // #99e1af + "--color-success-400": "77 202 114", // #4dca72 + "--color-success-500": "0 179 54", // #00b336 + "--color-success-600": "0 161 49", // #00a131 + "--color-success-700": "0 134 41", // #008629 + "--color-success-800": "0 107 32", // #006b20 + "--color-success-900": "0 88 26", // #00581a + // warning | #EAB308 + "--color-warning-50": "252 244 218", // #fcf4da + "--color-warning-100": "251 240 206", // #fbf0ce + "--color-warning-200": "250 236 193", // #faecc1 + "--color-warning-300": "247 225 156", // #f7e19c + "--color-warning-400": "240 202 82", // #f0ca52 + "--color-warning-500": "234 179 8", // #EAB308 + "--color-warning-600": "211 161 7", // #d3a107 + "--color-warning-700": "176 134 6", // #b08606 + "--color-warning-800": "140 107 5", // #8c6b05 + "--color-warning-900": "115 88 4", // #735804 + // error | #db004d + "--color-error-50": "250 217 228", // #fad9e4 + "--color-error-100": "248 204 219", // #f8ccdb + "--color-error-200": "246 191 211", // #f6bfd3 + "--color-error-300": "241 153 184", // #f199b8 + "--color-error-400": "230 77 130", // #e64d82 + "--color-error-500": "219 0 77", // #db004d + "--color-error-600": "197 0 69", // #c50045 + "--color-error-700": "164 0 58", // #a4003a + "--color-error-800": "131 0 46", // #83002e + "--color-error-900": "107 0 38", // #6b0026 + // surface | #272835 + "--color-surface-50": "223 223 225", // #dfdfe1 + "--color-surface-100": "212 212 215", // #d4d4d7 + "--color-surface-200": "201 201 205", // #c9c9cd + "--color-surface-300": "169 169 174", // #a9a9ae + "--color-surface-400": "104 105 114", // #686972 + "--color-surface-500": "39 40 53", // #272835 + "--color-surface-600": "35 36 48", // #232430 + "--color-surface-700": "29 30 40", // #1d1e28 + "--color-surface-800": "23 24 32", // #171820 + "--color-surface-900": "19 20 26", // #13141a + + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..02fc550 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "btsw-api6", + "version": "6.2.0", + "private": true, + "scripts": { + "start": "vite build && bun ./server/server.js", + "dev": "vite dev --host", + "build": "vite build", + "server": "bun ./server/server.js" + }, + "devDependencies": { + "@skeletonlabs/skeleton": "2.10.2", + "@skeletonlabs/tw-plugin": "^0.4.1", + "@sveltejs/adapter-auto": "^3.3.1", + "@sveltejs/kit": "^2.48.4", + "@sveltejs/vite-plugin-svelte": "^3.1.2", + "@tailwindcss/forms": "^0.5.10", + "@types/node": "22.7.5", + "autoprefixer": "10.4.20", + "postcss": "8.4.47", + "svelte": "^4.2.20", + "svelte-check": "^4.3.3", + "tailwindcss": "3.4.14", + "typescript": "^5.9.3", + "vite": "^5.4.21", + "vite-plugin-tailwind-purgecss": "0.3.3" + }, + "type": "module", + "dependencies": { + "@floating-ui/dom": "^1.7.4", + "@iconify/json": "^2.2.403", + "@iconify/tailwind": "^1.2.0", + "@sveltejs/adapter-node": "^5.4.0", + "btsw-api6": "file:", + "cors": "^2.8.5", + "dotenv": "^16.6.1", + "express": "^4.21.2", + "ms": "^2.1.3" + } +} diff --git a/postcss.config.cjs b/postcss.config.cjs new file mode 100644 index 0000000..1ff78f7 --- /dev/null +++ b/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/server/server.js b/server/server.js new file mode 100644 index 0000000..beaa9ed --- /dev/null +++ b/server/server.js @@ -0,0 +1,18 @@ +import { handler } from '../build/handler.js'; +import dotenv from 'dotenv'; +import http from 'http'; +import express from 'express'; +import cors from 'cors'; + +dotenv.config(); + +const app = express(); +const server = http.Server(app); + +app.use(cors()); + +app.use(handler); + +server.listen(process.env.PORT, () => { + console.log('listening on port http://localhost:' + process.env.PORT); +}); \ No newline at end of file diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..42436ee --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,9 @@ +// 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 {} + // interface Error {} + // interface Platform {} +} diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..3d31b04 --- /dev/null +++ b/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/app.postcss b/src/app.postcss new file mode 100644 index 0000000..d8770cd --- /dev/null +++ b/src/app.postcss @@ -0,0 +1,25 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; +@tailwind variants; + +html, +body { + @apply h-full overflow-hidden; +} + +.insta-gradient { + @apply bg-gradient-to-r from-[#f09433] to-[#c90076]; +} + +.profile-gradient { + @apply bg-gradient-to-r from-[#10d3ff] to-[#008cac]; +} + +.projects-gradient { + @apply bg-gradient-to-r from-[#ffe299] to-[#ffb700]; +} + +.btn-no-bordeer { + @apply border-none; +} \ No newline at end of file diff --git a/src/lib/components/BlobPFP.svelte b/src/lib/components/BlobPFP.svelte new file mode 100644 index 0000000..4ac8b22 --- /dev/null +++ b/src/lib/components/BlobPFP.svelte @@ -0,0 +1,65 @@ + + +
+
+ {alt} +
+ + \ No newline at end of file diff --git a/src/lib/components/EngineerCard.svelte b/src/lib/components/EngineerCard.svelte new file mode 100644 index 0000000..6f6f05e --- /dev/null +++ b/src/lib/components/EngineerCard.svelte @@ -0,0 +1,49 @@ + + +
+
+
+ -{Math.round((contributions/totalassets)*100)}% + +
+
+
+

{username}

+
+ { #each roles as role} + {role} + {/each} +

+

{bio}

+
+
+
+ +
\ No newline at end of file diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte new file mode 100644 index 0000000..adcafad --- /dev/null +++ b/src/lib/components/Footer.svelte @@ -0,0 +1,11 @@ + + + +
+
+ Made with ❤️ by Sir Blob +
+
+
\ No newline at end of file diff --git a/src/lib/components/HackCard.svelte b/src/lib/components/HackCard.svelte new file mode 100644 index 0000000..dc72f18 --- /dev/null +++ b/src/lib/components/HackCard.svelte @@ -0,0 +1,100 @@ + + +
+ +
+ {title} +
+ +
+
+
+

+ {title} +

+ {#if date} +

{date}

+ {/if} +
+ + {#if featured} + Featured + {/if} +
+ +

{description}

+ +
+
+ {#each tags as tag} + {tag} + {/each} +
+ +
+ {#if repo} + Repo + {/if} + {#if link} + Live + {/if} +
+
+
+
+ + diff --git a/src/lib/components/NavBar.svelte b/src/lib/components/NavBar.svelte new file mode 100644 index 0000000..06907f6 --- /dev/null +++ b/src/lib/components/NavBar.svelte @@ -0,0 +1,87 @@ + + + + + + + + + Logo + + + + + + + + + + + \ No newline at end of file diff --git a/src/lib/css/style.css b/src/lib/css/style.css new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/images/logo.png b/src/lib/images/logo.png new file mode 100644 index 0000000..4f45041 Binary files /dev/null and b/src/lib/images/logo.png differ diff --git a/src/lib/images/tgs-start.jpeg b/src/lib/images/tgs-start.jpeg new file mode 100644 index 0000000..9f9334e Binary files /dev/null and b/src/lib/images/tgs-start.jpeg differ diff --git a/src/lib/ts/index.ts b/src/lib/ts/index.ts new file mode 100644 index 0000000..4ff096e --- /dev/null +++ b/src/lib/ts/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte new file mode 100644 index 0000000..a250baa --- /dev/null +++ b/src/routes/+error.svelte @@ -0,0 +1,3 @@ +
+

404 or 500 or idk :(

+
\ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..e518335 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,31 @@ + + + + Sir Blob + + + + + + + + + + + + + + + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..1b902e4 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,70 @@ + + +
+
+
+ +
+
+

Sir Blob

+
+

Projects, Games, API, and More

+
+
+ + + + +
+
+
+ + diff --git a/src/routes/hackathons/+page.svelte b/src/routes/hackathons/+page.svelte new file mode 100644 index 0000000..53a2767 --- /dev/null +++ b/src/routes/hackathons/+page.svelte @@ -0,0 +1,79 @@ + + +
+
+
+
+ {#each cards as c} +
+ +
+ {/each} +
+
+
+
+ + diff --git a/src/routes/models/+page.server.ts b/src/routes/models/+page.server.ts new file mode 100644 index 0000000..c347975 --- /dev/null +++ b/src/routes/models/+page.server.ts @@ -0,0 +1,18 @@ +import fs from 'fs'; + +/** @type {import('./$types').PageServerLoad} */ +export async function load({ params }) { + + let files = []; + const models = fs.readdirSync(`./static/models`).filter(file => file.endsWith('.glb')); + + for(let model of models) { + let obj = { + path: "/models/" + model, + name: model.split('.')[0] + } + files.push(obj); + } + + return { files }; +} \ No newline at end of file diff --git a/src/routes/models/+page.svelte b/src/routes/models/+page.svelte new file mode 100644 index 0000000..aa2fdb9 --- /dev/null +++ b/src/routes/models/+page.svelte @@ -0,0 +1,55 @@ + + + + + + + +
+ +
\ No newline at end of file diff --git a/src/routes/portfolio/+page.svelte b/src/routes/portfolio/+page.svelte new file mode 100644 index 0000000..b26bfc9 --- /dev/null +++ b/src/routes/portfolio/+page.svelte @@ -0,0 +1,103 @@ + + +
+
+
+
+
+

Sir Blob

+
+ + + + +
+

+ Hi, I am Sir Blob (aka GamerBoss101) a developer that loves making things. + My passion is using Computer Science with practical Engineering to bring “Forgotten” technology into the future. + Therefore, I do fun coding projects, Game Jams, and Hackathons. + I like to play video games, like Minecraft and Pokémon TCG Live. +

+ + + +
+
+
+ +
+
+
+

Programming Languages

+
+ + + + + + + +
+

Applications

+
+ + + + + + + + +
+

Frameworks

+
+ + + + + + + + +
+

Projects

+
+ + + + +
+ +
+
+
\ No newline at end of file diff --git a/src/routes/portfolio/ContactChip.svelte b/src/routes/portfolio/ContactChip.svelte new file mode 100644 index 0000000..33f8e90 --- /dev/null +++ b/src/routes/portfolio/ContactChip.svelte @@ -0,0 +1,13 @@ + + + + + . + + \ No newline at end of file diff --git a/src/routes/portfolio/LangChip.svelte b/src/routes/portfolio/LangChip.svelte new file mode 100644 index 0000000..71397f9 --- /dev/null +++ b/src/routes/portfolio/LangChip.svelte @@ -0,0 +1,8 @@ + + + + {content} + \ No newline at end of file diff --git a/src/routes/portfolio/OrgCard.svelte b/src/routes/portfolio/OrgCard.svelte new file mode 100644 index 0000000..5dd26dc --- /dev/null +++ b/src/routes/portfolio/OrgCard.svelte @@ -0,0 +1,27 @@ + + +
+ +

+ {name} +

+
+ + \ No newline at end of file diff --git a/src/routes/portfolio/ProjectCard.svelte b/src/routes/portfolio/ProjectCard.svelte new file mode 100644 index 0000000..e4ea695 --- /dev/null +++ b/src/routes/portfolio/ProjectCard.svelte @@ -0,0 +1,25 @@ + + +
+ {name} Icon + {name} +
+ + \ No newline at end of file diff --git a/src/routes/portfolio/RoleChip.svelte b/src/routes/portfolio/RoleChip.svelte new file mode 100644 index 0000000..18d02e8 --- /dev/null +++ b/src/routes/portfolio/RoleChip.svelte @@ -0,0 +1,5 @@ + + +{role} \ No newline at end of file diff --git a/static/ChakraPetch-Regular.ttf b/static/ChakraPetch-Regular.ttf new file mode 100644 index 0000000..5a54c88 Binary files /dev/null and b/static/ChakraPetch-Regular.ttf differ diff --git a/static/Froggy_bois_2.gif b/static/Froggy_bois_2.gif new file mode 100644 index 0000000..bb59d2c Binary files /dev/null and b/static/Froggy_bois_2.gif differ diff --git a/static/blob_nerd.png b/static/blob_nerd.png new file mode 100644 index 0000000..f62990d Binary files /dev/null and b/static/blob_nerd.png differ diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..13602ee Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000..6e9f3d4 Binary files /dev/null and b/static/favicon.png differ diff --git a/static/favicon.svg b/static/favicon.svg new file mode 100644 index 0000000..b612402 --- /dev/null +++ b/static/favicon.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/static/models/BakePotato.glb b/static/models/BakePotato.glb new file mode 100644 index 0000000..d1953b4 Binary files /dev/null and b/static/models/BakePotato.glb differ diff --git a/static/models/Soda.glb b/static/models/Soda.glb new file mode 100644 index 0000000..d4aba06 Binary files /dev/null and b/static/models/Soda.glb differ diff --git a/static/tgs-start.jpeg b/static/tgs-start.jpeg new file mode 100644 index 0000000..9f9334e Binary files /dev/null and b/static/tgs-start.jpeg differ diff --git a/static/tgs/game-settings.png b/static/tgs/game-settings.png new file mode 100644 index 0000000..07e7ac4 Binary files /dev/null and b/static/tgs/game-settings.png differ diff --git a/static/tgs/game-start.png b/static/tgs/game-start.png new file mode 100644 index 0000000..7a2272a Binary files /dev/null and b/static/tgs/game-start.png differ diff --git a/static/tgs/game.jpg b/static/tgs/game.jpg new file mode 100644 index 0000000..f7e57d1 Binary files /dev/null and b/static/tgs/game.jpg differ diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..9b8363b --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,22 @@ +import adapter from '@sveltejs/adapter-node'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + extensions: ['.svelte'], + tsconfigFile: "./tsconfig.json", + compilerOptions: { + enableSourcemap: true, + }, + preprocess: [vitePreprocess({ + sourceMap: true + })], + kit: { + adapter: adapter() + }, + csrf: { + origin: process.env.PUBLIC_HOST, + checkOrigin: false, + } +}; +export default config; \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..003b1fa --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,32 @@ +import { join } from 'path' +import type { Config } from 'tailwindcss' +import { skeleton } from '@skeletonlabs/tw-plugin' + +import { myCustomTheme } from './CustomTheme'; + +import { addDynamicIconSelectors } from '@iconify/tailwind'; +import forms from '@tailwindcss/forms'; + +export default { + darkMode: 'selector', + content: ['./src/**/*.{html,js,svelte,ts}', join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')], + theme: { + extend: {}, + }, + plugins: [ + forms, + skeleton({ + themes: { + custom: [ + myCustomTheme + ] + }, + }), + addDynamicIconSelectors({ + prefix: 'icon', + scale: 2, + iconSets: {}, + customise: (content, name, prefix) => content + }) + ], +} satisfies Config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c6dac2d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..753bb11 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,7 @@ +import { purgeCss } from 'vite-plugin-tailwind-purgecss'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit(), purgeCss()] +}); \ No newline at end of file