for coded
diff --git a/src/utils/calculate.ts b/src/utils/calculate.ts
new file mode 100644
index 0000000..174c401
--- /dev/null
+++ b/src/utils/calculate.ts
@@ -0,0 +1,66 @@
+const logs = [
+    "channelUpdate",
+    "channelPinsUpdate",
+    "emojiUpdate",
+    "stickerUpdate",
+    "guildUpdate",
+    "guildMemberUpdate",
+    "guildMemberPunish",
+    "guildEventUpdate",
+    "guildEventMemberUpdate",
+    "guildRoleUpdate",
+    "guildInviteUpdate",
+    "messageUpdate",
+    "messageDelete",
+    "messageDeleteBulk",
+    "messageReactionUpdate",
+    "messagePing",
+    "messageMassPing",
+    "messageAnnounce",
+    "stageUpdate",
+    "threadUpdate",
+    "voiceStateUpdate",
+    "webhookUpdate"
+]
+
+const tickets = [
+    "support",
+    "report",
+    "question",
+    "issue",
+    "suggestion",
+    "other"
+]
+
+const toHexInteger = (permissions, array?) => {
+    if (!array) {
+        array = logs;
+    }
+    let int = 0n;
+
+    for(let perm of permissions) {
+        int += BigInt(2 ** array.indexOf(perm));
+    }
+    return int.toString(16)
+}
+
+const toHexArray = (permissionsHex, array?) => {
+    if (!array) {
+        array = logs;
+    }
+    let permissions = [];
+    let int = (BigInt("0x" + permissionsHex)).toString(2).split('').reverse();
+    for (let index in int) {
+        if (int[index] == "1") {
+            permissions.push(array[index]);
+        }
+    }
+    return permissions;
+}
+
+export {
+	toHexInteger,
+	toHexArray,
+    tickets,
+    logs
+}
\ No newline at end of file
diff --git a/src/utils/convertCurlyBracketString.ts b/src/utils/convertCurlyBracketString.ts
new file mode 100644
index 0000000..093e522
--- /dev/null
+++ b/src/utils/convertCurlyBracketString.ts
@@ -0,0 +1,15 @@
+async function convertCurlyBracketString(str, memberID, memberName, serverName, members): Promise<string> {
+    let memberCount = (await members.fetch()).size
+    let bots = (await members.fetch()).filter(m => m.user.bot).size
+    str = str
+        .replace("{@}", `<@${memberID}>`)
+        .replace("{server}", `${serverName}`)
+        .replace("{name}", `${memberName}`)
+        .replace("{count}", `${memberCount}`)
+        .replace("{count:bots}", `${bots}`)
+        .replace("{count:humans}", `${memberCount - bots}`);
+
+    return str
+}
+
+export default convertCurlyBracketString;
\ No newline at end of file
diff --git a/src/utils/generateConfig.ts b/src/utils/generateConfig.ts
new file mode 100644
index 0000000..6dc4e52
--- /dev/null
+++ b/src/utils/generateConfig.ts
@@ -0,0 +1,92 @@
+import * as fs from 'fs';
+
+function writeLogConfig(guild, logs) {
+    if( !fs.existsSync(`./data/guilds/${guild.id}/config.json`) ) {
+        fs.rmSync(`./data/guilds/${guild.id}/config.json`);
+    }
+    if( !fs.existsSync(`./data/guilds/${guild.id}/pins.json`) ) {
+        let pins = guild.channels.cache.filter(c => c.type === "GUILD_TEXT").map(
+            c => c.messages.fetchPinned().then(m => m.map(m => m.id))
+        );
+        fs.writeFileSync(`./data/guilds/${guild.id}/pins.json`, JSON.stringify(pins));
+    }
+    if( !fs.existsSync(`./data/guilds/${guild.id}/logs.json`) ) {
+        fs.writeFileSync(`./data/guilds/${guild.id}/logs.json`, JSON.stringify([]));
+    } else if( logs ) {
+        fs.rmSync(`./data/guilds/${guild.id}/logs.json`);
+        fs.writeFileSync(`./data/guilds/${guild.id}/logs.json`, JSON.stringify([]));
+    }
+    fs.writeFileSync(`./data/guilds/${guild.id}/config.json`, JSON.stringify({
+        metadata: {
+            premium: false
+        },
+        logs: {
+            enabled: true,
+            logChannel: guild.systemChannelId,
+            toLog: "8be71",
+            toIgnore: {
+                bots: false,
+                channels: [],
+                members: [],
+                roles: []
+            }
+        },
+        userVerification: {
+            enabled: false,
+            roleID: null,
+            customMessage: null
+        },
+        modmail: {
+            enabled: false,
+            categoryId: null,
+            namingScheme: "rsm-{user}-{discriminator}",
+        },
+        welcome: {
+            enabled: false,
+            channelId: null,
+            message: null,
+            messageType: "embed",
+        },
+        filters: {
+			images: {
+				NSFW: true,
+				size: true
+			},
+			malware: true,
+			wordFilter: {
+				enabled: true,
+				words: {
+					strict: [],
+					loose: []
+				},
+				allowed: {
+					users: [],
+					roles: [],
+					channels: []
+				}
+			},
+			invite: {
+				enabled: true,
+				allowed: {
+					users: [],
+					channels: [],
+					roles: []
+				}
+			},
+			pings: {
+				mass: 5,
+				everyone: true,
+				roles: true,
+				allowed: {
+					roles: [],
+					rolesToMention: [],
+					users: [],
+					channels: []
+				}
+			}
+		},
+        tags: {}
+    }));
+}
+
+export default writeLogConfig;
\ No newline at end of file
diff --git a/src/utils/log.ts b/src/utils/log.ts
new file mode 100644
index 0000000..d807831
--- /dev/null
+++ b/src/utils/log.ts
@@ -0,0 +1,101 @@
+import * as fs from 'fs';
+import * as Discord from 'discord.js';
+import getEmojiByName from './getEmojiByName.js';
+import readConfig from './readConfig.js';
+import { toHexArray } from './calculate.js';
+import { promisify } from 'util';
+import generateKeyValueList from './generateKeyValueList.js';
+
+const wait = promisify(setTimeout);
+
+
+export class Logger {
+	renderUser(user: Discord.User) {
+		return `${user.username} [<@${user.id}>]`;
+	}
+	renderTime(t: number) {
+		t = Math.floor(t /= 1000)
+		return `<t:${t}:D> at <t:${t}:T>`;
+	}
+	renderDelta(t: number) {
+		t = Math.floor(t /= 1000)
+		return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
+	}
+	renderNumberDelta(num1, num2) {
+		let delta = num2 - num1;
+		return `${num1} -> ${num2} (${delta > 0 ? '+' : ''}${delta})`;
+	}
+	entry(value, displayValue) {
+		return { value: value, displayValue: displayValue }
+	}
+	renderChannel(channel: Discord.GuildChannel) {
+		return `${channel.name} [<#${channel.id}>]`;
+	}
+	renderRole(role: Discord.Role) {
+		return `${role.name} [<@&${role.id}>]`;
+	}
+	renderEmoji(emoji: Discord.GuildEmoji) {
+		return `<${emoji.animated ? 'a' : ''}:${emoji.name}:${emoji.id}> [\`:${emoji.name}:\`]`;
+	}
+
+	public readonly NucleusColors = {
+		red: 0xF27878,
+		yellow: 0xF2D478,
+		green: 0x68D49E,
+
+	}
+
+
+	async getAuditLog(guild: Discord.Guild, event) {
+		await wait(250)
+		let auditLog = await guild.fetchAuditLogs({type: event});
+		return auditLog;
+	}
+
+	async log(log: any, client): Promise<void> {
+		let config = await readConfig(log.hidden.guild);
+		if (!config.logging.logs.enabled) return;
+		if (!(log.meta.calculateType == true)) if(!toHexArray(config.logging.logs.toLog).includes(log.meta.calculateType)) return console.log('Not logging this type of event');
+		if (config.logging.logs.channel) {
+			let channel = await client.channels.fetch(config.logging.logs.channel) as Discord.TextChannel;
+			let description = {};
+			Object.entries(log.list).map(entry => {
+				let key = entry[0];
+				let value:any = entry[1];
+				if(value.displayValue) {
+					description[key] = value.displayValue;
+				} else {
+					description[key] = value;
+				}
+			})
+			if (channel) {
+				log.separate = log.separate || {};
+				let embed = new Discord.MessageEmbed()
+					.setTitle(`${getEmojiByName(log.meta.emoji)} ${log.meta.displayName}`)
+					.setDescription(
+						(log.separate.start ? log.separate.start + "\n" : "") +
+						generateKeyValueList(description) +
+						(log.separate.end ? "\n" + log.separate.end : "")
+					)
+					.setTimestamp(log.meta.timestamp)
+					.setColor(log.meta.color);
+				channel.send({embeds: [embed]});
+			}
+		}
+		saveLog(log);
+	}
+}
+
+
+export default {}
+
+async function saveLog(log: any): Promise<void> {
+}
+
+export function readLogs(guild: string) {
+	
+}
+
+export function readSpecificLog(guild: string, id: number) {
+	
+}
diff --git a/src/utils/readConfig.ts b/src/utils/readConfig.ts
new file mode 100644
index 0000000..c53d2cc
--- /dev/null
+++ b/src/utils/readConfig.ts
@@ -0,0 +1,85 @@
+
+export default async function readConfig(guild: string): Promise<any> {
+
+	let config = {
+		filters: {
+			images: {
+				NSFW: true,
+				size: true
+			},
+			malware: true,
+			wordFilter: {
+				enabled: true,
+				words: {
+					strict: [],
+					loose: []
+				},
+				allowed: {
+					users: [],
+					roles: [],
+					channels: []
+				}
+			},
+			invite: {
+				enabled: false,
+				allowed: {
+					users: [],
+					channels: [],
+					roles: []
+				}
+			},
+			pings: {
+				mass: 5,
+				everyone: true,
+				roles: true,
+				allowed: {
+					roles: [],
+					rolesToMention: [],
+					users: [],
+					channels: []
+				}
+			}
+		},
+		welcome: {
+			enabled: true,
+			verificationRequired: {
+				message: false,
+				role: false
+			},
+			welcomeRole: null,
+			channel: '895209752315961344', // null, channel ID or 'dm'
+			message: "Welcome to the server, {@}!"
+		},
+		stats: [
+			{
+				enabled: true,
+				channel: '951910554291818526',
+				text: "{count} members | {count:bots} bots | {count:humans} humans"
+			}
+		],
+		logging: {
+			logs: {
+				enabled: true,
+				channel: '952247098437427260',
+				toLog: "3fffff" // "3ffffe" = - channelUpdate, "3fffff" = all
+			},
+			staff: {}
+		},
+		verify: {
+			enabled: true,
+			channel: '895210691479355392',
+			role: '934941369137524816',
+		},
+		tickets: {
+			enabled: true,
+			category: "952302254302584932",
+			types: "3f",
+			customTypes: null,
+			supportRole: null,
+			maxTickets: 5
+		}
+	};
+
+	return config
+
+}
\ No newline at end of file
diff --git a/src/utils/scanners.ts b/src/utils/scanners.ts
new file mode 100644
index 0000000..97e9bf4
--- /dev/null
+++ b/src/utils/scanners.ts
@@ -0,0 +1,30 @@
+import * as us from 'unscan'
+import fetch from 'node-fetch'
+import { writeFileSync } from 'fs'
+import generateFileName from './temp/generateFileName.js'
+import * as path from 'path'
+import {fileURLToPath} from 'url';
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+export async function testNSFW(link: string): Promise<JSON> {
+	const image = (await (await fetch(link)).buffer()).toString('base64')
+	let fileName = generateFileName(link.split('/').pop().split('.').pop())
+	let p = path.join(__dirname, '/temp', fileName)
+	writeFileSync(p, image, 'base64')
+	let result = await us.nsfw.file(p)
+    return result
+}
+
+export async function testMalware(link: string): Promise<JSON> {
+	const file = (await (await fetch(link)).buffer()).toString('base64')
+	let fileName = generateFileName(link.split('/').pop().split('.').pop())
+	let p = path.join(__dirname, '/temp', fileName)
+	writeFileSync(p, file, 'base64')
+	let result = await us.malware.file(p)
+    return result
+}
+
+export async function testLink(link: string): Promise<JSON> {
+	return await us.link.scan(link)
+}
diff --git a/src/utils/temp/generateFileName.ts b/src/utils/temp/generateFileName.ts
new file mode 100644
index 0000000..98240a1
--- /dev/null
+++ b/src/utils/temp/generateFileName.ts
@@ -0,0 +1,11 @@
+import * as fs from 'fs';
+import * as crypto from 'crypto';
+
+export default function generateFileName(ending: string): string {
+    let fileName = crypto.randomBytes(35).toString('hex');
+    fileName = fileName.replace(/([a-zA-Z0-9]{8})/g, '$1-');
+    if (fs.existsSync(`./${fileName}`)) {
+        fileName = generateFileName(ending);
+    }
+    return fileName + '.' + ending;
+}
\ No newline at end of file