Initial Commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..445071a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,147 @@
+# Created by https://www.toptal.com/developers/gitignore/api/node
+# Edit at https://www.toptal.com/developers/gitignore?templates=node
+
+### 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
+
+# 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.*
+
+### Node Patch ###
+# Serverless Webpack directories
+.webpack/
+
+# Optional stylelint cache
+
+# SvelteKit build / generate output
+.svelte-kit
+
+# End of https://www.toptal.com/developers/gitignore/api/node
+
+config/
+.DS_Store
\ No newline at end of file
diff --git a/backend/checkAuth.js b/backend/checkAuth.js
new file mode 100644
index 0000000..39db231
--- /dev/null
+++ b/backend/checkAuth.js
@@ -0,0 +1,5 @@
+module.exports = async (req, res, next) => {
+    if (req.isAuthenticated()) return next();
+    req.session.backURL = req.url;
+    res.redirect("/login");
+}
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
new file mode 100755
index 0000000..cb1f98c
--- /dev/null
+++ b/bun.lockb
Binary files differ
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..86430e1
--- /dev/null
+++ b/index.js
@@ -0,0 +1,42 @@
+const {
+  Client,
+  GatewayIntentBits
+} = require('discord.js');
+
+const client = new Client({
+  intents: [
+    GatewayIntentBits.Guilds,
+    GatewayIntentBits.GuildMembers,
+    GatewayIntentBits.DirectMessages,
+  ],
+});
+
+require("dotenv").config({
+  path: "config/.env"
+});
+
+require('./utils/functions')(client);
+
+client.mongoose = require('./utils/mongoose');
+
+client.on('ready', () => {
+  console.log(`Starting Server`);
+  const webPortal = require('./server');
+  webPortal.load(client);
+});
+
+// Listening for error & warn events.
+client.on("error", console.error);
+client.on("warn", console.warn);
+
+process.on('unhandledRejection', error => {
+  console.error('Unhandled promise rejection:', error);
+});
+
+process.on('uncaughtException', function (err) {
+  console.log('Caught exception: ' + err);
+});
+
+client.mongoose.init();
+
+client.login(process.env.TOKEN);
\ No newline at end of file
diff --git a/models/auth.js b/models/auth.js
new file mode 100644
index 0000000..eca7725
--- /dev/null
+++ b/models/auth.js
@@ -0,0 +1,9 @@
+const mongoose = require('mongoose');
+
+const authSchema = mongoose.Schema({
+    discord: { type: String, require: true },
+    minecraft: { type: String, require: false },
+    banned: { type: Boolean, require: true, default: false },
+});
+
+module.exports = mongoose.model('Auth', authSchema);
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..20e016e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+  "name": "Appeel",
+  "version": "0.1.0",
+  "description": "Appeel bot",
+  "main": "node index.js",
+  "scripts": {
+    "start": "node index.js"
+  },
+  "engines": {
+    "node": "17.x"
+  },
+  "author": "Cleo",
+  "license": "MIT",
+  "dependencies": {
+    "body-parser": "^1.20.0",
+    "discord.js": "^14.3.0",
+    "dotenv": "^16.0.2",
+    "ejs": "^3.1.8",
+    "express": "^4.18.1",
+    "express-session": "^1.17.3",
+    "mongoose": "^6.6.1",
+    "passport": "^0.6.0",
+    "passport-discord": "^0.1.4"
+  },
+  "devDependencies": {
+    "eslint": "^8.15.0",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^6.0.0"
+  }
+}
diff --git a/public/assets/blahaj.png b/public/assets/blahaj.png
new file mode 100644
index 0000000..8d24d08
--- /dev/null
+++ b/public/assets/blahaj.png
Binary files differ
diff --git a/public/assets/boat.png b/public/assets/boat.png
new file mode 100644
index 0000000..1e2bfe2
--- /dev/null
+++ b/public/assets/boat.png
Binary files differ
diff --git a/public/assets/bush_left.png b/public/assets/bush_left.png
new file mode 100644
index 0000000..efa019d
--- /dev/null
+++ b/public/assets/bush_left.png
Binary files differ
diff --git a/public/assets/bush_right.png b/public/assets/bush_right.png
new file mode 100644
index 0000000..df90408
--- /dev/null
+++ b/public/assets/bush_right.png
Binary files differ
diff --git a/public/assets/cloud_left.png b/public/assets/cloud_left.png
new file mode 100644
index 0000000..9ea751d
--- /dev/null
+++ b/public/assets/cloud_left.png
Binary files differ
diff --git a/public/assets/cloud_right.png b/public/assets/cloud_right.png
new file mode 100644
index 0000000..72e8dcd
--- /dev/null
+++ b/public/assets/cloud_right.png
Binary files differ
diff --git a/public/assets/embed.png b/public/assets/embed.png
new file mode 100644
index 0000000..65afc0b
--- /dev/null
+++ b/public/assets/embed.png
Binary files differ
diff --git a/public/assets/favicon.png b/public/assets/favicon.png
new file mode 100644
index 0000000..9c09d02
--- /dev/null
+++ b/public/assets/favicon.png
Binary files differ
diff --git a/public/assets/icon/discord.jpg b/public/assets/icon/discord.jpg
new file mode 100644
index 0000000..4f6d534
--- /dev/null
+++ b/public/assets/icon/discord.jpg
Binary files differ
diff --git a/public/assets/icon/reddit.png b/public/assets/icon/reddit.png
new file mode 100644
index 0000000..a403178
--- /dev/null
+++ b/public/assets/icon/reddit.png
Binary files differ
diff --git a/public/assets/icon/revolt.png b/public/assets/icon/revolt.png
new file mode 100644
index 0000000..7a4357a
--- /dev/null
+++ b/public/assets/icon/revolt.png
Binary files differ
diff --git a/public/assets/lake.png b/public/assets/lake.png
new file mode 100644
index 0000000..46b10ab
--- /dev/null
+++ b/public/assets/lake.png
Binary files differ
diff --git a/public/assets/mountains.png b/public/assets/mountains.png
new file mode 100644
index 0000000..ab8c007
--- /dev/null
+++ b/public/assets/mountains.png
Binary files differ
diff --git a/public/assets/sky.png b/public/assets/sky.png
new file mode 100644
index 0000000..1af09ae
--- /dev/null
+++ b/public/assets/sky.png
Binary files differ
diff --git a/public/css/style.css b/public/css/style.css
new file mode 100644
index 0000000..0629490
--- /dev/null
+++ b/public/css/style.css
@@ -0,0 +1,230 @@
+@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap");
+
+html,
+body {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  overflow: hidden; /* Prevent page scrolling */
+}
+
+body {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.background {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: -1;
+}
+
+.bush {
+  position: fixed;
+  top: 3%;
+  width: 100%;
+  height: 100%;
+  z-index: 7;
+  filter: blur(5px);
+}
+
+.bush-left-overlay {
+  left: -3%;
+  background-image: url("./../assets/bush_left.png");
+  background-size: cover;
+  background-position: center bottom;
+}
+
+.bush-right-overlay {
+  left: 3%;
+  background-image: url("./../assets/bush_right.png");
+  background-size: cover;
+  background-position: center bottom;
+}
+
+.blahaj-overlay {
+  background-image: url("./../assets/blahaj.png");
+  background-size: cover;
+  background-position: calc(50% - 50px) bottom;
+  z-index: 6;
+}
+
+.boat-overlay {
+  background-image: url("./../assets/boat.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  z-index: 5;
+}
+
+.cloud-left-overlay {
+  background-image: url("./../assets/cloud_left.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  top: -10px;
+  z-index: 4;
+}
+
+.cloud-right-overlay {
+  background-image: url("./../assets/cloud_right.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  top: -20px;
+  z-index: 4;
+}
+
+.lake-overlay {
+  background-image: url("./../assets/lake.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  z-index: 3;
+}
+
+.mountains-overlay {
+  background-image: url("./../assets/mountains.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  z-index: 2;
+}
+
+.sky-overlay {
+  background-image: url("./../assets/sky.png");
+  background-size: cover;
+  background-position: calc(50% + 250px) bottom;
+  z-index: 1;
+}
+
+.canvas-overlay {
+  position: relative;
+  top: 100px;
+  left: -250px;
+  z-index: 1;
+  filter: blur(5px);
+}
+
+.discord {
+  background-color: #5865f2;
+}
+
+.revolt {
+  background-color: rgb(255, 70, 84);
+}
+
+.reddit {
+  background-color: #ff4300;
+}
+
+.image-button {
+  display: inline-block;
+  padding: 13px;
+  border-radius: 5px;
+  color: white;
+  border: none;
+  font-size: px;
+  text-align: left;
+  text-decoration: none;
+  margin-bottom: 10px;
+  font-family: "Poppins", "San Francisco", sans-serif;
+  font-weight: 400;
+  text-align: center;
+  width: 90%;
+}
+
+
+.button-icon {
+  display: inline-block;
+  vertical-align: middle;
+  width: 20px;
+  height: 20px;
+  margin-right: 13px;
+}
+
+.container {
+  position: absolute;
+  right: 50px;
+  background-color: #a789a8a2;
+  padding: 50px 50px;
+  border-radius: 5px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+  transition: background-color 2s ease-out;
+  max-width: 300px;
+  flex-direction: column;
+  align-items: center;
+  z-index: 9;
+}
+
+h1 {
+  margin-top: 0;
+  font-family: "Poppins", "San Francisco", sans-serif;
+  font-weight: 600;
+  color: rgb(236, 236, 236);
+  text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+  font-size: 40px;
+}
+
+h2 {
+  margin-top: -35px;
+  font-family: "Poppins", "San Francisco", sans-serif;
+  font-weight: 500;
+  color: rgb(236, 236, 236);
+  text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+  font-size: 25px;
+}
+
+p {
+  margin-top: -20px; /* Adjust the margin as needed */
+  padding-bottom: 7px;
+  font-family: "Poppins", "San Francisco", sans-serif;
+  font-weight: 400;
+  color: rgb(236, 236, 236);
+  text-shadow: 0 0 10px rgba(43, 43, 43, 0.5);
+  font-size: 17px;
+}
+
+p.indent {
+  font-weight: 400;
+  margin-top: -10px;
+  margin-left: 25px;
+}
+
+.blur {
+  backdrop-filter: blur(7px);
+}
+
+@media only screen and (max-width: 700px) {
+  .container {
+    right: auto;
+    padding: 50px 30px;
+    max-width: 400px;
+  }
+
+  h1 {
+    font-size: 30px;
+  }
+
+  p {
+    margin-top: -25px;
+    font-size: 15px;
+  }
+
+  .image-button {
+    font-size: 15px;
+  }
+
+  .button-icon {
+    width: 15px;
+    height: 15px;
+  }
+
+  .discord {
+    padding: 10px;
+  }
+
+  .revolt {
+    padding: 10px;
+  }
+
+}
diff --git a/public/grayscale aroace.png b/public/grayscale aroace.png
new file mode 100644
index 0000000..96efcbe
--- /dev/null
+++ b/public/grayscale aroace.png
Binary files differ
diff --git a/public/grayscale barcode.png b/public/grayscale barcode.png
new file mode 100644
index 0000000..e256ee4
--- /dev/null
+++ b/public/grayscale barcode.png
Binary files differ
diff --git a/public/grayscale prideplace.png b/public/grayscale prideplace.png
new file mode 100644
index 0000000..e5604dd
--- /dev/null
+++ b/public/grayscale prideplace.png
Binary files differ
diff --git a/public/grayscale trans 1.png b/public/grayscale trans 1.png
new file mode 100644
index 0000000..a088dc8
--- /dev/null
+++ b/public/grayscale trans 1.png
Binary files differ
diff --git a/public/grayscale trans 2.png b/public/grayscale trans 2.png
new file mode 100644
index 0000000..0cb02c3
--- /dev/null
+++ b/public/grayscale trans 2.png
Binary files differ
diff --git a/public/grayscale trans pikmin.png b/public/grayscale trans pikmin.png
new file mode 100644
index 0000000..1d6c5f2
--- /dev/null
+++ b/public/grayscale trans pikmin.png
Binary files differ
diff --git a/public/js/canvas.js b/public/js/canvas.js
new file mode 100644
index 0000000..3d2c1cc
--- /dev/null
+++ b/public/js/canvas.js
@@ -0,0 +1,98 @@
+const canvas = document.querySelector("canvas");
+const ctx = canvas.getContext("2d");
+
+let amplitud = 10;
+let speed = 0.025;
+let points = [];
+
+let cw = (canvas.width = 1500),
+  cx = cw / 2;
+let ch = (canvas.height = 1500),
+  cy = ch / 2;
+ctx.fillStyle = "#ffffff";
+ctx.strokeStyle = "transparent";
+
+let corners = [];
+let n = 15;
+let r = cx - amplitud - 100;
+for (var i = 0; i < n; i++) {
+  corners.push([
+    cx + r * Math.cos((2 * Math.PI * i) / n),
+    cy + r * Math.sin((2 * Math.PI * i) / n),
+  ]);
+}
+
+class Point {
+  constructor(x, y, hv) {
+    this.cx = x;
+    this.cy = y;
+    this.a = Math.random() * 2 * Math.PI;
+    this.hv = hv;
+
+    this.update();
+  }
+
+  update() {
+    this.a += speed;
+
+    if (this.hv == 0) {
+      this.x = this.cx;
+      this.y = this.cy + amplitud * Math.cos(this.a);
+    } else {
+      this.x = this.cx + amplitud * Math.cos(this.a);
+      this.y = this.cy;
+    }
+  }
+}
+
+function divide(n, a, b) {
+  for (var i = 0; i <= n; i++) {
+    let p = {
+      x: ((b[0] - a[0]) * i) / n + a[0],
+      y: ((b[1] - a[1]) * i) / n + a[1],
+      hv: b[1] - a[1],
+    };
+    points.push(new Point(p.x, p.y, p.hv));
+  }
+}
+
+for (let i = 0; i < corners.length; i++) {
+  let currentCorner = corners[i];
+  let nextCorner = corners[(i + 1) % corners.length];
+  divide(10, currentCorner, nextCorner);
+  points.pop();
+}
+
+function drawCurves() {
+  let p = {};
+  p.x = (points[points.length - 1].x + points[0].x) / 2;
+  p.y = (points[points.length - 1].y + points[0].y) / 2;
+  ctx.beginPath();
+  ctx.moveTo(p.x, p.y);
+  for (var i = 0; i < points.length - 1; i++) {
+    let mp = {};
+    mp.x = (points[i].x + points[i + 1].x) / 2;
+    mp.y = (points[i].y + points[i + 1].y) / 2;
+    ctx.quadraticCurveTo(points[i].x, points[i].y, mp.x, mp.y);
+  }
+
+  ctx.quadraticCurveTo(
+    points[points.length - 1].x,
+    points[points.length - 1].y,
+    p.x,
+    p.y
+  );
+  ctx.stroke();
+  ctx.fill();
+}
+
+function Draw() {
+  window.requestAnimationFrame(Draw);
+  ctx.clearRect(0, 0, cw, ch);
+  points.map((p) => {
+    p.update();
+  });
+  drawCurves();
+}
+
+Draw();
diff --git a/public/js/script.js b/public/js/script.js
new file mode 100644
index 0000000..e9a51f2
--- /dev/null
+++ b/public/js/script.js
@@ -0,0 +1,66 @@
+function changeContainerColor(color) {
+  const container = document.querySelector(".container");
+  container.style.backgroundColor = color;
+}
+
+const blahajOverlay = document.querySelector(".blahaj-overlay");
+const boatOverlay = document.querySelector(".boat-overlay");
+const cloudLeftOverlay = document.querySelector(".cloud-left-overlay");
+const cloudRightOverlay = document.querySelector(".cloud-right-overlay");
+const lakeOverlay = document.querySelector(".lake-overlay");
+const mountainsOverlay = document.querySelector(".mountains-overlay");
+
+const bushLeftOverlay = document.querySelector(".bush-left-overlay");
+const bushRightOverlay = document.querySelector(".bush-right-overlay");
+const canvasOverlay = document.querySelector(".canvas-overlay");
+
+blahajOverlay.style.transition = "transform 2s ease-out";
+boatOverlay.style.transition = "transform 2s ease-out";
+lakeOverlay.style.transition = "transform 2s ease-out";
+cloudLeftOverlay.style.transition = "transform 2s ease-out";
+cloudRightOverlay.style.transition = "transform 2s ease-out";
+bushLeftOverlay.style.transition = "transform 2s ease-out";
+bushRightOverlay.style.transition = "transform 2s ease-out";
+
+canvasOverlay.style.transform = "scale(0.9)";
+
+window.addEventListener("resize", () => {
+  canvasOverlay.style.transform =
+    "scale(" + scaleValue(window.innerWidth) + ")";
+});
+
+function parallaxStart() {
+  blahajOverlay.style.transform = "scale(1.01)";
+  boatOverlay.style.transform = "scale(1.01)";
+  lakeOverlay.style.transform = "scale(1.003)";
+  cloudLeftOverlay.style.transform = "translateX(-5px)";
+  cloudRightOverlay.style.transform = "translateX(5px)";
+  bushLeftOverlay.style.transform = "translateX(-100px)";
+  bushRightOverlay.style.transform = "translateX(150px)";
+}
+
+function parallaxEnd() {
+  blahajOverlay.style.transform = "scale(1)";
+  boatOverlay.style.transform = "scale(1)";
+  lakeOverlay.style.transform = "scale(1)";
+  cloudLeftOverlay.style.transform = "translateX(0px)";
+  cloudRightOverlay.style.transform = "translateX(0px)";
+  bushLeftOverlay.style.transform = "translateX(0px)";
+  bushRightOverlay.style.transform = "translateX(0px)";
+}
+
+function scaleValue(windowWidth) {
+  const minWindowWidth = 500; // Minimum window.innerWidth value
+  const maxWindowWidth = 2000; // Maximum window.innerWidth value
+  const minValue = 0.8; // Minimum scaled value
+  const maxValue = 0.9; // Maximum scaled value
+
+  // Scale the value based on the window.innerWidth
+  const scaledValue =
+    minValue +
+    ((windowWidth - minWindowWidth) / (maxWindowWidth - minWindowWidth)) *
+      (maxValue - minValue);
+
+  // Return the scaled value (rounded to the nearest integer)
+  return scaledValue;
+}
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..04cda75
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,6 @@
+User-agent: *
+Disallow: /css/
+Disallow: /js/
+Disallow: /assets/
+
+Sitemap: https://trans.gg/sitemap.xml
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..eb9ed83
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset
+      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
+            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
+
+<url>
+  <loc>https://trans.gg/</loc>
+  <lastmod>2023-06-23T02:21:30+00:00</lastmod>
+</url>
+
+</urlset>
\ No newline at end of file
diff --git a/public/template.json b/public/template.json
new file mode 100644
index 0000000..f1d7612
--- /dev/null
+++ b/public/template.json
@@ -0,0 +1,121 @@
+{
+  "contact": "discord.gg/TransPlace",
+  "notifications": "https://broadcaster.trans.gg",
+  "templates": [
+    {
+      "name": "First Trans Flag Grayscaled",
+      "sources": [
+        "https://i.imgur.com/IRfl6TH.png"
+      ],
+      "x": 1548,
+      "y": 997
+    },
+    {
+      "name": "Second Trans Flag Grayscaled",
+      "sources": [
+        "https://i.imgur.com/TNw7fGE.png"
+      ],
+      "x": 864,
+      "y": 816
+    },
+    {
+      "name": "Aro/Ace flags",
+      "sources": [
+        "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20aroace.png"
+      ],
+      "x": 1134,
+      "y": 1588
+    },
+    {
+      "name": "Barcode trans pikmin",
+      "sources": [
+        "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20trans%20pikmin.png"
+      ],
+      "x": 542,
+      "y": 1755
+    },
+    {
+      "name": "barcode flags",
+      "sources": [
+        "https://raw.githubusercontent.com/TransPlace-Devs/trans.gg/master/grayscale%20barcode.png"
+      ],
+      "x": 500,
+      "y": 1754
+    },
+    {
+      "name": "Whiteout",
+      "sources": [
+        "https://place.army/default_target.png?cachebust=1"
+      ],
+      "x": 0,
+      "y": 0
+    }
+  ],
+  "whitelist": [
+    {
+      "name": "Tally Hall",
+      "url": "https://raw.githubusercontent.com/TransPlace-Devs/rplace-tallyhall/production/tallyhall.json"
+    },
+    {
+      "name": "r/PlacePride",
+      "url": "https://pride.place/template.json"
+    },
+    {
+      "name": "Outer Wilds",
+      "url": "https://raw.githubusercontent.com/souleaub/TGR_Overlay/main/outer_wilds.json"
+    },
+    {
+      "name": "YTTD",
+      "url": "https://rentry.co/yttdgang2/raw"
+    },
+    {
+      "name": "r/Femboy",
+      "url": "https://pastebin.com/raw/ESaN3Csh"
+    },
+    {
+      "name": "SeverslvtEvents",
+      "url": "https://raw.githubusercontent.com/Celarye/r-place-alliance/master/templates/JVNEPlace.json"
+    },
+    {
+      "name": "Echoplace",
+      "url": "https://raw.githubusercontent.com/DancingNerd/echoplace/main/echoplace.json"
+    },
+    {
+      "name": "eighty six",
+      "url": "https://raw.githubusercontent.com/Celarye/r-place-alliance/master/templates/86Place.json"
+    },
+    {
+      "name": "Celeste",
+      "url": "https://raw.githubusercontent.com/GabRioBlu/place2023celeste/main/template.json"
+    },
+    {
+      "name": "Chibi",
+      "url": "https://rentry.co/SDRA2Sora/raw"
+    },
+    {
+      "name": "Furryirl",
+      "url": "https://gist.githubusercontent.com/Furryirlburner1/09ce4195fada18db6dc5e32e30a8e34b/raw"
+    },
+    {
+      "name": "DutchGekte",
+      "url": "https://cdn.discordapp.com/attachments/982274631538987078/1132727141595881602/gekteDutch.json"
+    },
+    {
+      "name": "One Piece",
+      "url": "https://raw.githubusercontent.com/Lopeh/onepiece-place/main/oneplace-template.json"
+    },
+    {
+      "name": "Fuck Spez",
+      "url": "https://fmxal.mooo.com/fuck-spez-live/template.json"
+    },
+    {
+      "name": "Anarchy",
+      "url": "https://rentry.co/scc3v/raw"
+    },
+    {
+      "name": "barcode",
+      "url": "https://pride.place/barcode.png"
+    }
+  ],
+  "blacklist": []
+}
diff --git a/routes/index.js b/routes/index.js
new file mode 100644
index 0000000..4e7590f
--- /dev/null
+++ b/routes/index.js
@@ -0,0 +1,56 @@
+const express = require("express");
+
+const passport = require("passport");
+
+const router = express.Router();
+
+router.get("/", async (req, res) => {
+  res.render("index", {});
+});
+router.get("/auth", async (req, res) => {
+  let auth;
+  if (req.user?.id) {
+    auth = await req.client.getUserData(req.user.id);
+
+	console.log(auth.minecraft)
+	console.log(req.query.minecraft)
+	console.log(!auth.minecraft && req.query.minecraft)
+
+    if (!auth.minecraft && req.query.minecraft) {
+		console.log("hit")
+		auth = await req.client.setMC(req.user.id, req.query.minecraft);
+
+	}
+  } else auth = null;
+
+  res.render("auth", {
+    tag: req.user ? req.user.tag : "Auth",
+    auth: auth,
+    bot: req.client,
+    user: req.user || null,
+  });
+});
+
+router.get(
+  "/login",
+  passport.authenticate("discord", {
+    failureRedirect: "/",
+  }),
+  async function (req, res) {
+    if (!req.user.id || !req.user.guilds) {
+      // failed auth page
+      res.redirect("/");
+    } else {
+      res.redirect("/auth");
+    }
+  }
+);
+
+router.get("/logout", async function (req, res, next) {
+  req.session.destroy(() => {
+    req.logout(function () {});
+    res.redirect("/");
+  });
+});
+
+module.exports = router;
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..9ce7823
--- /dev/null
+++ b/server.js
@@ -0,0 +1,62 @@
+const express = require('express');
+const app = express();
+const bodyparser = require('body-parser');
+const session = require('express-session');
+const ejs = require('ejs');
+const passport = require('passport');
+const { Strategy } = require('passport-discord');
+
+module.exports.load = async (client) => {
+	app.use(bodyparser.json());
+	app.use(bodyparser.urlencoded({ extended: true }));
+	app.engine('html', ejs.renderFile);
+	app.set('view engine', 'ejs');
+	app.set('views', "./views");
+	app.use(express.static("./public"));
+	app.use(session({
+		secret: 'BotDashboardExample101',
+		resave: false,
+		saveUninitialized: false,
+	}));
+
+	app.use(async function(req, res, next) {
+		req.client = client;
+		next();
+	});
+
+	app.use(passport.initialize());
+	app.use(passport.session());
+
+	passport.serializeUser((user, done) => {
+		done(null, user);
+	});
+	passport.deserializeUser((obj, done) => {
+		done(null, obj);
+	});
+
+	passport.use(new Strategy({
+		clientID: process.env.CLIENT_ID,
+		clientSecret: process.env.CLIENT_SECRET,
+		callbackURL: process.env.CALLBACK_URL,
+		scope: [ 'identify', 'guilds' ],
+	}, function(accessToken, refreshToken, profile, done) {
+		process.nextTick(function() {
+			return done(null, profile);
+		});
+	}));
+
+	app.use('/', require('./routes/index'));
+	// app.use('/dashboard', require('./routes/dashboard'));
+	// app.use('/appeal', require('./routes/appeal'));
+
+	app.get('*', (req, res) => {
+		res.render('../views/404', {
+			bot: req.client,
+			user: req.user,
+		});
+	});
+
+	app.listen(process.env.PORT, () => {
+		console.log(`Web Server now online on port ${process.env.PORT} | Dashboard: http://localhost:${process.env.PORT}/`);
+	});
+};
\ No newline at end of file
diff --git a/utils/functions.js b/utils/functions.js
new file mode 100644
index 0000000..ad1fc03
--- /dev/null
+++ b/utils/functions.js
@@ -0,0 +1,22 @@
+const Auth = require('../models/auth');

+

+module.exports = client => {

+ 

+    client.createUser = async (userID) => {

+        let merged = Object.assign({discord: userID});

+        const newAuth = await new Auth(merged);

+        return newAuth.save()

+    };

+

+    client.getUserData = async (userID) => {

+        let data = await Auth.findOne({ discord: userID });

+        if (data) return data;

+        else return await client.createUser(userID)

+    };

+

+    client.setMC = async (userID, username) => {

+        let data = await client.getUserData(userID);

+        data.minecraft == username;

+        return data.save()

+    }

+}
\ No newline at end of file
diff --git a/utils/mongoose.js b/utils/mongoose.js
new file mode 100644
index 0000000..93f5558
--- /dev/null
+++ b/utils/mongoose.js
@@ -0,0 +1,21 @@
+const mongoose = require('mongoose');

+

+module.exports = {

+    init: () => {

+        mongoose.connect(process.env.MONGO_URL).catch(err => console.log(err.reason));

+

+        mongoose.Promise = global.Promise;

+

+        mongoose.connection.on('connected', () => {

+            console.log('\nMongoose connection successfully opened');

+        });

+

+        mongoose.connection.on('err', err => {

+            console.error(`Mongoose connection Error\n ${err.stack}`);

+        });

+

+        mongoose.connection.on('disconnected', () => {

+            console.log('Mongoose connection disconnected');

+        });

+    }

+};
\ No newline at end of file
diff --git a/views/404.ejs b/views/404.ejs
new file mode 100644
index 0000000..f8cd59e
--- /dev/null
+++ b/views/404.ejs
@@ -0,0 +1,9 @@
+<title>TransGG » 404 Not Found</title>
+
+<div style="padding-top: 65px;">
+  <div>
+    <div class="container">
+      <h2>404 - Not Found</h2>
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/views/auth.ejs b/views/auth.ejs
new file mode 100644
index 0000000..c53be71
--- /dev/null
+++ b/views/auth.ejs
@@ -0,0 +1,37 @@
+<div>
+  <% if (user) { %>
+  <p>You are logged in</p>
+
+  <% if (auth && auth.minecraft) { %>
+  <p>Already Linked MC</p>
+  <p>MC username = <%= auth.minecraft %></p>
+
+  <% } else { %>
+  <p>No Minecraft Added</p>
+  <form action="/auth" method="GET`">
+    <label for="minecraft">Enter your Minecraft username:</label><br />
+    <input
+      type="text"
+      id="minecraft"
+      name="minecraft"
+      pattern="^[a-zA-Z0-9_]{2,16}$"
+      title="Please enter a valid Minecraft username (2-16 characters, only letters, numbers, and underscores)"
+      required
+    />
+    <input type="submit" value="Link Minecraft" />
+  </form>
+  <% } %>
+
+  <!-- If not ask them for their minecraft username -->
+  <% } else { %>
+  <h2>Welcome to the TransGG Minecraft Server!</h2>
+  <p>
+    To join our Minecraft server, you must first become a member of one of our
+    partnered Minecraft communities and get verified. If you're not already part
+    of a community, you can join one below. Otherwise, if you're already
+    verified, please log in below:
+  </p>
+  <a href="/login">Login</a>
+
+  <% } %>
+</div>
diff --git a/views/index.ejs b/views/index.ejs
new file mode 100644
index 0000000..b4510e5
--- /dev/null
+++ b/views/index.ejs
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>TransPlace - A Place For Trans People</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta charset="UTF-8" />
+    <meta property="og:title" content="TransPlace" />
+    <meta
+      property="og:description"
+      content="A community and safe space to talk about gaming, art, and more, while being you."
+    />
+    <meta property="og:image" content="https://trans.gg/assets/embed.png" />
+    <meta property="og:image:type" content="image/jpeg" />
+    <meta property="og:image:width" content="1920" />
+    <meta property="og:image:height" content="1080" />
+    <meta property="og:url" content="Trans.gg" />
+    <meta property="og:type" content="website" />
+    <meta name="twitter:title" content="TransPlace" />
+    <meta
+      name="twitter:description"
+      content="A community and safe space to talk about gaming, art, and more, while being you."
+    />
+    <meta name="twitter:card" content="summary_large_image" />
+    <meta name="twitter:image" content="https://trans.gg/assets/embed.png" />
+    <meta name="'twitter:image:alt" content="TransPlace Boat" />
+
+    <meta
+      name="description"
+      content="A community and safe space to talk about gaming, art, and more, while being you."
+    />
+    <meta
+      name="keywords"
+      content="TransPlace, Trans, Transgender, Non Binary, LGBT, LGBTQ, community, safe space, gaming, art, community forum, Discord, Revolt, Reddit"
+    />
+    <meta name="theme-color" content="#f6c4bb" />
+    <link
+      rel="icon"
+      href="./assets/favicon.png"
+      type="image/png"
+      sizes="16x16"
+    />
+    <link rel="stylesheet" href="./css/style.css" />
+  </head>
+
+  <body>
+    <div class="bush bush-left-overlay"></div>
+    <div class="bush bush-right-overlay"></div>
+
+    <div class="background blahaj-overlay"></div>
+    <div class="background boat-overlay"></div>
+    <div class="background cloud-left-overlay"></div>
+    <div class="background cloud-right-overlay"></div>
+    <div class="background lake-overlay"></div>
+    <div class="background mountains-overlay"></div>
+    <div class="background sky-overlay"></div>
+
+    <canvas class="canvas-overlay"></canvas>
+
+    <section
+      class="container blur"
+      onmouseover="parallaxStart()"
+      onmouseout="parallaxEnd()"
+    >
+      <h1>TransPlace</h1>
+      <h2>/ˈtrænspleɪs/</h2>
+
+      <p>noun</p>
+      <p class="indent">
+        A community and safe space to talk about gaming, art, and more, while
+        being you.
+      </p>
+      <div>
+        <a
+          href="https://discord.gg/TransPlace"
+          class="image-button discord"
+          onmouseover="changeContainerColor('rgba(65, 71, 140, 0.75)')"
+          onmouseout="changeContainerColor('#a789a8a2')"
+        >
+          <img
+            src="./assets/icon/discord.jpg"
+            alt="Discord Icon"
+            class="button-icon"
+          />
+          Join our Discord!
+        </a>
+        <a
+          href="https://rvlt.gg/wEXFtr9s"
+          class="image-button revolt"
+          onmouseover="changeContainerColor('rgba(135, 61, 66, 0.75)')"
+          onmouseout="changeContainerColor('#a789a8a2')"
+        >
+          <img
+            src="./assets/icon/revolt.png"
+            alt="Revolt Icon"
+            class="button-icon"
+          />
+          Join our Revolt!
+        </a>
+      </div>
+      <div>
+        <a
+          href="https://reddit.com/r/TransPlace"
+          class="image-button reddit"
+          onmouseover="changeContainerColor('rgba(135, 59, 32, 0.75)')"
+          onmouseout="changeContainerColor('#a789a8a2')"
+        >
+          <img
+            src="./assets/icon/reddit.png"
+            alt="Reddit Icon"
+            class="button-icon"
+          />
+          Join our Reddit!
+        </a>
+      </div>
+      <div>
+        <a
+          href="/auth"
+          class="image-button minectaft"
+          onmouseover="changeContainerColor('rgba(143, 114, 126, 0.75)')"
+          onmouseout="changeContainerColor('#8f727ea2')"
+        >
+          Login / Authenticate
+        </a>
+      </div>
+    </section>
+    <script src="./js/script.js"></script>
+    <script src="./js/canvas.js"></script>
+  </body>
+</html>